[
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: [jordyamc]\npatreon: animeflvapp\nopen_collective: # Replace with a single Open Collective username\nko_fi: unbarredstream\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncustom: https://paypal.me/jordyamc\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Smartphone (please complete the following information):**\n - Device: [e.g. Google Pixel]\n - Android Version: [e.g. 5.0]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".gitignore",
    "content": "*.iml\n.gradle\nlocal.properties\n.idea/workspace.xml\n.idea/libraries\n.DS_Store\nbuild\ncaptures\n.externalNativeBuild\napp/google-services.json\napp/src/main/java/knf/kuma/commons/EAHelper.java\napp/src/main/res/values/styles_colors.xml\n/*.png\n*.psd\n*.zip\n*.json\n*.pepk\nkeys.keystore\n.idea\n/web/\n/web/public/thumbs/\n/resizer/\n/app/playstore/\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socio-economic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at jordyamc@hotmail.com. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see\nhttps://www.contributor-covenant.org/faq\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 Jordy Alexis Mendoza Caballero\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "![](https://github.com/jordyamc/UKIKU/blob/master/web/img/UKIKU%20Facebook.png)\n\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/4f8228880e0a4d3da8ee1c861801e5bf)](https://app.codacy.com/app/jordyamc/UKIKU?utm_source=github.com&utm_medium=referral&utm_content=jordyamc/UKIKU&utm_campaign=Badge_Grade_Dashboard)\n[![GitHub last commit](https://img.shields.io/github/last-commit/google/skia.svg)](https://github.com/jordyamc/UKIKU/commits/master)\n[![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/jordyamc/UKIKU/blob/master/LICENSE)\n[![GitHub forks](https://img.shields.io/github/forks/jordyamc/UKIKU.svg)](https://github.com/jordyamc/UKIKU/network/members)\n\n## ¿Qué es UKIKU?\n\nEs una app derivada de mi antiguo proyecto [Animeflv App](https://github.com/jordyamc/Animeflv), tiene casi las mismas funciones, pero hecha desde cero para dispositivos con Android 5 o superior, esta pensada para tener mejor rendimiento y optimización, así como menor tamaño de [APK](https://github.com/jordyamc/UKIKU/raw/master/app/release/app-release.apk) (~6MB)\n\n## ¿Por que un proyecto tan grande no tiene mucha publicidad y es código abierto?\n\nSoy un programador por hobby, no tengo experiencia profesional en la programación, pero aun así decidí aprender por mi cuenta, mis proyectos están hechos con el propósito de aprender a programar en el camino, aun con todo ese tiempo invertido quise que mis apps sean hechas por un fan para fans de anime, me gusta que la comunidad se apoye entre si, así que decidí que los propios usuarios elijan como y cuando apoyar a la app, pero aun así las donaciones son muy bien recibidas ;)\n\n## ¿Como puedo modificar este proyecto?\n\nEn la [wiki](https://github.com/jordyamc/UKIKU/wiki) de éste repositorio encontrarás los pasos para hacerlo!"
  },
  {
    "path": "app/.gitattributes",
    "content": "* -crlf"
  },
  {
    "path": "app/.gitignore",
    "content": "build\napp/src/main/java/knf/kuma/commons/EAHelper.java\napp/src/main/res/values/styles_colors.xml\nrelease/baselineProfiles\ntv/baselineProfiles"
  },
  {
    "path": "app/build.gradle",
    "content": "apply plugin: 'com.android.application'\napply plugin: 'kotlin-android'\napply plugin: 'kotlin-kapt'\napply plugin: 'com.google.gms.google-services'\napply plugin: 'com.google.firebase.crashlytics'\n\ndef localProperties = new Properties()\nlocalProperties.load(new FileInputStream(rootProject.file(\"local.properties\")))\n\nandroid {\n    compileSdk 36\n    defaultConfig {\n        applicationId \"knf.kuma\"\n        minSdkVersion 24\n        targetSdkVersion 36\n        versionCode 228\n        versionName \"5.3.18\"\n        multiDexEnabled true\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        javaCompileOptions {\n            annotationProcessorOptions {\n                arguments = [\"room.schemaLocation\": \"$projectDir/schemas\".toString()]\n            }\n        }\n    }\n    buildTypes {\n        debug {\n            manifestPlaceholders.admobID = localProperties['UKIKU_ADMOB_ID'] ?: \"\"\n            buildConfigField \"String\", \"IAB_KEY\", localProperties['APPCOINS_IAB_KEY'] ?: \"\"\n            buildConfigField \"String\", \"IAB_UPDATE_ACTION\", localProperties['APPCOINS_IAB_UPDATE_ACTION'] ?: \"\"\n            buildConfigField \"String\", \"IAB_BIND_ACTION\", localProperties['APPCOINS_DEV_IAB_BIND_ACTION'] ?: \"\"\n            buildConfigField \"String\", \"IAB_BIND_PACKAGE\", localProperties['APPCOINS_DEV_IAB_BIND_PACKAGE'] ?: \"\"\n            buildConfigField \"String\", \"APPCOINS_ADDRESS\", localProperties['APPCOINS_ADDRESS'] ?: \"\"\n            buildConfigField \"String\", \"DROPBOX_TOKEN\", localProperties['DROPBOX_TOKEN'] ?: \"\"\n            buildConfigField \"String\", \"EASTER_SEARCH\", localProperties['EASTER_SEARCH'] ?: \"\"\n            buildConfigField \"String\", \"CIPHER_PWD_12\", localProperties['UKIKU_PWD_12'] ?: \"\"\n            buildConfigField \"String\", \"CIPHER_PWD_16\", localProperties['UKIKU_PWD_16'] ?: \"\"\n            buildConfigField \"String\", \"CIPHER_PWD_32\", localProperties['UKIKU_PWD_32'] ?: \"\"\n            buildConfigField \"String\", \"ADM_FILE\", localProperties['UKIKU_ADM_FILE'] ?: \"\"\n            buildConfigField \"String\", \"APPODEAL_KEY\", localProperties['UKIKU_APPODEAL_KEY'] ?: \"\"\n            resValue \"string\", \"twitter_consumer_key\", localProperties['UKIKU_TWITTER_API_KEY'] ?: \"\"\n            resValue \"string\", \"twitter_consumer_secret\", localProperties['UKIKU_TWITTER_API_SECRET'] ?: \"\"\n        }\n        release {\n            minifyEnabled true\n            shrinkResources true\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', 'proguard-android.txt'\n            manifestPlaceholders.admobID = localProperties['UKIKU_ADMOB_ID'] ?: \"\"\n            buildConfigField \"String\", \"IAB_KEY\", localProperties['APPCOINS_IAB_KEY'] ?: \"\"\n            buildConfigField \"String\", \"IAB_UPDATE_ACTION\", localProperties['APPCOINS_IAB_UPDATE_ACTION'] ?: \"\"\n            buildConfigField \"String\", \"IAB_BIND_ACTION\", localProperties['APPCOINS_DEV_IAB_BIND_ACTION'] ?: \"\"\n            buildConfigField \"String\", \"IAB_BIND_PACKAGE\", localProperties['APPCOINS_DEV_IAB_BIND_PACKAGE'] ?: \"\"\n            buildConfigField \"String\", \"APPCOINS_ADDRESS\", localProperties['APPCOINS_ADDRESS'] ?: \"\"\n            buildConfigField \"String\", \"DROPBOX_TOKEN\", localProperties['DROPBOX_TOKEN'] ?: \"\"\n            buildConfigField \"String\", \"EASTER_SEARCH\", localProperties['EASTER_SEARCH'] ?: \"\"\n            buildConfigField \"String\", \"CIPHER_PWD_12\", localProperties['UKIKU_PWD_12'] ?: \"\"\n            buildConfigField \"String\", \"CIPHER_PWD_16\", localProperties['UKIKU_PWD_16'] ?: \"\"\n            buildConfigField \"String\", \"CIPHER_PWD_32\", localProperties['UKIKU_PWD_32'] ?: \"\"\n            buildConfigField \"String\", \"ADM_FILE\", localProperties['UKIKU_ADM_FILE'] ?: \"\"\n            buildConfigField \"String\", \"APPODEAL_KEY\", localProperties['UKIKU_APPODEAL_KEY'] ?: \"\"\n            resValue \"string\", \"twitter_consumer_key\", localProperties['UKIKU_TWITTER_API_KEY'] ?: \"\"\n            resValue \"string\", \"twitter_consumer_secret\", localProperties['UKIKU_TWITTER_API_SECRET'] ?: \"\"\n        }\n        tv {\n            initWith release\n            applicationIdSuffix \".tv\"\n        }\n        playstore {\n            initWith release\n        }\n        amazon {\n            initWith release\n        }\n    }\n    sourceSets {\n        androidTest.assets.srcDirs += files(\"$projectDir/schemas\".toString())\n    }\n    buildFeatures {\n        viewBinding = true\n    }\n    compileOptions {\n        sourceCompatibility = '17'\n        targetCompatibility = '17'\n    }\n    kotlinOptions {\n        jvmTarget = '17'\n    }\n    packagingOptions {\n        resources {\n            excludes += ['AndroidManifest.xml']\n            excludes += ['META-INF/versions/9/OSGI-INF/MANIFEST.MF']\n        }\n    }\n    namespace 'knf.kuma'\n}\n\nconfigurations.all {\n    resolutionStrategy { \n        force 'org.jsoup:jsoup:1.10.3'\n        //force 'androidx.core:core-ktx:1.6.0'\n    }\n}\n\nallprojects {\n    repositories {\n        mavenLocal()\n        google()\n        mavenCentral()\n        //jcenter()\n        maven { url \"https://jitpack.io\" }\n        maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }\n        maven { url \"https://s3.amazonaws.com/repo.commonsware.com\" }\n        maven { url \"https://dl.bintray.com/drummer-aidan/maven/\" }\n        maven { url \"https://dl.bintray.com/blockchainds/bds\" }\n        maven { url \"https://dl.bintray.com/asf/asf\" }\n    }\n}\n\ndependencies {\n    //implementation project(path:':multidisplaycast', configuration:'default')\n    implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')\n    implementation 'com.github.jordyamc:Multi-Display-Cast:2.20'\n    implementation 'com.github.jordyamc:PersistentSearchView:1.0.10'\n    implementation 'com.github.jordyamc:UAGenerator:1.2.2'\n    implementation 'com.github.jordyamc:AndroidVideoCache:2.7.6'\n    implementation 'com.github.jordyamc:Cloudflare-Bypasser:1.0.26'\n    implementation 'androidx.appcompat:appcompat:1.7.1'\n    implementation 'androidx.preference:preference-ktx:1.2.1'\n    implementation 'androidx.constraintlayout:constraintlayout:2.2.1'\n    implementation 'androidx.legacy:legacy-support-v4:1.0.0'\n    implementation 'androidx.browser:browser:1.5.0' //Keep\n    implementation 'androidx.lifecycle:lifecycle-common-java8:2.10.0'\n    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.10.0'\n    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0'\n    implementation 'androidx.activity:activity-ktx:1.7.2' //Keep\n    implementation 'androidx.fragment:fragment-ktx:1.8.9'\n    implementation 'androidx.startup:startup-runtime:1.2.0'\n    implementation 'com.google.android.material:material:1.13.0'\n    implementation 'androidx.vectordrawable:vectordrawable-animated:1.2.0'\n    implementation 'androidx.cardview:cardview:1.0.0'\n    implementation 'androidx.mediarouter:mediarouter:1.4.0' //Keep\n    implementation 'androidx.recyclerview:recyclerview:1.4.0'\n    implementation 'androidx.leanback:leanback:1.2.0'\n    implementation 'androidx.tvprovider:tvprovider:1.1.0'\n    implementation 'androidx.palette:palette-ktx:1.0.0'\n    implementation 'com.google.android.gms:play-services-cast:22.2.0'\n    implementation platform('com.google.firebase:firebase-bom:34.7.0')\n    implementation 'com.google.firebase:firebase-firestore'\n    implementation 'com.google.firebase:firebase-auth'\n    implementation 'com.google.firebase:firebase-config'\n    implementation 'com.google.firebase:firebase-crashlytics'\n    implementation 'com.google.android.gms:play-services-auth:20.5.0' //Keep\n    //implementation 'com.google.ads.mediation:adcolony:4.4.1.0'\n    implementation 'com.firebaseui:firebase-ui-auth:9.1.1'\n    implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'\n    implementation 'io.reactivex.rxjava3:rxjava:3.1.12'\n    implementation 'com.google.android.gms:play-services-maps:19.2.0'\n    api 'com.google.guava:guava:33.5.0-android'\n    implementation 'androidx.annotation:annotation:1.9.1'\n    implementation 'androidx.slice:slice-builders-ktx:1.0.0-alpha08'\n    implementation 'androidx.slice:slice-builders:1.0.0'\n    implementation 'androidx.work:work-runtime-ktx:2.11.0'\n    implementation 'androidx.room:room-runtime:2.8.4'\n    implementation 'androidx.room:room-ktx:2.8.4'\n    kapt 'androidx.room:room-compiler:2.8.4'\n    androidTestImplementation 'androidx.room:room-testing:2.8.4'\n    implementation 'com.google.dagger:dagger-android-support:2.57.2'\n    kapt 'com.google.dagger:dagger-android-processor:2.57.2'\n    implementation 'androidx.paging:paging-runtime-ktx:3.3.6'\n    implementation 'pl.droidsonroids:jspoon:1.3.3'\n    implementation 'pl.droidsonroids.retrofit2:converter-jspoon:1.3.2'\n    implementation 'org.jsoup:jsoup:1.13.1' //Keep\n    implementation 'com.squareup.retrofit2:adapter-rxjava2:3.0.0'\n    implementation 'com.squareup.picasso:picasso:2.8'\n    implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.1.0'\n    implementation 'com.squareup.okhttp3:okhttp:5.3.2'\n    implementation 'com.squareup.okhttp3:okhttp-dnsoverhttps:5.3.2'\n    implementation 'com.github.jordyamc:ChipsLayoutManager:0.5.3'\n    implementation 'com.google.code.gson:gson:2.13.2'\n    implementation 'me.zhanghai.android.materialratingbar:library:1.4.0'\n    implementation 'at.blogc:expandabletextview:1.0.5'\n    implementation 'com.google.android.exoplayer:exoplayer:2.19.1'\n    implementation 'com.google.android.exoplayer:exoplayer-hls:2.19.1'\n    implementation 'com.google.android.exoplayer:extension-mediasession:2.19.1'\n    implementation 'com.google.android.exoplayer:extension-okhttp:2.19.1'\n    //MaterialDialogs\n    implementation 'com.afollestad.material-dialogs:core:3.3.0'\n    implementation 'com.afollestad.material-dialogs:lifecycle:3.3.0'\n    implementation 'com.afollestad.material-dialogs:input:3.3.0'\n    implementation 'com.afollestad.material-dialogs:bottomsheets:3.3.0'\n    //---------\n    implementation 'org.apache.commons:commons-text:1.15.0'\n    implementation 'com.shamanland:xdroid-toaster:0.3.0'\n    implementation 'com.github.MFlisar:DragSelectRecyclerView:0.3'\n    implementation 'com.github.StephenVinouze:MaterialNumberPicker:1.1.0'\n    implementation 'biz.kasual:materialnumberpicker:1.2.1'\n    implementation 'org.nanohttpd:nanohttpd:2.3.1'\n    implementation 'com.dropbox.core:dropbox-core-sdk:7.0.0'\n    implementation 'com.dropbox.core:dropbox-android-sdk:7.0.0'\n    implementation 'com.github.daniel-stoneuk:material-about-library:3.2.0-rc01'\n    implementation 'io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:1.2.0'\n    implementation 'nl.dionsegijn:konfetti:1.3.2'\n    implementation 'me.zhanghai.android.materialprogressbar:library:1.6.1'\n    implementation \"com.github.tonyofrancis.Fetch:fetch2:3.4.1\"\n    implementation \"com.github.tonyofrancis.Fetch:fetch2:3.4.1\"\n    implementation \"com.github.tonyofrancis.Fetch:fetch2rx:3.4.1\"\n    implementation \"com.github.tonyofrancis.Fetch:fetch2okhttp:3.4.1\"\n    implementation 'q.rorbin:badgeview:1.1.3'\n    implementation 'com.jaredrummler:android-device-names:2.1.1'\n    implementation 'com.simplecityapps:recyclerview-fastscroll:2.0.1'\n    implementation 'com.mikhaellopez:circularprogressbar:2.0.0'\n    implementation 'moe.feng:MaterialStepperView:0.2.4.2'\n    implementation 'com.github.bumptech.glide:glide:4.16.0'\n    implementation 'com.github.jordyamc:kprobability:1.0.5'\n    implementation 'org.nield:kotlin-statistics:1.2.1'\n    implementation 'com.github.Jamshid-M:ExactRatingBar:1.0.0'\n    implementation 'com.github.jordyamc:CloudflareBypassWebview:1.0.4'\n    implementation 'com.github.jordyamc:apk-signatures:1.0.3'\n    implementation 'com.github.sephiroth74:android-target-tooltip:2.0.4'\n    implementation 'com.github.jordyamc.oasis-jsbridge-android:oasis-jsbridge-duktape:1.0.2'\n    kapt 'com.github.bumptech.glide:compiler:4.16.0'\n    implementation 'com.tbuonomo.andrui:viewpagerdotsindicator:4.1.2'\n    implementation 'fr.bmartel:jspeedtest:1.32.1'\n    implementation 'com.mani:ThinDownloadManager:1.4.0'\n    implementation 'com.github.simbiose:Encryption:1.4.0'\n    implementation 'com.github.marlonlom:timeago:4.1.0'\n    implementation 'com.scottyab:secure-preferences-lib:0.1.7'\n    implementation 'com.github.florent37:expansionpanel:1.2.2'\n    implementation 'com.github.evgenyneu:js-evaluator-for-android:v5.0.0'\n    implementation 'com.github.vkay94:DoubleTapPlayerView:1.0.4'\n    implementation 'org.conscrypt:conscrypt-android:2.5.3'\n    testImplementation 'junit:junit:4.13.2'\n    //Kotlin\n    implementation 'org.jetbrains.kotlin:kotlin-stdlib:2.1.21'\n    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.1.0'\n    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2'\n    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2'\n    implementation 'org.jetbrains.anko:anko:0.10.8'\n    implementation 'org.jetbrains.anko:anko-coroutines:0.10.8'\n    //------\n    //Moon\n    //implementation 'io.github.darkryh.moongetter:moongetter-core:2.0.0-alpha02'\n    //implementation 'io.github.darkryh.moongetter:moongetter-client-okhttp:2.0.0-alpha02'\n    //implementation 'io.github.darkryh.moongetter:moongetter-client-cookie-java-net:2.0.0-alpha02'\n    //implementation 'io.github.darkryh.moongetter:moongetter-client-trustmanager-java-net:2.0.0-alpha02'\n    //implementation 'io.github.darkryh.moongetter:moongetter-android-robot:2.0.0-alpha02'\n    //\n    //Applovin\n    implementation 'com.applovin:applovin-sdk:+'\n    implementation 'com.applovin.mediation:inmobi-adapter:+'\n    implementation 'com.google.android.ump:user-messaging-platform:3.1.0'\n    //-------\n    androidTestImplementation 'androidx.test:runner:1.5.2'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'\n    androidTestImplementation 'androidx.work:work-testing:2.8.1'\n    //debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'\n}\n"
  },
  {
    "path": "app/fabric.properties",
    "content": "#Contains API Secret used to validate your application. Commit to internal source control; avoid making secret public.\n#Sun Jan 07 11:02:25 CST 2018\napiSecret=88ba4d6880340c6e16c2690f626c60dcedff2e3a38650f2a8fb206f22f3e62d8\n"
  },
  {
    "path": "app/proguard-android.txt",
    "content": "# This is a configuration file for ProGuard.\n# http://proguard.sourceforge.net/index.html#manual/usage.html\n#\n# This file is no longer maintained and is not used by new (2.2+) versions of the\n# Android plugin for Gradle. Instead, the Android plugin for Gradle generates the\n# default rules at build time and stores them in the build directory.\n\n-dontusemixedcaseclassnames\n-dontskipnonpubliclibraryclasses\n-verbose\n\n# Optimization is turned off by default. Dex does not like code run\n# through the ProGuard optimize and preverify steps (and performs some\n# of these optimizations on its own).\n-dontoptimize\n-dontpreverify\n# Note that if you want to enable optimization, you cannot just\n# include optimization flags in your own project configuration file;\n# instead you will need to point to the\n# \"proguard-android-optimize.txt\" file instead of this one from your\n# project.properties file.\n\n-keepattributes *Annotation*\n-keep public class com.google.vending.licensing.ILicensingService\n-keep public class com.android.vending.licensing.ILicensingService\n\n# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native\n-keepclasseswithmembernames class * {\n    native <methods>;\n}\n\n# keep setters in Views so that animations can still work.\n# see http://proguard.sourceforge.net/manual/examples.html#beans\n-keepclassmembers public class * extends android.view.View {\n   void set*(***);\n   *** get*();\n}\n\n# We want to keep methods in Activity that could be used in the XML attribute onClick\n-keepclassmembers class * extends android.app.Activity {\n   public void *(android.view.View);\n}\n\n# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations\n-keepclassmembers enum * {\n    public static **[] values();\n    public static ** valueOf(java.lang.String);\n}\n\n-keepclassmembers class * implements android.os.Parcelable {\n  public static final android.os.Parcelable$Creator CREATOR;\n}\n\n-keepclassmembers class **.R$* {\n    public static <fields>;\n}\n\n# The support library contains references to newer platform versions.\n# Don't warn about those in case this app is linking against an older\n# platform version.  We know about them, and they are safe.\n-dontwarn android.support.**\n\n# Understand the @Keep support annotation.\n-keep class android.support.annotation.Keep\n\n-keep @android.support.annotation.Keep class * {*;}\n\n-keepclasseswithmembers class * {\n    @android.support.annotation.Keep <methods>;\n}\n\n-keepclasseswithmembers class * {\n    @android.support.annotation.Keep <fields>;\n}\n\n-keepclasseswithmembers class * {\n    @android.support.annotation.Keep <init>(...);\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\n\n-keepattributes *Annotation*\n-keepattributes SourceFile,LineNumberTable\n-keep public class * extends java.lang.Exception\n-keep @interface kotlin.coroutines.jvm.internal.DebugMetadata { *; }\n\n-keep class **$$TypeAdapter { *; }\n-keep class knf.kuma.pojos.AnimeObject.WebInfo.AnimeChapter {*;}\n-keep class knf.kuma.pojos.AnimeObject.WebInfo.AnimeRelated {*;}\n-keep class androidx.startup.InitializationProvider {*;}\n\n-keepclasseswithmembernames class * {\n    @com.tickaroo.tikxml.* <fields>;\n}\n\n-keepclasseswithmembernames class * {\n    @com.tickaroo.tikxml.* <methods>;\n}\n\n-keepclassmembers enum * {\n    public static **[] values();\n    public static ** valueOf(java.lang.String);\n}\n\n-dontwarn retrofit2.**\n-keep class retrofit2.** { *; }\n-keepclassmembers class * implements pl.droidsonroids.jspoon.ElementConverter\n-keep class pl.droidsonroids.jspoon.** { *; }\n-keepattributes Signature\n-keepattributes Exceptions\n\n-keepclasseswithmembers class * {\n    @retrofit2.http.* <methods>;\n}\n-keep class okhttp3.** { *; }\n-keep interface okhttp3.** { *; }\n-dontwarn okhttp3.**\n\n-dontwarn knf.kuma.**\n-dontwarn kotlinx.coroutines.**\n-keep public enum knf.kuma.**{*;}\n-keep class es.munix.multidisplaycast.**{*;}\n-keep class com.connectsdk.**{* ;}\n-keepclassmembers public class * implements pl.droidsonroids.jspoon.ElementConverter {\n   public <init>(...);\n}\n-keepclassmembernames class kotlinx.** {\n    volatile <fields>;\n}\n-keep public class * extends java.lang.Exception\n-keep class org.jsoup.**{*;}\n-keep class com.google.gson.reflect.TypeToken\n-keep class * extends com.google.gson.reflect.TypeToken\n-keep public class * implements java.lang.reflect.Type\n-keeppackagenames org.jsoup.nodes\n-dontwarn com.amazon.client.metrics.**\n-dontwarn com.beloo.widget.chipslayoutmanager.**\n-dontwarn com.squareup.okhttp.**\n-dontwarn dagger.android.**\n-dontwarn dagger.android.support.**\n-dontwarn okhttp3.**\n-dontwarn okhttp3.internal.**\n-dontwarn okio.**\n-dontwarn retrofit2.**\n-dontwarn com.dropbox.core.**\n-dontwarn io.branch.**\n-dontwarn com.bumptech.glide.**\n-dontwarn com.smaato.soma.SomaUnityPlugin*\n-dontwarn com.millennialmedia**\n-dontwarn com.facebook.**\n-dontwarn com.google.common.**\n-dontwarn com.google.android.**\n-dontwarn com.google.firebase.**\n-dontwarn org.jetbrains.anko.db.**\n-dontwarn com.afollestad.materialdialogs.**\n-dontwarn com.amazon.**\n-dontwarn xdroid.toaster.**\n-dontwarn com.pavelsikun.seekbarpreference.**\n-dontwarn com.jakewharton.picasso.**\n-dontwarn io.grpc.**\n-dontwarn kotlin.internal.**\n-dontwarn at.blogc.android.**\n-dontwarn com.afollestad.**\n-dontwarn com.connectsdk.**\n-dontwarn com.danielstone.materialaboutlibrary.**\n-dontwarn com.github.rubensousa.previewseekbar.**\n-dontwarn com.mikhaellopez.circularprogressbar.**\n-dontwarn com.simplecityapps.**\n-dontwarn com.tbuonomo.viewpagerdotsindicator.**\n-dontwarn es.munix.multidisplaycast.**\n-dontwarn fr.bmartel.speedtest.**\n-dontwarn me.zhanghai.android.**\n-dontwarn moe.feng.common.**\n-dontwarn com.github.stephenvinouze.materialnumberpickercore.**\n-dontwarn org.cryse.widget.persistentsearch.**\n-dontwarn pl.droidsonroids.jspoon.**\n-dontwarn org.jetbrains.anko.**\n-dontwarn nl.dionsegijn.konfetti.**\n-dontwarn kotlinx.android.**\n-dontwarn kotlin.**\n-dontwarn io.opencensus.**\n-dontwarn dagger.**\n-dontwarn com.tonyodev.**\n-dontwarn ir.mahdiparastesh.chlm.Orientation"
  },
  {
    "path": "app/src/amazon/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-feature\n        android:name=\"android.software.leanback\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.touchscreen\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.microphone\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.faketouch\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.telephony\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.camera\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.nfc\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.location.gps\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.location\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.sensor\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.wifi\"\n        android:required=\"false\" />\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.CHANGE_WIFI_MULTICAST_STATE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\" />\n    <uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\" />\n\n    <application\n        android:name=\".App\"\n        android:allowBackup=\"true\"\n        android:fullBackupContent=\"@xml/backup_descriptor\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:resizeableActivity=\"true\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:theme=\"@style/AppTheme.DayNight\"\n        android:usesCleartextTraffic=\"true\"\n        tools:replace=\"android:fullBackupContent\">\n\n        <meta-data\n            android:name=\"com.google.android.geo.API_KEY\"\n            android:value=\"@string/google_maps_key\" />\n        <meta-data\n            android:name=\"com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME\"\n            android:value=\"knf.kuma.cast.CastOptionsProvider\" />\n\n\n        <activity\n            android:name=\".commons.EAMapActivity\"\n            android:label=\"@string/title_activity_eamap\" />\n        <activity\n            android:name=\".SplashActivity\"\n            android:label=\"@string/title_activity_main\"\n            android:theme=\"@style/AppTheme.Splash\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"http\" />\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n            <intent-filter>\n                <data\n                    android:host=\"open\"\n                    android:scheme=\"ukiku\" />\n\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n            </intent-filter>\n\n            <meta-data\n                android:name=\"android.app.shortcuts\"\n                android:resource=\"@xml/shortcuts\" />\n        </activity>\n        <activity\n            android:name=\".Main\"\n            android:label=\"@string/title_activity_main\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/search\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".animeinfo.ActivityAnime\"\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            android:windowSoftInputMode=\"stateHidden\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/anime/\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".player.CustomExoPlayer\"\n            android:configChanges=\"screenSize|smallestScreenSize|screenLayout|orientation\"\n            android:immersive=\"true\"\n            android:launchMode=\"singleTask\"\n            android:resizeableActivity=\"true\"\n            android:supportsPictureInPicture=\"true\">\n            <intent-filter android:label=\"UKIKU\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"http\" />\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".player.VideoActivity\"\n            android:configChanges=\"screenSize|smallestScreenSize|screenLayout|orientation\"\n            android:immersive=\"true\"\n            android:launchMode=\"singleTask\"\n            android:resizeableActivity=\"true\"\n            android:supportsPictureInPicture=\"true\">\n            <intent-filter android:label=\"UKIKU experimental\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"http\" />\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".animeinfo.img.ActivityImgFull\"\n            android:theme=\"@style/AppTheme.FullScreen\" />\n        <activity android:name=\".record.RecordActivity\" />\n        <activity android:name=\".seeing.SeeingActivity\" />\n        <activity android:name=\".emision.EmissionActivity\" />\n        <activity android:name=\".explorer.ExplorerActivity\" />\n        <activity\n            android:name=\".updater.UpdateActivity\"\n            android:excludeFromRecents=\"true\"\n            android:exported=\"true\" />\n        <activity android:name=\".random.RandomActivity\" />\n        <activity android:name=\".changelog.ChangelogActivity\" />\n        <activity\n            android:name=\".backup.BackUpActivity\"\n            android:theme=\"@style/AppTheme.Translucent\" />\n        <activity\n            android:name=\"com.dropbox.core.android.AuthActivity\"\n            android:configChanges=\"orientation|keyboard\"\n            android:launchMode=\"singleTask\">\n            <intent-filter>\n                <data android:scheme=\"db-qtjow4hsk06vt19\" />\n\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".backup.MigrationActivity\"\n            android:theme=\"@style/AppTheme.Translucent\" />\n        <activity android:name=\".recommended.RecommendActivity\" />\n        <activity android:name=\".recommended.RankingActivity\" />\n        <activity android:name=\".search.GenreActivity\" />\n\n        <service android:name=\".directory.DirectoryService\" />\n        <service android:name=\".directory.DirectoryUpdateService\" />\n        <service android:name=\".download.DownloadService\" />\n        <service\n            android:name=\".widgets.emision.WEmissionService\"\n            android:permission=\"android.permission.BIND_REMOTEVIEWS\" />\n        <service android:name=\".download.DownloadManager\" />\n        <service android:name=\".commons.SelfServer\" />\n\n        <receiver\n            android:name=\".widgets.emision.WEmisionProvider\"\n            android:label=\"Emisión\">\n            <intent-filter>\n                <action android:name=\"android.appwidget.action.APPWIDGET_UPDATE\" />\n            </intent-filter>\n\n            <meta-data\n                android:name=\"android.appwidget.provider\"\n                android:resource=\"@xml/widget_emision\" />\n        </receiver>\n        <receiver android:name=\".download.DownloadReceiver\" />\n        <receiver android:name=\".recents.RecentsNotReceiver\" />\n\n        <provider\n            android:name=\"androidx.core.content.FileProvider\"\n            android:authorities=\"${applicationId}.fileprovider\"\n            android:exported=\"false\"\n            android:grantUriPermissions=\"true\">\n            <meta-data\n                android:name=\"android.support.FILE_PROVIDER_PATHS\"\n                android:resource=\"@xml/path_providers\" />\n        </provider>\n\n        <meta-data\n            android:name=\"io.fabric.ApiKey\"\n            android:value=\"8971b3733a2fd699ebd101e18ce228d80baeab92\" />\n        <meta-data\n            android:name=\"com.google.android.gms.ads.APPLICATION_ID\"\n            android:value=\"${admobID}\" />\n        <meta-data\n            android:name=\"com.google.android.gms.ads.AD_MANAGER_APP\"\n            android:value=\"true\" />\n\n        <activity android:name=\".queue.QueueActivity\" />\n        <activity\n            android:name=\".download.DownloadDialogActivity\"\n            android:excludeFromRecents=\"true\"\n            android:theme=\"@style/Theme.AppCompat.DayNight.Dialog\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/ver/\"\n                    android:scheme=\"https\" />\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/ver/\"\n                    android:scheme=\"http\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".custom.ThemedControlsActivity\" />\n        <activity android:name=\".news.NewsActivity\" />\n        <activity android:name=\".achievements.AchievementActivity\" />\n        <activity android:name=\".commons.EAUnlockActivity\" />\n        <activity\n            android:name=\"es.munix.multidisplaycast.CastControlsActivity\"\n            android:screenOrientation=\"sensor\"\n            tools:node=\"merge\"\n            tools:replace=\"android:screenOrientation\" />\n        <activity android:name=\".Diagnostic\" />\n        <activity android:name=\".recents.RecentsActivity\" />\n        <activity android:name=\".Diagnostic$FullBypass\" />\n\n        <uses-library\n            android:name=\"org.apache.http.legacy\"\n            android:required=\"false\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/amazon/res/drawable/ic_launcher_foregound.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"4045.2056\"\n    android:viewportHeight=\"4045.2056\">\n    <group\n        android:translateX=\"546.1027\"\n        android:translateY=\"546.1027\">\n        <path\n            android:name=\"UKIKU\"\n            android:fillColor=\"#fff\"\n            android:pathData=\"m395.4 1256.4v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.2 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3zm533.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm164 0v440.5h79.9v-440.5zm173.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm154.5 0v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.3 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3z\" />\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/amazon/res/drawable/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"4596.8247\"\n    android:viewportHeight=\"4596.8247\">\n    <group\n        android:translateX=\"275.80948\"\n        android:translateY=\"275.80948\">\n        <group\n            android:translateX=\"546.1027\"\n            android:translateY=\"546.1027\">\n            <path\n                android:name=\"UKIKU\"\n                android:fillColor=\"#fff\"\n                android:pathData=\"m395.4 1256.4v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.2 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3zm533.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm164 0v440.5h79.9v-440.5zm173.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm154.5 0v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.3 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3z\" />\n        </group>\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/amazon/res/menu/activity_main_drawer_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu 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    tools:showIn=\"navigation_view\">\n    <item\n        android:id=\"@+id/drawer_explorer\"\n        android:icon=\"@drawable/ic_files\"\n        android:title=\"Explorador\"\n        android:visible=\"false\" />\n    <item\n        android:id=\"@+id/drawer_emision\"\n        android:icon=\"@drawable/ic_emision\"\n        android:title=\"Emisión\"\n        app:actionViewClass=\"android.widget.TextView\" />\n    <item\n        android:id=\"@+id/drawer_seeing\"\n        android:icon=\"@drawable/ic_seeing_drawer\"\n        android:title=\"Siguiendo\"\n        app:actionViewClass=\"android.widget.TextView\" />\n    <item\n        android:id=\"@+id/drawer_queue\"\n        android:icon=\"@drawable/ic_clock\"\n        android:title=\"Pendientes\"\n        android:visible=\"false\"\n        app:actionViewClass=\"android.widget.TextView\" />\n    <item\n        android:id=\"@+id/drawer_suggestions\"\n        android:icon=\"@drawable/ic_suggestions\"\n        android:title=\"Sugerencias\" />\n    <item\n        android:id=\"@+id/drawer_news\"\n        android:icon=\"@drawable/ic_news\"\n        android:title=\"Noticias\" />\n    <item\n        android:id=\"@+id/drawer_records\"\n        android:icon=\"@drawable/ic_record\"\n        android:title=\"Historial\"\n        android:visible=\"false\" />\n    <item\n        android:id=\"@+id/drawer_random\"\n        android:icon=\"@drawable/ic_random\"\n        android:title=\"Random\" />\n    <item\n        android:id=\"@+id/drawer_faq\"\n        android:icon=\"@drawable/ic_faq\"\n        android:title=\"FAQ\" />\n</menu>\n"
  },
  {
    "path": "app/src/amazon/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <background android:drawable=\"@color/ic_launcher_background\" />\r\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\r\n</adaptive-icon>"
  },
  {
    "path": "app/src/amazon/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <background android:drawable=\"@color/ic_launcher_background\" />\r\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\r\n</adaptive-icon>"
  },
  {
    "path": "app/src/amazon/res/values/bool.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <bool name=\"isLandscape\">false</bool>\r\n    <bool name=\"isDark\">false</bool>\r\n    <bool name=\"isNotDark\">true</bool>\r\n    <bool name=\"isTv\">false</bool>\r\n    <bool name=\"isTablet\">false</bool>\r\n    <string name=\"layType\">0</string>\r\n    <bool name=\"showUncensored\">false</bool>\r\n</resources>"
  },
  {
    "path": "app/src/amazon/res/values/google_maps_api.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <string name=\"google_maps_key\" templateMergeStrategy=\"preserve\" translatable=\"false\">AIzaSyD2QS_E66qKxXmJhlXW8eRT7OYNdHphWUY</string>\r\n</resources>"
  },
  {
    "path": "app/src/amazon/res/values/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <color name=\"ic_launcher_background\">#000000</color>\r\n</resources>"
  },
  {
    "path": "app/src/amazon/res/xml/preferences.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<PreferenceScreen xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <PreferenceCategory android:title=\"Actualizaciones\">\n\n        <ListPreference\n            android:defaultValue=\"1\"\n            android:entries=\"@array/recents_options\"\n            android:entryValues=\"@array/recents_values\"\n            android:icon=\"@drawable/ic_recents\"\n            android:key=\"recents_time\"\n            android:summary=\"%s\"\n            android:title=\"Revisar recientes\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_group\"\n            android:key=\"group_notifications\"\n            android:title=\"Agrupar notificaciones\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_heart\"\n            android:key=\"notify_favs\"\n            android:summaryOff=\"Se notificaran todos los capitulos\"\n            android:summaryOn=\"Se notificaran capitulos solo si estan en favoritos\"\n            android:title=\"Solo favoritos\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_img\"\n            android:key=\"recent_image\"\n            android:summary=\"Episodios recientes\"\n            android:title=\"Portada en notificación\" />\n        <ListPreference\n            android:defaultValue=\"7\"\n            android:entries=\"@array/dir_options\"\n            android:entryValues=\"@array/dir_values\"\n            android:icon=\"@drawable/ic_directory\"\n            android:key=\"dir_update_time\"\n            android:summary=\"%s\"\n            android:title=\"Recrear directorio\" />\n        <Preference\n            android:icon=\"@drawable/ic_note\"\n            android:key=\"custom_tone\"\n            android:summary=\"Sistema\"\n            android:title=\"Tono de notificación\" />\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:enabled=\"false\"\n            android:entries=\"@array/autobackup\"\n            android:entryValues=\"@array/autobackup_values\"\n            android:icon=\"@drawable/ic_cloud_upload\"\n            android:key=\"auto_backup\"\n            android:summary=\"%s\"\n            android:title=\"Auto respaldo\" />\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:key=\"storage_group\"\n        android:title=\"Almacenamiento\"\n        app:isPreferenceVisible=\"false\">\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/storage_type\"\n            android:entryValues=\"@array/storage_values\"\n            android:icon=\"@drawable/ic_download\"\n            android:key=\"download_type\"\n            android:summary=\"%s\"\n            android:title=\"Descargas\" />\n        <Preference\n            android:icon=\"@drawable/ic_download\"\n            android:key=\"download_type_q\"\n            android:title=\"Descargas\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_hide_pref\"\n            android:key=\"hide_chaps\"\n            android:title=\"Ocultar de galeria\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_import\"\n            android:key=\"show_import\"\n            android:title=\"Importar archivos\" />\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/savetype\"\n            android:entryValues=\"@array/savetype_values\"\n            android:icon=\"@drawable/ic_save\"\n            android:key=\"save_type\"\n            android:summary=\"%s\"\n            android:title=\"Formato de guardado\" />\n        <ListPreference\n            android:defaultValue=\"1\"\n            android:entries=\"@array/downloader_type\"\n            android:entryValues=\"@array/downloader_type_values\"\n            android:icon=\"@drawable/ic_downloader\"\n            android:key=\"downloader_type\"\n            android:summary=\"%s\"\n            android:title=\"Administrador de descarga\" />\n        <ListPreference\n            android:defaultValue=\"3\"\n            android:entries=\"@array/parallel_count\"\n            android:entryValues=\"@array/parallel_count\"\n            android:icon=\"@drawable/ic_download_multiple\"\n            android:key=\"max_parallel_downloads\"\n            android:summary=\"Máximo %s\"\n            android:title=\"Descargas paralelas\" />\n        <ListPreference\n            android:defaultValue=\"32\"\n            android:entries=\"@array/buffer_size\"\n            android:entryValues=\"@array/buffer_size_values\"\n            android:icon=\"@drawable/ic_buffer\"\n            android:key=\"buffer_size\"\n            android:summary=\"%s\"\n            android:title=\"Tamaño de buffer\" />\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Reproducción\"\n        app:isPreferenceVisible=\"false\">\n\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/player_options\"\n            android:entryValues=\"@array/player_values\"\n            android:icon=\"@drawable/ic_player\"\n            android:key=\"player_type\"\n            android:summary=\"%s\"\n            android:title=\"Tipo de reproductor\" />\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/player_resize_options\"\n            android:entryValues=\"@array/player_resize_values\"\n            android:icon=\"@drawable/ic_resize\"\n            android:key=\"player_resize\"\n            android:summary=\"%s\"\n            android:title=\"Redimensión de video\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_experimental\"\n            android:key=\"experimental_player\"\n            android:title=\"Reproductor experimental\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_samsung_tv\"\n            android:key=\"force_local_cast\"\n            android:summary=\"Usar proxy para cast\"\n            android:title=\"Cast local\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_remember\"\n            android:key=\"remember_server\"\n            android:title=\"Recordar último servidor\" />\n\n    </PreferenceCategory>\n    <PreferenceCategory android:title=\"Diseño\">\n\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/recents_type\"\n            android:entryValues=\"@array/recents_type_values\"\n            android:icon=\"@drawable/ic_home\"\n            android:key=\"recents_design\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de recientes\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_setting_asc_list\"\n            android:key=\"asc_chapters\"\n            android:summaryOff=\"Descendente\"\n            android:summaryOn=\"Ascendente\"\n            android:title=\"Orden de capitulos\" />\n        <ListPreference\n            android:defaultValue=\"@string/layType\"\n            android:entries=\"@array/layType_options\"\n            android:entryValues=\"@array/layType_values\"\n            android:icon=\"@drawable/ic_lay_type\"\n            android:key=\"lay_type\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de listas\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_download_progress\"\n            android:key=\"show_progress\"\n            android:title=\"Progreso de descarga\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_sectioned_favs\"\n            android:key=\"fav_sections\"\n            android:title=\"Favoritos por categoria\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_number\"\n            android:key=\"show_fav_count\"\n            android:title=\"Indicador de favoritos\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_collapse\"\n            android:key=\"collapse_dir_nots\"\n            android:summary=\"Crear y actualizar directorio\"\n            android:title=\"Notificaciones pequeñas\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_scale\"\n            android:key=\"scale_img\"\n            android:summary=\"Portada en pantalla completa\"\n            android:title=\"Mejor calidad de imagen\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_animations\"\n            android:key=\"smooth_animations\"\n            android:title=\"Mejorar animaciones\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_heart_full_menu\"\n            android:key=\"show_favs\"\n            android:summary=\"Marcar favoritos en emisión\"\n            android:title=\"Indicador de favoritos\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_list_placeholder\"\n            android:key=\"list_placeholder\"\n            android:title=\"Usar placeholder en listas\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_cash\"\n            android:key=\"ads_enabled_new\"\n            android:summary=\"Mostrar anuncios para ayudar al programador\"\n            android:title=\"Mostrar anuncios\" />\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:key=\"category_design\"\n        android:title=\"Personalización\">\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/theme_options\"\n            android:entryValues=\"@array/theme_values\"\n            android:icon=\"@drawable/ic_theme\"\n            android:key=\"theme_option\"\n            android:summary=\"%s\"\n            android:title=\"Estilo de tema\" />\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/theme_colors\"\n            android:entryValues=\"@array/theme_colors_values\"\n            android:icon=\"@drawable/ic_palette\"\n            android:key=\"theme_color\"\n            android:summary=\"%s\"\n            android:title=\"Color de tema\" />\n    </PreferenceCategory>\n    <PreferenceCategory android:title=\"Extras\">\n\n        <androidx.preference.ListPreference\n            android:defaultValue=\"10\"\n            android:entries=\"@array/timeout_options\"\n            android:entryValues=\"@array/timeout_values\"\n            android:icon=\"@drawable/ic_timeout\"\n            android:key=\"timeout_time\"\n            android:summary=\"%s\"\n            android:title=\"Espera de conexión\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_incognito\"\n            android:key=\"default_useragent\"\n            android:summaryOff=\"Se usará agente al azar en bypass\"\n            android:summaryOn=\"Se usará agente por defecto en bypass\"\n            android:title=\"Usar agente del dispositivo\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_setting_gps\"\n            android:key=\"daynigth_permission\"\n            android:title=\"Tema dia/noche preciso\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_trophy_normal\"\n            android:key=\"achievements_permissions\"\n            android:title=\"Habilitar logros\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_changelog_get\"\n            android:key=\"changelog_load\"\n            android:summaryOff=\"Web\"\n            android:summaryOn=\"Archivo local\"\n            android:title=\"Obtencion de changelog\" />\n        <Preference\n            android:icon=\"@drawable/ic_settings_reload\"\n            android:key=\"dir_update\"\n            android:title=\"Actualizar directorio\" />\n        <Preference\n            android:icon=\"@drawable/ic_danger\"\n            android:key=\"dir_destroy\"\n            android:title=\"Recrear directorio\" />\n    </PreferenceCategory>\n</PreferenceScreen>"
  },
  {
    "path": "app/src/androidTest/java/knf/kuma/ExampleInstrumentedTest.kt",
    "content": "package knf.kuma\n\n\nimport android.util.Log\nimport androidx.test.InstrumentationRegistry\nimport androidx.test.runner.AndroidJUnit4\nimport androidx.work.Configuration\nimport androidx.work.testing.SynchronousExecutor\nimport androidx.work.testing.WorkManagerTestInitHelper\nimport org.junit.Before\nimport org.junit.Test\nimport org.junit.runner.RunWith\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    @Before\n    fun setup() {\n        val context = InstrumentationRegistry.getTargetContext()\n        val config = Configuration.Builder()\n            .setMinimumLoggingLevel(Log.DEBUG)\n            .setExecutor(SynchronousExecutor())\n            .build()\n        WorkManagerTestInitHelper.initializeTestWorkManager(context, config)\n    }\n\n    @Test\n    @Throws(Exception::class)\n    fun testRecentWork() {\n\n    }\n}\n"
  },
  {
    "path": "app/src/debug/res/xml/preferences.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<PreferenceScreen\n    xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <PreferenceCategory\n        android:title=\"Actualizaciones\">\n\n        <ListPreference\n            android:defaultValue=\"1\"\n            android:entries=\"@array/recents_options\"\n            android:entryValues=\"@array/recents_values\"\n            android:icon=\"@drawable/ic_recents\"\n            android:key=\"recents_time\"\n            android:summary=\"%s\"\n            android:title=\"Revisar recientes\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_group\"\n            android:key=\"group_notifications\"\n            android:title=\"Agrupar notificaciones\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_heart\"\n            android:key=\"notify_favs\"\n            android:summaryOff=\"Se notificaran todos los capitulos\"\n            android:summaryOn=\"Se notificaran capitulos solo si estan en favoritos\"\n            android:title=\"Solo favoritos\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_img\"\n            android:key=\"recent_image\"\n            android:summary=\"Episodios recientes\"\n            android:title=\"Portada en notificación\"/>\n        <ListPreference\n            android:defaultValue=\"7\"\n            android:entries=\"@array/dir_options\"\n            android:entryValues=\"@array/dir_values\"\n            android:icon=\"@drawable/ic_directory\"\n            android:key=\"dir_update_time\"\n            android:summary=\"%s\"\n            android:title=\"Recrear directorio\"/>\n        <Preference\n            android:icon=\"@drawable/ic_note\"\n            android:key=\"custom_tone\"\n            android:summary=\"Sistema\"\n            android:title=\"Tono de notificación\"/>\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:enabled=\"false\"\n            android:entries=\"@array/autobackup\"\n            android:entryValues=\"@array/autobackup_values\"\n            android:icon=\"@drawable/ic_cloud_upload\"\n            android:key=\"auto_backup\"\n            android:summary=\"%s\"\n            android:title=\"Auto respaldo\"/>\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Almacenamiento\">\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/storage_type\"\n            android:entryValues=\"@array/storage_values\"\n            android:icon=\"@drawable/ic_download\"\n            android:key=\"download_type\"\n            android:summary=\"%s\"\n            android:title=\"Descargas\"/>\n        <Preference\n            android:icon=\"@drawable/ic_download\"\n            android:key=\"download_type_q\"\n            android:title=\"Descargas\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_hide_pref\"\n            android:key=\"hide_chaps\"\n            android:title=\"Ocultar de galeria\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_import\"\n            android:key=\"show_import\"\n            android:title=\"Importar archivos\"/>\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/savetype\"\n            android:entryValues=\"@array/savetype_values\"\n            android:icon=\"@drawable/ic_save\"\n            android:key=\"save_type\"\n            android:summary=\"%s\"\n            android:title=\"Formato de guardado\"/>\n        <ListPreference\n            android:defaultValue=\"1\"\n            android:entries=\"@array/downloader_type\"\n            android:entryValues=\"@array/downloader_type_values\"\n            android:icon=\"@drawable/ic_downloader\"\n            android:key=\"downloader_type\"\n            android:summary=\"%s\"\n            android:title=\"Administrador de descarga\"/>\n        <ListPreference\n            android:defaultValue=\"3\"\n            android:entries=\"@array/parallel_count\"\n            android:entryValues=\"@array/parallel_count\"\n            android:icon=\"@drawable/ic_download_multiple\"\n            android:key=\"max_parallel_downloads\"\n            android:summary=\"Máximo %s\"\n            android:title=\"Descargas paralelas\"/>\n        <ListPreference\n            android:defaultValue=\"32\"\n            android:entries=\"@array/buffer_size\"\n            android:entryValues=\"@array/buffer_size_values\"\n            android:icon=\"@drawable/ic_buffer\"\n            android:key=\"buffer_size\"\n            android:summary=\"%s\"\n            android:title=\"Tamaño de buffer\"/>\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Reproducción\">\n\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/player_options\"\n            android:entryValues=\"@array/player_values\"\n            android:icon=\"@drawable/ic_player\"\n            android:key=\"player_type\"\n            android:summary=\"%s\"\n            android:title=\"Tipo de reproductor\"/>\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/player_resize_options\"\n            android:entryValues=\"@array/player_resize_values\"\n            android:icon=\"@drawable/ic_resize\"\n            android:key=\"player_resize\"\n            android:summary=\"%s\"\n            android:title=\"Redimensión de video\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_experimental\"\n            android:key=\"experimental_player\"\n            android:title=\"Reproductor avanzado\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_samsung_tv\"\n            android:key=\"force_local_cast\"\n            android:summary=\"Usar proxy para cast\"\n            android:title=\"Cast local\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_remember\"\n            android:key=\"remember_server\"\n            android:title=\"Recordar último servidor\"/>\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Diseño\">\n\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/recents_type\"\n            android:entryValues=\"@array/recents_type_values\"\n            android:icon=\"@drawable/ic_home\"\n            android:key=\"recents_design\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de recientes\"/>\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/recents_action_options\"\n            android:entryValues=\"@array/design_values\"\n            android:icon=\"@drawable/ic_cloud_download\"\n            android:key=\"recentActionType\"\n            android:summary=\"%s\"\n            android:title=\"Accion de click en recientes\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_setting_asc_list\"\n            android:key=\"asc_chapters\"\n            android:summaryOff=\"Descendente\"\n            android:summaryOn=\"Ascendente\"\n            android:title=\"Orden de capitulos\"/>\n        <ListPreference\n            android:defaultValue=\"@string/layType\"\n            android:entries=\"@array/layType_options\"\n            android:entryValues=\"@array/layType_values\"\n            android:icon=\"@drawable/ic_lay_type\"\n            android:key=\"lay_type\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de listas\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_download_progress\"\n            android:key=\"show_progress\"\n            android:title=\"Progreso de descarga\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_sectioned_favs\"\n            android:key=\"fav_sections\"\n            android:title=\"Favoritos por categoria\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_number\"\n            android:key=\"show_fav_count\"\n            android:title=\"Indicador de favoritos\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_collapse\"\n            android:key=\"collapse_dir_nots\"\n            android:summary=\"Crear y actualizar directorio\"\n            android:title=\"Notificaciones pequeñas\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_scale\"\n            android:key=\"scale_img\"\n            android:summary=\"Portada en pantalla completa\"\n            android:title=\"Mejor calidad de imagen\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_animations\"\n            android:key=\"smooth_animations\"\n            android:title=\"Mejorar animaciones\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_heart_full_menu\"\n            android:key=\"show_favs\"\n            android:summary=\"Marcar favoritos en emisión\"\n            android:title=\"Indicador de favoritos\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_list_placeholder\"\n            android:key=\"list_placeholder\"\n            android:title=\"Usar placeholder en listas\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_cash\"\n            android:key=\"ads_enabled_new\"\n            android:summary=\"Mostrar anuncios para ayudar al programador\"\n            android:title=\"Mostrar anuncios\" />\n        <Preference\n            android:icon=\"@drawable/ic_cash\"\n            android:key=\"ads_settings\"\n            android:title=\"Configuracion de anuncios\" />\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:key=\"category_design\"\n        android:title=\"Personalización\">\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/design_options\"\n            android:entryValues=\"@array/design_values\"\n            android:icon=\"@drawable/ic_design_ab\"\n            android:key=\"designStyleType\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de UI\"/>\n        <ListPreference\n            android:defaultValue=\"@string/theme_default\"\n            android:entries=\"@array/theme_options\"\n            android:entryValues=\"@array/theme_values\"\n            android:icon=\"@drawable/ic_theme\"\n            android:key=\"theme_option\"\n            android:summary=\"%s\"\n            android:title=\"Estilo de tema\"/>\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/theme_colors\"\n            android:entryValues=\"@array/theme_colors_values\"\n            android:icon=\"@drawable/ic_palette\"\n            android:key=\"theme_color\"\n            android:summary=\"%s\"\n            android:title=\"Color de tema\"/>\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Extras\">\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_ff\"\n            android:key=\"family_friendly_enabled\"\n            android:title=\"Modo family friendly\" />\n        <androidx.preference.ListPreference\n            android:defaultValue=\"10\"\n            android:entries=\"@array/timeout_options\"\n            android:entryValues=\"@array/timeout_values\"\n            android:icon=\"@drawable/ic_timeout\"\n            android:key=\"timeout_time\"\n            android:summary=\"%s\"\n            android:title=\"Espera de conexión\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_incognito\"\n            android:key=\"may_use_random_useragent_1\"\n            android:summaryOn=\"Se usará agente al azar cuando sea posible\"\n            android:summaryOff=\"Se usará la configuracion actual\"\n            android:title=\"Usar agente al azar cuando sea posible\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_bug\"\n            android:key=\"security_blocking_firestore\"\n            android:summaryOff=\"Desactivada\"\n            android:summaryOn=\"Activada\"\n            android:title=\"Protección contra SP \" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_trophy_normal\"\n            android:key=\"achievements_permissions\"\n            android:title=\"Habilitar logros\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_changelog_get\"\n            android:key=\"changelog_load\"\n            android:summaryOff=\"Web\"\n            android:summaryOn=\"Archivo local\"\n            android:title=\"Obtencion de changelog\"/>\n        <Preference\n            android:icon=\"@drawable/ic_settings_reload\"\n            android:key=\"dir_update\"\n            android:title=\"Actualizar directorio\"/>\n        <Preference\n            android:icon=\"@drawable/ic_danger\"\n            android:key=\"dir_destroy\"\n            android:title=\"Recrear directorio\"/>\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Debug\">\n        <Preference\n            android:key=\"reset_recents\"\n            android:title=\"Reiniciar recientes\"/>\n    </PreferenceCategory>\n</PreferenceScreen>"
  },
  {
    "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    <queries>\n        <intent>\n            <action android:name=\"android.speech.RecognitionService\" />\n        </intent>\n    </queries>\n\n    <uses-feature\n        android:name=\"android.software.leanback\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.touchscreen\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.telephony\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.location\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.sensor\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.wifi\"\n        android:required=\"false\" />\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\" />\n    <uses-permission android:name=\"android.permission.CHANGE_WIFI_MULTICAST_STATE\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE_DATA_SYNC\" />\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK\" />\n    <uses-permission android:name=\"android.permission.RUN_USER_INITIATED_JOBS\" />\n    <uses-permission\n        android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"\n        android:maxSdkVersion=\"28\" />\n    <uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\" />\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\" />\n    <uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\" />\n    <uses-permission\n        android:name=\"android.permission.RECORD_AUDIO\"\n        android:requiredFeature=\"android.software.leanback\" />\n    <uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\" />\n    <uses-permission android:name=\"com.android.providers.tv.permission.WRITE_EPG_DATA\" />\n    <uses-permission\n        android:name=\"android.permission.ACCESS_COARSE_LOCATION\"\n        tools:node=\"remove\" />\n    <uses-permission\n        android:name=\"android.permission.ACCESS_FINE_LOCATION\"\n        tools:node=\"remove\" />\n\n\n    <application\n        android:name=\".App\"\n        android:allowBackup=\"true\"\n        android:banner=\"@drawable/tv_banner\"\n        android:fullBackupContent=\"@xml/backup_descriptor\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:resizeableActivity=\"true\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:theme=\"@style/AppTheme.DayNight\"\n        android:networkSecurityConfig=\"@xml/network_security\"\n        android:usesCleartextTraffic=\"true\"\n        tools:replace=\"android:fullBackupContent\">\n\n        <meta-data\n            android:name=\"com.google.android.geo.API_KEY\"\n            android:value=\"@string/google_maps_key\" />\n        <meta-data\n            android:name=\"com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME\"\n            android:value=\"knf.kuma.cast.CastOptionsProvider\" />\n\n        <activity\n            android:name=\".commons.EAMapActivity\"\n            android:label=\"@string/title_activity_eamap\" />\n        <activity\n            android:name=\".SplashActivity\"\n            android:label=\"@string/title_activity_main\"\n            android:exported=\"true\"\n            android:theme=\"@style/AppTheme.Splash\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"http\" />\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"ukiku.ga\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"http\" />\n                <data\n                    android:host=\"ukiku.ga\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n            <intent-filter>\n                <data\n                    android:host=\"open\"\n                    android:scheme=\"ukiku\" />\n\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n            </intent-filter>\n\n            <meta-data\n                android:name=\"android.app.shortcuts\"\n                android:resource=\"@xml/shortcuts\" />\n        </activity>\n        <activity\n            android:name=\".Main\"\n            android:enabled=\"false\"\n            android:exported=\"true\"\n            android:label=\"@string/title_activity_main\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/search\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".tv.ui.TVMain\"\n            android:banner=\"@drawable/tv_banner\"\n            android:exported=\"true\"\n            android:theme=\"@style/AppTheme.TV.Browser\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.LEANBACK_LAUNCHER\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data\n                    android:host=\"tv\"\n                    android:pathPrefix=\"/home\"\n                    android:scheme=\"ukiku\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".animeinfo.ActivityAnime\"\n            android:enabled=\"false\"\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            android:exported=\"true\"\n            android:windowSoftInputMode=\"stateHidden\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/anime/\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".player.CustomExoPlayer\"\n            android:configChanges=\"screenSize|smallestScreenSize|screenLayout|orientation\"\n            android:immersive=\"true\"\n            android:launchMode=\"singleTask\"\n            android:resizeableActivity=\"true\"\n            android:exported=\"true\"\n            android:supportsPictureInPicture=\"true\">\n            <intent-filter android:label=\"UKIKU\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"http\" />\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".player.VideoActivity\"\n            android:configChanges=\"screenSize|smallestScreenSize|screenLayout|orientation\"\n            android:immersive=\"true\"\n            android:launchMode=\"singleTask\"\n            android:resizeableActivity=\"true\"\n            android:exported=\"true\"\n            android:supportsPictureInPicture=\"true\">\n            <intent-filter android:label=\"UKIKU experimental\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"http\" />\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".animeinfo.img.ActivityImgFull\"\n            android:theme=\"@style/AppTheme.FullScreen\" />\n        <activity android:name=\".record.RecordActivity\" />\n        <activity android:name=\".seeing.SeeingActivity\" />\n        <activity android:name=\".emision.EmissionActivity\" />\n        <activity android:name=\".explorer.ExplorerActivity\" />\n        <activity\n            android:name=\".updater.UpdateActivity\"\n            android:excludeFromRecents=\"true\"\n            android:exported=\"true\" />\n        <activity android:name=\".random.RandomActivity\" />\n        <activity android:name=\".changelog.ChangelogActivity\" />\n        <activity\n            android:name=\".backup.BackUpActivity\"\n            android:theme=\"@style/AppTheme.Translucent\" />\n        <activity\n            android:name=\"com.dropbox.core.android.AuthActivity\"\n            android:configChanges=\"orientation|keyboard\"\n            android:exported=\"true\"\n            android:launchMode=\"singleTask\">\n            <intent-filter>\n                <data android:scheme=\"db-qtjow4hsk06vt19\" />\n\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".backup.MigrationActivity\"\n            android:theme=\"@style/AppTheme.Translucent\" />\n        <activity android:name=\".recommended.RecommendActivity\" />\n        <activity android:name=\".recommended.RankingActivity\" />\n        <activity android:name=\".search.GenreActivity\" />\n\n        <service\n            android:name=\".directory.DirectoryService\"\n            android:foregroundServiceType=\"dataSync\" />\n        <service\n            android:name=\".directory.DirectoryUpdateService\"\n            android:foregroundServiceType=\"dataSync\" />\n        <service\n            android:name=\".download.DownloadService\"\n            android:foregroundServiceType=\"dataSync\" />\n        <service\n            android:name=\".widgets.emision.WEmissionService\"\n            android:foregroundServiceType=\"dataSync\"\n            android:permission=\"android.permission.BIND_REMOTEVIEWS\" />\n        <service\n            android:name=\".download.DownloadManager\"\n            android:foregroundServiceType=\"dataSync\" />\n        <service\n            android:name=\".download.DownloadManagerJob\"\n            android:exported=\"false\"\n            android:permission=\"android.permission.BIND_JOB_SERVICE\" />\n        <service\n            android:name=\".commons.SelfServer\"\n            android:foregroundServiceType=\"mediaPlayback\" />\n\n        <receiver\n            android:name=\".widgets.emision.WEmisionProvider\"\n            android:exported=\"true\"\n            android:label=\"Emisión\">\n            <intent-filter>\n                <action android:name=\"android.appwidget.action.APPWIDGET_UPDATE\" />\n            </intent-filter>\n\n            <meta-data\n                android:name=\"android.appwidget.provider\"\n                android:resource=\"@xml/widget_emision\" />\n        </receiver>\n        <receiver android:name=\".download.DownloadReceiver\" />\n        <receiver android:name=\".recents.RecentsNotReceiver\" />\n\n        <provider\n            android:name=\"androidx.core.content.FileProvider\"\n            android:authorities=\"${applicationId}.fileprovider\"\n            android:exported=\"false\"\n            android:grantUriPermissions=\"true\">\n            <meta-data\n                android:name=\"android.support.FILE_PROVIDER_PATHS\"\n                android:resource=\"@xml/path_providers\" />\n        </provider>\n\n        <meta-data\n            android:name=\"com.google.android.gms.ads.APPLICATION_ID\"\n            android:value=\"${admobID}\" />\n        <meta-data\n            android:name=\"com.google.android.gms.ads.AD_MANAGER_APP\"\n            android:value=\"true\" />\n        <meta-data\n            android:name=\"preloaded_fonts\"\n            android:resource=\"@array/preloaded_fonts\" />\n\n        <activity android:name=\".queue.QueueActivity\" />\n        <activity\n            android:name=\".tv.streaming.TVServerSelection\"\n            android:theme=\"@style/AppTheme.TV.Guided\" />\n        <activity\n            android:name=\".tv.exoplayer.TVPlayer\"\n            android:theme=\"@style/AppTheme.TV.Base\" />\n        <activity\n            android:name=\".tv.details.TVAnimesDetails\"\n            android:theme=\"@style/AppTheme.TV.Details\" />\n        <activity\n            android:name=\".tv.search.TVSearch\"\n            android:theme=\"@style/AppTheme.TV.Base\" />\n        <activity\n            android:name=\".tv.search.TVTag\"\n            android:theme=\"@style/AppTheme.TV.Grid\" />\n        <activity\n            android:name=\".tv.directory.TVDir\"\n            android:theme=\"@style/AppTheme.TV.Grid\" />\n        <activity\n            android:name=\".tv.emission.TVEmission\"\n            android:theme=\"@style/AppTheme.TV.Browser\" />\n        <activity\n            android:name=\".download.DownloadDialogActivity\"\n            android:excludeFromRecents=\"true\"\n            android:exported=\"true\"\n            android:theme=\"@style/Theme.AppCompat.DayNight.Dialog\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data android:scheme=\"https\" />\n                <data android:host=\"animeflv.net\" />\n                <data android:pathPrefix=\"/ver/\" />\n                <data android:scheme=\"http\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".custom.ThemedControlsActivity\" />\n        <activity android:name=\".news.NewsActivity\" />\n        <activity android:name=\".achievements.AchievementActivity\" />\n        <activity android:name=\".commons.EAUnlockActivity\" />\n        <activity\n            android:name=\"es.munix.multidisplaycast.CastControlsActivity\"\n            android:screenOrientation=\"sensor\"\n            tools:node=\"merge\"\n            tools:replace=\"android:screenOrientation\" />\n        <activity\n            android:name=\".tv.streaming.TVMultiSelection\"\n            android:theme=\"@style/AppTheme.TV.Guided\" />\n        <activity android:name=\".Diagnostic\" />\n        <activity android:name=\".recents.RecentsActivity\" />\n        <activity android:name=\".Diagnostic$FullBypass\" />\n        <activity android:name=\".profile.TopActivity\" />\n        <activity android:name=\".faq.FaqActivity\" />\n        <activity android:name=\".news.MaterialNewsActivity\" />\n        <activity android:name=\".preferences.AdsPreferenceActivity\" />\n        <activity\n            android:name=\".MainMaterial\"\n            android:exported=\"true\"\n            android:label=\"@string/title_activity_main\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/search\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".recents.RecentsModelActivity\" />\n        <activity android:name=\".search.SearchActivity\" />\n        <activity android:name=\".explorer.ExplorerActivityMaterial\" />\n        <activity android:name=\".emision.EmissionActivityMaterial\" />\n        <activity android:name=\".seeing.SeeingActivityMaterial\" />\n        <activity android:name=\".queue.QueueActivityMaterial\" />\n        <activity android:name=\".recommended.RecommendActivityMaterial\" />\n        <activity android:name=\".recommended.RankingActivityMaterial\" />\n        <activity android:name=\".record.RecordActivityMaterial\" />\n        <activity android:name=\".random.RandomActivityMaterial\" />\n        <activity android:name=\".faq.FaqActivityMaterial\" />\n        <activity android:name=\".achievements.AchievementActivityMaterial\" />\n        <activity android:name=\".AppInfoActivityMaterial\" />\n        <activity android:name=\".AppInfoActivity\" />\n        <activity\n            android:name=\".animeinfo.ActivityAnimeMaterial\"\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            android:exported=\"true\"\n            android:windowSoftInputMode=\"stateHidden\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/anime/\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".search.GenreActivityMaterial\" />\n        <activity android:name=\".DiagnosticMaterial\" />\n        <activity android:name=\".changelog.ChangelogActivityMaterial\" />\n        <activity android:name=\".DiagnosticMaterial$FullBypass\" />\n        <activity android:name=\".shortcuts.DummyMainActivity\" />\n        <activity android:name=\".shortcuts.DummyExplorerActivity\" />\n        <activity android:name=\".shortcuts.DummyEmissionActivity\" />\n        <activity android:name=\".profile.TopActivityMaterial\" />\n        <activity\n            android:name=\".tv.streaming.StreamTvActivity\"\n            android:exported=\"true\"\n            android:theme=\"@style/Theme.AppCompat.DayNight.Dialog\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"tv\"\n                    android:pathPrefix=\"/chapter\"\n                    android:scheme=\"ukiku\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\"knf.kuma.player.WebPlayerActivity\"\n            android:configChanges=\"orientation\"\n            android:screenOrientation=\"sensorLandscape\"/>\n\n        <provider\n            android:name=\"androidx.startup.InitializationProvider\"\n            android:authorities=\"${applicationId}.androidx-startup\"\n            tools:node=\"remove\" />\n\n\n        <uses-library\n            android:name=\"org.apache.http.legacy\"\n            android:required=\"false\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/assets/changelog.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<changelog>\n    <release code=\"228\" version=\"5.3.18\">\n        <change type=\"fix\">Mejoras StreamWish</change>\n        <change type=\"fix\">Error al mostrar lista de recientes en modo \"Home\"</change>\n    </release>\n    <release code=\"227\" version=\"5.3.17\">\n        <change type=\"fix\">Corrección servidor StreamWish</change>\n    </release>\n    <release code=\"226\" version=\"5.3.16\">\n        <change type=\"change\">Prevenir error al descargar actualización</change>\n    </release>\n    <release code=\"225\" version=\"5.3.15\">\n        <change type=\"change\">Enlaces de telegram actualizados</change>\n    </release>\n    <release code=\"224\" version=\"5.3.14\">\n        <change type=\"fix\">Corrección StreamWish</change>\n        <change type=\"fix\">Corrección imágenes en explorador</change>\n        <change type=\"fix\">Error al reproducir videos en el reproductor interno en algunos casos</change>\n    </release>\n    <release code=\"223\" version=\"5.3.13\">\n        <change type=\"fix\">Error al descargar en algunos dispositivos</change>\n    </release>\n    <release code=\"222\" version=\"5.3.12\">\n        <change type=\"fix\">Corrección de imágenes</change>\n        <change type=\"fix\">Error al obtener lista de recientes en algunos casos</change>\n    </release>\n    <release code=\"221\" version=\"5.3.11\">\n        <change type=\"fix\">Corrección servidor StreamWish</change>\n    </release>\n    <release code=\"220\" version=\"5.3.10\">\n        <change type=\"fix\">Corrección de imágenes en recientes</change>\n        <change type=\"change\">Soporte Android 16</change>\n    </release>\n    <release code=\"219\" version=\"5.3.9\">\n        <change type=\"fix\">Corrección en login de firebase</change>\n        <change type=\"fix\">Correcciónes generales para Android 15</change>\n    </release>\n    <release code=\"218\" version=\"5.3.8\">\n        <change type=\"fix\">Corrección en noticias</change>\n    </release>\n    <release code=\"217\" version=\"5.3.7\">\n        <change type=\"fix\">Corrección StreamWish</change>\n        <change type=\"fix\">Corrección comentarios</change>\n    </release>\n    <release code=\"216\" version=\"5.3.6\">\n        <change type=\"fix\">Corrección StreamWish</change>\n        <change type=\"fix\">Mejora de conexión para CAST</change>\n    </release>\n    <release code=\"215\" version=\"5.3.5\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Corrección StreamWish</change>\n        <change type=\"fix\">Eliminar librerias sin usar</change>\n    </release>\n    <release code=\"214\" version=\"5.3.4\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"213\" version=\"5.3.3\">\n        <change type=\"fix\">Error al reproducir en TV</change>\n    </release>\n    <release code=\"212\" version=\"5.3.2\">\n        <change type=\"fix\">Error en streaming iniciado desde informacion de anime</change>\n        <change type=\"fix\">Error al obtener información de animes con comillas en el nombre</change>\n    </release>\n    <release code=\"211\" version=\"5.3.1\">\n        <change type=\"fix\">Error en descargas</change>\n    </release>\n    <release code=\"210\" version=\"5.3.0\">\n        <change type=\"change\">Soporte Android 14</change>\n        <change type=\"fix\">Corrección de bugs</change>\n    </release>\n    <release code=\"209\" version=\"5.2.11\">\n        <change type=\"fix\">Corrección especifica para Xiaomi de SSL</change>\n        <change type=\"fix\">Corrección de bugs</change>\n    </release>\n    <release code=\"208\" version=\"5.2.10\">\n        <change type=\"fix\">Corrección de SSL para telefonos sin GPlay</change>\n    </release>\n    <release code=\"207\" version=\"5.2.9\">\n        <change type=\"fix\">Corrección de Streamwish para algunos capitulos viejos</change>\n    </release>\n    <release code=\"206\" version=\"5.2.8\">\n        <change type=\"fix\">Corrección de bugs</change>\n    </release>\n    <release code=\"205\" version=\"5.2.7\">\n        <change type=\"fix\">Corrección StreamWish</change>\n    </release>\n    <release code=\"204\" version=\"5.2.6\">\n        <change type=\"fix\">Error al mostrar dialogo de actualizacion</change>\n        <change type=\"fix\">Error en bypass</change>\n    </release>\n    <release code=\"203\" version=\"5.2.5\">\n        <change type=\"fix\">Error en bypass</change>\n    </release>\n    <release code=\"202\" version=\"5.2.4\">\n        <change type=\"fix\">Error en bypass</change>\n    </release>\n    <release code=\"200\" version=\"5.2.1\">\n        <change type=\"new\">Servidor Streamwish (Solo streaming)</change>\n        <change type=\"change\">Mensaje de error para error desconocido en Peru</change>\n        <change type=\"change\">Soporte mejorado para Okru y Yourupload</change>\n    </release>\n    <release code=\"199\" version=\"5.2.1\">\n        <change type=\"fix\">Error al expandir texto en informacion de anime</change>\n        <change type=\"fix\">Error al buscar imagenes de mejor calidad</change>\n    </release>\n    <release code=\"198\" version=\"5.2.0\">\n        <change type=\"fix\">Error al verificar suscripciones</change>\n    </release>\n    <release code=\"197\" version=\"5.1.28\">\n        <change type=\"fix\">Error en backup local</change>\n    </release>\n    <release code=\"196\" version=\"5.1.27\">\n        <change type=\"fix\">Error al iniciar en TV</change>\n    </release>\n    <release code=\"195\" version=\"5.1.26\">\n        <change type=\"fix\">Correccion para noticias</change>\n    </release>\n    <release code=\"194\" version=\"5.1.25\">\n        <change type=\"fix\">Correccion para Android 12</change>\n    </release>\n    <release code=\"193\" version=\"5.1.24\">\n        <change type=\"fix\">Imagenes de noticias</change>\n    </release>\n    <release code=\"192\" version=\"5.1.23\">\n        <change type=\"new\">Servidor SBVideo</change>\n    </release>\n    <release code=\"191\" version=\"5.1.22\">\n        <change type=\"fix\">Error al guardar progreso en reproductor interno</change>\n    </release>\n    <release code=\"190\" version=\"5.1.21\">\n        <change type=\"fix\">Botón de pausa en reproductor interno</change>\n    </release>\n    <release code=\"189\" version=\"5.1.20\">\n        <change type=\"change\">Diagnostico reflejara el bypass en estado general</change>\n        <change type=\"fix\">Servidor stape</change>\n    </release>\n    <release code=\"188\" version=\"5.1.19\">\n        <change type=\"fix\">Arreglo en version de TV</change>\n    </release>\n    <release code=\"187\" version=\"5.1.18\">\n        <change type=\"fix\">Error al mostrar imagenes en noticias</change>\n    </release>\n    <release code=\"186\" version=\"5.1.17\">\n        <change type=\"fix\">Errores en login de Firestore</change>\n    </release>\n    <release code=\"185\" version=\"5.1.16\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Error al mostrar noticias</change>\n    </release>\n    <release code=\"184\" version=\"5.1.15\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"183\" version=\"5.1.14\">\n        <change type=\"fix\">Mejoras de bypass</change>\n    </release>\n    <release code=\"182\" version=\"5.1.13\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Mejoras de bypass para TV</change>\n    </release>\n    <release code=\"181\" version=\"5.1.12\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Servidor stape</change>\n    </release>\n    <release code=\"180\" version=\"5.1.11\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"179\" version=\"5.1.10\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"178\" version=\"5.1.9\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"177\" version=\"5.1.8\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Error al mostrar algunas secciones en telefonos sin Play Services\n        </change>\n        <change type=\"fix\">Error al mostrar memoria disponible en versiones de Android recientes\n        </change>\n    </release>\n    <release code=\"176\" version=\"5.1.7\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Cambio de pagina Ukiku.app</change>\n    </release>\n    <release code=\"174\" version=\"5.1.5\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Seleccion de carpeta para descargas en Android 11</change>\n        <change type=\"change\">Mejora en creacion de bypass</change>\n        <change type=\"change\">Mejora al cargar recientes</change>\n        <change type=\"change\">Mejoras en explorador</change>\n    </release>\n    <release code=\"174\" version=\"5.1.5\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Nuevo metodo de bypass</change>\n    </release>\n    <release code=\"173\" version=\"5.1.4\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"172\" version=\"5.1.3\">\n        <change type=\"fix\">Errores en servidores</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"171\" version=\"5.1.2\">\n        <change type=\"change\">Descargar directorio para aligerar carga</change>\n        <change type=\"fix\">Errores al abrir informacion de anime</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"170\" version=\"5.1.1\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"169\" version=\"5.1.0\">\n        <change type=\"change\">Optimización general</change>\n        <change type=\"change\">Mejoras en reproductor</change>\n        <change type=\"change\">Reproductor Experimental renombrado a Avanzado</change>\n        <change type=\"change\">Intento para sobrepasar bloqueo 403</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"168\" version=\"5.0.3\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"167\" version=\"5.0.2\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"166\" version=\"5.0.1\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"165\" version=\"5.0.0\">\n        <change type=\"new\">Nuevo diseño de la app</change>\n        <change type=\"change\">Agregada opcion para cambiar a diseño clasico</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"164\" version=\"4.4.0\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Anuncios activados por defecto</change>\n        <change type=\"change\">Cambios en personalización de anuncios</change>\n    </release>\n    <release code=\"163\" version=\"4.3.47\">\n        <change type=\"fix\">Error al crear directorio</change>\n    </release>\n    <release code=\"162\" version=\"4.3.46\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Optimizacion para anuncios generales</change>\n    </release>\n    <release code=\"161\" version=\"4.3.45\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Optimizacion para anuncios en listas</change>\n    </release>\n    <release code=\"160\" version=\"4.3.44\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Servidor GoCDN</change>\n        <change type=\"new\">Servidor Stape</change>\n    </release>\n    <release code=\"159\" version=\"4.3.43\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"158\" version=\"4.3.42\">\n        <change type=\"fix\">Error al detectar numero de episodio en explorador</change>\n    </release>\n    <release code=\"157\" version=\"4.3.41\">\n        <change type=\"fix\">Error al detectar episodios en explorador</change>\n    </release>\n    <release code=\"156\" version=\"4.3.40\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"155\" version=\"4.3.39\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"154\" version=\"4.3.38\">\n        <change type=\"fix\">Error al detectar capitulos descargados en Android 10</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"153\" version=\"4.3.37\">\n        <change type=\"change\">Barra de estado con aviso para creacion de directorio</change>\n        <change type=\"change\">Avisos mas claros cuando falta permiso de almacenamiento</change>\n        <change type=\"fix\">Error al reproducir animes descargados en reproductor interno</change>\n        <change type=\"fix\">Error al marcar como visto desde explorador</change>\n        <change type=\"fix\">Error al desmarcar como visto en algunas secciones</change>\n    </release>\n    <release code=\"152\" version=\"4.3.36\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"151\" version=\"4.3.35\">\n        <change type=\"fix\">Error al detectar capitulos descargados</change>\n    </release>\n    <release code=\"150\" version=\"4.3.34\">\n        <change type=\"fix\">Mensajes de error al otorgar permiso de almacenamiento</change>\n        <change type=\"fix\">Errores por cambio en Animeflv</change>\n    </release>\n    <release code=\"149\" version=\"4.3.33\">\n        <change type=\"change\">Comentarios por Disqus</change>\n        <change type=\"fix\">Fembed revivido</change>\n    </release>\n    <release code=\"148\" version=\"4.3.32\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"147\" version=\"4.3.31\">\n        <change type=\"change\">Servidor Fembed revivido</change>\n    </release>\n    <release code=\"146\" version=\"4.3.30\">\n        <change type=\"new\">Servidor ZippyShare</change>\n    </release>\n    <release code=\"145\" version=\"4.3.29\">\n        <change type=\"fix\">Error al reproducir izanagi en ALGUNOS episodios</change>\n    </release>\n    <release code=\"144\" version=\"4.3.28\">\n        <change type=\"fix\">Error al abrir animes con modo Home</change>\n    </release>\n    <release code=\"143\" version=\"4.3.27\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"142\" version=\"4.3.26\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"141\" version=\"4.3.25\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"140\" version=\"4.3.24\">\n        <change type=\"fix\">Error en explorador - Android 10</change>\n    </release>\n    <release code=\"139\" version=\"4.3.23\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"138\" version=\"4.3.22\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"137\" version=\"4.3.21\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"136\" version=\"4.3.20\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"135\" version=\"4.3.19\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"134\" version=\"4.3.18\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"133\" version=\"4.3.17\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"132\" version=\"4.3.16\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"131\" version=\"4.3.15\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"130\" version=\"4.3.14\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"129\" version=\"4.3.13\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"128\" version=\"4.3.12\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"127\" version=\"4.3.11\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"126\" version=\"4.3.10\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Seccion FAQ (Preguntas frecuentes)</change>\n    </release>\n    <release code=\"125\" version=\"4.3.9\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Suscripcion para Firestore sin anuncios</change>\n    </release>\n    <release code=\"124\" version=\"4.3.8\">\n        <change type=\"fix\">Error al reproducir en modo TV</change>\n    </release>\n    <release code=\"123\" version=\"4.3.7\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Suscripcion para Firestore sin anuncios</change>\n    </release>\n    <release code=\"122\" version=\"4.3.6\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Overlay para mejorar visibilidad de botones en informacion de anime\n        </change>\n    </release>\n    <release code=\"121\" version=\"4.3.5\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"120\" version=\"4.3.4\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"119\" version=\"4.3.3\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Error al notificar recientes</change>\n    </release>\n    <release code=\"118\" version=\"4.3.2\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">UI mas compacta en pantalla de backups</change>\n        <change type=\"new\">Top de videos vistos</change>\n    </release>\n    <release code=\"117\" version=\"4.3.1\">\n        <change type=\"fix\">Modo obscuro por defecto para Android 10</change>\n        <change type=\"fix\">Error al obtener monedas en algunos telefonos</change>\n    </release>\n    <release code=\"116\" version=\"4.3\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Anuncios opcionales</change>\n        <change type=\"new\">Método de backup Firestore</change>\n        <change type=\"new\">Modo family friendly</change>\n        <change type=\"new\">Moneda de la app loli-coins</change>\n        <change type=\"change\">Nuevo servidor VeryStream</change>\n    </release>\n    <release code=\"114\" version=\"4.2.10\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Mejoras en interfaz de TV</change>\n    </release>\n    <release code=\"113\" version=\"4.2.9\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"112\" version=\"4.2.8\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Opción para ocultar animes nuevos en \"Home\"</change>\n    </release>\n    <release code=\"111\" version=\"4.2.7\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"110\" version=\"4.2.6\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"109\" version=\"4.2.5\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"108\" version=\"4.2.4\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Estructura interna de respaldos mejorado</change>\n        <change type=\"change\">Método de respaldo local (memoria interna)</change>\n    </release>\n    <release code=\"107\" version=\"4.2.3\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"106\" version=\"4.2.2\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"105\" version=\"4.2.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Barra de estado para Animeflv</change>\n    </release>\n    <release code=\"104\" version=\"4.2\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Estilo home para recientes</change>\n        <change type=\"new\">Botón para saltar 1:30m en CAST (OP y ED)</change>\n    </release>\n    <release code=\"103\" version=\"4.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Prueba rapida de velocidad en diagnostico</change>\n        <change type=\"new\">Soporte previo para Android Q</change>\n        <change type=\"change\">Filtros de busqueda mejorados</change>\n        <change type=\"change\">Comentarios mejorados</change>\n        <change type=\"change\">Lista de descargas mejorada</change>\n    </release>\n    <release code=\"102\" version=\"4.0.4\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Servidor Fembed</change>\n        <change type=\"change\">Restaurar compras al entrar a la pantalla del easter egg</change>\n    </release>\n    <release code=\"101\" version=\"4.0.3\">\n        <change type=\"fix\">Errores generales en TV</change>\n    </release>\n    <release code=\"100\" version=\"4.0.2\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"99\" version=\"4.0.1\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"98\" version=\"4.0\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Errores en TV</change>\n        <change type=\"fix\">Errores en respaldos</change>\n        <change type=\"fix\">Errores en autobackup</change>\n        <change type=\"change\">Cambios al diseño para MD2</change>\n        <change type=\"change\">Nuevo dato en informacion: \"Seguidores\"</change>\n        <change type=\"change\">Optimizacion general (sobre todo en sugeridos)</change>\n        <change type=\"change\">Google Drive deshabilitado</change>\n        <change type=\"new\">Categoría pausado en seguidos</change>\n        <change type=\"new\">Recordar último servidor</change>\n        <change type=\"new\">Descarga por lotes</change>\n        <change type=\"new\">Añadir a cola por lotes</change>\n        <change type=\"new\">Preview al avanzar en reproductor experimental</change>\n        <change type=\"new\">Opcion para usar proxy en CAST</change>\n    </release>\n    <release code=\"97\" version=\"3.1.6\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Material Design 2</change>\n        <change type=\"change\">Mejora de carga en historial</change>\n        <change type=\"new\">Pantalla de diagnóstico en informacion de la app</change>\n    </release>\n    <release code=\"96\" version=\"3.1.6\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Opción para subir tiempo de espera de conexión (timeout)</change>\n    </release>\n    <release code=\"95\" version=\"3.1.5\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"94\" version=\"3.1.4\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Opción para comprar pasos de Easter egg</change>\n        <change type=\"new\">Mostrar todas las imágenes disponibles de MAL</change>\n    </release>\n    <release code=\"93\" version=\"3.1.3\">\n        <change type=\"fix\">Errores de bypass en TV</change>\n        <change type=\"new\">Mensajes de servicio</change>\n    </release>\n    <release code=\"92\" version=\"3.1.2\">\n        <change type=\"fix\">Errores de bypass en TV</change>\n    </release>\n    <release code=\"91\" version=\"3.1.1\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"90\" version=\"3.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Indicador de favoritos en emisión</change>\n    </release>\n    <release code=\"89\" version=\"3.0.15\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"88\" version=\"3.0.14\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"87\" version=\"3.0.13\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"86\" version=\"3.0.12\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"85\" version=\"3.0.11\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"84\" version=\"3.0.10\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Soporte para multiples idiomas en algunos animes</change>\n    </release>\n    <release code=\"83\" version=\"3.0.9\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"82\" version=\"3.0.8\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"81\" version=\"3.0.7\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"80\" version=\"3.0.6\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"79\" version=\"3.0.5\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Mejora en imagen de Splash</change>\n    </release>\n    <release code=\"78\" version=\"3.0.4\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"77\" version=\"3.0.3\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"76\" version=\"3.0.2\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"71\" version=\"3.0.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Errores con algunos logros</change>\n        <change type=\"change\">Mejoras esteticas para modo claro en Android 8+</change>\n        <change type=\"changes\">Mejora de modo cuadrícula para teléfonos anchos y tablets</change>\n    </release>\n    <release code=\"70\" version=\"3.0\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Logros</change>\n        <change type=\"changes\">Mejoras generales</change>\n        <change type=\"change\">Tema claro mejorado</change>\n        <change type=\"change\">Cambios con Material Design 2</change>\n    </release>\n    <release code=\"69\" version=\"2.2\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Sección simple de noticias</change>\n    </release>\n    <release code=\"68\" version=\"2.1.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Arreglos menores con CAST</change>\n        <change type=\"change\">Mejora en imagenes de error en siguiendo</change>\n    </release>\n    <release code=\"67\" version=\"2.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Mejoras graficas en algunas partes</change>\n        <change type=\"change\">Mejoras al modificar categorias en favoritos</change>\n        <change type=\"new\">Opcion para cambiar tono de notificación en recientes</change>\n        <change type=\"new\">Seccion de Siguiendo recreada</change>\n    </release>\n    <release code=\"66\" version=\"2.0.2\">\n        <change type=\"fix\">Error en pantalla de actualización</change>\n    </release>\n    <release code=\"65\" version=\"2.0.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Errores en Android TV</change>\n    </release>\n    <release code=\"64\" version=\"2.0\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Migración de Java a Kotlin</change>\n        <change type=\"new\">Mejoras de estabilidad</change>\n        <change type=\"new\">Launch screen al iniciar la app</change>\n        <change type=\"change\">Algunos dialogos cambiados a snackbar</change>\n    </release>\n    <release code=\"63\" version=\"1.9.6\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"62\" version=\"1.9.5\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Botón en reproductor para saltar 1:25min(Oppening)</change>\n        <change type=\"new\">Carátula del anime en notificacion de reciente</change>\n        <change type=\"change\">Mejora al ocultar barras en reproductor interno</change>\n    </release>\n    <release code=\"61\" version=\"1.9.4\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"60\" version=\"1.9.3\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"59\" version=\"1.9.2\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Opción para auto respaldar periodicamente</change>\n    </release>\n    <release code=\"58\" version=\"1.9.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Botón cast en información de anime</change>\n        <change type=\"change\">Filtrado por ID en directorio</change>\n    </release>\n    <release code=\"57\" version=\"1.9\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Importacion multiple</change>\n        <change type=\"change\">Cambio en easteregg, se necesita completar de nuevo</change>\n    </release>\n    <release code=\"56\" version=\"1.8.1\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"55\" version=\"1.8\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Indicadores numericos en algunas partes de la app</change>\n        <change type=\"change\">Migración a librerias androidx</change>\n    </release>\n    <release code=\"54\" version=\"1.7.5\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Cambiar administrador de descargas</change>\n        <change type=\"change\">Mejora en notificaciones de descarga</change>\n        <change type=\"change\">Mejora en iconos de atajos</change>\n    </release>\n    <release code=\"53\" version=\"1.7.4\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"52\" version=\"1.7.3\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Servidor Fenix</change>\n        <change type=\"new\">Servidor Natsuki</change>\n        <change type=\"change\">Las descargas ahora mostraran tiempo restante y velocidad de\n            descarga\n        </change>\n    </release>\n    <release code=\"51\" version=\"1.7.2\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"50\" version=\"1.7.1\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"49\" version=\"1.7\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Administrador de descargas rehecho</change>\n        <change type=\"change\">Descargas paralelas</change>\n        <change type=\"change\">Pausar descargas</change>\n        <change type=\"change\">Tiempo estimado de descarga</change>\n    </release>\n    <release code=\"48\" version=\"1.6.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Configurar buffer de descarga</change>\n        <change type=\"change\">Mejoras al importar</change>\n    </release>\n    <release code=\"47\" version=\"1.6\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Importar videos a la app</change>\n        <change type=\"new\">Descarga/Streaming desde notificacion de reciente</change>\n        <change type=\"change\">Mejoras generales</change>\n    </release>\n    <release code=\"46\" version=\"1.5\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Compartir links de episodios</change>\n        <change type=\"new\">Descarga/Streaming abriendo links de episodios</change>\n    </release>\n    <release code=\"45\" version=\"1.4.7\">\n        <change type=\"change\">Se podra añadir animes a seguidos y favoritos</change>\n    </release>\n    <release code=\"44\" version=\"1.4.6\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"43\" version=\"1.4.5\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Servidor Mango</change>\n    </release>\n    <release code=\"42\" version=\"1.4.4\">\n        <change type=\"fix\">Error en preview de episodio</change>\n    </release>\n    <release code=\"41\" version=\"1.4.3\">\n        <change type=\"fix\">Errores en explorador</change>\n        <change type=\"fix\">Error al mostrar algunas imagenes</change>\n    </release>\n    <release code=\"40\" version=\"1.4.2\">\n        <change type=\"new\">Servidor Mp4Upload (Gracias raulhaag)</change>\n        <change type=\"change\">Tiempo reducido al obtener lista de animes en explorador</change>\n    </release>\n    <release code=\"39\" version=\"1.4.1\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Errores en RV</change>\n        <change type=\"change\">Servidor Izanagi restaurado</change>\n    </release>\n    <release code=\"38\" version=\"1.4\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Errores en OKRU y RV</change>\n        <change type=\"new\">Categorias en favoritos</change>\n    </release>\n    <release code=\"37\" version=\"1.3.8\">\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"36\" version=\"1.3.7\">\n        <change type=\"fix\">Seccion emision</change>\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"change\">Migracion de datos mejorada</change>\n    </release>\n    <release code=\"35\" version=\"1.3.6\">\n        <change type=\"fix\">Obtencion de imagenes de episodios</change>\n        <change type=\"change\">Opción para deshabilitar progreso en pantalla</change>\n    </release>\n    <release code=\"34\" version=\"1.3.5\">\n        <change type=\"fix\">Obtencion de lista de episodios</change>\n        <change type=\"new\">Progreso de descarga en recientes y lista de episodios</change>\n    </release>\n    <release code=\"33\" version=\"1.3.4\">\n        <change type=\"fix\">Notificacion persistente al crear/recrear directorio</change>\n    </release>\n    <release code=\"32\" version=\"1.3.3\">\n        <change type=\"fix\">Error en listar episodios de animes largos</change>\n    </release>\n    <release code=\"31\" version=\"1.3.2\">\n        <change type=\"fix\">Errores en Cast</change>\n    </release>\n    <release code=\"30\" version=\"1.3.1\">\n        <change type=\"fix\">Errores generales en Android TV</change>\n    </release>\n    <release code=\"29\" version=\"1.3\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Diseño especial para Android TV</change>\n    </release>\n    <release code=\"28\" version=\"1.2.5\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Servidor RV</change>\n        <change type=\"change\">Mejora en pendientes</change>\n    </release>\n    <release code=\"27\" version=\"1.2.4\">\n        <change type=\"change\">Mejora en explorador</change>\n    </release>\n    <release code=\"26\" version=\"1.2.3\">\n        <change type=\"fix\">Error en nombre de animes</change>\n        <change type=\"new\">Soporte para Android TV</change>\n    </release>\n    <release code=\"25\" version=\"1.2.2\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"fix\">Error al hacer cast de archivos locales</change>\n    </release>\n    <release code=\"24\" version=\"1.2.1\">\n        <change type=\"fix\">Servidor Mega duplicado</change>\n        <change type=\"fix\">Servidor Fire corregido</change>\n        <change type=\"change\">Marcar episodios pendientes como vistos y el ultimo es añadido a\n            historial\n        </change>\n    </release>\n    <release code=\"23\" version=\"1.2\">\n        <change type=\"fix\">Errores generales</change>\n        <change type=\"new\">Cola de reproducción</change>\n    </release>\n    <release code=\"22\" version=\"1.1.1\">\n        <change type=\"fix\">Error de colores</change>\n        <change type=\"fix\">Error al abrir informacion de animes sin conexion</change>\n    </release>\n    <release code=\"21\" version=\"1.1\">\n        <change type=\"new\">Click largo en emisión para ocultar</change>\n        <change type=\"new\">Widget de emisión agregado</change>\n        <change type=\"new\">Abrir pantalla de genero desde informacion de anime</change>\n        <change type=\"new\">Easter egg agregado, pista: \"easteregg\"</change>\n        <change type=\"change\">Modo PIP en reproductor mejorado</change>\n        <change type=\"change\">Explorador optimizado</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"20\" version=\"1.0\">\n        <change type=\"change\">Version final</change>\n        <change type=\"new\">Accesos directos en launcher</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"19\" version=\"0.4.2 beta\">\n        <change type=\"change\">Agregada mas informacion en acerca de</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"18\" version=\"0.4.1 beta\">\n        <change type=\"fix\">Error al notificar animes nuevos</change>\n    </release>\n    <release code=\"17\" version=\"0.4 beta\">\n        <change type=\"new\">Seccion de sugerencias</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"16\" version=\"0.3.12 beta\">\n        <change type=\"fix\">Icono arreglado para algunos telefonos</change>\n    </release>\n    <release code=\"15\" version=\"0.3.11 beta\">\n        <change type=\"fix\">Bypass de cloudflare agregado</change>\n        <change type=\"change\">Boton cast en explorador ahora abre controles</change>\n    </release>\n    <release code=\"14\" version=\"0.3.10 beta\">\n        <change type=\"new\">Pantalla de informacion</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"12\" version=\"0.3.9 beta\">\n        <change type=\"fix\">Error al actualizar app en Android 5 y 6</change>\n    </release>\n    <release code=\"11\" version=\"0.3.8 beta\">\n        <change type=\"new\">Pantalla para descargas activas (Explorador>Descargas)</change>\n    </release>\n    <release code=\"10\" version=\"0.3.7 beta\">\n        <change type=\"fix\">Error al migrar datos</change>\n    </release>\n    <release code=\"9\" version=\"0.3.6 beta\">\n        <change type=\"new\">Sincronizacion en la nube (Dropbox y Google Drive)</change>\n        <change type=\"new\">Migración de favoritos desde AnimeflvApp</change>\n        <change type=\"fix\">Errores en explorador al girar la pantalla</change>\n    </release>\n    <release code=\"8\" version=\"0.3.5 beta\">\n        <change type=\"new\">Cast de episodios descargados</change>\n        <change type=\"fix\">Error al abrir la app sin conexión</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n    <release code=\"7\" version=\"0.3.4 beta\">\n        <change type=\"new\">Changelog</change>\n        <change type=\"new\">Sección de animes random</change>\n        <change type=\"fix\">Errores generales</change>\n    </release>\n</changelog>"
  },
  {
    "path": "app/src/main/java/knf/kuma/App.kt",
    "content": "package knf.kuma\n\n/*import com.asf.appcoins.sdk.ads.AppCoinsAds\nimport com.asf.appcoins.sdk.ads.AppCoinsAdsBuilder*/\nimport android.annotation.SuppressLint\nimport android.annotation.TargetApi\nimport android.app.Application\nimport android.app.NotificationChannel\nimport android.app.NotificationManager\nimport android.content.Context\nimport android.media.AudioAttributes\nimport android.os.Build\nimport androidx.appcompat.app.AppCompatDelegate\nimport androidx.work.Configuration\nimport es.munix.multidisplaycast.CastManager\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.commons.AllSSLOkHttpClient\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.directory.DirectoryService\nimport knf.kuma.download.DownloadManager\nimport knf.kuma.download.DownloadService\nimport knf.kuma.jobscheduler.BackUpWork\nimport knf.kuma.jobscheduler.RecentsWork\nimport knf.kuma.jobscheduler.UpdateWork\nimport knf.kuma.widgets.emision.WEmissionService\n\nclass App : Application(), Configuration.Provider {\n    //private lateinit var appCoinsAds: AppCoinsAds\n\n    @TargetApi(Build.VERSION_CODES.O)\n    private fun createChannels() {\n        val manager = getSystemService(NOTIFICATION_SERVICE) as? NotificationManager\n        val dirChannel = NotificationChannel(\n            DirectoryService.CHANNEL,\n            getString(R.string.directory_channel_title),\n            NotificationManager.IMPORTANCE_MIN\n        )\n        dirChannel.setSound(\n            null,\n            AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)\n                .setUsage(AudioAttributes.USAGE_NOTIFICATION).build()\n        )\n        dirChannel.setShowBadge(false)\n        manager?.createNotificationChannel(dirChannel)\n        manager?.createNotificationChannel(\n            NotificationChannel(\n                RecentsWork.CHANNEL_RECENTS,\n                \"Capitulos recientes\",\n                NotificationManager.IMPORTANCE_HIGH\n            )\n        )\n        manager?.createNotificationChannel(\n            NotificationChannel(\n                DownloadService.CHANNEL,\n                \"Descargas\",\n                NotificationManager.IMPORTANCE_HIGH\n            )\n        )\n        manager?.createNotificationChannel(\n            NotificationChannel(\n                DownloadService.CHANNEL_ONGOING,\n                \"Descargas en progreso\",\n                NotificationManager.IMPORTANCE_LOW\n            ).apply { setShowBadge(false) })\n        manager?.createNotificationChannel(\n            NotificationChannel(\n                DownloadManager.CHANNEL_FOREGROUND,\n                \"Administrador de descargas\",\n                NotificationManager.IMPORTANCE_MIN\n            ).apply { setShowBadge(false) })\n        manager?.createNotificationChannel(\n            NotificationChannel(\n                UpdateWork.CHANNEL,\n                \"Actualización de la app\",\n                NotificationManager.IMPORTANCE_DEFAULT\n            )\n        )\n        manager?.createNotificationChannel(\n            NotificationChannel(\n                WEmissionService.CHANNEL,\n                \"Actualizador de widget\",\n                NotificationManager.IMPORTANCE_MIN\n            ).apply { setShowBadge(false) })\n    }\n\n    override val workManagerConfiguration: Configuration\n        get() = Configuration.Builder().build()\n\n    override fun onCreate() {\n        super.onCreate()\n        context = this\n        if (!PrefsUtil.isFetchDBReset) {\n            PrefsUtil.isFetchDBReset = true\n            deleteDatabase(\"LibGlobalFetchLib.db\")\n        }\n        AppCompatDelegate.setDefaultNightMode(PrefsUtil.themeOption.toInt())\n        AllSSLOkHttpClient.enableTLS()\n        BackUpWork.checkInit()\n        CastManager.register(this)\n        AchievementManager.init(this)\n        initAppCoins()\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)\n            createChannels()\n    }\n\n    private fun initAppCoins() {\n        /*appCoinsAds= AppCoinsAdsBuilder()\n                .withDebug(BuildConfig.DEBUG)\n                .createAdvertisementSdk(this)\n                .also { it.init(this) }*/\n    }\n\n    companion object {\n        @SuppressLint(\"StaticFieldLeak\")\n        lateinit var context: Context\n            private set\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/AppInfoActivity.kt",
    "content": "package knf.kuma\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport androidx.fragment.app.Fragment\r\nimport knf.kuma.custom.SingleFragmentActivity\r\n\r\nclass AppInfoActivity: SingleFragmentActivity() {\r\n    override fun createFragment(): Fragment = AppInfoFragment().apply {\r\n        arguments = Bundle().apply {\r\n            putBoolean(\"isFlat\",false)\r\n        }\r\n    }\r\n\r\n    override fun getActivityTitle(): String = \"Acerca de\"\r\n\r\n    companion object{\r\n        fun open(context: Context){\r\n            context.startActivity(Intent(context,AppInfoActivity::class.java))\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/AppInfoActivityMaterial.kt",
    "content": "package knf.kuma\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport androidx.fragment.app.Fragment\r\nimport knf.kuma.custom.SingleFragmentMaterialActivity\r\n\r\nclass AppInfoActivityMaterial: SingleFragmentMaterialActivity() {\r\n    override fun createFragment(): Fragment = AppInfoFragment().apply {\r\n        arguments = Bundle().apply {\r\n            putBoolean(\"isFlat\",true)\r\n        }\r\n    }\r\n\r\n    override fun getActivityTitle(): String = \"Acerca de\"\r\n\r\n    companion object{\r\n        fun open(context: Context){\r\n            context.startActivity(Intent(context,AppInfoActivityMaterial::class.java))\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/AppInfoFragment.kt",
    "content": "package knf.kuma\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.net.Uri\r\nimport android.os.Bundle\r\nimport android.view.View\r\nimport androidx.appcompat.content.res.AppCompatResources.getDrawable\r\nimport androidx.core.net.toUri\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.danielstone.materialaboutlibrary.ConvenienceBuilder\r\nimport com.danielstone.materialaboutlibrary.MaterialAboutFragment\r\nimport com.danielstone.materialaboutlibrary.items.MaterialAboutActionItem\r\nimport com.danielstone.materialaboutlibrary.model.MaterialAboutCard\r\nimport com.danielstone.materialaboutlibrary.model.MaterialAboutList\r\nimport knf.kuma.ads.AdsUtils\r\nimport knf.kuma.ads.FullscreenAdLoader\r\nimport knf.kuma.ads.getFAdLoaderInterstitial\r\nimport knf.kuma.ads.getFAdLoaderRewarded\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.changelog.ChangelogActivity\r\nimport knf.kuma.changelog.ChangelogActivityMaterial\r\nimport knf.kuma.commons.DesignUtils\r\nimport knf.kuma.commons.EAUnlockActivity\r\nimport knf.kuma.commons.Economy\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.isFullMode\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.profile.TopActivity\r\nimport knf.kuma.profile.TopActivityMaterial\r\nimport knf.tools.kprobability.item\r\nimport knf.tools.kprobability.probabilityOf\r\nimport org.jetbrains.anko.support.v4.toast\r\n\r\nclass AppInfoFragment: MaterialAboutFragment() {\r\n    private val paypalUri: Uri\r\n        get() {\r\n            val uriBuilder = Uri.Builder()\r\n            uriBuilder.scheme(\"https\").authority(\"www.paypal.com\").path(\"cgi-bin/webscr\")\r\n            uriBuilder.appendQueryParameter(\"cmd\", \"_donations\")\r\n            uriBuilder.appendQueryParameter(\"business\", \"jordyamc@hotmail.com\")\r\n            uriBuilder.appendQueryParameter(\"lc\", \"US\")\r\n            uriBuilder.appendQueryParameter(\"item_name\", \"Donación UKIKU\")\r\n            uriBuilder.appendQueryParameter(\"no_note\", \"1\")\r\n            uriBuilder.appendQueryParameter(\"no_shipping\", \"1\")\r\n            uriBuilder.appendQueryParameter(\"currency_code\", \"USD\")\r\n            return uriBuilder.build()\r\n        }\r\n\r\n    private val isFlat: Boolean by lazy { requireArguments().getBoolean(\"isFlat\",true) }\r\n    private val rewardedAd: FullscreenAdLoader by lazy { getFAdLoaderRewarded(requireActivity()) }\r\n    private lateinit var interstitial: FullscreenAdLoader\r\n    private lateinit var videoItem: MaterialAboutActionItem\r\n\r\n    private fun showAd() {\r\n        probabilityOf<() -> Unit> {\r\n            item({ rewardedAd.show() }, AdsUtils.remoteConfigs.getDouble(\"rewarded_percent\"))\r\n            item({ interstitial.show() }, AdsUtils.remoteConfigs.getDouble(\"interstitial_percent\"))\r\n        }.random()()\r\n    }\r\n\r\n    private fun setupUpdateCount() {\r\n        Economy.rewardedVideoLiveData.observe(viewLifecycleOwner) {\r\n            if (::videoItem.isInitialized) {\r\n                videoItem.subText = \"Vistos: $it\"\r\n                setMaterialAboutList(getMaterialAboutList(requireContext()))\r\n            }\r\n        }\r\n    }\r\n\r\n\r\n    override fun getMaterialAboutList(context: Context): MaterialAboutList {\r\n        val infoCard = MaterialAboutCard.Builder()\r\n        infoCard.outline(isFlat)\r\n        infoCard.addItem(ConvenienceBuilder.createAppTitleItem(requireContext()))\r\n        infoCard.addItem(ConvenienceBuilder.createVersionActionItem(requireContext(), getDrawable(requireContext(),R.drawable.ic_version), \"Versión\", true))\r\n        infoCard.addItem(MaterialAboutActionItem.Builder().text(\"Changelog\").icon(R.drawable.ic_changelog_get).setOnClickAction { openChangelog() }.build())\r\n        infoCard.addItem(MaterialAboutActionItem.Builder().text(\"Diagnóstico\").icon(R.drawable.ic_diagnostic).setOnClickAction { openDiagnostic() }.build())\r\n        infoCard.addItem(MaterialAboutActionItem.Builder().text(\"Suscripción\").icon(R.drawable.ic_key).setOnClickAction {\r\n            if (Backups.isKeyInstalled) {\r\n                val intent = requireContext().packageManager.getLaunchIntentForPackage(\"knf.kuma.key\")\r\n                intent?.let { startActivity(intent) } ?: toast(\"Error al abrir UKIKU Key\")\r\n            } else {\r\n                MaterialDialog(requireContext()).safeShow {\r\n                    message(text = \"Con la suscripción podrás usar el backup por Firestore sin activar los anuncios!\")\r\n                    positiveButton(text = \"Suscribirse\") {\r\n                        startActivity(Intent(Intent.ACTION_VIEW, \"https://play.google.com/store/apps/details?id=knf.kuma.key\".toUri()))\r\n                    }\r\n                    negativeButton(text = \"cancelar\")\r\n                }\r\n            }\r\n        }.build())\r\n        val authorCard = MaterialAboutCard.Builder()\r\n        authorCard.outline(isFlat)\r\n        authorCard.title(\"Autor\")\r\n        authorCard.addItem(\r\n            ConvenienceBuilder.createWebsiteActionItem(\r\n                requireContext(),\r\n                getDrawable(requireContext(), R.drawable.ic_author),\r\n                \"Jordy Mendoza\",\r\n                true,\r\n                \"https://t.me/unbarred_stream\".toUri()\r\n            )\r\n        )\r\n        val donateCard = MaterialAboutCard.Builder()\r\n        if (isFullMode) {\r\n            donateCard.outline(isFlat)\r\n            donateCard.title(\"Donar\")\r\n            donateCard.addItem(\r\n                ConvenienceBuilder.createWebsiteActionItem(\r\n                    requireContext(),\r\n                    getDrawable(requireContext(), R.drawable.ic_paypal),\r\n                    \"Paypal\",\r\n                    false,\r\n                    \"https://www.paypal.com/donate/?hosted_button_id=9WXSCG3AP639J\".toUri()\r\n                )\r\n            )\r\n            donateCard.addItem(\r\n                ConvenienceBuilder.createWebsiteActionItem(\r\n                    requireContext(),\r\n                    getDrawable(requireContext(), R.drawable.ic_patreon),\r\n                    \"Patreon\",\r\n                    false,\r\n                    \"https://www.patreon.com/animeflvapp\".toUri()\r\n                )\r\n            )\r\n            donateCard.addItem(\r\n                ConvenienceBuilder.createWebsiteActionItem(\r\n                    requireContext(),\r\n                    getDrawable(requireContext(), R.drawable.ic_cuplogo),\r\n                    \"Ko-fi\",\r\n                    false,\r\n                    \"https://ko-fi.com/unbarredstream\".toUri()\r\n                )\r\n            )\r\n            donateCard.addItem(\r\n                MaterialAboutActionItem.Builder().text(\"Ver anuncio\")\r\n                    .subText(\"Vistos: ${PrefsUtil.userRewardedVideoCount}\").icon(R.drawable.ic_cash)\r\n                    .setOnClickAction {\r\n                        showAd()\r\n                    }.build().also { videoItem = it })\r\n        }\r\n        val extraCard = MaterialAboutCard.Builder()\r\n        extraCard.outline(isFlat)\r\n        extraCard.title(\"Extras\")\r\n        extraCard.addItem(\r\n            MaterialAboutActionItem.Builder().text(\"Cartera de loli-coins\").icon(R.drawable.ic_coin)\r\n                .setOnClickAction { Economy.showWallet(requireActivity(), true) { showAd() } }\r\n                .build()\r\n        )\r\n        extraCard.addItem(\r\n            MaterialAboutActionItem.Builder().text(\"Top videos vistos\").icon(R.drawable.ic_podium)\r\n                .setOnClickAction { openTop() }.build()\r\n        )\r\n        extraCard.addItem(\r\n            ConvenienceBuilder.createWebsiteActionItem(\r\n                requireContext(),\r\n                getDrawable(requireContext(), R.drawable.ic_web),\r\n                \"Politica de privacidad\",\r\n                true,\r\n                \"https://ukiku.app/policy.html\".toUri()\r\n            )\r\n        )\r\n        extraCard.addItem(\r\n            ConvenienceBuilder.createWebsiteActionItem(\r\n                requireContext(),\r\n                getDrawable(requireContext(), R.drawable.ic_github),\r\n                \"Proyecto en github\",\r\n                true,\r\n                \"https://github.com/jordyamc/UKIKU\".toUri()\r\n            )\r\n        )\r\n        extraCard.addItem(\r\n            ConvenienceBuilder.createWebsiteActionItem(\r\n                requireContext(),\r\n                getDrawable(requireContext(), R.drawable.ic_discord),\r\n                \"Discord\",\r\n                false,\r\n                \"https://discord.gg/6hzpua6\".toUri()\r\n            )\r\n        )\r\n        extraCard.addItem(\r\n            ConvenienceBuilder.createWebsiteActionItem(\r\n                requireContext(),\r\n                getDrawable(requireContext(), R.drawable.ic_beta),\r\n                \"Grupo Beta\",\r\n                false,\r\n                \"https://t.me/ukiku_group\".toUri()\r\n            )\r\n        )\r\n        extraCard.addItem(\r\n            MaterialAboutActionItem.Builder().text(\"Easter egg\").icon(R.drawable.ic_egg)\r\n                .setOnClickAction { EAUnlockActivity.start(requireContext()) }.build()\r\n        )\r\n        return MaterialAboutList.Builder().apply {\r\n            addCard(infoCard.build())\r\n            addCard(authorCard.build())\r\n            donateCard.build().let {\r\n                if (it.items.isNotEmpty()) addCard(it)\r\n            }\r\n            addCard(extraCard.build())\r\n        }.build()\r\n    }\r\n\r\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\r\n        super.onViewCreated(view, savedInstanceState)\r\n        interstitial = getFAdLoaderInterstitial(requireActivity())\r\n        rewardedAd.load()\r\n        interstitial.load()\r\n        setupUpdateCount()\r\n    }\r\n\r\n    fun openChangelog(){\r\n        if (DesignUtils.isFlat)\r\n            ChangelogActivityMaterial.open(requireContext())\r\n        else\r\n            ChangelogActivity.open(requireContext())\r\n    }\r\n\r\n    fun openDiagnostic(){\r\n        if (DesignUtils.isFlat)\r\n            DiagnosticMaterial.open(requireContext())\r\n        else\r\n            Diagnostic.open(requireContext())\r\n    }\r\n\r\n    fun openTop() {\r\n        if (DesignUtils.isFlat)\r\n            TopActivityMaterial.open(requireContext())\r\n        else\r\n            TopActivity.open(requireContext())\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/BottomFragment.kt",
    "content": "package knf.kuma\n\nimport android.app.Activity\nimport android.content.Intent\n\nimport androidx.fragment.app.Fragment\nimport knf.kuma.download.FileAccessHelper\nimport xdroid.toaster.Toaster\n\nabstract class BottomFragment : Fragment() {\n    abstract fun onReselect()\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        if (requestCode == FileAccessHelper.SD_REQUEST && resultCode == Activity.RESULT_OK) {\n            val validation = FileAccessHelper.isUriValid(data?.data)\n            if (!validation.isValid) {\n                Toaster.toast(\"Directorio invalido: $validation\")\n                FileAccessHelper.openTreeChooser(this)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/Diagnostic.kt",
    "content": "package knf.kuma\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport android.text.format.Formatter\r\nimport android.text.method.ScrollingMovementMethod\r\nimport android.view.View\r\nimport android.widget.TextView\r\nimport androidx.core.view.isVisible\r\nimport androidx.lifecycle.lifecycleScope\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\r\nimport fr.bmartel.speedtest.SpeedTestReport\r\nimport fr.bmartel.speedtest.SpeedTestSocket\r\nimport fr.bmartel.speedtest.inter.ISpeedTestListener\r\nimport fr.bmartel.speedtest.model.SpeedTestError\r\nimport knf.kuma.ads.SubscriptionReceiver\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.backup.firestore.FirestoreManager\r\nimport knf.kuma.commons.BypassUtil\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.jsoupCookies\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.custom.StateView\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.databinding.LayoutDiagnosticBinding\r\nimport knf.kuma.directory.DirectoryService\r\nimport knf.kuma.directory.DirectoryUpdateService\r\nimport knf.kuma.uagen.randomUA\r\nimport knf.tools.bypass.startBypass\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.find\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\nimport org.json.JSONObject\r\nimport org.jsoup.HttpStatusException\r\nimport org.jsoup.Jsoup\r\nimport java.math.BigDecimal\r\nimport java.math.RoundingMode\r\nimport java.net.ConnectException\r\nimport java.net.URL\r\nimport java.net.UnknownHostException\r\n\r\nclass Diagnostic : GenericActivity() {\r\n\r\n    private val binding by lazy { LayoutDiagnosticBinding.inflate(layoutInflater) }\r\n    private val networkStatus by lazy { NetworkStatus() }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(binding.root)\r\n        setSupportActionBar(binding.toolbar)\r\n        supportActionBar?.title = \"Diagnóstico\"\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        binding.toolbar.setNavigationOnClickListener { finish() }\r\n        startTests()\r\n    }\r\n\r\n    private fun startTests() {\r\n        runNetworkTests()\r\n        //runInternetTest()\r\n        runDirectoryTest()\r\n        runMemoryTest()\r\n        runBackupTest()\r\n    }\r\n\r\n    private suspend fun runMainTest() {\r\n        val startTime = System.currentTimeMillis()\r\n        val responseCode = try {\r\n            val response = Jsoup.connect(BypassUtil.testLink).timeout(0).execute()\r\n            response.body()\r\n            response.statusCode()\r\n        } catch (e: HttpStatusException) {\r\n            e.statusCode\r\n        } catch (_: UnknownHostException) {\r\n            3000\r\n        } catch (_: ConnectException) {\r\n            4000\r\n        } catch (_: Exception) {\r\n            5000\r\n        }\r\n        networkStatus.mainResult = responseCode\r\n        val loadingTime = System.currentTimeMillis() - startTime\r\n        withContext(Dispatchers.Main) {\r\n            binding.codeState.load(\r\n                responseCode.toString(), when (responseCode) {\r\n                    200 -> StateView.STATE_OK\r\n                    503 -> StateView.STATE_WARNING\r\n                    else -> StateView.STATE_ERROR\r\n                }\r\n            )\r\n            binding.timeoutState.load(\r\n                \"$loadingTime ms\", when {\r\n                    responseCode < 1000 && loadingTime < 1000 -> StateView.STATE_OK\r\n                    responseCode < 1000 && loadingTime < 2000 -> StateView.STATE_WARNING\r\n                    else -> StateView.STATE_ERROR\r\n                }\r\n            )\r\n            binding.generalState.load(when {\r\n                responseCode == 200 && loadingTime < 1000 -> \"Correcto\"\r\n                responseCode == 502 -> \"Animeflv caido\"\r\n                responseCode == 503 -> \"Cloudflare activado\"\r\n                responseCode == 403 -> \"Bloqueado por animeflv\"\r\n                responseCode in listOf(3000, 4000) -> \"Error de conexión a Animeflv\"\r\n                responseCode == 5000 -> \"Error al intentar conectar\"\r\n                loadingTime > 1000 -> \"Página lenta\"\r\n                else -> \"Desconocido\"\r\n            }, when {\r\n                responseCode == 200 && loadingTime < 1000 -> StateView.STATE_OK.also {\r\n                    binding.info.visibility = View.GONE\r\n                }\r\n                responseCode in listOf(503, 403) || loadingTime > 1000 -> StateView.STATE_WARNING.also {\r\n                    binding.info.visibility = View.VISIBLE\r\n                }\r\n                responseCode == 502 -> StateView.STATE_ERROR.also {\r\n                    binding.info.visibility = View.VISIBLE\r\n                }\r\n                else -> StateView.STATE_ERROR.also { binding.info.visibility = View.GONE }\r\n            })\r\n            binding.info.setOnClickListener {\r\n                when {\r\n                    networkStatus.mainResult == 502 -> show502Info()\r\n                    networkStatus.mainResult == 503 -> show503Info()\r\n                    networkStatus.mainResult == 403 -> show403Info()\r\n                    loadingTime > 1000 -> showTimeoutInfo()\r\n                }\r\n            }\r\n        }\r\n        networkStatus.isMainTestExecuted = true\r\n    }\r\n\r\n    private suspend fun runBypassTest() {\r\n        try {\r\n            Jsoup.connect(BypassUtil.testLink).followRedirects(true).timeout(0).execute()\r\n            binding.bypassState.load(\"No se necesita\")\r\n            withContext(Dispatchers.Main) { binding.bypassRecreate.visibility = View.GONE }\r\n        } catch (e: HttpStatusException) {\r\n            withContext(Dispatchers.Main) {\r\n                binding.bypassRecreate.apply {\r\n                    visibility = View.VISIBLE\r\n                    onClick {\r\n                        startBypass(\r\n                            5546,\r\n                            BypassUtil.createRequest()\r\n                        )\r\n                    }\r\n                }\r\n            }\r\n            try {\r\n                jsoupCookies(BypassUtil.testLink).timeout(0).get()\r\n                binding.bypassState.load(\"Valido\", StateView.STATE_OK)\r\n                if (networkStatus.isMainTestExecuted && networkStatus.mainResult in listOf(\r\n                        403,\r\n                        503\r\n                    )\r\n                ) {\r\n                    withContext(Dispatchers.Main) {\r\n                        binding.codeState.load(\"200\", StateView.STATE_OK)\r\n                        binding.generalState.load(\"Bypass activo\", StateView.STATE_OK)\r\n                        binding.info.isVisible = false\r\n                    }\r\n                }\r\n            } catch (e: HttpStatusException) {\r\n                when (e.statusCode) {\r\n                    502 -> binding.bypassState.load(\"Animeflv caido\", StateView.STATE_ERROR)\r\n                    503 -> binding.bypassState.load(\"Caducado\", StateView.STATE_WARNING)\r\n                    else -> binding.bypassState.load(\r\n                        \"Error en página: HTTP ${e.statusCode}\",\r\n                        StateView.STATE_ERROR\r\n                    )\r\n                }\r\n            }\r\n            loadBypassInfo()\r\n        } catch (e: Exception) {\r\n            e.printStackTrace()\r\n            binding.bypassState.load(\"Error en página: ${e.message}\", StateView.STATE_ERROR)\r\n        }\r\n        networkStatus.isBypassTestExecuted = true\r\n    }\r\n\r\n    private fun runNetworkTests() {\r\n        lifecycleScope.launch(Dispatchers.IO) {\r\n            runMainTest()\r\n            runBypassTest()\r\n        }\r\n    }\r\n\r\n    private fun loadBypassInfo() {\r\n        doAsync {\r\n            val json = JSONObject(URL(\"https://ipinfo.io/json\").readText())\r\n            val region = json.getString(\"region\")\r\n            val country = json.getString(\"country\")\r\n            if (country == \"PE\") {\r\n                binding.countryState.load(\"$region - VPN necesario\", StateView.STATE_ERROR)\r\n            } else {\r\n                binding.countryState.load(region, StateView.STATE_OK)\r\n            }\r\n        }\r\n        binding.clearanceState.apply {\r\n            val data = BypassUtil.getClearance(this@Diagnostic)\r\n            if (data.isNotEmpty())\r\n                load(data)\r\n        }\r\n        binding.cfduidState.apply {\r\n            val data = BypassUtil.getCFDuid(this@Diagnostic)\r\n            if (data.isNotEmpty())\r\n                load(data)\r\n        }\r\n        binding.userAgentState.apply {\r\n            load(BypassUtil.userAgent)\r\n        }\r\n    }\r\n\r\n    private fun runInternetTest() {\r\n        doAsync {\r\n            SpeedTestSocket().apply {\r\n                addSpeedTestListener(object : ISpeedTestListener {\r\n                    override fun onCompletion(report: SpeedTestReport?) {\r\n                        report?.let { binding.downState.load(formatBigDecimal(it.transferRateOctet)) }\r\n                    }\r\n\r\n                    override fun onProgress(percent: Float, report: SpeedTestReport?) {\r\n                        report?.let { binding.downState.load(formatBigDecimal(it.transferRateOctet)) }\r\n                    }\r\n\r\n                    override fun onError(speedTestError: SpeedTestError?, errorMessage: String?) {\r\n                        binding.downState.load(\"Error: ${errorMessage ?: \"\"}\", StateView.STATE_ERROR)\r\n                    }\r\n                })\r\n                startDownload(\"http://1.testdebit.info/10M.iso\")\r\n            }\r\n        }\r\n        doAsync {\r\n            SpeedTestSocket().apply {\r\n                addSpeedTestListener(object : ISpeedTestListener {\r\n                    override fun onCompletion(report: SpeedTestReport?) {\r\n                        report?.let { binding.upState.load(formatBigDecimal(it.transferRateOctet)) }\r\n                    }\r\n\r\n                    override fun onProgress(percent: Float, report: SpeedTestReport?) {\r\n                        report?.let { binding.upState.load(formatBigDecimal(it.transferRateOctet)) }\r\n                    }\r\n\r\n                    override fun onError(speedTestError: SpeedTestError?, errorMessage: String?) {\r\n                        binding.upState.load(\"Error: ${errorMessage ?: \"\"}\", StateView.STATE_ERROR)\r\n                    }\r\n                })\r\n                startUpload(\"http://ipv4.ikoula.testdebit.info/\", 5000000)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun formatBigDecimal(bigDecimal: BigDecimal): String {\r\n        var decimal = bigDecimal.movePointLeft(3)\r\n        val unit = when {\r\n            decimal >= BigDecimal.valueOf(1000000) -> {\r\n                decimal = decimal.movePointLeft(6)\r\n                \"Gb/s\"\r\n            }\r\n            decimal >= BigDecimal.valueOf(1000) -> {\r\n                decimal = decimal.movePointLeft(3)\r\n                \"Mb/s\"\r\n            }\r\n            else -> \"Kb/s\"\r\n        }\r\n        return \"${decimal.setScale(1, RoundingMode.HALF_UP)}$unit~\"\r\n    }\r\n\r\n    private fun runDirectoryTest() {\r\n        binding.dirState.load(\r\n            when {\r\n                PrefsUtil.isDirectoryFinished && !DirectoryUpdateService.isRunning -> \"Completo\"\r\n                PrefsUtil.isDirectoryFinished && DirectoryUpdateService.isRunning -> \"Actualizando\"\r\n                !PrefsUtil.isDirectoryFinished && DirectoryService.isRunning -> \"Creando\"\r\n                else -> \"Incompleto\"\r\n            }\r\n        )\r\n        CacheDB.INSTANCE.animeDAO().countLive.observe(this) {\r\n            binding.dirTotalState.load(it.toString())\r\n        }\r\n    }\r\n\r\n    private fun runMemoryTest() {\r\n        val dirs = getExternalFilesDirs(null)\r\n        noCrash {\r\n            binding.internalState.load(getAvailable(dirs[0].freeSpace))\r\n        }\r\n        noCrash {\r\n            if (dirs.size > 1)\r\n                binding.externalState.load(getAvailable(dirs[1].freeSpace))\r\n        }\r\n    }\r\n\r\n    private fun getAvailable(size: Long): String {\r\n        return Formatter.formatFileSize(this, size)\r\n    }\r\n\r\n    private fun runBackupTest() {\r\n        binding.uuid.text = FirestoreManager.uid ?: \"Solo firestore\"\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            if (PrefsUtil.isSubscriptionEnabled) {\r\n                val status = SubscriptionReceiver.checkStatus(\r\n                    PrefsUtil.subscriptionToken\r\n                        ?: \"\"\r\n                )\r\n                if (status.isActive) {\r\n                    if (status.isActive)\r\n                        binding.subscriptionState.load(\"Activa\")\r\n                    else\r\n                        binding.subscriptionState.load(\"Activa pero no renovada\")\r\n                } else\r\n                    binding.subscriptionState.load(\"Cancelada o inexistente\")\r\n            } else\r\n                binding.subscriptionState.load(\"No suscrito\")\r\n        }\r\n        binding.backupState.load(\r\n            when (Backups.type) {\r\n                Backups.Type.DROPBOX -> \"Dropbox\"\r\n                Backups.Type.FIRESTORE -> \"Firestore\"\r\n                Backups.Type.LOCAL -> \"Local\"\r\n                else -> \"Sin respaldos\"\r\n            }\r\n        )\r\n        if (Backups.type != Backups.Type.NONE)\r\n            binding.lastBackupState.load(PrefsUtil.lastBackup)\r\n    }\r\n\r\n    private fun show502Info() {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"HTTP 502\")\r\n            message(text = \"Animeflv esta caido por el momento, revisa de nuevo en unas horas\")\r\n        }\r\n    }\r\n\r\n    private fun show503Info() {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"HTTP 503\")\r\n            message(text = \"Animeflv tiene el cloudflare activado, la app crea un bypass para funcionar normalmente\")\r\n        }\r\n    }\r\n\r\n    private fun show403Info() {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"HTTP 403\")\r\n            message(text = \"Tu proveedor de internet bloquea la conexión con Animeflv, reinicia tu modem!\")\r\n        }\r\n    }\r\n\r\n    private fun showTimeoutInfo() {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"Timeout\")\r\n            message(text = \"La página de Animeflv carga muy lento, modifica la espera de conexión desde configuración\")\r\n        }\r\n    }\r\n\r\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\r\n        super.onActivityResult(requestCode, resultCode, data)\r\n        if (requestCode == 5546) {\r\n            data?.let {\r\n                PrefsUtil.useDefaultUserAgent = false\r\n                PrefsUtil.userAgent = it.getStringExtra(\"user_agent\") ?: randomUA()\r\n                BypassUtil.saveCookies(this, it.getStringExtra(\"cookies\") ?: \"null\")\r\n            }\r\n            runNetworkTests()\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        fun open(context: Context) {\r\n            context.startActivity(Intent(context, Diagnostic::class.java))\r\n        }\r\n    }\r\n\r\n    private data class NetworkStatus(\r\n        var isMainTestExecuted: Boolean = false,\r\n        var isBypassTestExecuted: Boolean = false,\r\n        var mainResult: Int = -1,\r\n    )\r\n\r\n    class FullBypass : GenericActivity() {\r\n        private val overlay: View by lazy { find(R.id.overlay) as View }\r\n        private val logText: TextView by lazy { find(R.id.logText) as TextView }\r\n        private val fab: FloatingActionButton by lazy { find(R.id.fab) as FloatingActionButton }\r\n        private var isOpened = false\r\n        private var isFinishPending = false\r\n        private val builder = StringBuilder(\"Initializing log...\\n\")\r\n        override fun onCreate(savedInstanceState: Bundle?) {\r\n            setTheme(EAHelper.getTheme())\r\n            super.onCreate(savedInstanceState)\r\n            try {\r\n                setContentView(R.layout.activity_webview)\r\n            } catch (e: Exception) {\r\n                setContentView(R.layout.activity_webview_nwv)\r\n            }\r\n            logText.movementMethod = ScrollingMovementMethod()\r\n            fab.setOnClickListener {\r\n                if (isOpened && isFinishPending)\r\n                    finish()\r\n                else if (isOpened) {\r\n                    isOpened = false\r\n                    overlay.visibility = View.GONE\r\n                    logText.visibility = View.GONE\r\n                    fab.setImageResource(R.drawable.ic_terminal)\r\n                } else {\r\n                    isOpened = true\r\n                    overlay.visibility = View.VISIBLE\r\n                    logText.visibility = View.VISIBLE\r\n                    fab.setImageResource(R.drawable.ic_close)\r\n                }\r\n            }\r\n            logText(\"On Create check\")\r\n            checkBypass()\r\n        }\r\n\r\n        override fun forceCreation(): Boolean = true\r\n\r\n        //override fun getSnackbarAnchor(): View? = find(R.id.coordinator)\r\n\r\n        override fun onBypassUpdated() {\r\n            if (isOpened)\r\n                isFinishPending = true\r\n            else\r\n                finish()\r\n        }\r\n\r\n        override fun logText(text: String) {\r\n            super.logText(text)\r\n            builder.apply {\r\n                append(text)\r\n                append(\"\\n\")\r\n            }\r\n            doOnUI { logText.text = builder.toString() }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/DiagnosticMaterial.kt",
    "content": "package knf.kuma\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport android.text.format.Formatter\r\nimport android.text.method.ScrollingMovementMethod\r\nimport android.view.View\r\nimport android.widget.TextView\r\nimport androidx.core.view.isVisible\r\nimport androidx.lifecycle.Observer\r\nimport androidx.lifecycle.lifecycleScope\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\r\nimport fr.bmartel.speedtest.SpeedTestReport\r\nimport fr.bmartel.speedtest.SpeedTestSocket\r\nimport fr.bmartel.speedtest.inter.ISpeedTestListener\r\nimport fr.bmartel.speedtest.model.SpeedTestError\r\nimport knf.kuma.ads.SubscriptionReceiver\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.backup.firestore.FirestoreManager\r\nimport knf.kuma.commons.BypassUtil\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.jsoupCookies\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.commons.setSurfaceBars\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.custom.StateView\r\nimport knf.kuma.custom.StateViewMaterial\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.databinding.LayoutDiagnosticMaterialBinding\r\nimport knf.kuma.directory.DirectoryService\r\nimport knf.kuma.directory.DirectoryUpdateService\r\nimport knf.kuma.uagen.randomUA\r\nimport knf.tools.bypass.startBypass\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.find\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\nimport org.json.JSONObject\r\nimport org.jsoup.HttpStatusException\r\nimport org.jsoup.Jsoup\r\nimport java.math.BigDecimal\r\nimport java.math.RoundingMode\r\nimport java.net.ConnectException\r\nimport java.net.URL\r\nimport java.net.UnknownHostException\r\n\r\nclass DiagnosticMaterial : GenericActivity() {\r\n\r\n    private val binding by lazy { LayoutDiagnosticMaterialBinding.inflate(layoutInflater) }\r\n    private val networkStatus by lazy { NetworkStatus() }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setSurfaceBars()\r\n        setContentView(binding.root)\r\n        setSupportActionBar(binding.toolbar)\r\n        supportActionBar?.title = \"Diagnóstico\"\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        binding.toolbar.setNavigationOnClickListener { finish() }\r\n        startTests()\r\n    }\r\n\r\n    private fun startTests() {\r\n        runNetworkTests()\r\n        //runInternetTest()\r\n        runDirectoryTest()\r\n        runMemoryTest()\r\n        runBackupTest()\r\n    }\r\n\r\n    private suspend fun runMainTest() {\r\n        val startTime = System.currentTimeMillis()\r\n        val responseCode = try {\r\n            val response = Jsoup.connect(BypassUtil.testLink).timeout(0).execute()\r\n            response.body()\r\n            response.statusCode()\r\n        } catch (e: HttpStatusException) {\r\n            e.statusCode\r\n        } catch (_: UnknownHostException) {\r\n            404\r\n        } catch (_: ConnectException) {\r\n            4000\r\n        } catch (_: Throwable) {\r\n            5000\r\n        }\r\n        networkStatus.mainResult = responseCode\r\n        val loadingTime = System.currentTimeMillis() - startTime\r\n        withContext(Dispatchers.Main) {\r\n            binding.codeState.load(\r\n                responseCode.toString(), when (responseCode) {\r\n                    200 -> StateView.STATE_OK\r\n                    503 -> StateView.STATE_WARNING\r\n                    else -> StateView.STATE_ERROR\r\n                }\r\n            )\r\n            binding.timeoutState.load(\r\n                \"$loadingTime ms\", when {\r\n                    responseCode < 1000 && loadingTime < 1000 -> StateView.STATE_OK\r\n                    responseCode < 1000 && loadingTime < 2000 -> StateView.STATE_WARNING\r\n                    else -> StateView.STATE_ERROR\r\n                }\r\n            )\r\n            binding.generalState.load(when {\r\n                responseCode == 200 && loadingTime < 1000 -> \"Correcto\"\r\n                responseCode == 502 -> \"Animeflv caido\"\r\n                responseCode == 503 -> \"Cloudflare activado\"\r\n                responseCode == 403 -> \"Bloqueado por animeflv\"\r\n                responseCode in listOf(3000, 4000) -> \"Error de conexión a Animeflv\"\r\n                responseCode == 5000 -> \"Error al intentar conectar\"\r\n                loadingTime > 1000 -> \"Página lenta\"\r\n                else -> \"Desconocido\"\r\n            }, when {\r\n                responseCode == 200 && loadingTime < 1000 -> StateView.STATE_OK.also {\r\n                    binding.info.visibility = View.GONE\r\n                }\r\n                responseCode in listOf(503, 403) || loadingTime > 1000 -> StateView.STATE_WARNING.also {\r\n                    binding.info.visibility = View.VISIBLE\r\n                }\r\n                responseCode == 502 -> StateView.STATE_ERROR.also {\r\n                    binding.info.visibility = View.VISIBLE\r\n                }\r\n                else -> StateView.STATE_ERROR.also { binding.info.visibility = View.GONE }\r\n            })\r\n            binding.info.setOnClickListener {\r\n                when {\r\n                    networkStatus.mainResult == 502 -> show502Info()\r\n                    networkStatus.mainResult == 503 -> show503Info()\r\n                    networkStatus.mainResult == 403 -> show403Info()\r\n                    loadingTime > 1000 -> showTimeoutInfo()\r\n                }\r\n            }\r\n        }\r\n        networkStatus.isMainTestExecuted = true\r\n    }\r\n\r\n    private suspend fun runBypassTest() {\r\n        try {\r\n            Jsoup.connect(BypassUtil.testLink).followRedirects(true).timeout(0).execute()\r\n            binding.bypassState.load(\"No se necesita\")\r\n            withContext(Dispatchers.Main) { binding.bypassRecreate.visibility = View.GONE }\r\n        } catch (e: HttpStatusException) {\r\n            withContext(Dispatchers.Main) {\r\n                binding.bypassRecreate.apply {\r\n                    visibility = View.VISIBLE\r\n                    onClick {\r\n                        startBypass(\r\n                            5546,\r\n                            BypassUtil.createRequest()\r\n                        )\r\n                    }\r\n                }\r\n            }\r\n            try {\r\n                jsoupCookies(BypassUtil.testLink).timeout(0).get()\r\n                binding.bypassState.load(\"Valido\", StateView.STATE_OK)\r\n                if (networkStatus.isMainTestExecuted && networkStatus.mainResult in listOf(\r\n                        403,\r\n                        503\r\n                    )\r\n                ) {\r\n                    withContext(Dispatchers.Main) {\r\n                        binding.codeState.load(\"200\", StateView.STATE_OK)\r\n                        binding.generalState.load(\"Bypass activo\", StateView.STATE_OK)\r\n                        binding.info.isVisible = false\r\n                    }\r\n                }\r\n            } catch (e: HttpStatusException) {\r\n                when (e.statusCode) {\r\n                    502 -> binding.bypassState.load(\"Animeflv caido\", StateView.STATE_ERROR)\r\n                    503 -> binding.bypassState.load(\"Caducado\", StateView.STATE_WARNING)\r\n                    else -> binding.bypassState.load(\r\n                        \"Error en página: HTTP ${e.statusCode}\",\r\n                        StateView.STATE_ERROR\r\n                    )\r\n                }\r\n            }\r\n            loadBypassInfo()\r\n        } catch (e: Throwable) {\r\n            e.printStackTrace()\r\n            binding.bypassState.load(\"Error en página: ${e.message}\", StateView.STATE_ERROR)\r\n        }\r\n        networkStatus.isBypassTestExecuted = true\r\n    }\r\n\r\n    private fun runNetworkTests() {\r\n        lifecycleScope.launch(Dispatchers.IO) {\r\n            runMainTest()\r\n            runBypassTest()\r\n        }\r\n    }\r\n\r\n    private fun loadBypassInfo() {\r\n        doAsync {\r\n            val json = JSONObject(URL(\"https://ipinfo.io/json\").readText())\r\n            val region = json.getString(\"region\")\r\n            val country = json.getString(\"country\")\r\n            if (country == \"PE\") {\r\n                binding.countryState.load(\"$region - VPN necesario\", StateView.STATE_ERROR)\r\n            } else {\r\n                binding.countryState.load(region, StateView.STATE_OK)\r\n            }\r\n        }\r\n        binding.clearanceState.apply {\r\n            val data = BypassUtil.getClearance(this@DiagnosticMaterial)\r\n            if (data.isNotEmpty())\r\n                load(data)\r\n        }\r\n        binding.cfduidState.apply {\r\n            val data = BypassUtil.getCFDuid(this@DiagnosticMaterial)\r\n            if (data.isNotEmpty())\r\n                load(data)\r\n        }\r\n        binding.userAgentState.apply {\r\n            load(BypassUtil.userAgent)\r\n        }\r\n    }\r\n\r\n    private fun runInternetTest() {\r\n        doAsync {\r\n            SpeedTestSocket().apply {\r\n                addSpeedTestListener(object : ISpeedTestListener {\r\n                    override fun onCompletion(report: SpeedTestReport?) {\r\n                        report?.let { binding.downState.load(formatBigDecimal(it.transferRateOctet)) }\r\n                    }\r\n\r\n                    override fun onProgress(percent: Float, report: SpeedTestReport?) {\r\n                        report?.let { binding.downState.load(formatBigDecimal(it.transferRateOctet)) }\r\n                    }\r\n\r\n                    override fun onError(speedTestError: SpeedTestError?, errorMessage: String?) {\r\n                        binding.downState.load(\"Error: ${errorMessage ?: \"\"}\", StateViewMaterial.STATE_ERROR)\r\n                    }\r\n                })\r\n                startDownload(\"https://speed.hetzner.de/100MB.bin\")\r\n            }\r\n        }\r\n        doAsync {\r\n            SpeedTestSocket().apply {\r\n                addSpeedTestListener(object : ISpeedTestListener {\r\n                    override fun onCompletion(report: SpeedTestReport?) {\r\n                        report?.let { binding.upState.load(formatBigDecimal(it.transferRateOctet)) }\r\n                    }\r\n\r\n                    override fun onProgress(percent: Float, report: SpeedTestReport?) {\r\n                        report?.let { binding.upState.load(formatBigDecimal(it.transferRateOctet)) }\r\n                    }\r\n\r\n                    override fun onError(speedTestError: SpeedTestError?, errorMessage: String?) {\r\n                        binding.upState.load(\"Error: ${errorMessage ?: \"\"}\", StateViewMaterial.STATE_ERROR)\r\n                    }\r\n                })\r\n                startUpload(\"http://bouygues.testdebit.info/ul/\", 5000000)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun formatBigDecimal(bigDecimal: BigDecimal): String {\r\n        var decimal = bigDecimal.movePointLeft(3)\r\n        val unit = when {\r\n            decimal >= BigDecimal.valueOf(1000000) -> {\r\n                decimal = decimal.movePointLeft(6)\r\n                \"Gb/s\"\r\n            }\r\n            decimal >= BigDecimal.valueOf(1000) -> {\r\n                decimal = decimal.movePointLeft(3)\r\n                \"Mb/s\"\r\n            }\r\n            else -> \"Kb/s\"\r\n        }\r\n        return \"${decimal.setScale(1, RoundingMode.HALF_UP)}$unit~\"\r\n    }\r\n\r\n    private fun runDirectoryTest() {\r\n        binding.dirState.load(when {\r\n            PrefsUtil.isDirectoryFinished && !DirectoryUpdateService.isRunning -> \"Completo\"\r\n            PrefsUtil.isDirectoryFinished && DirectoryUpdateService.isRunning -> \"Actualizando\"\r\n            !PrefsUtil.isDirectoryFinished && DirectoryService.isRunning -> \"Creando\"\r\n            else -> \"Incompleto\"\r\n        })\r\n        CacheDB.INSTANCE.animeDAO().countLive.observe(this, Observer {\r\n            binding.dirTotalState.load(it.toString())\r\n        })\r\n    }\r\n\r\n    private fun runMemoryTest() {\r\n        val dirs = getExternalFilesDirs(null).toList().filterNotNull()\r\n        noCrash {\r\n            binding.internalState.load(getAvailable(dirs[0].freeSpace))\r\n        }\r\n        noCrash {\r\n            if (dirs.size > 1)\r\n                binding.externalState.load(getAvailable(dirs[1].freeSpace))\r\n        }\r\n    }\r\n\r\n    private fun getAvailable(size: Long): String {\r\n        return Formatter.formatFileSize(this, size)\r\n    }\r\n\r\n    private fun runBackupTest() {\r\n        binding.uuid.text = FirestoreManager.uid ?: \"Solo firestore\"\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            if (PrefsUtil.isSubscriptionEnabled) {\r\n                val status = SubscriptionReceiver.checkStatus(PrefsUtil.subscriptionToken\r\n                        ?: \"\")\r\n                if (status.isActive) {\r\n                    if (status.isActive)\r\n                        binding.subscriptionState.load(\"Activa\")\r\n                    else\r\n                        binding.subscriptionState.load(\"Activa pero no renovada\")\r\n                } else\r\n                    binding.subscriptionState.load(\"Cancelada o inexistente\")\r\n            } else\r\n                binding.subscriptionState.load(\"No suscrito\")\r\n        }\r\n        binding.backupState.load(when (Backups.type) {\r\n            Backups.Type.DROPBOX -> \"Dropbox\"\r\n            Backups.Type.FIRESTORE -> \"Firestore\"\r\n            Backups.Type.LOCAL -> \"Local\"\r\n            else -> \"Sin respaldos\"\r\n        })\r\n        if (Backups.type != Backups.Type.NONE)\r\n            binding.lastBackupState.load(PrefsUtil.lastBackup)\r\n    }\r\n\r\n    private fun show502Info() {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"HTTP 502\")\r\n            message(text = \"Animeflv esta caido por el momento, revisa de nuevo en unas horas\")\r\n        }\r\n    }\r\n\r\n    private fun show503Info() {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"HTTP 503\")\r\n            message(text = \"Animeflv tiene el cloudflare activado, la app crea un bypass para funcionar normalmente\")\r\n        }\r\n    }\r\n\r\n    private fun show403Info() {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"HTTP 403\")\r\n            message(text = \"Tu proveedor de internet bloquea la conexión con Animeflv, reinicia tu modem!\")\r\n        }\r\n    }\r\n\r\n    private fun showTimeoutInfo() {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"Timeout\")\r\n            message(text = \"La página de Animeflv carga muy lento, modifica la espera de conexión desde configuración\")\r\n        }\r\n    }\r\n\r\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\r\n        super.onActivityResult(requestCode, resultCode, data)\r\n        if (requestCode == 5546) {\r\n            data?.let {\r\n                PrefsUtil.useDefaultUserAgent = false\r\n                PrefsUtil.userAgent = it.getStringExtra(\"user_agent\") ?: randomUA()\r\n                BypassUtil.saveCookies(this, it.getStringExtra(\"cookies\") ?: \"null\")\r\n            }\r\n            runNetworkTests()\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        fun open(context: Context) {\r\n            context.startActivity(Intent(context, DiagnosticMaterial::class.java))\r\n        }\r\n    }\r\n\r\n    private data class NetworkStatus(\r\n        var isMainTestExecuted: Boolean = false,\r\n        var isBypassTestExecuted: Boolean = false,\r\n        var mainResult: Int = -1,\r\n    )\r\n\r\n    class FullBypass : GenericActivity() {\r\n        private val overlay: View by lazy { find(R.id.overlay) as View }\r\n        private val logText: TextView by lazy { find(R.id.logText) as TextView }\r\n        private val fab: FloatingActionButton by lazy { find(R.id.fab) as FloatingActionButton }\r\n        private var isOpened = false\r\n        private var isFinishPending = false\r\n        private val builder = StringBuilder(\"Initializing log...\\n\")\r\n        override fun onCreate(savedInstanceState: Bundle?) {\r\n            setTheme(EAHelper.getTheme())\r\n            super.onCreate(savedInstanceState)\r\n            try {\r\n                setContentView(R.layout.activity_webview)\r\n            } catch (e: Exception) {\r\n                setContentView(R.layout.activity_webview_nwv)\r\n            }\r\n            logText.movementMethod = ScrollingMovementMethod()\r\n            fab.setOnClickListener {\r\n                if (isOpened && isFinishPending)\r\n                    finish()\r\n                else if (isOpened) {\r\n                    isOpened = false\r\n                    overlay.visibility = View.GONE\r\n                    logText.visibility = View.GONE\r\n                    fab.setImageResource(R.drawable.ic_terminal)\r\n                } else {\r\n                    isOpened = true\r\n                    overlay.visibility = View.VISIBLE\r\n                    logText.visibility = View.VISIBLE\r\n                    fab.setImageResource(R.drawable.ic_close)\r\n                }\r\n            }\r\n            logText(\"On Create check\")\r\n            checkBypass()\r\n        }\r\n\r\n        override fun forceCreation(): Boolean = true\r\n\r\n        //override fun getSnackbarAnchor(): View? = find(R.id.coordinator)\r\n\r\n        override fun onBypassUpdated() {\r\n            if (isOpened)\r\n                isFinishPending = true\r\n            else\r\n                finish()\r\n        }\r\n\r\n        override fun logText(text: String) {\r\n            super.logText(text)\r\n            builder.apply {\r\n                append(text)\r\n                append(\"\\n\")\r\n            }\r\n            lifecycleScope.launch(Dispatchers.Main) { logText.text = builder.toString() }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/Main.kt",
    "content": "package knf.kuma\n\nimport androidx.activity.addCallback\nimport android.Manifest\nimport android.annotation.SuppressLint\nimport android.annotation.TargetApi\nimport android.content.ActivityNotFoundException\nimport android.content.Intent\nimport android.content.pm.ActivityInfo\nimport android.content.pm.PackageManager\nimport android.graphics.Typeface\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport android.os.Handler\nimport android.provider.Settings\nimport android.text.InputType\nimport android.util.Log\nimport android.view.Gravity\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.TextView\nimport androidx.appcompat.app.ActionBarDrawerToggle\nimport androidx.appcompat.widget.Toolbar\nimport androidx.coordinatorlayout.widget.CoordinatorLayout\nimport androidx.core.app.ActivityCompat\nimport androidx.core.content.ContextCompat\nimport androidx.core.view.GravityCompat\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.drawerlayout.widget.DrawerLayout\nimport androidx.lifecycle.lifecycleScope\nimport androidx.preference.PreferenceManager\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.android.material.bottomnavigation.BottomNavigationMenuView\nimport com.google.android.material.bottomnavigation.BottomNavigationView\nimport com.google.android.material.navigation.NavigationBarView\nimport com.google.android.material.navigation.NavigationView\nimport knf.kuma.achievements.AchievementActivity\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.backup.BackUpActivity\nimport knf.kuma.backup.Backups\nimport knf.kuma.backup.MigrationActivity\nimport knf.kuma.backup.firestore.FirestoreManager\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.BypassUtil\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.DesignUtils\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.EAMapActivity\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.changeToolbarFont\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.jsoupCookiesDir\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.noCrashLet\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.stringLiveData\nimport knf.kuma.commons.toast\nimport knf.kuma.commons.verifiyFF\nimport knf.kuma.custom.ConnectionState\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport knf.kuma.directory.DirManager\nimport knf.kuma.directory.DirectoryFragment\nimport knf.kuma.directory.DirectoryService\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.emision.EmissionActivity\nimport knf.kuma.explorer.ExplorerActivity\nimport knf.kuma.faq.FaqActivity\nimport knf.kuma.favorite.FavoriteFragment\nimport knf.kuma.jobscheduler.DirUpdateWork\nimport knf.kuma.jobscheduler.RecentsWork\nimport knf.kuma.jobscheduler.UpdateWork\nimport knf.kuma.news.NewsActivity\nimport knf.kuma.pojos.migrateSeen\nimport knf.kuma.preferences.BottomPreferencesFragment\nimport knf.kuma.preferences.ConfigurationFragment\nimport knf.kuma.queue.QueueActivity\nimport knf.kuma.random.RandomActivity\nimport knf.kuma.recents.RecentFragment\nimport knf.kuma.recents.RecentsNotReceiver\nimport knf.kuma.recommended.RecommendActivity\nimport knf.kuma.record.RecordActivity\nimport knf.kuma.search.FiltersSuggestion\nimport knf.kuma.search.SearchFragment\nimport knf.kuma.seeing.SeeingActivity\nimport knf.kuma.uagen.randomUA\nimport knf.kuma.updater.UpdateActivity\nimport knf.kuma.updater.UpdateChecker\nimport knh.kuma.commons.cloudflarebypass.CfCallback\nimport knh.kuma.commons.cloudflarebypass.Cloudflare\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.cryse.widget.persistentsearch.PersistentSearchView\nimport org.cryse.widget.persistentsearch.SearchItem\nimport org.jetbrains.anko.hintTextColor\nimport org.jetbrains.anko.sdk27.coroutines.onClick\nimport org.jetbrains.anko.textColor\nimport q.rorbin.badgeview.Badge\nimport q.rorbin.badgeview.QBadgeView\nimport xdroid.toaster.Toaster\nimport java.net.HttpCookie\nimport kotlin.coroutines.resume\nimport kotlin.coroutines.suspendCoroutine\nimport androidx.core.net.toUri\n\nclass Main : GenericActivity(),\n        NavigationView.OnNavigationItemSelectedListener,\n        NavigationBarView.OnItemSelectedListener,\n        NavigationBarView.OnItemReselectedListener,\n        UpdateChecker.CheckListener, BypassUtil.BypassListener,\n        ConfigurationFragment.UAChangeListener {\n\n    private val toolbar by bind<Toolbar>(R.id.toolbar)\n    private val searchView by bind<PersistentSearchView>(R.id.searchview)\n    private val drawer by bind<DrawerLayout>(R.id.drawer_layout)\n    private val navigationView by bind<NavigationView>(R.id.nav_view)\n    private val coordinator by bind<CoordinatorLayout>(R.id.coordinator)\n    private val connectionState by bind<ConnectionState>(R.id.connectionState)\n    private val bottomNavigationView by bind<BottomNavigationView>(R.id.bottomNavigation)\n    internal var selectedFragment: BottomFragment? = null\n    private var searchFragment: SearchFragment? = null\n    private lateinit var badgeEmission: TextView\n    private lateinit var badgeSeeing: TextView\n    private lateinit var badgeQueue: TextView\n    private var badgeView: Badge? = null\n    private var readyToFinish = false\n    private var isFirst = true\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getThemeNA())\n        super.onCreate(savedInstanceState)\n        if (getString(R.string.app_name) != \"UKIKU\") {\n            Toaster.toast(\"Te dije que no lo cambiaras\")\n            finish()\n            return\n        }\n        try {\n            setContentView(R.layout.activity_main_drawer)\n        } catch (e: Exception) {\n            setContentView(R.layout.activity_main_drawer_nwv)\n        }\n        //setDefaults()\n        setSupportActionBar(toolbar)\n        val toggle = ActionBarDrawerToggle(\n                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)\n        drawer.addDrawerListener(toggle)\n        toggle.syncState()\n        toolbar.changeToolbarFont(R.font.audiowide)\n        setNavigationButtons()\n        navigationView.setNavigationItemSelectedListener(this)\n        bottomNavigationView.setOnItemSelectedListener(this)\n        bottomNavigationView.setOnItemReselectedListener(this)\n        setSearch()\n        if (savedInstanceState == null) {\n            checkServices()\n            startChange()\n        } else\n            returnSelectFragment()\n        //checkBypass()\n        migrateSeen()\n        FirestoreManager.start()\n        onBackPressedDispatcher.addCallback(this) {\n            when {\n                drawer.isDrawerOpen(GravityCompat.START) -> drawer.closeDrawer(GravityCompat.START)\n                searchView.isSearching -> closeSearch()\n                readyToFinish -> finish()\n                else -> {\n                    readyToFinish = true\n                    Toaster.toast(\"Presione de nuevo para salir\")\n                    Handler().postDelayed({ readyToFinish = false }, 2000)\n                }\n            }\n        }\n        DesignUtils.listenDesignChange(this)\n    }\n\n    private fun checkServices() {\n        lifecycleScope.launch(Dispatchers.IO) {\n            BypassUtil.clearCookiesIfNeeded()\n            checkPermissions()\n            checkDirectoryState()\n            UpdateWork.schedule()\n            RecentsWork.schedule(this@Main)\n            DirUpdateWork.schedule(this@Main)\n            RecentsNotReceiver.removeAll(this@Main)\n            EAHelper.clear1()\n            verifiyFF()\n        }\n    }\n\n    private suspend fun checkDirectoryState() {\n        DirManager.checkPreDir()\n        if (PrefsUtil.useDefaultUserAgent && Network.isConnected) {\n            val isBrowserOk = noCrashLet(false) {\n                jsoupCookiesDir(\"https://www3.animeflv.net/browse?order=added&page=5\", BypassUtil.isCloudflareActive()).execute()\n                true\n            }\n            if (!isBrowserOk) {\n                val randomUA = randomUA()\n                PrefsUtil.userAgentDir = randomUA\n                suspendCoroutine<Boolean> {\n                    lifecycleScope.launch(Dispatchers.Main) {\n                        noCrash {\n                            Cloudflare(this@Main, \"https://www3.animeflv.net/browse?order=added&page=5\", PrefsUtil.userAgentDir).apply {\n                                setCfCallback(object : CfCallback {\n                                    override fun onSuccess(cookieList: MutableList<HttpCookie>?, hasNewUrl: Boolean, newUrl: String?) {\n                                        PrefsUtil.dirCookies = cookieList ?: emptyList()\n                                        noCrash { it.resume(true) }\n                                    }\n\n                                    override fun onFail(code: Int, msg: String?) {\n                                        Log.e(\"Dir cookies\", \"On error, code $code, msg: $msg\")\n                                        noCrash { it.resume(false) }\n                                    }\n                                })\n                            }.getCookies()\n                        }\n                    }\n                }\n            }\n        }\n        DirectoryService.run(this)\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    private fun setNavigationButtons() {\n        lifecycleScope.launch(Dispatchers.Main) {\n            badgeEmission = navigationView.menu.findItem(R.id.drawer_emision).actionView as TextView\n            badgeSeeing = navigationView.menu.findItem(R.id.drawer_seeing).actionView as TextView\n            badgeQueue = navigationView.menu.findItem(R.id.drawer_queue).actionView as TextView\n            navigationView.getHeaderView(0).findViewById<View>(R.id.img).setBackgroundResource(EAHelper.getThemeImg())\n            val header = navigationView.getHeaderView(0).findViewById<View>(R.id.img)\n            ViewCompat.setOnApplyWindowInsetsListener(header) { v, insets ->\n                v.apply {\n                    if (insets.getInsets(WindowInsetsCompat.Type.systemBars()).top > 0)\n                        setPadding(paddingLeft, insets.getInsets(WindowInsetsCompat.Type.systemBars()).top, paddingRight, paddingBottom)\n                }\n                insets\n            }\n            val actionShare = navigationView.getHeaderView(0).findViewById<View>(R.id.action_share)\n            val actionInfo = navigationView.getHeaderView(0).findViewById<View>(R.id.action_info)\n            val actionTrophy = navigationView.getHeaderView(0).findViewById<View>(R.id.action_trophy)\n            val actionLogin = navigationView.getHeaderView(0).findViewById<View>(R.id.action_login)\n            val actionMigrate = navigationView.getHeaderView(0).findViewById<View>(R.id.action_migrate)\n            val actionMap = navigationView.getHeaderView(0).findViewById<View>(R.id.action_map)\n            actionShare.onClick {\n                startActivity(Intent.createChooser(Intent(Intent.ACTION_SEND).apply {\n                    type = \"text/plain\"\n                    putExtra(Intent.EXTRA_TEXT, \"Hola,\\n\" +\n                            \"\\n\" +\n                            \"UKIKU es una aplicación rápida y simple que uso para ver mis animes favoritos.\\n\" +\n                            \"\\n\" +\n                            \"Descárgala gratis desde https://ukiku.app/\")\n                }, \"Compartir UKIKU\"))\n            }\n            actionInfo.onClick { AppInfoActivity.open(this@Main) }\n            actionTrophy.onClick { AchievementActivity.open(this@Main) }\n            actionLogin.onClick { BackUpActivity.start(this@Main) }\n            actionMigrate.onClick { MigrationActivity.start(this@Main) }\n            actionMap.onClick { EAMapActivity.start(this@Main) }\n            actionMigrate.visibility = if (Backups.isAnimeflvInstalled) View.VISIBLE else View.GONE\n            actionMap.visibility = if (EAHelper.phase == 3) View.VISIBLE else View.GONE\n            val backupLocation = navigationView.getHeaderView(0).findViewById<TextView>(R.id.backupLocation)\n            backupLocation.text = when (Backups.type) {\n                Backups.Type.NONE -> \"Sin respaldos\"\n                Backups.Type.DROPBOX -> \"Dropbox\"\n                Backups.Type.FIRESTORE -> \"Firestore\"\n                Backups.Type.LOCAL -> \"Local\"\n            }\n            subscribeBadges()\n        }\n    }\n\n    private fun subscribeBadges() {\n        val bottomNavigationMenuView = bottomNavigationView.getChildAt(0) as BottomNavigationMenuView\n        try {\n            val v = bottomNavigationMenuView.getChildAt(1)\n            if (badgeView == null) {\n                badgeView = QBadgeView(this)\n                        .bindTarget(v)\n                        .setExactMode(true)\n                        .setShowShadow(false)\n                        .setGravityOffset(5f, 5f, true)\n                        .setBadgeBackgroundColor(ContextCompat.getColor(this, EAHelper.getThemeColorLight()))\n                CacheDB.INSTANCE.favsDAO().countLive.observe(this) { integer ->\n                    if (badgeView != null && integer != null)\n                        if (PrefsUtil.showFavIndicator)\n                            badgeView?.badgeNumber = integer\n                        else\n                            badgeView?.hide(false)\n                }\n                PrefsUtil.getLiveShowFavIndicator().observe(this) { aBoolean ->\n                    if (badgeView != null) {\n                        if (aBoolean)\n                            lifecycleScope.launch { badgeView?.badgeNumber = withContext(Dispatchers.IO) { CacheDB.INSTANCE.favsDAO().count } }\n                        else\n                            badgeView?.hide(false)\n                    }\n                }\n                PreferenceManager.getDefaultSharedPreferences(this).stringLiveData(\"theme_color\", \"0\")\n                        .observe(this) {\n                            (badgeView as? QBadgeView)?.badgeBackgroundColor = ContextCompat.getColor(this, EAHelper.getThemeColorLight(it))\n                            badgeEmission.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor(it)))\n                            badgeSeeing.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor(it)))\n                            badgeQueue.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor(it)))\n                            navigationView.getHeaderView(0).findViewById<View>(R.id.img).setBackgroundResource(EAHelper.getThemeImg(it))\n                        }\n            }\n            badgeEmission.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor()))\n            badgeEmission.setTypeface(null, Typeface.BOLD)\n            badgeEmission.gravity = Gravity.CENTER_VERTICAL\n            badgeSeeing.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor()))\n            badgeSeeing.setTypeface(null, Typeface.BOLD)\n            badgeSeeing.gravity = Gravity.CENTER_VERTICAL\n            badgeQueue.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor()))\n            badgeQueue.setTypeface(null, Typeface.BOLD)\n            badgeQueue.gravity = Gravity.CENTER_VERTICAL\n            PrefsUtil.getLiveEmissionBlackList().observe(this) { strings ->\n                CacheDB.INSTANCE.animeDAO().getInEmission(strings).observe(this) { integer ->\n                    badgeEmission.text = integer.toString()\n                    badgeEmission.visibility = if (integer == 0) View.GONE else View.VISIBLE\n                }\n            }\n            CacheDB.INSTANCE.seeingDAO().countWatchingLive.observe(this) { integer ->\n                badgeSeeing.text = integer.toString()\n                badgeSeeing.visibility = if (integer == 0) View.GONE else View.VISIBLE\n            }\n            CacheDB.INSTANCE.queueDAO().countLive.observe(this) { integer ->\n                badgeQueue.text = integer.toString()\n                badgeQueue.visibility = if (integer == 0) View.GONE else View.VISIBLE\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n    }\n\n    private fun checkPermissions() {\n        try {\n            val permissions = mutableListOf<String>()\n            if (isFullMode) {\n                if (Build.VERSION.SDK_INT in Build.VERSION_CODES.M..Build.VERSION_CODES.P &&\n                    ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {\n                    permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)\n                }\n            }\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n                permissions.add(Manifest.permission.POST_NOTIFICATIONS)\n            }\n            if (permissions.isNotEmpty()) {\n                requestPermissions(permissions.toTypedArray(), 55498)\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }\n\n    private fun showRationalPermission(denied: Boolean = false) {\n        MaterialDialog(this).safeShow {\n            title(text = \"Permiso de escritura\")\n            message(text = \"Esta aplicación necesita el permiso obligatoriamente para guardar cache y descargar los episodios\")\n            positiveButton(text = \"Aceptar\") {\n                if (denied) {\n                    try {\n                        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, \"package:$packageName\".toUri()).apply {\n                            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n                        }\n                        finish()\n                        startActivity(intent)\n                    } catch (e: ActivityNotFoundException) {\n                        \"Error al mostrar configuración\".toast()\n                    }\n                } else\n                    checkPermissions()\n            }\n            negativeButton(text = \"Salir\") { finish() }\n            cancelable(false)\n        }\n    }\n\n    override fun onNeedUpdate(o_code: String, n_code: String) {\n        runOnUiThread {\n            try {\n                if (n_code.toInt() > AdsUtils.remoteConfigs.getLong(\"min_version\").toInt()) {\n                    MaterialDialog(this@Main).safeShow {\n                        title(text = \"Actualización\")\n                        message(text = \"Parece que la versión $n_code está disponible, ¿Quieres actualizar?\")\n                        positiveButton(text = \"si\") { UpdateActivity.start(this@Main, true, n_code) }\n                        negativeButton(text = \"despues\") {\n                            checkBypass()\n                        }\n                    }\n                } else {\n                    finish()\n                    UpdateActivity.start(\n                        this@Main,\n                        false,\n                        n_code\n                    )\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n    }\n\n    override fun onUpdateNotRequired() {\n        checkBypass()\n    }\n\n    private fun setSearch() {\n        searchView.searchEditText.apply {\n            inputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS\n            textColor = ContextCompat.getColor(this@Main, android.R.color.black)\n            hintTextColor = ContextCompat.getColor(this@Main, android.R.color.darker_gray)\n        }\n        searchView.setSuggestionBuilder(FiltersSuggestion(this))\n        searchView.setSearchListener(object : PersistentSearchView.SearchListener {\n            override fun onSearchCleared() {\n                searchFragment?.setSearch(\"\")\n            }\n\n            override fun onSearchTermChanged(term: String) {\n                EAHelper.checkStart(term)\n                AchievementManager.onSearch(term)\n                searchFragment?.setSearch(term)\n            }\n\n            override fun onSearch(query: String) {}\n\n            override fun onSearchEditOpened() {\n                requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED\n            }\n\n            override fun onSearchEditClosed() {\n                /*closeSearch();*/\n            }\n\n            override fun onSearchEditBackPressed(): Boolean {\n                closeSearch()\n                return true\n            }\n\n            override fun onSearchExit() {\n                closeSearch()\n            }\n\n            override fun onSuggestion(searchItem: SearchItem?): Boolean = true\n        })\n    }\n\n    private fun onStateDialog(message: String) {\n        MaterialDialog(this).safeShow {\n            message(text = message)\n            positiveButton()\n        }\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        if (selectedFragment == null || selectedFragment is RecentFragment) {\n            menuInflater.inflate(R.menu.main, menu)\n        } else if (selectedFragment is FavoriteFragment) {\n            menuInflater.inflate(R.menu.fav_menu, menu)\n            when (PrefsUtil.favsOrder) {\n                0 -> menu.findItem(R.id.by_name).isChecked = true\n                1 -> menu.findItem(R.id.by_id).isChecked = true\n            }\n            if (!PrefsUtil.showFavSections())\n                menu.findItem(R.id.action_new_category).isVisible = false\n        } else if (selectedFragment is DirectoryFragment) {\n            menuInflater.inflate(R.menu.dir_menu, menu)\n            when (PrefsUtil.dirOrder) {\n                0 -> menu.findItem(R.id.by_name_dir).isChecked = true\n                1 -> menu.findItem(R.id.by_votes).isChecked = true\n                2 -> menu.findItem(R.id.by_id_dir).isChecked = true\n                3 -> menu.findItem(R.id.by_added_dir).isChecked = true\n                4 -> menu.findItem(R.id.by_followers).isChecked = true\n            }\n        } else {\n            menuInflater.inflate(R.menu.main, menu)\n        }\n        searchView.setStartPositionFromMenuItem(findViewById(R.id.action_search))\n        CastUtil.registerActivity(this, menu, R.id.castMenu)\n        return true\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_search -> {\n                searchView.openSearch()\n                searchFragment = SearchFragment.get()\n                setFragment(searchFragment as BottomFragment)\n            }\n            R.id.action_new_category -> if (selectedFragment is FavoriteFragment)\n                (selectedFragment as FavoriteFragment).showNewCategory(null)\n            R.id.by_name -> {\n                PrefsUtil.favsOrder = 0\n                changeOrder()\n            }\n            R.id.by_name_dir -> {\n                PrefsUtil.dirOrder = 0\n                changeOrder()\n            }\n            R.id.by_votes -> {\n                PrefsUtil.dirOrder = 1\n                changeOrder()\n            }\n            R.id.by_id -> {\n                PrefsUtil.favsOrder = 1\n                changeOrder()\n            }\n            R.id.by_id_dir -> {\n                PrefsUtil.dirOrder = 2\n                changeOrder()\n            }\n            R.id.by_added_dir -> {\n                PrefsUtil.dirOrder = 3\n                changeOrder()\n            }\n            R.id.by_followers -> {\n                PrefsUtil.dirOrder = 4\n                changeOrder()\n            }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    private fun changeOrder() {\n        if (selectedFragment is FavoriteFragment) {\n            (selectedFragment as FavoriteFragment).onChangeOrder()\n        } else if (selectedFragment is DirectoryFragment) {\n            (selectedFragment as DirectoryFragment).onChangeOrder()\n        }\n        invalidateOptionsMenu()\n    }\n\n    override fun onNavigationItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_bottom_recents -> setFragment(RecentFragment.get())\n            R.id.action_bottom_favorites -> setFragment(FavoriteFragment.get())\n            R.id.action_bottom_directory -> setFragment(DirectoryFragment.get())\n            R.id.action_bottom_settings -> setFragment(BottomPreferencesFragment.get())\n            R.id.drawer_explorer -> ExplorerActivity.open(this)\n            R.id.drawer_emision -> EmissionActivity.open(this)\n            R.id.drawer_queue -> QueueActivity.open(this)\n            R.id.drawer_suggestions -> RecommendActivity.open(this)\n            R.id.drawer_news -> NewsActivity.open(this)\n            R.id.drawer_records -> RecordActivity.open(this)\n            R.id.drawer_seeing -> SeeingActivity.open(this)\n            R.id.drawer_random -> RandomActivity.open(this)\n            R.id.drawer_faq -> FaqActivity.open(this)\n        }\n        closeSearchBar()\n        closeDrawer()\n        return true\n    }\n\n    private fun setFragment(fragment: BottomFragment) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            try {\n                if (fragment !is SearchFragment)\n                    selectedFragment = fragment\n                val transaction = supportFragmentManager.beginTransaction()\n                //transaction.setCustomAnimations(R.anim.fadein, R.anim.fadeout)\n                transaction.replace(R.id.root, fragment)\n                transaction.commit()\n                invalidateOptionsMenu()\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n    }\n\n    private fun closeDrawer() {\n        drawer.closeDrawer(GravityCompat.START)\n    }\n\n    private fun closeSearch() {\n        closeSearchBar()\n        returnFragment()\n    }\n\n    private fun closeSearchBar() {\n        searchView.closeSearch()\n    }\n\n    private fun returnFragment() {\n        selectedFragment?.let {\n            setFragment(it)\n        } ?: let {\n            bottomNavigationView.selectedItemId = R.id.action_bottom_recents\n            setFragment(RecentFragment.get())\n        }\n        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n    }\n\n    private fun returnSelectFragment() {\n        if (selectedFragment != null) {\n            when (selectedFragment) {\n                is FavoriteFragment -> bottomNavigationView.selectedItemId = R.id.action_bottom_favorites\n                is DirectoryFragment -> bottomNavigationView.selectedItemId = R.id.action_bottom_directory\n                is BottomPreferencesFragment -> bottomNavigationView.selectedItemId = R.id.action_bottom_settings\n                else -> bottomNavigationView.selectedItemId = R.id.action_bottom_recents\n            }\n        }\n        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n    }\n\n    private fun startChange() {\n        if (intent.dataString?.let {\n                    return@let if (\"ukiku.app/search/\" in it) {\n                        val query = it.substringAfter(\"ukiku.app/search/\")\n                        selectedFragment = RecentFragment.get()\n                        searchView.openSearch()\n                        setFragment(SearchFragment[query])\n                        searchView.setSearchString(query, false)\n                        true\n                    } else\n                        false\n                } == true) return\n        when (intent.getIntExtra(\"start_position\", -1)) {\n            0 -> setFragment(RecentFragment.get())\n            1 -> bottomNavigationView.selectedItemId = R.id.action_bottom_favorites\n            2 -> bottomNavigationView.selectedItemId = R.id.action_bottom_directory\n            3 -> bottomNavigationView.selectedItemId = R.id.action_bottom_settings\n            4 -> {\n                selectedFragment = RecentFragment.get()\n                searchView.openSearch()\n                setFragment(SearchFragment[intent.getStringExtra(\"search_query\") ?: \"\"])\n                searchView.setSearchString(intent.getStringExtra(\"search_query\") ?: \"\", false)\n            }\n            else -> setFragment(RecentFragment.get())\n        }\n    }\n\n    private fun reselectFragment() {\n        if (selectedFragment != null) {\n            when (selectedFragment) {\n                is FavoriteFragment -> bottomNavigationView.selectedItemId = R.id.action_bottom_recents\n                is DirectoryFragment -> bottomNavigationView.selectedItemId = R.id.action_bottom_directory\n                is BottomPreferencesFragment -> bottomNavigationView.selectedItemId = R.id.action_bottom_settings\n                else -> bottomNavigationView.selectedItemId = R.id.action_bottom_recents\n            }\n        }\n        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n    }\n\n    override fun onNavigationItemReselected(item: MenuItem) {\n        if (selectedFragment != null && searchView.isSearching) {\n            closeSearch()\n        } else if (selectedFragment != null) {\n            selectedFragment?.onReselect()\n        }\n    }\n\n    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {\n        super.onRequestPermissionsResult(requestCode, permissions, grantResults)\n        permissions.forEachIndexed { result, permission ->\n            if (permission == Manifest.permission.WRITE_EXTERNAL_STORAGE && result != PackageManager.PERMISSION_GRANTED) {\n                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE))\n                    showRationalPermission()\n                else\n                    showRationalPermission(true)\n            }\n        }\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onResume() {\n        super.onResume()\n        invalidateOptionsMenu()\n        connectionState.setUp(this, ::onStateDialog)\n        lifecycleScope.launch(Dispatchers.Main) {\n            val backupLocation = navigationView.getHeaderView(0).findViewById<TextView>(R.id.backupLocation)\n            backupLocation.text = when (Backups.type) {\n                Backups.Type.NONE -> \"Sin respaldos\"\n                Backups.Type.DROPBOX -> \"Dropbox\"\n                Backups.Type.FIRESTORE -> \"Firestore\"\n                Backups.Type.LOCAL -> \"Local\"\n            }\n        }\n        if (isFirst) {\n            isFirst = false\n        }\n    }\n\n    override fun onPause() {\n        syncData { achievements() }\n        super.onPause()\n    }\n\n    override fun onUAChange() {\n        checkBypass()\n    }\n\n    override fun onAttachedToWindow() {\n        super.onAttachedToWindow()\n        //ChangelogActivity.check(this)\n        UpdateChecker.check(this, this)\n    }\n\n    override fun onNeedRecreate() {\n        reselectFragment()\n    }\n\n    override fun onDestroy() {\n        if (!isChangingConfigurations)\n            CastUtil.get().onDestroy()\n        super.onDestroy()\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        noCrash {\n            if (requestCode == FileAccessHelper.SD_REQUEST && resultCode == RESULT_OK) {\n                val validation = FileAccessHelper.isUriValid(data?.data)\n                if (!validation.isValid) {\n                    Toaster.toast(\"Directorio invalido: $validation\")\n                    FileAccessHelper.openTreeChooser(this)\n                }\n            }\n        }\n        setNavigationButtons()\n    }\n\n    override fun onBypassUpdated() {\n        onNeedRecreate()\n    }\n\n    override fun getSnackbarAnchor(): View {\n        return coordinator\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/MainMaterial.kt",
    "content": "package knf.kuma\n\nimport androidx.activity.addCallback\nimport android.Manifest\nimport android.annotation.SuppressLint\nimport android.annotation.TargetApi\nimport android.content.ActivityNotFoundException\nimport android.content.Intent\nimport android.content.pm.ActivityInfo\nimport android.content.pm.PackageManager\nimport android.graphics.Typeface\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport android.os.Handler\nimport android.provider.Settings\nimport android.util.Log\nimport android.view.Gravity\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.TextView\nimport androidx.appcompat.widget.Toolbar\nimport androidx.core.app.ActivityCompat\nimport androidx.core.content.ContextCompat\nimport androidx.core.view.GravityCompat\nimport androidx.core.view.ViewCompat\nimport androidx.drawerlayout.widget.DrawerLayout\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.preference.PreferenceManager\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.android.material.bottomnavigation.BottomNavigationMenuView\nimport com.google.android.material.bottomnavigation.BottomNavigationView\nimport com.google.android.material.navigation.NavigationBarView\nimport com.google.android.material.navigation.NavigationView\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport com.google.gson.Gson\nimport knf.kuma.achievements.AchievementActivityMaterial\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.backup.BackUpActivity\nimport knf.kuma.backup.Backups\nimport knf.kuma.backup.MigrationActivity\nimport knf.kuma.backup.firestore.FirestoreManager\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.changelog.ChangelogActivityMaterial\nimport knf.kuma.commons.BypassUtil\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.DesignUtils\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.EAMapActivity\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.changeToolbarFont\nimport knf.kuma.commons.getSurfaceColor\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.stringLiveData\nimport knf.kuma.commons.toast\nimport knf.kuma.commons.verifiyFF\nimport knf.kuma.custom.ConnectionState\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport knf.kuma.directory.DirManager\nimport knf.kuma.directory.DirectoryFragmentMaterial\nimport knf.kuma.directory.DirectoryService\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.emision.EmissionActivityMaterial\nimport knf.kuma.explorer.ExplorerActivityMaterial\nimport knf.kuma.faq.FaqActivityMaterial\nimport knf.kuma.favorite.FavoriteFragmentMaterial\nimport knf.kuma.jobscheduler.DirUpdateWork\nimport knf.kuma.jobscheduler.RecentsWork\nimport knf.kuma.jobscheduler.UpdateWork\nimport knf.kuma.news.MaterialNewsActivity\nimport knf.kuma.pojos.migrateSeen\nimport knf.kuma.preferences.BottomPreferencesFragment\nimport knf.kuma.preferences.BottomPreferencesMaterialFragment\nimport knf.kuma.preferences.ConfigurationFragment\nimport knf.kuma.queue.QueueActivityMaterial\nimport knf.kuma.random.RandomActivityMaterial\nimport knf.kuma.recents.RecentFragment\nimport knf.kuma.recents.RecentModelsFragment\nimport knf.kuma.recents.RecentsNotReceiver\nimport knf.kuma.recommended.RecommendActivityMaterial\nimport knf.kuma.record.RecordActivityMaterial\nimport knf.kuma.search.SearchActivity\nimport knf.kuma.seeing.SeeingActivityMaterial\nimport knf.kuma.updater.UpdateActivity\nimport knf.kuma.updater.UpdateChecker\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.sdk27.coroutines.onClick\nimport org.json.JSONObject\nimport q.rorbin.badgeview.Badge\nimport q.rorbin.badgeview.QBadgeView\nimport xdroid.toaster.Toaster\nimport java.io.File\n\nclass MainMaterial : GenericActivity(),\n        NavigationView.OnNavigationItemSelectedListener,\n        NavigationBarView.OnItemSelectedListener,\n        NavigationBarView.OnItemReselectedListener,\n        UpdateChecker.CheckListener, BypassUtil.BypassListener,\n        ConfigurationFragment.UAChangeListener {\n\n    private val toolbar by bind<Toolbar>(R.id.toolbar)\n    private val drawer by bind<DrawerLayout>(R.id.drawer_layout)\n    private val navigationView by bind<NavigationView>(R.id.nav_view)\n    private val connectionState by bind<ConnectionState>(R.id.connectionState)\n    private val root by bind<View>(R.id.root)\n    private val bottomNavigationView by bind<BottomNavigationView>(R.id.bottomNavigation)\n    internal var selectedFragment: BottomFragment? = null\n    private lateinit var badgeEmission: TextView\n    private lateinit var badgeSeeing: TextView\n    private lateinit var badgeQueue: TextView\n    private var badgeView: Badge? = null\n    private var readyToFinish = false\n    private var isFirst = true\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getThemeNA())\n        super.onCreate(savedInstanceState)\n        if (getString(R.string.app_name) != \"UKIKU\") {\n            Toaster.toast(\"Te dije que no lo cambiaras\")\n            finish()\n            return\n        }\n        try {\n            setContentView(R.layout.activity_main_material)\n        } catch (_: Exception) {\n            setContentView(R.layout.activity_main_drawer_nwv)\n        }\n        //setDefaults()\n        drawer.setStatusBarBackgroundColor(getSurfaceColor())\n        setSupportActionBar(toolbar)\n        supportActionBar?.title = \"Buscar animes\"\n        toolbar.setNavigationOnClickListener { drawer.openDrawer(GravityCompat.START) }\n        toolbar.setOnClickListener {\n            if (selectedFragment !is BottomPreferencesMaterialFragment)\n                SearchActivity.open(this)\n        }\n        setNavigationButtons()\n        navigationView.setNavigationItemSelectedListener(this)\n        bottomNavigationView.setOnItemSelectedListener(this)\n        bottomNavigationView.setOnItemReselectedListener(this)\n        if (savedInstanceState == null) {\n            checkServices()\n            startChange()\n        } else\n            returnSelectFragment()\n        //checkBypass()\n        migrateSeen()\n        FirestoreManager.start()\n        onBackPressedDispatcher.addCallback(this) {\n            if (drawer.isDrawerOpen(GravityCompat.START)) {\n                drawer.closeDrawer(GravityCompat.START)\n            } else {\n                if (readyToFinish) {\n                    finish()\n                } else {\n                    readyToFinish = true\n                    Toaster.toast(\"Presione de nuevo para salir\")\n                    Handler().postDelayed({ readyToFinish = false }, 2000)\n                }\n            }\n        }\n        DesignUtils.listenDesignChange(this)\n        //BypassUtil.doConnectionTests()\n        //ThumbsDownloader.start(this)\n        /*lifecycleScope.launch(Dispatchers.IO) {\n            StapeServer(this@MainMaterial, \"https://streamtape.com/v/lW9e90W7b0S7ylb/\").videoServer\n        }*/\n    }\n\n    private fun checkServices() {\n        lifecycleScope.launch(Dispatchers.IO) {\n            BypassUtil.clearCookiesIfNeeded()\n            checkPermissions()\n            checkDirectoryState()\n            UpdateWork.schedule()\n            RecentsWork.schedule(this@MainMaterial)\n            DirUpdateWork.schedule(this@MainMaterial)\n            RecentsNotReceiver.removeAll(this@MainMaterial)\n            EAHelper.clear1()\n            verifiyFF()\n            saveDir()\n        }\n    }\n\n    private fun saveDir() {\n        if (!BuildConfig.DEBUG) return\n        val lists = CacheDB.INSTANCE.animeDAO().all.chunked(500)\n        var number = 0\n        val json = JSONObject()\n        lists.forEach { list ->\n            val info = JSONObject().apply {\n                put(\"idF\", list.first().aid)\n                put(\"idL\", list.last().aid)\n            }\n            json.put(number.toString(), info)\n            val file = File(getExternalFilesDir(null), \"directory$number.json\")\n            if (!file.exists()) {\n                file.createNewFile()\n                file.writeText(Gson().toJson(list))\n            }\n            number++\n            Log.e(\"Dir files\", \"Process chunk: $number\")\n        }\n        val file = File(getExternalFilesDir(null), \"directoryInfo.json\")\n        if (!file.exists()) {\n            file.createNewFile()\n            file.writeText(json.toString())\n            Log.e(\"Dir files\", \"Save finished\")\n        }\n    }\n\n    private fun checkDirectoryState() {\n        DirManager.checkPreDir()\n        DirectoryService.run(this@MainMaterial)\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    private fun setNavigationButtons() {\n        lifecycleScope.launch(Dispatchers.Main) {\n            badgeEmission = navigationView.menu.findItem(R.id.drawer_emision).actionView as TextView\n            badgeSeeing = navigationView.menu.findItem(R.id.drawer_seeing).actionView as TextView\n            badgeQueue = navigationView.menu.findItem(R.id.drawer_queue).actionView as TextView\n            navigationView.getHeaderView(0).findViewById<View>(R.id.img).setBackgroundResource(EAHelper.getThemeImg())\n            val header = navigationView.getHeaderView(0).findViewById<View>(R.id.img)\n            ViewCompat.setOnApplyWindowInsetsListener(header) { v, insets ->\n                v.apply {\n                    if (insets.systemWindowInsetTop > 0)\n                        setPadding(paddingLeft, insets.systemWindowInsetTop, paddingRight, paddingBottom)\n                }\n                insets\n            }\n            val actionShare = navigationView.getHeaderView(0).findViewById<View>(R.id.action_share)\n            val actionInfo = navigationView.getHeaderView(0).findViewById<View>(R.id.action_info)\n            val actionTrophy = navigationView.getHeaderView(0).findViewById<View>(R.id.action_trophy)\n            val actionLogin = navigationView.getHeaderView(0).findViewById<View>(R.id.action_login)\n            val actionMigrate = navigationView.getHeaderView(0).findViewById<View>(R.id.action_migrate)\n            val actionMap = navigationView.getHeaderView(0).findViewById<View>(R.id.action_map)\n            actionShare.onClick {\n                startActivity(Intent.createChooser(Intent(Intent.ACTION_SEND).apply {\n                    type = \"text/plain\"\n                    putExtra(Intent.EXTRA_TEXT, \"Hola,\\n\" +\n                            \"\\n\" +\n                            \"UKIKU es una aplicación rápida y simple que uso para ver mis animes favoritos.\\n\" +\n                            \"\\n\" +\n                            \"Descárgala gratis desde https://ukiku.app/\")\n                }, \"Compartir UKIKU\"))\n            }\n            actionInfo.onClick { AppInfoActivityMaterial.open(this@MainMaterial) }\n            actionTrophy.onClick { AchievementActivityMaterial.open(this@MainMaterial) }\n            actionLogin.onClick { BackUpActivity.start(this@MainMaterial) }\n            actionMigrate.onClick { MigrationActivity.start(this@MainMaterial) }\n            actionMap.onClick { EAMapActivity.start(this@MainMaterial) }\n            actionMigrate.visibility = if (Backups.isAnimeflvInstalled) View.VISIBLE else View.GONE\n            actionMap.visibility = if (EAHelper.phase == 3) View.VISIBLE else View.GONE\n            val backupLocation = navigationView.getHeaderView(0).findViewById<TextView>(R.id.backupLocation)\n            backupLocation.text = when (Backups.type) {\n                Backups.Type.NONE -> \"Sin respaldos\"\n                Backups.Type.DROPBOX -> \"Dropbox\"\n                Backups.Type.FIRESTORE -> \"Firestore\"\n                Backups.Type.LOCAL -> \"Local\"\n            }\n            subscribeBadges()\n        }\n    }\n\n    private fun subscribeBadges() {\n        val bottomNavigationMenuView = bottomNavigationView.getChildAt(0) as BottomNavigationMenuView\n        try {\n            val v = bottomNavigationMenuView.getChildAt(1)\n            if (badgeView == null) {\n                badgeView = QBadgeView(this)\n                        .bindTarget(v)\n                        .setExactMode(true)\n                        .setShowShadow(false)\n                        .setGravityOffset(5f, 5f, true)\n                        .setBadgeBackgroundColor(ContextCompat.getColor(this, EAHelper.getThemeColorLight()))\n                CacheDB.INSTANCE.favsDAO().countLive.observe(this, Observer { integer ->\n                    if (badgeView != null && integer != null)\n                        if (PrefsUtil.showFavIndicator)\n                            badgeView?.badgeNumber = integer\n                        else\n                            badgeView?.hide(false)\n                })\n                PrefsUtil.getLiveShowFavIndicator().observe(this, Observer { aBoolean ->\n                    if (badgeView != null) {\n                        if (aBoolean)\n                            lifecycleScope.launch { badgeView?.badgeNumber = withContext(Dispatchers.IO) { CacheDB.INSTANCE.favsDAO().count } }\n                        else\n                            badgeView?.hide(false)\n                    }\n                })\n                PreferenceManager.getDefaultSharedPreferences(this).stringLiveData(\"theme_color\", \"0\")\n                        .observe(this, Observer {\n                            (badgeView as? QBadgeView)?.badgeBackgroundColor = ContextCompat.getColor(this, EAHelper.getThemeColorLight(it))\n                            badgeEmission.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor(it)))\n                            badgeSeeing.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor(it)))\n                            badgeQueue.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor(it)))\n                            navigationView.getHeaderView(0).findViewById<View>(R.id.img).setBackgroundResource(EAHelper.getThemeImg(it))\n                        })\n            }\n            badgeEmission.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor()))\n            badgeEmission.setTypeface(null, Typeface.BOLD)\n            badgeEmission.gravity = Gravity.CENTER_VERTICAL\n            badgeSeeing.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor()))\n            badgeSeeing.setTypeface(null, Typeface.BOLD)\n            badgeSeeing.gravity = Gravity.CENTER_VERTICAL\n            badgeQueue.setTextColor(ContextCompat.getColor(this, EAHelper.getThemeColor()))\n            badgeQueue.setTypeface(null, Typeface.BOLD)\n            badgeQueue.gravity = Gravity.CENTER_VERTICAL\n            PrefsUtil.getLiveEmissionBlackList().observe(this, Observer { strings ->\n                CacheDB.INSTANCE.animeDAO().getInEmission(strings).observe(this, Observer { integer ->\n                    badgeEmission.text = integer.toString()\n                    badgeEmission.visibility = if (integer == 0) View.GONE else View.VISIBLE\n                })\n            })\n            CacheDB.INSTANCE.seeingDAO().countWatchingLive.observe(this, Observer { integer ->\n                badgeSeeing.text = integer.toString()\n                badgeSeeing.visibility = if (integer == 0) View.GONE else View.VISIBLE\n            })\n            CacheDB.INSTANCE.queueDAO().countLive.observe(this, Observer { integer ->\n                badgeQueue.text = integer.toString()\n                badgeQueue.visibility = if (integer == 0) View.GONE else View.VISIBLE\n            })\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n    }\n\n    @TargetApi(Build.VERSION_CODES.M)\n    private fun checkPermissions() {\n        val permissions = mutableListOf<String>()\n        if (isFullMode) {\n            if (Build.VERSION.SDK_INT in Build.VERSION_CODES.M..Build.VERSION_CODES.P &&\n                ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {\n                permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)\n            }\n        }\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {\n            permissions.add(Manifest.permission.POST_NOTIFICATIONS)\n        }\n        if (permissions.isNotEmpty()) {\n            noCrash {\n                requestPermissions(permissions.toTypedArray(), 55498)\n            }\n        }\n    }\n\n    private fun showRationalPermission(denied: Boolean = false) {\n        MaterialDialog(this).safeShow {\n            title(text = \"Permiso de escritura\")\n            message(text = \"Esta aplicación necesita el permiso obligatoriamente para guardar cache y descargar los episodios\")\n            positiveButton(text = \"Aceptar\") {\n                if (denied) {\n                    try {\n                        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse(\"package:$packageName\")).apply {\n                            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n                        }\n                        finish()\n                        startActivity(intent)\n                    } catch (e: ActivityNotFoundException) {\n                        \"Error al mostrar configuración\".toast()\n                    }\n                } else\n                    checkPermissions()\n            }\n            negativeButton(text = \"Salir\") { finish() }\n            cancelable(false)\n        }\n    }\n\n    override fun onNeedUpdate(o_code: String, n_code: String) {\n        runOnUiThread {\n            try {\n                if (n_code.toInt() > AdsUtils.remoteConfigs.getLong(\"min_version\").toInt()) {\n                    MaterialDialog(this@MainMaterial).safeShow {\n                        title(text = \"Actualización\")\n                        message(text = \"Parece que la versión $n_code está disponible, ¿Quieres actualizar?\")\n                        positiveButton(text = \"si\") { UpdateActivity.start(this@MainMaterial, true, n_code) }\n                        negativeButton(text = \"despues\") {\n                            checkBypass()\n                        }\n                    }\n                } else {\n                    finish()\n                    UpdateActivity.start(\n                        this@MainMaterial,\n                        false,\n                        n_code\n                    )\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n    }\n\n    override fun onUpdateNotRequired() {\n        ChangelogActivityMaterial.check(this)\n        checkBypass()\n    }\n\n    private fun onStateDialog(message: String) {\n        MaterialDialog(this).safeShow {\n            message(text = message)\n            positiveButton()\n        }\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        if (selectedFragment == null || selectedFragment is RecentFragment) {\n            menuInflater.inflate(R.menu.main_material, menu)\n        } else if (selectedFragment is FavoriteFragmentMaterial) {\n            menuInflater.inflate(R.menu.fav_menu_material, menu)\n            when (PrefsUtil.favsOrder) {\n                0 -> menu.findItem(R.id.by_name).isChecked = true\n                1 -> menu.findItem(R.id.by_id).isChecked = true\n            }\n            if (!PrefsUtil.showFavSections())\n                menu.findItem(R.id.action_new_category).isVisible = false\n        } else if (selectedFragment is DirectoryFragmentMaterial && (PrefsUtil.isDirectoryFinished || !Network.isConnected)) {\n            menuInflater.inflate(R.menu.dir_menu_material, menu)\n            when (PrefsUtil.dirOrder) {\n                0 -> menu.findItem(R.id.by_name_dir).isChecked = true\n                1 -> menu.findItem(R.id.by_votes).isChecked = true\n                2 -> menu.findItem(R.id.by_id_dir).isChecked = true\n                3 -> menu.findItem(R.id.by_added_dir).isChecked = true\n                4 -> menu.findItem(R.id.by_followers).isChecked = true\n            }\n        } else {\n            menuInflater.inflate(R.menu.main_material, menu)\n        }\n        CastUtil.registerActivity(this, menu, R.id.castMenu)\n        return true\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_new_category -> if (selectedFragment is FavoriteFragmentMaterial)\n                (selectedFragment as FavoriteFragmentMaterial).showNewCategory(null)\n            R.id.by_name -> {\n                PrefsUtil.favsOrder = 0\n                changeOrder()\n            }\n            R.id.by_name_dir -> {\n                PrefsUtil.dirOrder = 0\n                changeOrder()\n            }\n            R.id.by_votes -> {\n                PrefsUtil.dirOrder = 1\n                changeOrder()\n            }\n            R.id.by_id -> {\n                PrefsUtil.favsOrder = 1\n                changeOrder()\n            }\n            R.id.by_id_dir -> {\n                PrefsUtil.dirOrder = 2\n                changeOrder()\n            }\n            R.id.by_added_dir -> {\n                PrefsUtil.dirOrder = 3\n                changeOrder()\n            }\n            R.id.by_followers -> {\n                PrefsUtil.dirOrder = 4\n                changeOrder()\n            }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    private fun changeOrder() {\n        if (selectedFragment is FavoriteFragmentMaterial) {\n            (selectedFragment as FavoriteFragmentMaterial).onChangeOrder()\n        } else if (selectedFragment is DirectoryFragmentMaterial) {\n            (selectedFragment as DirectoryFragmentMaterial).onChangeOrder()\n        }\n        invalidateOptionsMenu()\n    }\n\n    override fun onNavigationItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_bottom_recents -> setFragment(RecentModelsFragment.get())\n            R.id.action_bottom_favorites -> setFragment(FavoriteFragmentMaterial.get())\n            R.id.action_bottom_directory -> setFragment(DirectoryFragmentMaterial.get())\n            R.id.action_bottom_settings -> setFragment(BottomPreferencesMaterialFragment.get())\n            R.id.drawer_explorer -> ExplorerActivityMaterial.open(this)\n            R.id.drawer_emision -> EmissionActivityMaterial.open(this)\n            R.id.drawer_queue -> QueueActivityMaterial.open(this)\n            R.id.drawer_suggestions -> RecommendActivityMaterial.open(this)\n            R.id.drawer_news -> MaterialNewsActivity.open(this)\n            R.id.drawer_records -> RecordActivityMaterial.open(this)\n            R.id.drawer_seeing -> SeeingActivityMaterial.open(this)\n            R.id.drawer_random -> RandomActivityMaterial.open(this)\n            R.id.drawer_faq -> FaqActivityMaterial.open(this)\n        }\n        closeDrawer()\n        return true\n    }\n\n    private fun setFragment(fragment: BottomFragment) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            try {\n                selectedFragment = fragment\n                if (selectedFragment is BottomPreferencesMaterialFragment) {\n                    toolbar.title = \"UKIKU\"\n                    toolbar.changeToolbarFont(R.font.audiowide)\n                } else {\n                    toolbar.title = \"Buscar animes\"\n                    toolbar.changeToolbarFont(R.font.open_sans)\n                }\n                val transaction = supportFragmentManager.beginTransaction()\n                //transaction.setCustomAnimations(R.anim.fade_in, R.anim.fade_out)\n                transaction.replace(R.id.root, fragment)\n                transaction.commit()\n                invalidateOptionsMenu()\n            } catch (e: Exception) {\n                e.printStackTrace()\n                FirebaseCrashlytics.getInstance().recordException(e)\n                Toaster.toastLong(\"Error en fragmento: ${e.message}\")\n            }\n        }\n    }\n\n    private fun closeDrawer() {\n        drawer.closeDrawer(GravityCompat.START)\n    }\n\n    private fun returnSelectFragment() {\n        if (selectedFragment != null) {\n            when (selectedFragment) {\n                is FavoriteFragmentMaterial -> bottomNavigationView.selectedItemId = R.id.action_bottom_favorites\n                is DirectoryFragmentMaterial -> bottomNavigationView.selectedItemId = R.id.action_bottom_directory\n                is BottomPreferencesFragment -> bottomNavigationView.selectedItemId = R.id.action_bottom_settings\n                else -> bottomNavigationView.selectedItemId = R.id.action_bottom_recents\n            }\n        }\n        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n    }\n\n    private fun startChange() {\n        when (intent.getIntExtra(\"start_position\", -1)) {\n            0 -> setFragment(RecentModelsFragment.get())\n            1 -> bottomNavigationView.selectedItemId = R.id.action_bottom_favorites\n            2 -> bottomNavigationView.selectedItemId = R.id.action_bottom_directory\n            3 -> bottomNavigationView.selectedItemId = R.id.action_bottom_settings\n            else -> setFragment(RecentModelsFragment.get())\n        }\n    }\n\n    private fun reselectFragment() {\n        if (selectedFragment != null) {\n            when (selectedFragment) {\n                is FavoriteFragmentMaterial -> bottomNavigationView.selectedItemId = R.id.action_bottom_recents\n                is DirectoryFragmentMaterial -> bottomNavigationView.selectedItemId = R.id.action_bottom_directory\n                is BottomPreferencesFragment -> bottomNavigationView.selectedItemId = R.id.action_bottom_settings\n                else -> bottomNavigationView.selectedItemId = R.id.action_bottom_recents\n            }\n        }\n        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n    }\n\n    override fun onNavigationItemReselected(item: MenuItem) {\n        selectedFragment?.onReselect()\n    }\n\n    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {\n        super.onRequestPermissionsResult(requestCode, permissions, grantResults)\n        permissions.forEachIndexed { result, permission ->\n            if (permission == Manifest.permission.WRITE_EXTERNAL_STORAGE && result != PackageManager.PERMISSION_GRANTED) {\n                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE))\n                    showRationalPermission()\n                else\n                    showRationalPermission(true)\n            }\n        }\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onResume() {\n        super.onResume()\n        invalidateOptionsMenu()\n        connectionState.setUp(this, ::onStateDialog)\n        lifecycleScope.launch(Dispatchers.Main) {\n            val backupLocation = navigationView.getHeaderView(0).findViewById<TextView>(R.id.backupLocation)\n            backupLocation.text = when (Backups.type) {\n                Backups.Type.NONE -> \"Sin respaldos\"\n                Backups.Type.DROPBOX -> \"Dropbox\"\n                Backups.Type.FIRESTORE -> \"Firestore\"\n                Backups.Type.LOCAL -> \"Local\"\n            }\n        }\n        if (isFirst) {\n            isFirst = false\n        }\n    }\n\n    override fun onPause() {\n        syncData { achievements() }\n        super.onPause()\n    }\n\n    override fun onUAChange() {\n        checkBypass()\n    }\n\n    override fun onAttachedToWindow() {\n        super.onAttachedToWindow()\n        UpdateChecker.check(this, this)\n    }\n\n    override fun onNeedRecreate() {\n        reselectFragment()\n    }\n\n    override fun onDestroy() {\n        if (!isChangingConfigurations)\n            CastUtil.get().onDestroy()\n        super.onDestroy()\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        noCrash {\n            if (requestCode == FileAccessHelper.SD_REQUEST && resultCode == RESULT_OK) {\n                val validation = FileAccessHelper.isUriValid(data?.data)\n                if (!validation.isValid) {\n                    Toaster.toast(\"Directorio invalido: $validation\")\n                    FileAccessHelper.openTreeChooser(this)\n                }\n            }\n        }\n        setNavigationButtons()\n    }\n\n    override fun onBypassUpdated() {\n        onNeedRecreate()\n    }\n\n    override fun getSnackbarAnchor(): View {\n        return root\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/SplashActivity.kt",
    "content": "package knf.kuma\r\n\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport android.util.Log\r\nimport androidx.lifecycle.lifecycleScope\r\nimport com.google.android.gms.common.GooglePlayServicesNotAvailableException\r\nimport com.google.android.gms.common.GooglePlayServicesRepairableException\r\nimport com.google.android.gms.security.ProviderInstaller\r\nimport com.google.android.ump.ConsentInformation\r\nimport com.google.android.ump.ConsentRequestParameters\r\nimport com.google.android.ump.UserMessagingPlatform\r\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\r\nimport knf.kuma.achievements.AchievementManager\r\nimport knf.kuma.ads.AdsUtils\r\nimport knf.kuma.ads.SubscriptionReceiver\r\nimport knf.kuma.commons.BypassUtil\r\nimport knf.kuma.commons.DesignUtils\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.tv.ui.TVMain\r\nimport knf.tools.signatures.getSignatures\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport xdroid.toaster.Toaster\r\nimport kotlin.coroutines.resume\r\nimport kotlin.coroutines.suspendCoroutine\r\n\r\n\r\nclass SplashActivity : GenericActivity() {\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(R.layout.activity_blank)\r\n        AchievementManager.onAppStart()\r\n        SubscriptionReceiver.check(intent)\r\n        printSignatures()\r\n        when {\r\n            resources.getBoolean(R.bool.isTv) -> {\r\n                startActivity(Intent(this, TVMain::class.java))\r\n                finish()\r\n            }\r\n            /*!isFullMode && BuildConfig.BUILD_TYPE != \"amazon\" && !PrefsUtil.isPSWarned -> MaterialDialog(\r\n                this\r\n            ).safeShow {\r\n                title(text = \"Aviso\")\r\n                message(text = \"Usted esta usando la version de Google Play, esta version tiene caracteristicas deshabilitadas, para una experiencia completa por favor use la version de la pagina oficial\\nEscriba \\\"confirmar\\\" para continuar.\")\r\n                input(hint = \"Respuesta...\", waitForPositiveButton = false) { _, text ->\r\n                    getActionButton(WhichButton.POSITIVE).isEnabled = text.toString()\r\n                        .lowercase(Locale.getDefault()) == \"confirmar\"\r\n                }\r\n                negativeButton(text = \"Web\") {\r\n                    noCrash {\r\n                        startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(\"https://ukiku.app\")))\r\n                    }\r\n                }\r\n                positiveButton(text = \"Continuar\") {\r\n                    PrefsUtil.isPSWarned = true\r\n                    startApp()\r\n                }\r\n                cancelOnTouchOutside(false)\r\n            }*/\r\n            else -> {\r\n                lifecycleScope.launch {\r\n                    showGDPR { startApp() }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private suspend fun showGDPR(onFinish: () -> Unit) {\r\n        val consentInfo = UserMessagingPlatform.getConsentInformation(this)\r\n        val params = ConsentRequestParameters.Builder().apply {\r\n            setTagForUnderAgeOfConsent(false)\r\n        }.build()\r\n        suspendCoroutine {\r\n            val ok = { it.resume(true) }\r\n            consentInfo.requestConsentInfoUpdate(this, params, { ok() }, { ok() })\r\n        }\r\n        Log.e(\"GDPR\", \"On consent, status: ${consentInfo.consentStatus}, available: ${consentInfo.isConsentFormAvailable}\")\r\n        if (consentInfo.consentStatus == ConsentInformation.ConsentStatus.REQUIRED && consentInfo.isConsentFormAvailable) {\r\n            val form = suspendCoroutine { continuation ->\r\n                UserMessagingPlatform.loadConsentForm(this,\r\n                    {\r\n                        continuation.resume(it)\r\n                    },\r\n                    {\r\n                        continuation.resume(null)\r\n                    }\r\n                )\r\n            }\r\n            form?.show(this) {\r\n                Log.e(\"GDPR\", \"On form dismiss, obtained: ${consentInfo.consentStatus == ConsentInformation.ConsentStatus.OBTAINED}\")\r\n                onFinish()\r\n            }\r\n        } else {\r\n            onFinish()\r\n        }\r\n    }\r\n\r\n    private fun doBlockTests(): Boolean {\r\n        var blockCount = 0\r\n        repeat(3) {\r\n            if (BypassUtil.isCloudflareActiveRandom())\r\n                blockCount++\r\n            if (blockCount >= 2)\r\n                return true\r\n        }\r\n        return blockCount >= 2\r\n    }\r\n\r\n    private fun printSignatures() {\r\n        if (BuildConfig.DEBUG) {\r\n            getSignatures().signatures.forEach {\r\n                Log.e(\"Signature\", it.encoded)\r\n            }\r\n        }\r\n    }\r\n\r\n    private suspend fun installSecurityProvider() {\r\n        withContext(Dispatchers.IO) {\r\n            try {\r\n                ProviderInstaller.installIfNeeded(this@SplashActivity)\r\n                PrefsUtil.isSecurityUpdated = true\r\n                PrefsUtil.spErrorType = null\r\n            } catch (e: GooglePlayServicesRepairableException) {\r\n                PrefsUtil.isSecurityUpdated = false\r\n                PrefsUtil.spErrorType = \"Gplay services deshabilitado o desactualizado\"\r\n                e.printStackTrace()\r\n            } catch (e: GooglePlayServicesNotAvailableException) {\r\n                PrefsUtil.isSecurityUpdated = false\r\n                PrefsUtil.spErrorType = \"GPlay services no esta disponible\"\r\n                e.printStackTrace()\r\n            } catch (e: Exception) {\r\n                PrefsUtil.isSecurityUpdated = false\r\n                Toaster.toastLong(\"SProvider: Unknown error, ${e.message}\")\r\n                PrefsUtil.spErrorType = \"Error desconocido: ${e.message}\"\r\n                e.printStackTrace()\r\n            }\r\n            if (!PrefsUtil.isSecurityUpdated && FirebaseCrashlytics.getInstance().didCrashOnPreviousExecution()) {\r\n                PrefsUtil.spProtectionEnabled = true\r\n                Toaster.toastLong(\"Proteccion de SP reactivada\")\r\n\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun startApp() {\r\n        lifecycleScope.launch(Dispatchers.Main) {\r\n            if (PrefsUtil.mayUseRandomUA)\r\n                PrefsUtil.alwaysGenerateUA = !withContext(Dispatchers.IO) { doBlockTests() }\r\n            else\r\n                PrefsUtil.alwaysGenerateUA = false\r\n            installSecurityProvider()\r\n            DesignUtils.change(this@SplashActivity, start = false)\r\n            AdsUtils.remoteConfigs.ensureInitialized().addOnCompleteListener {\r\n                var initializated = false\r\n                AdsUtils.setUp(this@SplashActivity) {\r\n                    if (!initializated) {\r\n                        initializated = true\r\n                        startActivity(Intent(this@SplashActivity, DesignUtils.mainClass))\r\n                        finish()\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/achievements/AchievementActivity.kt",
    "content": "package knf.kuma.achievements\r\n\r\nimport androidx.activity.addCallback\r\nimport android.annotation.SuppressLint\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.graphics.Rect\r\nimport android.net.Uri\r\nimport android.os.Build\r\nimport android.os.Bundle\r\nimport android.provider.Settings\r\nimport android.view.Menu\r\nimport android.view.MenuItem\r\nimport android.view.MotionEvent\r\nimport android.view.View\r\nimport android.widget.ImageView\r\nimport android.widget.ProgressBar\r\nimport android.widget.TextView\r\nimport androidx.appcompat.widget.Toolbar\r\nimport androidx.lifecycle.Observer\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.viewpager.widget.ViewPager\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.google.android.material.bottomsheet.BottomSheetBehavior\r\nimport com.google.android.material.button.MaterialButton\r\nimport com.google.android.material.card.MaterialCardView\r\nimport com.google.android.material.tabs.TabLayout\r\nimport com.mikhaellopez.circularprogressbar.CircularProgressBar\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsType\r\nimport knf.kuma.ads.AdsUtils\r\nimport knf.kuma.ads.FullscreenAdLoader\r\nimport knf.kuma.ads.getFAdLoaderInterstitial\r\nimport knf.kuma.ads.getFAdLoaderRewarded\r\nimport knf.kuma.ads.implBanner\r\nimport knf.kuma.ads.showRandomInterstitial\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.Economy\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.diceOf\r\nimport knf.kuma.commons.getPackage\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.custom.AchievementUnlocked\r\nimport knf.kuma.custom.BannerContainerView\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.Achievement\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.toast\r\nimport xdroid.toaster.Toaster\r\nimport java.text.NumberFormat\r\nimport java.util.Locale\r\nimport androidx.core.net.toUri\r\n\r\nclass AchievementActivity : GenericActivity() {\r\n\r\n    private val toolbar: Toolbar by bind(R.id.toolbar)\r\n    private val tabs: TabLayout by bind(R.id.tabs)\r\n    private val pager: ViewPager by bind(R.id.pager)\r\n    private val progress: CircularProgressBar by bind(R.id.progress)\r\n    private val level: TextView by bind(R.id.level)\r\n    private val countDown: TextView by bind(R.id.countdown)\r\n    private val cardView: MaterialCardView by bind(R.id.sheet)\r\n    private val buyButton: MaterialButton by bind(R.id.buyButton)\r\n    private val icon: ImageView by bind(R.id.achievement_icon)\r\n    private val xpIndicator: TextView by bind(R.id.achievement_xp)\r\n    private val state: TextView by bind(R.id.achievement_state)\r\n    private val progressIndicator: View by bind(R.id.progress_indicator)\r\n    private val progressBar: ProgressBar by bind(R.id.progress_bar)\r\n    private val progressText: TextView by bind(R.id.progress_text)\r\n    private val progressIndText: TextView by bind(R.id.progress_ind_text)\r\n    private val name: TextView by bind(R.id.achievement_name)\r\n    private val description: TextView by bind(R.id.achievement_description)\r\n    private val adContainer: BannerContainerView by bind(R.id.adContainer)\r\n    private lateinit var bottomSheet: BottomSheetBehavior<MaterialCardView>\r\n\r\n    private var syncButton: MenuItem? = null\r\n\r\n    private val levelCalculator = LevelCalculator()\r\n\r\n    private val rewardedAd: FullscreenAdLoader by lazy { getFAdLoaderRewarded(this) }\r\n    private var interstitial: FullscreenAdLoader = getFAdLoaderInterstitial(this)\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(R.layout.activity_achievement_profile)\r\n        setSupportActionBar(toolbar)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        supportActionBar?.title = \"Logros\"\r\n        toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\r\n        bottomSheet = BottomSheetBehavior.from(cardView)\r\n        bottomSheet.state = BottomSheetBehavior.STATE_HIDDEN\r\n        val backCallback = onBackPressedDispatcher.addCallback(this, false) {\r\n            bottomSheet.state = BottomSheetBehavior.STATE_HIDDEN\r\n        }\r\n        bottomSheet.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {\r\n            override fun onStateChanged(bottomSheet: View, newState: Int) {\r\n                backCallback.isEnabled = newState == BottomSheetBehavior.STATE_EXPANDED\r\n            }\r\n\r\n            override fun onSlide(bottomSheet: View, slideOffset: Float) {\r\n\r\n            }\r\n        })\r\n        pager.offscreenPageLimit = 2\r\n        pager.adapter = AchievementsFragmentsPagerAdapter(supportFragmentManager) {\r\n            onMoreInfo(it)\r\n        }\r\n        tabs.setupWithViewPager(pager)\r\n        rewardedAd.load()\r\n        interstitial.load()\r\n        if (!PrefsUtil.isNativeAdsEnabled)\r\n            adContainer.implBanner(AdsType.ACHIEVEMENT_BANNER)\r\n        showRandomInterstitial(this,PrefsUtil.fullAdsExtraProbability)\r\n    }\r\n\r\n    override fun onAttachedToWindow() {\r\n        super.onAttachedToWindow()\r\n        if (!PrefsUtil.isAchievementsOmitted && !Settings.canDrawOverlays(this))\r\n            MaterialDialog(this).safeShow {\r\n                message(text = \"Para mostrar una mejor animacion al desbloquear logros, la app necesita un permiso especial, ¿Deseas activarlo?\")\r\n                positiveButton(text = \"Activar\") {\r\n                    try {\r\n                        startActivityForResult(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION).setData(\r\n                            \"package:${getPackage()}\".toUri()), 5879)\r\n                    } catch (_: Exception) {\r\n                        Toaster.toast(\"No se pudo abrir la configuracion\")\r\n                    }\r\n                }\r\n                negativeButton(text = \"Omitir\") {\r\n                    PrefsUtil.isAchievementsOmitted = true\r\n                }\r\n            }\r\n    }\r\n\r\n    @SuppressLint(\"SetTextI18n\")\r\n    override fun onResume() {\r\n        super.onResume()\r\n        CacheDB.INSTANCE.achievementsDAO().totalUnlockedPoints.observe(this, Observer {\r\n            lifecycleScope.launch(Dispatchers.Main) {\r\n                levelCalculator.calculate(it ?: 0)\r\n                if (it != withContext(Dispatchers.IO){ CacheDB.INSTANCE.achievementsDAO().totalPoints }) {\r\n                    progress.progressMax = levelCalculator.max.toFloat()\r\n                    progress.progress = levelCalculator.progress.toFloat()\r\n                    progressIndText.visibility = View.VISIBLE\r\n                    countDown.text = \"${NumberFormat.getNumberInstance(Locale.US).format(levelCalculator.toLvlUp)} XP\"\r\n                } else {\r\n                    progress.progressMax = 100f\r\n                    progress.progress = 100f\r\n                    progressIndText.visibility = View.GONE\r\n                    countDown.text = \"MAXIMO NIVEL\"\r\n                }\r\n                level.text = levelCalculator.level.toString()\r\n            }\r\n        })\r\n    }\r\n\r\n    @SuppressLint(\"SetTextI18n\")\r\n    private fun onMoreInfo(achievement: Achievement) {\r\n        if (achievement.isSecret && !achievement.isRevealed && !achievement.isUnlocked) {\r\n            val cost = ((achievement.points / 1000) * 25)\r\n            buyButton.text = cost.toString()\r\n            buyButton.visibility = View.VISIBLE\r\n            buyButton.setOnClickListener {\r\n                if (Economy.buy(cost)) {\r\n                    achievement.isRevealed = true\r\n                    doAsync {\r\n                        CacheDB.INSTANCE.achievementsDAO().update(achievement)\r\n                        syncData { achievements() }\r\n                    }\r\n                    onMoreInfo(achievement)\r\n                } else\r\n                    toast(\"Loli-coins insuficientes\")\r\n            }\r\n        } else buyButton.visibility = View.GONE\r\n        icon.setImageResource(achievement.usableIcon())\r\n        xpIndicator.text = \"${NumberFormat.getNumberInstance(Locale.US).format(achievement.points)} XP\"\r\n        state.text = achievement.getState()\r\n        if (!achievement.isSecret && !achievement.isUnlocked && achievement.goal > 0) {\r\n            progressIndicator.visibility = View.VISIBLE\r\n            progressBar.apply {\r\n                max = achievement.goal\r\n                progress = achievement.count\r\n            }\r\n            progressText.text = \"${achievement.count} / ${achievement.goal}\"\r\n        } else progressIndicator.visibility = View.GONE\r\n        name.text = achievement.usableName()\r\n        description.text = achievement.usableDescription()\r\n        bottomSheet.state = BottomSheetBehavior.STATE_EXPANDED\r\n    }\r\n\r\n    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {\r\n        if (ev?.action == MotionEvent.ACTION_DOWN)\r\n            if (bottomSheet.state == BottomSheetBehavior.STATE_EXPANDED) {\r\n                val rect = Rect()\r\n                cardView.getGlobalVisibleRect(rect)\r\n                return if (!rect.contains(ev.rawX.toInt(), ev.rawY.toInt())) {\r\n                    bottomSheet.state = BottomSheetBehavior.STATE_HIDDEN\r\n                    true\r\n                } else\r\n                    super.dispatchTouchEvent(ev)\r\n            }\r\n        return super.dispatchTouchEvent(ev)\r\n    }\r\n\r\n    private fun showAd() {\r\n        diceOf<() -> Unit> {\r\n            put({ rewardedAd.show() }, AdsUtils.remoteConfigs.getDouble(\"rewarded_percent\"))\r\n            put({ interstitial.show() }, AdsUtils.remoteConfigs.getDouble(\"interstitial_percent\"))\r\n        }()\r\n    }\r\n\r\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\r\n        menuInflater.inflate(R.menu.menu_achievements, menu)\r\n        if (Backups.type != Backups.Type.NONE && Backups.type != Backups.Type.FIRESTORE) {\r\n            syncButton = menu.findItem(R.id.sync)\r\n        } else\r\n            menu.findItem(R.id.sync)?.isVisible = false\r\n        return super.onCreateOptionsMenu(menu)\r\n\r\n\r\n    }\r\n\r\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\r\n        when (item.itemId) {\r\n            R.id.backup -> {\r\n                syncButton?.isEnabled = false\r\n                AchievementManager.backup {\r\n                    invalidateOptionsMenu()\r\n                }\r\n            }\r\n            R.id.restore -> {\r\n                syncButton?.isEnabled = false\r\n                AchievementManager.restore {\r\n                    invalidateOptionsMenu()\r\n                }\r\n            }\r\n            R.id.coins -> {\r\n                Economy.showWallet(this) {\r\n                    showAd()\r\n                }\r\n            }\r\n        }\r\n        return super.onOptionsItemSelected(item)\r\n    }\r\n\r\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\r\n        super.onActivityResult(requestCode, resultCode, data)\r\n        if (requestCode == 5879) {\r\n            if (Settings.canDrawOverlays(this)) {\r\n                Toaster.toast(\"Logros mejorados!\")\r\n                val achievementUnlocked = AchievementUnlocked(this).apply {\r\n                    setRounded(false)\r\n                    setLarge(true)\r\n                    setDismissible(true)\r\n                }\r\n                lifecycleScope.launch(Dispatchers.IO) {\r\n                    val list = CacheDB.INSTANCE.achievementsDAO().completedAchievements\r\n                    val achievementList = mutableListOf<AchievementUnlocked.AchievementData>()\r\n                    list.forEach { achievementList.add(it.achievementData(this@AchievementActivity)) }\r\n                    launch(Dispatchers.Main) {\r\n                        achievementUnlocked.show(achievementList)\r\n                    }\r\n                }\r\n            } else\r\n                Toaster.toast(\"Permiso no concedido\")\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        fun open(context: Context) {\r\n            context.startActivity(Intent(context, AchievementActivity::class.java))\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/achievements/AchievementActivityMaterial.kt",
    "content": "package knf.kuma.achievements\r\n\r\nimport androidx.activity.addCallback\r\nimport android.annotation.SuppressLint\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.graphics.Rect\r\nimport android.net.Uri\r\nimport android.os.Bundle\r\nimport android.provider.Settings\r\nimport android.view.Menu\r\nimport android.view.MenuItem\r\nimport android.view.MotionEvent\r\nimport android.view.View\r\nimport android.widget.ImageView\r\nimport android.widget.ProgressBar\r\nimport android.widget.TextView\r\nimport androidx.appcompat.widget.Toolbar\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.viewpager.widget.ViewPager\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.google.android.material.bottomsheet.BottomSheetBehavior\r\nimport com.google.android.material.button.MaterialButton\r\nimport com.google.android.material.card.MaterialCardView\r\nimport com.google.android.material.tabs.TabLayout\r\nimport com.mikhaellopez.circularprogressbar.CircularProgressBar\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsType\r\nimport knf.kuma.ads.AdsUtils\r\nimport knf.kuma.ads.FullscreenAdLoader\r\nimport knf.kuma.ads.getFAdLoaderInterstitial\r\nimport knf.kuma.ads.getFAdLoaderRewarded\r\nimport knf.kuma.ads.implBanner\r\nimport knf.kuma.ads.showRandomInterstitial\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.Economy\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.diceOf\r\nimport knf.kuma.commons.getPackage\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.commons.setSurfaceBars\r\nimport knf.kuma.custom.AchievementUnlocked\r\nimport knf.kuma.custom.BannerContainerView\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.Achievement\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.toast\r\nimport xdroid.toaster.Toaster\r\nimport java.text.NumberFormat\r\nimport java.util.Locale\r\nimport androidx.core.net.toUri\r\n\r\nclass AchievementActivityMaterial : GenericActivity() {\r\n\r\n    private val toolbar: Toolbar by bind(R.id.toolbar)\r\n    private val tabs: TabLayout by bind(R.id.tabs)\r\n    private val pager: ViewPager by bind(R.id.pager)\r\n    private val progress: CircularProgressBar by bind(R.id.progress)\r\n    private val level: TextView by bind(R.id.level)\r\n    private val countDown: TextView by bind(R.id.countdown)\r\n    private val cardView: MaterialCardView by bind(R.id.sheet)\r\n    private val buyButton: MaterialButton by bind(R.id.buyButton)\r\n    private val icon: ImageView by bind(R.id.achievement_icon)\r\n    private val xpIndicator: TextView by bind(R.id.achievement_xp)\r\n    private val state: TextView by bind(R.id.achievement_state)\r\n    private val progressIndicator: View by bind(R.id.progress_indicator)\r\n    private val progressBar: ProgressBar by bind(R.id.progress_bar)\r\n    private val progressText: TextView by bind(R.id.progress_text)\r\n    private val progressIndText: TextView by bind(R.id.progress_ind_text)\r\n    private val name: TextView by bind(R.id.achievement_name)\r\n    private val description: TextView by bind(R.id.achievement_description)\r\n    private val adContainer: BannerContainerView by bind(R.id.adContainer)\r\n    private lateinit var bottomSheet: BottomSheetBehavior<MaterialCardView>\r\n\r\n    private var syncButton: MenuItem? = null\r\n\r\n    private val levelCalculator = LevelCalculator()\r\n\r\n    private val rewardedAd: FullscreenAdLoader by lazy { getFAdLoaderRewarded(this) }\r\n    private var interstitial: FullscreenAdLoader = getFAdLoaderInterstitial(this)\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setSurfaceBars()\r\n        setContentView(R.layout.activity_achievement_profile_material)\r\n        setSupportActionBar(toolbar)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        supportActionBar?.title = \"Logros\"\r\n        toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\r\n        bottomSheet = BottomSheetBehavior.from(cardView)\r\n        bottomSheet.state = BottomSheetBehavior.STATE_HIDDEN\r\n        val backCallback = onBackPressedDispatcher.addCallback(this, false) {\r\n            bottomSheet.state = BottomSheetBehavior.STATE_HIDDEN\r\n        }\r\n        bottomSheet.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {\r\n            override fun onStateChanged(bottomSheet: View, newState: Int) {\r\n                backCallback.isEnabled = newState == BottomSheetBehavior.STATE_EXPANDED\r\n            }\r\n\r\n            override fun onSlide(bottomSheet: View, slideOffset: Float) {\r\n\r\n            }\r\n        })\r\n        pager.offscreenPageLimit = 2\r\n        pager.adapter = AchievementsFragmentsPagerAdapter(supportFragmentManager) {\r\n            onMoreInfo(it)\r\n        }\r\n        tabs.setupWithViewPager(pager)\r\n        rewardedAd.load()\r\n        interstitial.load()\r\n        if (!PrefsUtil.isNativeAdsEnabled)\r\n            adContainer.implBanner(AdsType.ACHIEVEMENT_BANNER)\r\n        showRandomInterstitial(this,PrefsUtil.fullAdsExtraProbability)\r\n    }\r\n\r\n    override fun onAttachedToWindow() {\r\n        super.onAttachedToWindow()\r\n        if (!PrefsUtil.isAchievementsOmitted && !Settings.canDrawOverlays(this))\r\n            MaterialDialog(this).safeShow {\r\n                message(text = \"Para mostrar una mejor animacion al desbloquear logros, la app necesita un permiso especial, ¿Deseas activarlo?\")\r\n                positiveButton(text = \"Activar\") {\r\n                    try {\r\n                        startActivityForResult(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION).setData(\r\n                            \"package:${getPackage()}\".toUri()), 5879)\r\n                    } catch (_: Exception) {\r\n                        Toaster.toast(\"No se pudo abrir la configuracion\")\r\n                    }\r\n                }\r\n                negativeButton(text = \"Omitir\") {\r\n                    PrefsUtil.isAchievementsOmitted = true\r\n                }\r\n            }\r\n    }\r\n\r\n    @SuppressLint(\"SetTextI18n\")\r\n    override fun onResume() {\r\n        super.onResume()\r\n        CacheDB.INSTANCE.achievementsDAO().totalUnlockedPoints.observe(this) {\r\n            lifecycleScope.launch(Dispatchers.Main) {\r\n                levelCalculator.calculate(it ?: 0)\r\n                if (it != withContext(Dispatchers.IO) { CacheDB.INSTANCE.achievementsDAO().totalPoints }) {\r\n                    progress.progressMax = levelCalculator.max.toFloat()\r\n                    progress.progress = levelCalculator.progress.toFloat()\r\n                    progressIndText.visibility = View.VISIBLE\r\n                    countDown.text = \"${NumberFormat.getNumberInstance(Locale.US).format(levelCalculator.toLvlUp)} XP\"\r\n                } else {\r\n                    progress.progressMax = 100f\r\n                    progress.progress = 100f\r\n                    progressIndText.visibility = View.GONE\r\n                    countDown.text = \"MAXIMO NIVEL\"\r\n                }\r\n                level.text = levelCalculator.level.toString()\r\n            }\r\n        }\r\n    }\r\n\r\n    @SuppressLint(\"SetTextI18n\")\r\n    private fun onMoreInfo(achievement: Achievement) {\r\n        if (achievement.isSecret && !achievement.isRevealed && !achievement.isUnlocked) {\r\n            val cost = ((achievement.points / 1000) * 25)\r\n            buyButton.text = cost.toString()\r\n            buyButton.visibility = View.VISIBLE\r\n            buyButton.setOnClickListener {\r\n                if (Economy.buy(cost)) {\r\n                    achievement.isRevealed = true\r\n                    doAsync {\r\n                        CacheDB.INSTANCE.achievementsDAO().update(achievement)\r\n                        syncData { achievements() }\r\n                    }\r\n                    onMoreInfo(achievement)\r\n                } else\r\n                    toast(\"Loli-coins insuficientes\")\r\n            }\r\n        } else buyButton.visibility = View.GONE\r\n        icon.setImageResource(achievement.usableIcon())\r\n        xpIndicator.text = \"${NumberFormat.getNumberInstance(Locale.US).format(achievement.points)} XP\"\r\n        state.text = achievement.getState()\r\n        if (!achievement.isSecret && !achievement.isUnlocked && achievement.goal > 0) {\r\n            progressIndicator.visibility = View.VISIBLE\r\n            progressBar.apply {\r\n                max = achievement.goal\r\n                progress = achievement.count\r\n            }\r\n            progressText.text = \"${achievement.count} / ${achievement.goal}\"\r\n        } else progressIndicator.visibility = View.GONE\r\n        name.text = achievement.usableName()\r\n        description.text = achievement.usableDescription()\r\n        bottomSheet.state = BottomSheetBehavior.STATE_EXPANDED\r\n    }\r\n\r\n    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {\r\n        if (ev?.action == MotionEvent.ACTION_DOWN)\r\n            if (bottomSheet.state == BottomSheetBehavior.STATE_EXPANDED) {\r\n                val rect = Rect()\r\n                cardView.getGlobalVisibleRect(rect)\r\n                return if (!rect.contains(ev.rawX.toInt(), ev.rawY.toInt())) {\r\n                    bottomSheet.state = BottomSheetBehavior.STATE_HIDDEN\r\n                    true\r\n                } else\r\n                    super.dispatchTouchEvent(ev)\r\n            }\r\n        return super.dispatchTouchEvent(ev)\r\n    }\r\n\r\n    private fun showAd() {\r\n        diceOf<() -> Unit> {\r\n            put({ rewardedAd.show() }, AdsUtils.remoteConfigs.getDouble(\"rewarded_percent\"))\r\n            put({ interstitial.show() }, AdsUtils.remoteConfigs.getDouble(\"interstitial_percent\"))\r\n        }()\r\n    }\r\n\r\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\r\n        menuInflater.inflate(R.menu.menu_achievements, menu)\r\n        if (Backups.type != Backups.Type.NONE && Backups.type != Backups.Type.FIRESTORE) {\r\n            syncButton = menu.findItem(R.id.sync)\r\n        } else\r\n            menu.findItem(R.id.sync)?.isVisible = false\r\n        return super.onCreateOptionsMenu(menu)\r\n\r\n\r\n    }\r\n\r\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\r\n        when (item.itemId) {\r\n            R.id.backup -> {\r\n                syncButton?.isEnabled = false\r\n                AchievementManager.backup {\r\n                    invalidateOptionsMenu()\r\n                }\r\n            }\r\n            R.id.restore -> {\r\n                syncButton?.isEnabled = false\r\n                AchievementManager.restore {\r\n                    invalidateOptionsMenu()\r\n                }\r\n            }\r\n            R.id.coins -> {\r\n                Economy.showWallet(this) {\r\n                    showAd()\r\n                }\r\n            }\r\n        }\r\n        return super.onOptionsItemSelected(item)\r\n    }\r\n\r\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\r\n        super.onActivityResult(requestCode, resultCode, data)\r\n        if (requestCode == 5879) {\r\n            if (Settings.canDrawOverlays(this)) {\r\n                Toaster.toast(\"Logros mejorados!\")\r\n                val achievementUnlocked = AchievementUnlocked(this).apply {\r\n                    setRounded(false)\r\n                    setLarge(true)\r\n                    setDismissible(true)\r\n                }\r\n                lifecycleScope.launch(Dispatchers.IO) {\r\n                    val list = CacheDB.INSTANCE.achievementsDAO().completedAchievements\r\n                    val achievementList = mutableListOf<AchievementUnlocked.AchievementData>()\r\n                    list.forEach { achievementList.add(it.achievementData(this@AchievementActivityMaterial)) }\r\n                    launch(Dispatchers.Main) {\r\n                        achievementUnlocked.show(achievementList)\r\n                    }\r\n                }\r\n            } else\r\n                Toaster.toast(\"Permiso no concedido\")\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        fun open(context: Context) {\r\n            context.startActivity(Intent(context, AchievementActivityMaterial::class.java))\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/achievements/AchievementAdapter.kt",
    "content": "package knf.kuma.achievements\r\n\r\nimport android.annotation.SuppressLint\r\nimport android.view.LayoutInflater\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdCallback\r\nimport knf.kuma.ads.AdCardItemHolder\r\nimport knf.kuma.ads.AdsUtilsMob\r\nimport knf.kuma.ads.implAdsAchievement\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.noCrashLet\r\nimport knf.kuma.pojos.Achievement\r\nimport knf.kuma.pojos.AchievementAd\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\nimport java.text.NumberFormat\r\nimport java.util.Locale\r\n\r\nclass AchievementAdapter(private val onClick: (achievement: Achievement) -> Unit) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {\r\n\r\n    private var list: MutableList<Achievement> = mutableListOf()\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {\r\n        if (viewType == 1)\r\n            return AdCardItemHolder(parent, AdCardItemHolder.TYPE_ACHIEVEMENT).also {\r\n                it.loadAd(GlobalScope, object : AdCallback {\r\n                    override fun getID(): String = AdsUtilsMob.ACHIEVEMENT_NATIVE\r\n                }, 500)\r\n            }\r\n        return ItemHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_achievements, parent, false))\r\n    }\r\n\r\n    override fun getItemCount(): Int {\r\n        return list.size\r\n    }\r\n\r\n    override fun getItemViewType(position: Int): Int {\r\n        return noCrashLet { if (list[position] is AchievementAd) 1 else 0 } ?: 1\r\n    }\r\n\r\n    @SuppressLint(\"SetTextI18n\")\r\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\r\n        val achievement = list[position]\r\n        if (holder is ItemHolder) {\r\n            holder.icon.setImageResource(achievement.usableIcon())\r\n            holder.name.text = achievement.usableName()\r\n            holder.state.text = achievement.getState()\r\n            holder.exp.text = \"${NumberFormat.getNumberInstance(Locale.US).format(achievement.points)} XP\"\r\n            holder.root.setOnClickListener { noCrash { onClick.invoke(achievement) } }\r\n        }\r\n    }\r\n\r\n    fun setAchievements(list: MutableList<Achievement>) {\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            this@AchievementAdapter.list = list\r\n            if (PrefsUtil.isNativeAdsEnabled)\r\n                this@AchievementAdapter.list.implAdsAchievement()\r\n            launch(Dispatchers.Main) {\r\n                notifyDataSetChanged()\r\n            }\r\n        }\r\n    }\r\n\r\n    class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.root)\r\n        val icon: ImageView by itemView.bind(R.id.icon)\r\n        val name: TextView by itemView.bind(R.id.name)\r\n        val state: TextView by itemView.bind(R.id.state)\r\n        val exp: TextView by itemView.bind(R.id.exp)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/achievements/AchievementFragment.kt",
    "content": "package knf.kuma.achievements\r\n\r\nimport android.graphics.Color\r\nimport android.os.Bundle\r\nimport android.view.LayoutInflater\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.LinearLayout\r\nimport android.widget.TextView\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.lifecycle.Observer\r\nimport androidx.recyclerview.widget.DividerItemDecoration\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.Achievement\r\nimport nl.dionsegijn.konfetti.KonfettiView\r\nimport nl.dionsegijn.konfetti.models.Shape\r\nimport nl.dionsegijn.konfetti.models.Size\r\nimport org.jetbrains.anko.find\r\n\r\n\r\nclass AchievementFragment : Fragment() {\r\n\r\n    private lateinit var recyclerView: RecyclerView\r\n    private lateinit var error: View\r\n    private lateinit var errorText: TextView\r\n    private lateinit var onClick: OnClick\r\n    private lateinit var konfetti: KonfettiView\r\n    private val adapter = AchievementAdapter {\r\n        onClick.invoke(it)\r\n    }\r\n    private val isLockedScreen: Boolean by lazy { arguments?.getInt(isUnlockedKey, 0) ?: 0 == 0 }\r\n    private var isListEmpty: Boolean = false\r\n    private var isFirst = true\r\n\r\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\r\n        super.onActivityCreated(savedInstanceState)\r\n        CacheDB.INSTANCE.achievementsDAO().achievementList(arguments?.getInt(isUnlockedKey, 0) ?: 0)\r\n                .observe(viewLifecycleOwner, Observer {\r\n                    isListEmpty = it.isEmpty()\r\n                    adapter.setAchievements(it)\r\n                    error.visibility = if (it.isEmpty()) View.VISIBLE else View.GONE\r\n                    if (isFirst) {\r\n                        recyclerView.scheduleLayoutAnimation()\r\n                        isFirst = false\r\n                    }\r\n                })\r\n    }\r\n\r\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\r\n        return inflater.inflate(R.layout.fragment_achievements, container, false).also {\r\n            error = it.find(R.id.error)\r\n            errorText = it.find(R.id.error_text)\r\n            konfetti = it.find(R.id.konfetti)\r\n            errorText.text = if (arguments?.getInt(isUnlockedKey, 0) == 0) \"Has completado todos los logros\" else \"No has completado ningun logro\"\r\n            recyclerView = it.find(R.id.recycler)\r\n            recyclerView.addItemDecoration(DividerItemDecoration(context, LinearLayout.VERTICAL))\r\n            recyclerView.adapter = adapter\r\n        }\r\n    }\r\n\r\n    override fun onResume() {\r\n        super.onResume()\r\n        if (isLockedScreen && isListEmpty)\r\n            konfetti.build().apply {\r\n                addColors(Color.BLUE, Color.RED, Color.YELLOW, Color.GREEN, Color.MAGENTA)\r\n                setDirection(0.0, 359.0)\r\n                setSpeed(4f, 7f)\r\n                setFadeOutEnabled(true)\r\n                setTimeToLive(2000)\r\n                addShapes(Shape.RECT, Shape.CIRCLE)\r\n                addSizes(Size(12, 6f), Size(16, 6f))\r\n                setPosition(-50f, konfetti.width + 50f, -50f, -50f)\r\n            }.streamFor(200, 10000L)\r\n    }\r\n\r\n    override fun onPause() {\r\n        super.onPause()\r\n        if (isLockedScreen && isListEmpty)\r\n            konfetti.reset()\r\n    }\r\n\r\n    fun setCallback(onClick: OnClick) {\r\n        this.onClick = onClick\r\n    }\r\n\r\n    companion object {\r\n        private const val isUnlockedKey = \"isUnlocked\"\r\n\r\n        fun get(isUnlocked: Int, onClick: OnClick): AchievementFragment {\r\n            val achievementFragment = AchievementFragment()\r\n            val bundle = Bundle().apply {\r\n                this.putInt(isUnlockedKey, isUnlocked)\r\n            }\r\n            achievementFragment.arguments = bundle\r\n            achievementFragment.setCallback(onClick)\r\n            return achievementFragment\r\n        }\r\n    }\r\n}\r\n\r\ntypealias OnClick = (achievement: Achievement) -> Unit"
  },
  {
    "path": "app/src/main/java/knf/kuma/achievements/AchievementManager.kt",
    "content": "package knf.kuma.achievements\r\n\r\nimport android.annotation.SuppressLint\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.content.IntentFilter\r\nimport android.os.BatteryManager\r\nimport android.os.Build\r\nimport android.provider.Settings\r\nimport androidx.annotation.DrawableRes\r\nimport androidx.lifecycle.LiveData\r\nimport androidx.lifecycle.Observer\r\nimport knf.kuma.R\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.distinct\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.isTV\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.toast\r\nimport knf.kuma.custom.AchievementUnlocked\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.database.EADB\r\nimport knf.kuma.pojos.Achievement\r\nimport knf.kuma.pojos.FavoriteObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\nimport org.jetbrains.anko.doAsync\r\nimport xdroid.toaster.Toaster\r\nimport java.text.SimpleDateFormat\r\nimport java.util.Calendar\r\nimport java.util.Locale\r\n\r\n@SuppressLint(\"StaticFieldLeak\")\r\nobject AchievementManager {\r\n\r\n    private lateinit var context: Context\r\n    private lateinit var achievementUnlocked: AchievementUnlocked\r\n    private lateinit var completionLiveData: LiveData<List<Achievement>>\r\n    private val achievementsDAO = CacheDB.INSTANCE.achievementsDAO()\r\n    private val liveList = arrayListOf<LiveData<Int>>()\r\n    private const val VERSION = 3\r\n\r\n    fun init(context: Context) {\r\n        this.context = context\r\n        achievementUnlocked = AchievementUnlocked(context).apply {\r\n            setRounded(false)\r\n            setLarge(true)\r\n            setDismissible(true)\r\n        }\r\n        preloadAchievements()\r\n        achievementsDAO.completionListener.also { completionLiveData = it }.distinct.observeForever(Observer {\r\n            if (it.isEmpty()) return@Observer\r\n            val list: List<Int> = it.map { achievement -> achievement.key.toInt() }\r\n            unlock(list)\r\n        })\r\n        CacheDB.INSTANCE.seenDAO().countLive.also { liveList.add(it) }.distinct.observeForever {\r\n            updateCount(it, listOf(33, 39))\r\n        }\r\n        CacheDB.INSTANCE.favsDAO().countLive.also { liveList.add(it) }.distinct.observeForever {\r\n            updateCount(it, listOf(11, 1, 2, 3, 4, 5))\r\n        }\r\n        CacheDB.INSTANCE.seeingDAO().countLive.also { liveList.add(it) }.distinct.observeForever {\r\n            updateCount(it, listOf(16, 17, 18, 19))\r\n        }\r\n        CacheDB.INSTANCE.seeingDAO().countCompletedLive.also { liveList.add(it) }.distinct.observeForever {\r\n            updateCount(it, listOf(20, 21, 22, 23))\r\n        }\r\n        CacheDB.INSTANCE.seeingDAO().countDroppedLive.also { liveList.add(it) }.distinct.observeForever {\r\n            updateCount(it, listOf(24, 25, 26, 27))\r\n        }\r\n        CacheDB.INSTANCE.seeingDAO().isAnimeCompleted(listOf(\"363\", \"1706\", \"2950\", \"1182\", \"2479\", \"2478\")).also { liveList.add(it) }.distinct.observeForever {\r\n            if (it == 6) unlock(listOf(38))\r\n        }\r\n        CacheDB.INSTANCE.seeingDAO().isAnimeCompleted(listOf(\"1487\", \"1488\", \"1019\", \"460\", \"1493\", \"1494\")).also { liveList.add(it) }.distinct.observeForever {\r\n            if (it == 6) unlock(listOf(45))\r\n        }\r\n    }\r\n\r\n    private fun resetIndicator() {\r\n        achievementUnlocked.apply {\r\n            setRounded(false)\r\n            setLarge(true)\r\n            setDismissible(true)\r\n        }\r\n    }\r\n\r\n    private fun preloadAchievements() {\r\n        doAsync {\r\n            if (VERSION > PrefsUtil.achievementsVersion) {\r\n                achievementsDAO.nuke()\r\n                PrefsUtil.achievementsVersion = VERSION\r\n            }\r\n            achievementsDAO.insert(\r\n                    Achievement(0, \"Primeros pasos\", \"Abre la app por primera vez\", points = 1000),\r\n                    Achievement(1, \"Pathetic\", \"Agrega 10 favoritos\", points = 1000, goal = 10),\r\n                    Achievement(2, \"¿Lo estas intentando?\", \"Agrega 100 favoritos\", 2000, goal = 100),\r\n                    Achievement(3, \"Ya nos vamos entendiendo\", \"Agrega 200 favoritos\", 3000, goal = 200),\r\n                    Achievement(4, \"Oye tranquilo viejo\", \"Agrega 500 favoritos\", 4000, goal = 500),\r\n                    Achievement(5, \"Estas demente parker\", \"Agrega 1000 favoritos\", 6000, goal = 1000, isSecret = true),\r\n                    Achievement(6, \"Remoto\", \"Usa Cast por primera vez\", points = 1000, isSecret = true),\r\n                    Achievement(7, \"Veterano\", \"Ten instalado Animeflv App\", points = 3000, isSecret = true),\r\n                    Achievement(8, \"Iniciado\", \"Ten instalada la app por 3 meses\", points = 2000, isSecret = true),\r\n                    Achievement(9, \"Empezando a cultivar\", \"Ten instalada la app por 6 meses\", points = 3000, isSecret = true),\r\n                    Achievement(10, \"Feliz cumpleaños\", \"Ten instalada la app por 1 año\", points = 6000, isSecret = true),\r\n                    Achievement(11, \"Primer amor\", \"Añade tu primer favorito\", points = 1000, goal = 1),\r\n                    Achievement(12, \"Algo fácil para iniciar\", \"Inicia el misterio\", points = 1000, isSecret = true),\r\n                    Achievement(13, \"El mejor escondite esta a la vista\", \"Descubre la secuencia\", points = 2000, isSecret = true),\r\n                    Achievement(14, \"Va para el curriculum\", \"Descubre para que sirve US\", points = 6000, isSecret = true),\r\n                    Achievement(15, \"Cuna del manga\", \"Encuentra Akihabara\", points = 2000, isSecret = true),\r\n                    Achievement(16, \"Por algo se empieza\", \"Sigue 5 animes\", points = 1000, goal = 5),\r\n                    Achievement(17, \"Se prendió esta mierda\", \"Sigue 15 animes\", points = 2000, goal = 15),\r\n                    Achievement(18, \"Esto se va a descontrolar\", \"Sigue 40 animes\", points = 3000, goal = 40),\r\n                    Achievement(19, \"Con el Rinnegan lo veo todo\", \"Sigue 100 animes\", points = 4000, goal = 100),\r\n                    Achievement(20, \"El inicio del camino\", \"Marca 1 anime como completado\", points = 1000, goal = 1),\r\n                    Achievement(21, \"Te está gustando?\", \"Marca 5 animes como completados\", points = 2000, goal = 5),\r\n                    Achievement(22, \"Ya no hay vuelta atrás\", \"Marca 20 animes como completados\", points = 3000, goal = 20),\r\n                    Achievement(23, \"Otaku\", \"Marca 50 animes como completados\", points = 4000, goal = 50),\r\n                    Achievement(24, \"Mala elección\", \"Dropea 1 anime\", points = 1000, goal = 1, isSecret = true),\r\n                    Achievement(25, \"Algo anda mal...\", \"Dropea 5 animes\", points = 2000, goal = 5, isSecret = true),\r\n                    Achievement(26, \"No te gusta nada\", \"Dropea 15 animes\", points = 3000, goal = 15, isSecret = true),\r\n                    Achievement(27, \"Antes eras chido...\", \"Dropea 30 animes\", points = 4000, goal = 30, isSecret = true),\r\n                    Achievement(28, \"Lo has logrado!\", \"Completa el easter egg\", points = 12000, isSecret = true),\r\n                    Achievement(29, \"Viviendo al limite\", \"Reproduce un episodio con poca batería\", points = 2500, isSecret = true),\r\n                    Achievement(30, \"Informado\", \"Lee 20 noticias\", points = 1500, goal = 20),\r\n                    Achievement(31, \"Vampiro\", \"Ve anime pasada la media noche\", points = 2000, isSecret = true),\r\n                    Achievement(32, \"Estas aburrido?\", \"Refresca la pantalla random 15 veces\", points = 2500, isSecret = true),\r\n                    Achievement(33, \"Otaku definitivo\", \"Ve 15k episodios\", points = 15000, goal = 15000, isSecret = true),\r\n                    Achievement(34, \"Bien hecho puerco\", \"Agrega 10 ecchis a favoritos\", points = 2000, goal = 10),\r\n                    Achievement(35, \"Viajero\", \"Descarga un anime completo\", points = 2000),\r\n                    Achievement(36, \"Que milagro verte por aquí\", \"No uses la app por una semana\", points = 3000, isSecret = true),\r\n                    Achievement(37, \"La aventura comienza\", \"Agrega un shounen a favoritos\", points = 2000),\r\n                    Achievement(38, \"1.048596\", \"Completa toda la saga de Steins;Gate\", points = 10000, isSecret = true),\r\n                    Achievement(39, \"Sabio de los 6 caminos\", \"Ve 5000 episodios\", points = 5000, goal = 5000),\r\n                    Achievement(40, \"Que haces?\", \"Presiona el botón de configuracion 20 veces\", points = 5000, isSecret = true),\r\n                    Achievement(41, \"Mas vale prevenir\", \"Respalda tus datos en la nube\", points = 2000),\r\n                    Achievement(42, \"Compartiendo sabiduria\", \"Comparte 20 animes\", points = 2000, goal = 20),\r\n                    Achievement(43, \"Boku no pico?\", \"Busca boku no hero\", points = 2000, isSecret = true),\r\n                    Achievement(44, \"Alzheimer?\", \"Abre el historial 20 veces\", points = 2000, goal = 20),\r\n                    Achievement(45, \"A Sam le gusta esto\", \"Completa todo Evangelion\", points = 6000, isSecret = true),\r\n                    Achievement(46, \"Tu primera loli\", \"Obtén 1 loli-coin\", points = 1000, goal = 1, isSecret = true),\r\n                    Achievement(47, \"Nyanpasu\", \"Obtén 10 loli-coins\", points = 1500, goal = 10, isSecret = true),\r\n                    Achievement(48, \"Al dev le gusta esto\", \"Obtén 50 loli-coins\", points = 3000, goal = 50, isSecret = true),\r\n                    Achievement(49, \"Eso muerde el cebo\", \"Obtén 100 loli-coins\", points = 4500, goal = 100, isSecret = true),\r\n                    Achievement(50, \"La ONU te busca\", \"Obtén 500 loli-coins\", points = 6000, goal = 500, isSecret = true),\r\n                    Achievement(51, \"Al Chico Loli le gusta esto\", \"Obtén 1000 loli-coins\", points = 7500, goal = 1000, isSecret = true)\r\n            )\r\n        }\r\n    }\r\n\r\n    @DrawableRes\r\n    fun getIcon(key: Long): Int {\r\n        return when (key) {\r\n            0L -> R.drawable.ic_achievement_start\r\n            in 1..5, 11L -> R.drawable.ic_achievement_fav\r\n            6L -> R.drawable.ic_achievement_cast\r\n            7L -> R.drawable.ic_umaru_simple\r\n            in 8..10 -> R.drawable.ic_achievement_calendar\r\n            in 12..15, 28L -> R.drawable.ic_achievement_egg\r\n            in 16..19 -> R.drawable.ic_achievement_following\r\n            in 20..23 -> R.drawable.ic_achievement_completed\r\n            in 24..27 -> R.drawable.ic_achievement_droped\r\n            29L -> R.drawable.ic_achievement_battery\r\n            30L -> R.drawable.ic_achievement_news\r\n            31L -> R.drawable.ic_achievement_vampire\r\n            32L -> R.drawable.ic_achievement_bored\r\n            33L, 39L -> R.drawable.ic_achievement_otaku\r\n            34L -> R.drawable.ic_achievement_pig\r\n            35L -> R.drawable.ic_achievement_airplane\r\n            36L -> R.drawable.ic_achievement_sad\r\n            37L -> R.drawable.ic_achievement_onepiece\r\n            38L -> R.drawable.ic_achievement_clock\r\n            40L -> R.drawable.ic_achievement_question\r\n            41L -> R.drawable.ic_achievement_cloud\r\n            42L -> R.drawable.ic_achievement_share\r\n            43L -> R.drawable.ic_achievement_midoriya\r\n            44L -> R.drawable.ic_achievement_memory\r\n            45L -> R.drawable.ic_achievement_evangelion\r\n            in 46..51 -> R.drawable.ic_cash_multi\r\n            else -> R.drawable.ic_umaru_simple\r\n        }\r\n    }\r\n\r\n    fun backup(callback: () -> Unit = {}) =\r\n            Backups.backup(id = Backups.keyAchievements) {\r\n                callback()\r\n            }\r\n\r\n    fun restore(callback: () -> Unit = {}) {\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            val service = Backups.createService()\r\n            if (service?.isLoggedIn == true)\r\n                service.search(Backups.keyAchievements, true)?.let { backupObj ->\r\n                    CacheDB.INSTANCE.achievementsDAO().update((backupObj.data?.filterIsInstance<Achievement>()\r\n                        ?: arrayListOf()).filter { it.isUnlocked })\r\n                    callback()\r\n                }\r\n        }\r\n    }\r\n\r\n    private fun updateCount(count: Int, keys: List<Int>) {\r\n        doAsync {\r\n            val list = achievementsDAO.find(keys)\r\n            list.forEach { it.count = count }\r\n            achievementsDAO.update(list)\r\n        }\r\n    }\r\n\r\n    fun incrementCount(by: Int, keys: List<Int>) {\r\n        doAsync {\r\n            val list = achievementsDAO.find(keys)\r\n            list.forEach { it.count += by }\r\n            achievementsDAO.update(list)\r\n        }\r\n    }\r\n\r\n    fun isUnlocked(key: Int): Boolean {\r\n        return achievementsDAO.isUnlocked(key)\r\n    }\r\n\r\n    fun unlock(keys: Collection<Int>) {\r\n        if (context.resources.getBoolean(R.bool.isTv)) return\r\n        doAsync {\r\n            val list = mutableListOf<Achievement>()\r\n            keys.forEach {\r\n                noCrash {\r\n                    if (!achievementsDAO.isUnlocked(it) && !isTV) {\r\n                        val achievement = achievementsDAO.find(it)\r\n                        if (achievement != null) {\r\n                            list.add(achievement.apply {\r\n                                isUnlocked = true\r\n                                time = System.currentTimeMillis()\r\n                            })\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            achievementsDAO.update(list)\r\n\r\n            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context)) {\r\n                val achievementList = mutableListOf<AchievementUnlocked.AchievementData>()\r\n                list.forEach { achievementList.add(it.achievementData(context)) }\r\n                resetIndicator()\r\n                doOnUIGlobal {\r\n                    achievementUnlocked.show(achievementList)\r\n                }\r\n            } else\r\n                for (achievement in list)\r\n                    Toaster.toast(\"${achievement.name} | Desbloqueado\")\r\n        }\r\n    }\r\n\r\n    fun onAppStart() {\r\n        doAsync {\r\n            val list = mutableListOf<Int>()\r\n            list.add(0)\r\n            if (PrefsUtil.firstStart == 0L)\r\n                PrefsUtil.firstStart = System.currentTimeMillis()\r\n            val time = (System.currentTimeMillis() - PrefsUtil.firstStart)\r\n            if (time >= 7776000000) list.add(8)\r\n            if (time >= 15552000000) list.add(9)\r\n            if (time >= 31104000000) list.add(10)\r\n            if (System.currentTimeMillis() - PrefsUtil.lastStart >= 604800000)\r\n                list.add(36)\r\n            PrefsUtil.lastStart = System.currentTimeMillis()\r\n            if (EADB.INSTANCE.eaDAO().isUnlocked(0)) list.add(12)\r\n            if (EADB.INSTANCE.eaDAO().isUnlocked(1)) list.add(13)\r\n            if (EADB.INSTANCE.eaDAO().isUnlocked(2)) list.add(14)\r\n            if (EADB.INSTANCE.eaDAO().isUnlocked(3)) list.add(15)\r\n            if (EAHelper.isPart0Unlocked && EAHelper.isPart1Unlocked && EAHelper.isPart2Unlocked && EAHelper.isPart3Unlocked)\r\n                list.add(28)\r\n            unlock(list)\r\n        }\r\n    }\r\n\r\n    fun onPhaseUnlocked(phase: Int) {\r\n        when (phase) {\r\n            0 -> unlock(listOf(12))\r\n            1 -> unlock(listOf(13))\r\n            2 -> unlock(listOf(14))\r\n            3 -> unlock(listOf(15))\r\n        }\r\n        if (EAHelper.isAllUnlocked)\r\n            unlock(listOf(28))\r\n    }\r\n\r\n    fun onNewsOpened() {\r\n        incrementCount(1, listOf(30))\r\n    }\r\n\r\n    fun onBackup() {\r\n        unlock(listOf(41))\r\n    }\r\n\r\n    fun onShare() {\r\n        incrementCount(1, listOf(42))\r\n    }\r\n\r\n    fun onSearch(query: String) {\r\n        when (query.lowercase(Locale.getDefault())) {\r\n            \"boku no hero\" -> unlock(listOf(43))\r\n        }\r\n    }\r\n\r\n    fun onRecordsOpened() {\r\n        incrementCount(1, listOf(44))\r\n    }\r\n\r\n    fun onFavAdded(fav: FavoriteObject) {\r\n        doAsync {\r\n            if (CacheDB.INSTANCE.animeDAO().hasGenre(fav.aid, \"Ecchi\".like))\r\n                incrementCount(1, listOf(34))\r\n            if (CacheDB.INSTANCE.animeDAO().hasGenre(fav.aid, \"Shounen\".like))\r\n                unlock(listOf(37))\r\n        }\r\n    }\r\n\r\n    private val String.like: String get() = \"%$this%\"\r\n\r\n    fun onPlayQueue(count: Int) {\r\n        if (count == 0)\r\n            return\r\n        incrementCount(count - 1, listOf(33))\r\n        onPlayChapter()\r\n    }\r\n\r\n    fun onPlayChapter() {\r\n        doAsync {\r\n            noCrash {\r\n                val batteryStatus = context.registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))\r\n                val batteryLevel = batteryStatus?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1\r\n                val batteryScale = batteryStatus?.getIntExtra(BatteryManager.EXTRA_SCALE, -1) ?: -1\r\n                val batteryPct = batteryLevel / batteryScale.toFloat()\r\n                val isLivingAtLimit = (batteryPct * 100).toInt() <= 10 &&\r\n                        batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) != BatteryManager.BATTERY_STATUS_CHARGING &&\r\n                        batteryStatus?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) != BatteryManager.BATTERY_STATUS_FULL\r\n                if (isLivingAtLimit)\r\n                    unlock(listOf(29))\r\n                val timeFormat = SimpleDateFormat(\"HH\", Locale.getDefault())\r\n                val current = timeFormat.format(Calendar.getInstance().time).toInt()\r\n                if (current in 0..3)\r\n                    unlock(listOf(31))\r\n            }.toast()\r\n        }\r\n    }\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/achievements/AchievementsFragmentsPagerAdapter.kt",
    "content": "package knf.kuma.achievements\r\n\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.fragment.app.FragmentManager\r\nimport androidx.fragment.app.FragmentStatePagerAdapter\r\n\r\nclass AchievementsFragmentsPagerAdapter(fragmentManager: FragmentManager, private val onClick: OnClick) : FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {\r\n\r\n    override fun getItem(position: Int): Fragment = AchievementFragment.get(if (position == 0) 1 else 0, onClick)\r\n\r\n    override fun getCount(): Int {\r\n        return 2\r\n    }\r\n\r\n    override fun getPageTitle(position: Int): CharSequence? {\r\n        return when (position) {\r\n            1 -> \"Bloqueados\"\r\n            else -> \"Desbloqueados\"\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/achievements/AchievementsPagerAdapter.kt",
    "content": "package knf.kuma.achievements\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.fragment.app.FragmentManager\r\nimport androidx.viewpager.widget.PagerAdapter\r\n\r\nclass AchievementsPagerAdapter(private val fragmentManager: FragmentManager, private val onClick: OnClick) : PagerAdapter() {\r\n\r\n    private val fragments = arrayOfNulls<Fragment>(2)\r\n\r\n    override fun destroyItem(container: ViewGroup, position: Int, any: Any) {\r\n        assert(0 <= position && position < fragments.size)\r\n        val fragment = fragments[position]\r\n        fragment?.let {\r\n            val transaction = fragmentManager.beginTransaction()\r\n            transaction.remove(it)\r\n            transaction.commit()\r\n            fragments[position] = null\r\n        }\r\n    }\r\n\r\n    override fun instantiateItem(container: ViewGroup, position: Int): Any {\r\n        val fragment = getItem(position)\r\n        fragment?.let {\r\n            val transaction = fragmentManager.beginTransaction()\r\n            transaction.add(container.id, fragment, \"fragment:$position\")\r\n            transaction.commit()\r\n        }\r\n        return fragment ?: Any()\r\n    }\r\n\r\n    override fun isViewFromObject(view: View, any: Any): Boolean {\r\n        return (any as? Fragment)?.view == view\r\n    }\r\n\r\n    private fun getItem(position: Int): Fragment? {\r\n        assert(0 <= position && position < fragments.size)\r\n        if (fragments[position] == null)\r\n            fragments[position] = AchievementFragment.get(if (position == 0) 1 else 0, onClick)\r\n        return fragments[position]\r\n    }\r\n\r\n    override fun getCount(): Int {\r\n        return 2\r\n    }\r\n\r\n    override fun getPageTitle(position: Int): CharSequence? {\r\n        return when (position) {\r\n            1 -> \"Bloqueados\"\r\n            else -> \"Desbloqueados\"\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/achievements/LevelCalculator.kt",
    "content": "package knf.kuma.achievements\r\n\r\nclass LevelCalculator {\r\n    var level: Int = 0\r\n    var toLvlUp: Int = 400\r\n    var progress: Int = 0\r\n    var max: Int = 400\r\n    lateinit var levels: List<Int>\r\n\r\n    init {\r\n        createLevels()\r\n    }\r\n\r\n\r\n    fun calculate(points: Int) {\r\n        if (points < 400) {\r\n            level = 0\r\n            toLvlUp = 400 - points\r\n            progress = points\r\n            max = 400\r\n        } else {\r\n            var index = 0\r\n            for (value in levels) {\r\n                if (points < value) {\r\n                    level = index\r\n                    max = value - (400 * index)\r\n                    progress = points - levels[index - 1]\r\n                    toLvlUp = /*max - progress*/ value - points\r\n                    break\r\n                }\r\n                index++\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun createLevels() {\r\n        val lvls = mutableListOf<Int>()\r\n        var last = 0\r\n        for (i in 1..60) {\r\n            val xp = (last + (400 + (175 * (i - 1)))).also { last = it }\r\n            lvls.add(xp)\r\n        }\r\n        levels = lvls\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/AdAnimeObject.kt",
    "content": "package knf.kuma.ads\r\n\r\nimport knf.kuma.pojos.AnimeObject\r\n\r\ndata class AdAnimeObject(private val adID: String) : AnimeObject(), AdCallback {\r\n    override fun getID(): String {\r\n        return adID\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/AdCallback.kt",
    "content": "package knf.kuma.ads\r\n\r\ninterface AdCallback {\r\n    fun getID(): String\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/AdCardItemHolder.kt",
    "content": "package knf.kuma.ads\r\n\r\nimport android.view.LayoutInflater\r\nimport android.view.ViewGroup\r\nimport androidx.annotation.LayoutRes\r\nimport androidx.annotation.UiThread\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport kotlinx.coroutines.CoroutineScope\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.launch\r\nimport org.jetbrains.anko.find\r\n\r\n\r\nclass AdCardItemHolder(parent: ViewGroup, @LayoutRes type: Int = TYPE_NORMAL) : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(type, parent, false)) {\r\n    private val container = itemView.find<ViewGroup>(R.id.container)\r\n\r\n    @UiThread\r\n    fun loadAd(ad: AdCallback?) {\r\n        if (ad == null) return\r\n        container.implBanner(ad.getID(), true)\r\n    }\r\n\r\n    fun loadAd(scope: CoroutineScope, ad: AdCallback?, delayed: Long = 0) {\r\n        if (ad == null) return\r\n        scope.launch(Dispatchers.IO) {\r\n            delay(delayed)\r\n            container.implBanner(ad.getID(), true)\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        const val TYPE_NORMAL = R.layout.item_ad\r\n        const val TYPE_FAV = R.layout.item_ad_fav\r\n        const val TYPE_ACHIEVEMENT = R.layout.item_ad_achievements\r\n        const val TYPE_NEWS = R.layout.item_ad_news\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/AdFavoriteObject.kt",
    "content": "package knf.kuma.ads\r\n\r\nimport knf.kuma.pojos.FavoriteObject\r\n\r\ndata class AdFavoriteObject(private val adID: String) : FavoriteObject(), AdCallback {\r\n    override fun getID(): String {\r\n        return adID\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/AdRecentObject.kt",
    "content": "package knf.kuma.ads\r\n\r\nimport knf.kuma.pojos.RecentObject\r\n\r\ndata class AdRecentObject(private val adID: String) : RecentObject(), AdCallback {\r\n    override fun getID(): String {\r\n        return adID\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/AdsUtils.kt",
    "content": "package knf.kuma.ads\r\n\r\nimport android.app.Activity\r\nimport android.util.Log\r\nimport android.view.ViewGroup\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport com.google.firebase.remoteconfig.FirebaseRemoteConfig\r\nimport com.google.firebase.remoteconfig.FirebaseRemoteConfigSettings\r\nimport knf.kuma.BuildConfig\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.diceOf\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.noCrashLet\r\nimport knf.kuma.news.NewsObject\r\nimport knf.kuma.pojos.Achievement\r\nimport knf.kuma.pojos.FavoriteObject\r\nimport knf.kuma.pojos.RecentObject\r\nimport org.nield.kotlinstatistics.weightedCoinFlip\r\n\r\nenum class AdsType {\r\n    RECENT_BANNER,\r\n    RECENT_BANNER2,\r\n    FAVORITE_BANNER,\r\n    FAVORITE_BANNER2,\r\n    DIRECTORY_BANNER,\r\n    HOME_BANNER,\r\n    HOME_BANNER2,\r\n    EMISSION_BANNER,\r\n    SEEING_BANNER,\r\n    RECOMMEND_BANNER,\r\n    QUEUE_BANNER,\r\n    RECORD_BANNER,\r\n    NEWS_BANNER,\r\n    RANDOM_BANNER,\r\n    INFO_BANNER,\r\n    ACHIEVEMENT_BANNER,\r\n    EXPLORER_BANNER,\r\n    CAST_BANNER,\r\n    REWARDED,\r\n    INTERSTITIAL\r\n}\r\n\r\nobject AdsUtils {\r\n    val remoteConfigs = FirebaseRemoteConfig.getInstance().apply {\r\n        if (BuildConfig.DEBUG)\r\n            setConfigSettingsAsync(\r\n                FirebaseRemoteConfigSettings.Builder().apply { minimumFetchIntervalInSeconds = 0 }\r\n                    .build()\r\n            )\r\n        setDefaultsAsync(\r\n            mapOf(\r\n                \"admob_enabled\" to false,\r\n                \"appbrains_enabled\" to false,\r\n                \"startapp_enabled\" to false,\r\n                \"appodeal_enabled\" to false,\r\n                \"applovin_enabled\" to true,\r\n                \"admob_use_fallback\" to false,\r\n                \"ads_forced\" to false,\r\n                \"ads_remote_banner\" to true,\r\n                \"ads_remote_full\" to true,\r\n                \"ads_remote\" to 1.0,\r\n                \"admob_percent\" to 100.0,\r\n                \"appodeal_percent\" to 100.0,\r\n                \"applovin_percent\" to 100.0,\r\n                \"appbrains_percent\" to 0.0,\r\n                \"startapp_percent\" to 0.0,\r\n                \"appodeal_fullscreen_percent\" to 100.0,\r\n                \"applovin_fullscreen_percent\" to 100.0,\r\n                \"admob_fullscreen_percent\" to 100.0,\r\n                \"appbrains_fullscreen_percent\" to 100.0,\r\n                \"startappp_fullscreen_percent\" to 100.0,\r\n                \"appodeal_fullscreen_percent\" to 100.0,\r\n                \"rewarded_percent\" to 10.0,\r\n                \"interstitial_percent\" to 90.0,\r\n                \"disqus_version\" to \"9e3da5ae8d7caf8389087c4c35a6ca1b\",\r\n                \"min_version\" to 169L,\r\n                \"samsung_disable_foreground\" to false,\r\n                \"bypass_show_reload\" to false,\r\n                \"bypass_clear_cookies\" to false,\r\n                \"bypass_max_tries\" to 3L,\r\n                \"bypass_skip_captcha\" to true,\r\n                \"bypass_use_dialog\" to true,\r\n                \"bypass_dialog_style\" to 1L,\r\n                \"full_show_extra_probability\" to 60.0,\r\n                \"full_show_probability\" to 70.0\r\n            )\r\n        )\r\n        fetch().addOnCompleteListener {\r\n            it.exception?.printStackTrace()\r\n            if (it.isSuccessful) {\r\n                FirebaseRemoteConfig.getInstance().activate()\r\n            }\r\n        }\r\n    }\r\n\r\n    val isRemoteAdsEnabled by lazy {\r\n        weightedCoinFlip(remoteConfigs.getDouble(\"ads_remote\"))\r\n    }\r\n    val isRemoteBannerEnabled get() = remoteConfigs.getBoolean(\"ads_remote_banner\")\r\n    val isRemoteFullEnabled get() = remoteConfigs.getBoolean(\"ads_remote_full\")\r\n    val isAdmobEnabled get() = remoteConfigs.getBoolean(\"admob_enabled\")\r\n    val isApplovinEnabled get() = remoteConfigs.getBoolean(\"applovin_enabled\")\r\n\r\n    fun setUp(context: Activity, callback: () -> Unit) {\r\n        if (!isRemoteAdsEnabled || !listOf(isAdmobEnabled, isApplovinEnabled).any { it }) {\r\n            Log.e(\"ADS\", \"All disabled\")\r\n            callback()\r\n            return\r\n        }\r\n        if (isApplovinEnabled) {\r\n            Log.e(\"ADS\", \"Applovin enabled\")\r\n            AdsUtilsLovin.setUp(context, callback)\r\n        }\r\n        if (isAdmobEnabled) {\r\n            Log.e(\"ADS\", \"Admob enabled\")\r\n            AdsUtilsMob.setUp(context, callback)\r\n        }\r\n    }\r\n}\r\n\r\nfun MutableList<RecentObject>.implAdsRecent() {\r\n    if (AdsUtils.isRemoteAdsEnabled && AdsUtils.isRemoteBannerEnabled && PrefsUtil.isAdsEnabled)\r\n        noCrash {\r\n            diceOf({ implAdsRecentBrains() }) {\r\n                if (AdsUtils.isAdmobEnabled)\r\n                    put({ implAdsRecentMob() }, AdsUtils.remoteConfigs.getDouble(\"admob_percent\"))\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"appbrains_enabled\"))\r\n                    put({ implAdsRecentBrains() }, AdsUtils.remoteConfigs.getDouble(\"appbrains_percent\"))\r\n                if (AdsUtils.isApplovinEnabled)\r\n                    put({ implAdsRecentLovin() }, AdsUtils.remoteConfigs.getDouble(\"applovin_percent\"))\r\n            }()\r\n        }\r\n}\r\n\r\nfun MutableList<FavoriteObject>.implAdsFavorite() {\r\n    if (AdsUtils.isRemoteAdsEnabled && AdsUtils.isRemoteBannerEnabled && PrefsUtil.isAdsEnabled)\r\n        noCrash {\r\n            diceOf({ implAdsFavoriteBrains() }) {\r\n                if (AdsUtils.isAdmobEnabled)\r\n                    put({ implAdsFavoriteMob() }, AdsUtils.remoteConfigs.getDouble(\"admob_percent\"))\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"appbrains_enabled\"))\r\n                    put({ implAdsFavoriteBrains() }, AdsUtils.remoteConfigs.getDouble(\"appbrains_percent\"))\r\n                if (AdsUtils.isApplovinEnabled)\r\n                    put({ implAdsFavoriteLovin() }, AdsUtils.remoteConfigs.getDouble(\"applovin_percent\"))\r\n            }()\r\n        }\r\n}\r\n\r\nfun MutableList<NewsObject>.implAdsNews() {\r\n    if (AdsUtils.isRemoteAdsEnabled && AdsUtils.isRemoteBannerEnabled && PrefsUtil.isAdsEnabled)\r\n        noCrash {\r\n            diceOf({ implAdsNewsBrain() }) {\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"admob_enabled\"))\r\n                    put({ implAdsNewsMob() }, AdsUtils.remoteConfigs.getDouble(\"admob_percent\"))\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"appbrains_enabled\"))\r\n                    put({ implAdsNewsBrain() }, AdsUtils.remoteConfigs.getDouble(\"appbrains_percent\"))\r\n                if (AdsUtils.isApplovinEnabled)\r\n                    put({ implAdsNewsLovin() }, AdsUtils.remoteConfigs.getDouble(\"applovin_percent\"))\r\n            }()\r\n        }\r\n}\r\n\r\nfun MutableList<Achievement>.implAdsAchievement() {\r\n    if (AdsUtils.isRemoteAdsEnabled && AdsUtils.isRemoteBannerEnabled && PrefsUtil.isAdsEnabled)\r\n        noCrash {\r\n            diceOf({ implAdsAchievementBrain() }) {\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"admob_enabled\"))\r\n                    put({ implAdsAchievementMob() }, AdsUtils.remoteConfigs.getDouble(\"admob_percent\"))\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"appbrains_enabled\"))\r\n                    put({ implAdsAchievementBrain() }, AdsUtils.remoteConfigs.getDouble(\"appbrains_percent\"))\r\n                if (AdsUtils.isApplovinEnabled)\r\n                    put({ implAdsAchievementLovin() }, AdsUtils.remoteConfigs.getDouble(\"applovin_percent\"))\r\n            }()\r\n        }\r\n}\r\n\r\nfun ViewGroup.implBannerCast() {\r\n    if (AdsUtils.isRemoteAdsEnabled && AdsUtils.isRemoteBannerEnabled && PrefsUtil.isAdsEnabled)\r\n        noCrash {\r\n            diceOf({ implBannerCastBrains() }) {\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"admob_enabled\"))\r\n                    put({ implBannerCastMob() }, AdsUtils.remoteConfigs.getDouble(\"admob_percent\"))\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"applovin_enabled\"))\r\n                    put({ implBannerCastLovin() }, AdsUtils.remoteConfigs.getDouble(\"applovin_percent\"))\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"appbrains_enabled\"))\r\n                    put({ implBannerCastBrains() }, AdsUtils.remoteConfigs.getDouble(\"appbrains_percent\"))\r\n            }()\r\n        }\r\n}\r\n\r\nfun ViewGroup.implBanner(unitID: String, isSmart: Boolean = false) {\r\n    if (AdsUtils.isRemoteAdsEnabled && AdsUtils.isRemoteBannerEnabled && PrefsUtil.isAdsEnabled)\r\n        noCrash {\r\n            diceOf({ implBannerBrains(unitID, isSmart) }) {\r\n                if (AdsUtils.isAdmobEnabled)\r\n                    put(\r\n                        { implBannerMob(unitID, isSmart) },\r\n                        AdsUtils.remoteConfigs.getDouble(\"admob_percent\")\r\n                    )\r\n                if (AdsUtils.isApplovinEnabled)\r\n                    put(\r\n                        { implBannerLovin(AdsType.RECENT_BANNER) },\r\n                        AdsUtils.remoteConfigs.getDouble(\"applovin_percent\")\r\n                    )\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"appbrains_enabled\"))\r\n                    put(\r\n                        { implBannerBrains(unitID, isSmart) },\r\n                        AdsUtils.remoteConfigs.getDouble(\"appbrains_percent\")\r\n                    )\r\n            }()\r\n        }\r\n}\r\n\r\nfun ViewGroup.implBanner(unitID: AdsType, isSmart: Boolean = false) {\r\n    if (AdsUtils.isRemoteAdsEnabled && AdsUtils.isRemoteBannerEnabled && PrefsUtil.isAdsEnabled)\r\n        noCrash {\r\n            diceOf({ implBannerBrains(unitID, isSmart) }) {\r\n                if (AdsUtils.isAdmobEnabled)\r\n                    put(\r\n                        { implBannerMob(unitID, isSmart) },\r\n                        AdsUtils.remoteConfigs.getDouble(\"admob_percent\")\r\n                    )\r\n                if (AdsUtils.isApplovinEnabled)\r\n                    put(\r\n                        { implBannerLovin(unitID) },\r\n                        AdsUtils.remoteConfigs.getDouble(\"applovin_percent\")\r\n                    )\r\n                if (AdsUtils.remoteConfigs.getBoolean(\"appbrains_enabled\"))\r\n                    put(\r\n                        { implBannerBrains(unitID, isSmart) },\r\n                        AdsUtils.remoteConfigs.getDouble(\"appbrains_percent\")\r\n                    )\r\n            }()\r\n        }\r\n}\r\n\r\nfun getFAdLoaderRewarded(context: Activity, onUpdate: () -> Unit = {}): FullscreenAdLoader =\r\n    noCrashLet(getFAdLoaderBrains(context, onUpdate)) {\r\n        diceOf({ getFAdLoaderBrains(context, onUpdate) }) {\r\n            if (AdsUtils.isAdmobEnabled)\r\n                put(\r\n                    { getFAdLoaderRewardedMob(context, onUpdate) },\r\n                    AdsUtils.remoteConfigs.getDouble(\"admob_fullscreen_percent\")\r\n                )\r\n            if (AdsUtils.isApplovinEnabled)\r\n                put(\r\n                    { getFAdLoaderRewardedLovin(context, onUpdate) },\r\n                    AdsUtils.remoteConfigs.getDouble(\"applovin_fullscreen_percent\")\r\n                )\r\n        }()\r\n    }\r\n\r\nfun getFAdLoaderInterstitial(context: Activity, onUpdate: () -> Unit = {}): FullscreenAdLoader =\r\n    noCrashLet(getFAdLoaderBrains(context, onUpdate)) {\r\n        diceOf({ getFAdLoaderBrains(context, onUpdate) }) {\r\n            if (AdsUtils.isAdmobEnabled)\r\n                put(\r\n                    { getFAdLoaderInterstitialMob(context, onUpdate) },\r\n                    AdsUtils.remoteConfigs.getDouble(\"admob_fullscreen_percent\")\r\n                )\r\n            if (AdsUtils.remoteConfigs.getBoolean(\"appbrains_enabled\"))\r\n                put(\r\n                    { getFAdLoaderBrains(context, onUpdate) },\r\n                    AdsUtils.remoteConfigs.getDouble(\"appbrains_fullscreen_percent\")\r\n                )\r\n            if (AdsUtils.isApplovinEnabled)\r\n                put(\r\n                    { getFAdLoaderInterstitialLovin(context, onUpdate) },\r\n                    AdsUtils.remoteConfigs.getDouble(\"applovin_fullscreen_percent\")\r\n                )\r\n        }()\r\n    }\r\n\r\nfun showRandomInterstitial(\r\n    context: AppCompatActivity,\r\n    probability: Float = PrefsUtil.fullAdsProbability\r\n) {\r\n    if (AdsUtils.isRemoteAdsEnabled && PrefsUtil.isAdsEnabled && PrefsUtil.isFullAdsEnabled && probability > 0) {\r\n        val probDefault = 100f - probability\r\n        diceOf<() -> Unit> {\r\n            if (AdsUtils.isAdmobEnabled)\r\n                put(\r\n                    { FAdLoaderInterstitialLazyMob(context).show() },\r\n                    probability.toDouble()\r\n                )\r\n            if (AdsUtils.remoteConfigs.getBoolean(\"appbrains_enabled\"))\r\n                put(\r\n                    { FAdLoaderInterstitialLazyBrains(context).show() },\r\n                    probability.toDouble()\r\n                )\r\n            if (AdsUtils.isApplovinEnabled)\r\n                put(\r\n                    { FAdLoaderInterstitialLazyLovin(context).show() },\r\n                    probability.toDouble()\r\n                )\r\n            put({}, probDefault.toDouble())\r\n        }()\r\n    }\r\n}\r\n\r\ninterface FullscreenAdLoader {\r\n    fun load()\r\n    fun show()\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/AdsUtilsBrains.kt",
    "content": "package knf.kuma.ads\r\n\r\n//import com.appbrain.*\r\nimport android.content.Context\r\nimport android.view.ViewGroup\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport knf.kuma.commons.Network\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.news.AdNewsObject\r\nimport knf.kuma.news.NewsObject\r\nimport knf.kuma.pojos.Achievement\r\nimport knf.kuma.pojos.AchievementAd\r\nimport knf.kuma.pojos.FavoriteObject\r\nimport knf.kuma.pojos.RecentObject\r\nimport xdroid.toaster.Toaster\r\n\r\nobject AdsUtilsBrains {\r\n    const val RECENT_BANNER = \"recent_banner\"\r\n    const val RECENT_BANNER2 = \"recent_banner_2\"\r\n    const val FAVORITE_BANNER = \"favorite_banner\"\r\n    const val FAVORITE_BANNER2 = \"favorite_banner_2\"\r\n    const val DIRECTORY_BANNER = \"directory_banner\"\r\n    const val HOME_BANNER = \"home_banner\"\r\n    const val HOME_BANNER2 = \"home_banner_2\"\r\n    const val EMISSION_BANNER = \"emission_banner\"\r\n    const val SEEING_BANNER = \"seeing_banner\"\r\n    const val RECOMMEND_BANNER = \"recommend_banner\"\r\n    const val QUEUE_BANNER = \"queue_banner\"\r\n    const val RECORD_BANNER = \"record_banner\"\r\n    const val RANDOM_BANNER = \"random_banner\"\r\n    const val NEWS_BANNER = \"news_banner\"\r\n    const val INFO_BANNER = \"info_banner\"\r\n    const val ACHIEVEMENT_BANNER = \"achievement_banner\"\r\n    const val EXPLORER_BANNER = \"explorer_banner\"\r\n    const val CAST_BANNER = \"cast_banner\"\r\n    const val REWARDED = \"rewarded\"\r\n    const val INTERSTITIAL = \"interstitial\"\r\n}\r\n\r\nfun MutableList<RecentObject>.implAdsRecentBrains() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    ArrayList(this).forEachIndexed { index, _ ->\r\n        if (index % 5 == 0 && index > 0) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsBrains.RECENT_BANNER\r\n                }\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsBrains.RECENT_BANNER2\r\n                }\r\n            }\r\n            add(index, AdRecentObject(adID))\r\n        }\r\n    }\r\n}\r\n\r\nfun MutableList<FavoriteObject>.implAdsFavoriteBrains() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    ArrayList(this).apply {\r\n        forEachIndexed { index, _ ->\r\n            if (index % 8 == 0 && index > 0 && !this[index - 1].isSection) {\r\n                val adID: String = when (adIndex) {\r\n                    0 -> {\r\n                        adIndex = 1\r\n                        AdsUtilsBrains.FAVORITE_BANNER\r\n                    }\r\n                    else -> {\r\n                        adIndex = 0\r\n                        AdsUtilsBrains.FAVORITE_BANNER2\r\n                    }\r\n                }\r\n                this@implAdsFavoriteBrains.add(index, AdFavoriteObject(adID))\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nfun MutableList<NewsObject>.implAdsNewsBrain() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    ArrayList(this).forEachIndexed { index, _ ->\r\n        if (index % 5 == 0 && index > 0) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsBrains.NEWS_BANNER\r\n                }\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsBrains.NEWS_BANNER\r\n                }\r\n            }\r\n            add(index, AdNewsObject(adID))\r\n        }\r\n    }\r\n}\r\n\r\nfun MutableList<Achievement>.implAdsAchievementBrain() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    ArrayList(this).forEachIndexed { index, _ ->\r\n        if (index % 8 == 0 && index > 0) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsBrains.ACHIEVEMENT_BANNER\r\n                }\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsBrains.ACHIEVEMENT_BANNER\r\n                }\r\n            }\r\n            add(index, AchievementAd(adID))\r\n        }\r\n    }\r\n}\r\n\r\nfun ViewGroup.implBannerCastBrains() {\r\n    this.implBannerBrains(AdsUtilsBrains.CAST_BANNER)\r\n}\r\n\r\nfun ViewGroup.implBannerBrains(unitID: AdsType, isSmart: Boolean = false) {\r\n    val id = when (unitID) {\r\n        AdsType.RECENT_BANNER -> AdsUtilsBrains.RECENT_BANNER\r\n        AdsType.RECENT_BANNER2 -> AdsUtilsBrains.RECENT_BANNER2\r\n        AdsType.FAVORITE_BANNER -> AdsUtilsBrains.FAVORITE_BANNER\r\n        AdsType.FAVORITE_BANNER2 -> AdsUtilsBrains.FAVORITE_BANNER2\r\n        AdsType.DIRECTORY_BANNER -> AdsUtilsBrains.DIRECTORY_BANNER\r\n        AdsType.HOME_BANNER -> AdsUtilsBrains.HOME_BANNER\r\n        AdsType.HOME_BANNER2 -> AdsUtilsBrains.HOME_BANNER2\r\n        AdsType.EMISSION_BANNER -> AdsUtilsBrains.EMISSION_BANNER\r\n        AdsType.SEEING_BANNER -> AdsUtilsBrains.SEEING_BANNER\r\n        AdsType.RECOMMEND_BANNER -> AdsUtilsBrains.RECOMMEND_BANNER\r\n        AdsType.QUEUE_BANNER -> AdsUtilsBrains.QUEUE_BANNER\r\n        AdsType.RECORD_BANNER -> AdsUtilsBrains.RECORD_BANNER\r\n        AdsType.RANDOM_BANNER -> AdsUtilsBrains.RANDOM_BANNER\r\n        AdsType.NEWS_BANNER -> AdsUtilsBrains.NEWS_BANNER\r\n        AdsType.INFO_BANNER -> AdsUtilsBrains.INFO_BANNER\r\n        AdsType.ACHIEVEMENT_BANNER -> AdsUtilsBrains.ACHIEVEMENT_BANNER\r\n        AdsType.EXPLORER_BANNER -> AdsUtilsBrains.EXPLORER_BANNER\r\n        AdsType.CAST_BANNER -> AdsUtilsBrains.CAST_BANNER\r\n        AdsType.REWARDED -> AdsUtilsBrains.REWARDED\r\n        AdsType.INTERSTITIAL -> AdsUtilsBrains.INTERSTITIAL\r\n    }\r\n    implBannerBrains(id, isSmart)\r\n}\r\n\r\nfun ViewGroup.implBannerBrains(unitID: String, isSmart: Boolean = false) {\r\n\r\n}\r\n\r\nfun getFAdLoaderBrains(context: Context, onUpdate: () -> Unit): FullscreenAdLoader = FAdLoaderBrains(context, onUpdate)\r\n\r\nclass FAdLoaderBrains(private val context: Context, onUpdate: () -> Unit) : FullscreenAdLoader {\r\n    var isAdClicked = false\r\n    /*private val builder: InterstitialBuilder by lazy {\r\n        InterstitialBuilder.create().apply {\r\n            adId = AdId.DEFAULT\r\n            setOnDoneCallback { builder.preload(context) }\r\n            listener = object : InterstitialListener {\r\n                override fun onClick() {\r\n                    FirebaseAnalytics.getInstance(App.context).logEvent(\"Interstitial_Ad_clicked\", Bundle())\r\n                    isAdClicked = true\r\n                }\r\n\r\n                override fun onDismissed(p0: Boolean) {\r\n                    FirebaseAnalytics.getInstance(App.context).logEvent(\"Interstitial_Ad_watched\", Bundle())\r\n                    Economy.reward(isAdClicked)\r\n                    onUpdate()\r\n                }\r\n\r\n                override fun onAdFailedToLoad(p0: InterstitialListener.InterstitialError?) {\r\n                }\r\n\r\n                override fun onPresented() {\r\n                }\r\n\r\n                override fun onAdLoaded() {\r\n                }\r\n            }\r\n        }.also { it.preload(context) }\r\n    }*/\r\n\r\n    override fun load() {\r\n        ///builder.preload(context)\r\n    }\r\n\r\n    override fun show() {\r\n        if (Network.isAdsBlocked)\r\n            Toaster.toast(\"Anuncios bloqueados por host\")\r\n        /*else\r\n            builder.show(context)*/\r\n    }\r\n}\r\n\r\nclass FAdLoaderInterstitialLazyBrains(val context: AppCompatActivity) : FullscreenAdLoader {\r\n    var isAdClicked = false\r\n\r\n    /*private val builder: InterstitialBuilder by lazy {\r\n        InterstitialBuilder.create().apply {\r\n            adId = AdId.DEFAULT\r\n            setOnDoneCallback { builder.preload(context) }\r\n            listener = object : InterstitialListener {\r\n                override fun onClick() {\r\n                    FirebaseAnalytics.getInstance(App.context).logEvent(\"Interstitial_Ad_clicked\", Bundle())\r\n                    isAdClicked = true\r\n                }\r\n\r\n                override fun onDismissed(p0: Boolean) {\r\n                    FirebaseAnalytics.getInstance(App.context).logEvent(\"Interstitial_Ad_watched\", Bundle())\r\n                    Economy.reward(isAdClicked)\r\n                }\r\n\r\n                override fun onAdFailedToLoad(p0: InterstitialListener.InterstitialError?) {\r\n                }\r\n\r\n                override fun onPresented() {\r\n                }\r\n\r\n                override fun onAdLoaded() {\r\n                }\r\n            }\r\n        }\r\n    }*/\r\n\r\n    init {\r\n        load()\r\n    }\r\n\r\n    override fun load() {\r\n        //builder.preload(context)\r\n    }\r\n\r\n    override fun show() {\r\n        if (Network.isAdsBlocked)\r\n            Toaster.toast(\"Anuncios bloqueados por host\")\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/AdsUtilsLovin.kt",
    "content": "package knf.kuma.ads\r\n\r\nimport android.app.Activity\r\nimport android.view.ViewGroup\r\nimport android.widget.FrameLayout\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.core.content.ContextCompat\r\nimport androidx.lifecycle.lifecycleScope\r\nimport com.applovin.mediation.MaxAd\r\nimport com.applovin.mediation.MaxAdListener\r\nimport com.applovin.mediation.MaxError\r\nimport com.applovin.mediation.MaxReward\r\nimport com.applovin.mediation.MaxRewardedAdListener\r\nimport com.applovin.mediation.ads.MaxAdView\r\nimport com.applovin.mediation.ads.MaxInterstitialAd\r\nimport com.applovin.mediation.ads.MaxRewardedAd\r\nimport com.applovin.sdk.AppLovinMediationProvider\r\nimport com.applovin.sdk.AppLovinPrivacySettings\r\nimport com.applovin.sdk.AppLovinSdk\r\nimport com.applovin.sdk.AppLovinSdkInitializationConfiguration\r\nimport knf.kuma.App\r\nimport knf.kuma.BuildConfig\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.Economy\r\nimport knf.kuma.commons.Network\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.asPx\r\nimport knf.kuma.custom.BannerContainerView\r\nimport knf.kuma.news.AdNewsObject\r\nimport knf.kuma.news.NewsObject\r\nimport knf.kuma.pojos.Achievement\r\nimport knf.kuma.pojos.AchievementAd\r\nimport knf.kuma.pojos.FavoriteObject\r\nimport knf.kuma.pojos.RecentObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.launch\r\nimport org.jetbrains.anko.collections.forEachReversedWithIndex\r\nimport xdroid.toaster.Toaster.toast\r\n\r\nobject AdsUtilsLovin {\r\n    fun setUp(context: Activity, callback: () -> Unit) {\r\n        val initConfig = AppLovinSdkInitializationConfiguration.builder(\"QHQI9Sl_Fltmz6OzT9WBg6sTUG3SlJOaLf6E7G4xMGsOake13NQHoHFK6dAUnG0u_18dllB1Q7mGheTwmEl8AD\")\r\n            .setMediationProvider(AppLovinMediationProvider.MAX)\r\n            .build()\r\n        AppLovinSdk.getInstance(context).initialize(initConfig) {\r\n            if (!AppLovinPrivacySettings.hasUserConsent()) {\r\n                AppLovinPrivacySettings.setHasUserConsent(true)\r\n                AppLovinPrivacySettings.setDoNotSell(false)\r\n            }\r\n            callback()\r\n        }\r\n    }\r\n}\r\n\r\nfun MutableList<RecentObject>.implAdsRecentLovin() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    forEachReversedWithIndex { index, _ ->\r\n        if (index % 5 == 0 && index > 0) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsMob.RECENT_BANNER\r\n                }\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsMob.RECENT_BANNER\r\n                }\r\n            }\r\n            add(index, AdRecentObject(adID))\r\n        }\r\n    }\r\n    add(0, AdRecentObject(AdsUtilsMob.RECENT_BANNER))\r\n}\r\n\r\nfun MutableList<FavoriteObject>.implAdsFavoriteLovin() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    forEachReversedWithIndex { index, _ ->\r\n        if (index % 8 == 0 && index > 0 && !this[index - 1].isSection) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsMob.FAVORITE_BANNER\r\n                }\r\n\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsMob.FAVORITE_BANNER\r\n                }\r\n            }\r\n            this@implAdsFavoriteLovin.add(index, AdFavoriteObject(adID))\r\n        }\r\n    }\r\n    this@implAdsFavoriteLovin.add(0, AdFavoriteObject(AdsUtilsMob.FAVORITE_BANNER))\r\n}\r\n\r\nfun MutableList<NewsObject>.implAdsNewsLovin() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    forEachReversedWithIndex { index, _ ->\r\n        if (index % 5 == 0 && index > 0) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsMob.NEWS_BANNER\r\n                }\r\n\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsMob.NEWS_BANNER\r\n                }\r\n            }\r\n            add(index, AdNewsObject(adID))\r\n        }\r\n    }\r\n    add(0, AdNewsObject(AdsUtilsMob.NEWS_BANNER))\r\n}\r\n\r\nfun MutableList<Achievement>.implAdsAchievementLovin() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    forEachReversedWithIndex { index, _ ->\r\n        if (index % 8 == 0 && index > 0) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsMob.ACHIEVEMENT_BANNER\r\n                }\r\n\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsMob.ACHIEVEMENT_BANNER\r\n                }\r\n            }\r\n            add(index, AchievementAd(adID))\r\n        }\r\n    }\r\n    add(0, AchievementAd(AdsUtilsMob.ACHIEVEMENT_BANNER))\r\n}\r\n\r\nfun ViewGroup.implBannerCastLovin() {\r\n    this.implBannerMob(AdsUtilsMob.CAST_BANNER)\r\n}\r\n\r\nfun ViewGroup.implBannerLovin(unitID: AdsType, isSmart: Boolean = false) {\r\n    implBannerLovin()\r\n}\r\n\r\nfun ViewGroup.implBannerLovin() {\r\n    if (PrefsUtil.isAdsEnabled) {\r\n        GlobalScope.launch g@{\r\n            if (this@implBannerLovin.tag == \"AdView added\")\r\n                return@g\r\n            if (this@implBannerLovin !is BannerContainerView) {\r\n                GlobalScope.launch {\r\n                    val adView = MaxAdView(\"91d782c7eb7efc75\")\r\n                    adView.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 50.asPx)\r\n                    adView.setBackgroundColor(ContextCompat.getColor(App.context, R.color.cardview_background))\r\n                    launch(Dispatchers.Main) {\r\n                        addView(adView)\r\n                        this@implBannerLovin.tag = \"AdView added\"\r\n                        adView.loadAd()\r\n                    }\r\n                }\r\n            } else {\r\n                val adView = MaxAdView(\"91d782c7eb7efc75\")\r\n                adView.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 50.asPx)\r\n                adView.setBackgroundColor(ContextCompat.getColor(App.context, R.color.cardview_background))\r\n                launch(Dispatchers.Main) {\r\n                    show(adView)\r\n                    adView.loadAd()\r\n                    this@implBannerLovin.tag = \"AdView added\"\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n\r\nfun getFAdLoaderInterstitialLovin(context: Activity, onUpdate: () -> Unit): FullscreenAdLoader = FAdLoaderInterstitialLovin(context, onUpdate)\r\nfun getFAdLoaderRewardedLovin(context: Activity, onUpdate: () -> Unit): FullscreenAdLoader = FAdLoaderRewardedLovin(context, onUpdate)\r\n\r\nclass FAdLoaderInterstitialLovin(val context: Activity, private val onUpdate: () -> Unit) : FullscreenAdLoader {\r\n    private var interstitialAd: MaxInterstitialAd = MaxInterstitialAd(\"e5f776a3ccb9282e\")\r\n    private var isLoading = false\r\n\r\n    init {\r\n        isLoading = true\r\n        interstitialAd.setListener(object : MaxAdListener {\r\n            var isClicked = false\r\n            override fun onAdLoaded(p0: MaxAd) {\r\n                isLoading = false\r\n            }\r\n\r\n            override fun onAdLoadFailed(p0: String, p1: MaxError) {\r\n                GlobalScope.launch {\r\n                    delay(2000)\r\n                    interstitialAd.loadAd()\r\n                }\r\n            }\r\n\r\n            override fun onAdHidden(p0: MaxAd) {\r\n                isLoading = true\r\n                interstitialAd.loadAd()\r\n                Economy.reward(isClicked)\r\n                isClicked = false\r\n                onUpdate()\r\n            }\r\n\r\n            override fun onAdDisplayed(p0: MaxAd) {}\r\n            override fun onAdClicked(p0: MaxAd) {\r\n                isClicked = true\r\n            }\r\n\r\n            override fun onAdDisplayFailed(p0: MaxAd, p1: MaxError) {}\r\n        })\r\n        interstitialAd.loadAd()\r\n    }\r\n\r\n    override fun load() {\r\n        if (!isLoading && !interstitialAd.isReady) {\r\n            isLoading = true\r\n            interstitialAd.loadAd()\r\n        }\r\n    }\r\n\r\n    override fun show() {\r\n        when {\r\n            !AdsUtils.isRemoteAdsEnabled || !AdsUtils.isRemoteFullEnabled || BuildConfig.DEBUG -> return\r\n            interstitialAd.isReady -> {\r\n                interstitialAd.showAd(context)\r\n            }\r\n\r\n            Network.isAdsBlocked -> toast(\"Anuncios bloqueados por host\")\r\n            else -> toast(\"Anuncio aún cargando...\")\r\n        }\r\n    }\r\n}\r\n\r\nclass FAdLoaderRewardedLovin(val context: Activity, private val onUpdate: () -> Unit) : FullscreenAdLoader {\r\n    private var rewardedAd: MaxRewardedAd = MaxRewardedAd.getInstance(\"e3b2506478ae074c\")\r\n    private var isLoading = false\r\n\r\n    init {\r\n        isLoading = true\r\n        rewardedAd.setListener(object : MaxRewardedAdListener {\r\n            var isClicked = false\r\n            override fun onAdLoaded(p0: MaxAd) {\r\n                isLoading = false\r\n            }\r\n\r\n            override fun onAdDisplayed(p0: MaxAd) {}\r\n            override fun onAdHidden(p0: MaxAd) {\r\n                isClicked = false\r\n                isLoading = true\r\n                rewardedAd.loadAd()\r\n                onUpdate()\r\n            }\r\n\r\n            override fun onAdClicked(p0: MaxAd) {\r\n                isClicked = true\r\n            }\r\n\r\n            override fun onAdLoadFailed(p0: String, p1: MaxError) {}\r\n            override fun onAdDisplayFailed(p0: MaxAd, p1: MaxError) {}\r\n            override fun onUserRewarded(p0: MaxAd, p1: MaxReward) {\r\n                Economy.reward(isClicked)\r\n            }\r\n        })\r\n        rewardedAd.loadAd()\r\n    }\r\n\r\n    override fun load() {\r\n        if (!isLoading && !rewardedAd.isReady) {\r\n            isLoading = true\r\n            rewardedAd.loadAd()\r\n        }\r\n    }\r\n\r\n    override fun show() {\r\n        when {\r\n            !AdsUtils.isRemoteAdsEnabled || !AdsUtils.isRemoteFullEnabled || BuildConfig.DEBUG -> return\r\n            rewardedAd.isReady -> {\r\n                rewardedAd.showAd(context)\r\n            }\r\n\r\n            Network.isAdsBlocked -> toast(\"Anuncios bloqueados por host\")\r\n            else -> toast(\"Anuncio aún cargando...\")\r\n        }\r\n    }\r\n}\r\n\r\nclass FAdLoaderInterstitialLazyLovin(val context: AppCompatActivity) : FullscreenAdLoader {\r\n    private var interstitialAd: MaxInterstitialAd = MaxInterstitialAd(\"e5f776a3ccb9282e\")\r\n    private var isLoading = false\r\n\r\n    init {\r\n        isLoading = true\r\n        interstitialAd.setListener(object : MaxAdListener {\r\n            var isClicked = false\r\n            override fun onAdLoaded(p0: MaxAd) {\r\n                isLoading = false\r\n            }\r\n\r\n            override fun onAdLoadFailed(p0: String, p1: MaxError) {\r\n                GlobalScope.launch {\r\n                    delay(2000)\r\n                    interstitialAd.loadAd()\r\n                }\r\n            }\r\n\r\n            override fun onAdHidden(p0: MaxAd) {\r\n                isLoading = true\r\n                interstitialAd.loadAd()\r\n                Economy.reward(isClicked)\r\n                isClicked = false\r\n            }\r\n\r\n            override fun onAdDisplayed(p0: MaxAd) {}\r\n            override fun onAdClicked(p0: MaxAd) {\r\n                isClicked = true\r\n            }\r\n\r\n            override fun onAdDisplayFailed(p0: MaxAd, p1: MaxError) {}\r\n        })\r\n        interstitialAd.loadAd()\r\n    }\r\n\r\n    override fun load() {\r\n        if (!isLoading && !interstitialAd.isReady) {\r\n            isLoading = true\r\n            interstitialAd.loadAd()\r\n        }\r\n    }\r\n\r\n    override fun show() {\r\n        when {\r\n            !AdsUtils.isRemoteAdsEnabled || !AdsUtils.isRemoteFullEnabled || BuildConfig.DEBUG -> return\r\n            interstitialAd.isReady -> {\r\n                interstitialAd.showAd(context)\r\n            }\r\n\r\n            Network.isAdsBlocked -> toast(\"Anuncios bloqueados por host\")\r\n            else -> context.lifecycleScope.launch(Dispatchers.Main) {\r\n                var tryCount = 11\r\n                while (!interstitialAd.isReady && tryCount > 0) {\r\n                    delay(250)\r\n                    tryCount--\r\n                }\r\n                if (interstitialAd.isReady)\r\n                    show()\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/AdsUtilsMob.kt",
    "content": "package knf.kuma.ads\r\n\r\n/*import com.google.android.gms.ads.AdListener\r\nimport com.google.android.gms.ads.AdRequest\r\nimport com.google.android.gms.ads.AdSize\r\nimport com.google.android.gms.ads.AdView\r\nimport com.google.android.gms.ads.FullScreenContentCallback\r\nimport com.google.android.gms.ads.LoadAdError\r\nimport com.google.android.gms.ads.MobileAds\r\nimport com.google.android.gms.ads.RequestConfiguration\r\nimport com.google.android.gms.ads.interstitial.InterstitialAd\r\nimport com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback\r\nimport com.google.android.gms.ads.rewarded.RewardedAd\r\nimport com.google.android.gms.ads.rewarded.RewardedAdLoadCallback*/\r\nimport android.app.Activity\r\nimport android.view.ViewGroup\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport knf.kuma.BuildConfig\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.news.AdNewsObject\r\nimport knf.kuma.news.NewsObject\r\nimport knf.kuma.pojos.Achievement\r\nimport knf.kuma.pojos.AchievementAd\r\nimport knf.kuma.pojos.FavoriteObject\r\nimport knf.kuma.pojos.RecentObject\r\nimport org.jetbrains.anko.collections.forEachReversedWithIndex\r\n\r\nobject AdsUtilsMob {\r\n    val RECENT_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.RECENT_BANNER\r\n    val RECENT_BANNER2 get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.RECENT_BANNER2\r\n    val FAVORITE_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.FAVORITE_BANNER\r\n    val FAVORITE_BANNER2 get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.FAVORITE_BANNER2\r\n    val DIRECTORY_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.DIRECTORY_BANNER\r\n    val HOME_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.HOME_BANNER\r\n    val HOME_BANNER2 get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.HOME_BANNER2\r\n    val EMISSION_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.EMISSION_BANNER\r\n    val SEEING_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.SEEING_BANNER\r\n    val RECOMMEND_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.RECOMMEND_BANNER\r\n    val QUEUE_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.QUEUE_BANNER\r\n    val RECORD_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.RECORD_BANNER\r\n    val RANDOM_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.RANDOM_BANNER\r\n    val NEWS_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.NEWS_BANNER\r\n    val INFO_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.INFO_BANNER\r\n    val ACHIEVEMENT_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.ACHIEVEMENT_BANNER\r\n    val EXPLORER_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.EXPLORER_BANNER\r\n    val CAST_BANNER get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/6300978111\" else AdmobID.CAST_BANNER\r\n    val LIST_NATIVE get() = if (BuildConfig.DEBUG) \"ca-app-pub-5390653757953587/5447863415\" else AdmobID.LIST_NATIVE\r\n    val REWARDED get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/5224354917\" else AdmobID.REWARDED\r\n    val INTERSTITIAL get() = if (BuildConfig.DEBUG) \"ca-app-pub-3940256099942544/1033173712\" else AdmobID.INTERSTITIAL\r\n\r\n    //val adRequest: AdRequest get() = AdRequest.Builder().build()\r\n    val ACHIEVEMENT_NATIVE = \"achievement_native\"\r\n\r\n    fun setUp(context: Activity, callback: () -> Unit) {\r\n        /*MobileAds.initialize(context) {\r\n            NativeManager\r\n            callback()\r\n        }\r\n        if (!BuildConfig.DEBUG) return\r\n        val builder = RequestConfiguration.Builder().setTestDeviceIds(listOf(\"FE18DCEC5EE5755C3927E4EC30CD4F9D\"))\r\n        MobileAds.setRequestConfiguration(builder.build())*/\r\n    }\r\n}\r\n\r\nfun MutableList<RecentObject>.implAdsRecentMob() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    forEachReversedWithIndex { index, _ ->\r\n        if (index % 5 == 0 && index > 0) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsMob.RECENT_BANNER\r\n                }\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsMob.RECENT_BANNER\r\n                }\r\n            }\r\n            add(index, AdRecentObject(adID))\r\n        }\r\n    }\r\n    add(0, AdRecentObject(AdsUtilsMob.RECENT_BANNER))\r\n}\r\n\r\nfun MutableList<FavoriteObject>.implAdsFavoriteMob() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    forEachReversedWithIndex { index, _ ->\r\n        if (index % 8 == 0 && index > 0 && !this[index - 1].isSection) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsMob.FAVORITE_BANNER\r\n                }\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsMob.FAVORITE_BANNER\r\n                }\r\n            }\r\n            this@implAdsFavoriteMob.add(index, AdFavoriteObject(adID))\r\n        }\r\n    }\r\n    this@implAdsFavoriteMob.add(0, AdFavoriteObject(AdsUtilsMob.FAVORITE_BANNER))\r\n}\r\n\r\nfun MutableList<NewsObject>.implAdsNewsMob() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    forEachReversedWithIndex { index, _ ->\r\n        if (index % 5 == 0 && index > 0) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsMob.NEWS_BANNER\r\n                }\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsMob.NEWS_BANNER\r\n                }\r\n            }\r\n            add(index, AdNewsObject(adID))\r\n        }\r\n    }\r\n    add(0, AdNewsObject(AdsUtilsMob.NEWS_BANNER))\r\n}\r\n\r\nfun MutableList<Achievement>.implAdsAchievementMob() {\r\n    if (!PrefsUtil.isAdsEnabled || isEmpty()) return\r\n    var adIndex = 0\r\n    forEachReversedWithIndex { index, _ ->\r\n        if (index % 8 == 0 && index > 0) {\r\n            val adID: String = when (adIndex) {\r\n                0 -> {\r\n                    adIndex = 1\r\n                    AdsUtilsMob.ACHIEVEMENT_BANNER\r\n                }\r\n                else -> {\r\n                    adIndex = 0\r\n                    AdsUtilsMob.ACHIEVEMENT_BANNER\r\n                }\r\n            }\r\n            add(index, AchievementAd(adID))\r\n        }\r\n    }\r\n    add(0, AchievementAd(AdsUtilsMob.ACHIEVEMENT_BANNER))\r\n}\r\n\r\nfun ViewGroup.implBannerCastMob() {\r\n    this.implBannerMob(AdsUtilsMob.CAST_BANNER)\r\n}\r\n\r\nfun ViewGroup.implBannerMob(unitID: AdsType, isSmart: Boolean = false) {\r\n    val id = when (unitID) {\r\n        AdsType.RECENT_BANNER -> AdsUtilsMob.RECENT_BANNER\r\n        AdsType.RECENT_BANNER2 -> AdsUtilsMob.RECENT_BANNER2\r\n        AdsType.FAVORITE_BANNER -> AdsUtilsMob.FAVORITE_BANNER\r\n        AdsType.FAVORITE_BANNER2 -> AdsUtilsMob.FAVORITE_BANNER2\r\n        AdsType.DIRECTORY_BANNER -> AdsUtilsMob.DIRECTORY_BANNER\r\n        AdsType.HOME_BANNER -> AdsUtilsMob.HOME_BANNER\r\n        AdsType.HOME_BANNER2 -> AdsUtilsMob.HOME_BANNER2\r\n        AdsType.EMISSION_BANNER -> AdsUtilsMob.EMISSION_BANNER\r\n        AdsType.SEEING_BANNER -> AdsUtilsMob.SEEING_BANNER\r\n        AdsType.RECOMMEND_BANNER -> AdsUtilsMob.RECOMMEND_BANNER\r\n        AdsType.QUEUE_BANNER -> AdsUtilsMob.QUEUE_BANNER\r\n        AdsType.RECORD_BANNER -> AdsUtilsMob.RECORD_BANNER\r\n        AdsType.RANDOM_BANNER -> AdsUtilsMob.RANDOM_BANNER\r\n        AdsType.NEWS_BANNER -> AdsUtilsMob.NEWS_BANNER\r\n        AdsType.INFO_BANNER -> AdsUtilsMob.INFO_BANNER\r\n        AdsType.ACHIEVEMENT_BANNER -> AdsUtilsMob.ACHIEVEMENT_BANNER\r\n        AdsType.EXPLORER_BANNER -> AdsUtilsMob.EXPLORER_BANNER\r\n        AdsType.CAST_BANNER -> AdsUtilsMob.CAST_BANNER\r\n        AdsType.REWARDED -> AdsUtilsMob.REWARDED\r\n        AdsType.INTERSTITIAL -> AdsUtilsMob.INTERSTITIAL\r\n    }\r\n    implBannerMob(id, isSmart)\r\n}\r\n\r\nfun ViewGroup.implBannerMob(unitID: String, isSmart: Boolean = false) {\r\n    /*if (PrefsUtil.isAdsEnabled) {\r\n        GlobalScope.launch g@{\r\n            if (this@implBannerMob.tag == \"AdView added\")\r\n                return@g\r\n            if (this@implBannerMob !is BannerContainerView) {\r\n                NativeManager.take(GlobalScope, 1) {\r\n                    if (it.isEmpty())\r\n                        GlobalScope.launch {\r\n                            val adView = AdView(context)\r\n                            adView.setAdSize(getAdSize(width.toFloat()))\r\n                            adView.adUnitId = unitID\r\n                            adView.adListener = object : AbsAdListener() {\r\n                                override fun onAdClicked() {\r\n                                    FirebaseAnalytics.getInstance(App.context).logEvent(\"Ad_clicked\", Bundle())\r\n                                }\r\n                            }\r\n                            launch(Dispatchers.Main) {\r\n                                addView(adView)\r\n                                this@implBannerMob.tag = \"AdView added\"\r\n                                adView.loadAd(AdsUtilsMob.adRequest)\r\n                            }\r\n                        }\r\n                    else\r\n                        GlobalScope.launch {\r\n                            val adView = when (unitID) {\r\n                                AdsUtilsMob.RECENT_BANNER, AdsUtilsMob.FAVORITE_BANNER -> {\r\n                                    asyncInflate(context, R.layout.admob_ad_card).apply {\r\n                                        Log.e(\"Ad\", \"On recent\")\r\n                                        find<AdTemplateView>(R.id.admobAd).setNativeAd(it[0])\r\n                                    }\r\n                                }\r\n                                AdsUtilsMob.NEWS_BANNER -> {\r\n                                    asyncInflate(context, R.layout.admob_ad_news).apply {\r\n                                        Log.e(\"Ad\", \"On news\")\r\n                                        find<AdTemplateView>(R.id.admobAd).setNativeAd(it[0])\r\n                                    }\r\n                                }\r\n                                AdsUtilsMob.ACHIEVEMENT_BANNER, AdsUtilsMob.ACHIEVEMENT_NATIVE -> {\r\n                                    asyncInflate(context, R.layout.admob_ad_plain).apply {\r\n                                        Log.e(\"Ad\", \"On Achievement\")\r\n                                        find<AdTemplateView>(R.id.admobAd).setNativeAd(it[0])\r\n                                    }\r\n                                }\r\n                                AdsUtilsMob.CAST_BANNER -> {\r\n                                    asyncInflate(context, R.layout.admob_ad_alone).apply {\r\n                                        Log.e(\"Ad\", \"On Cast\")\r\n                                        find<AdTemplateView>(R.id.admobAd).setNativeAd(it[0])\r\n                                    }\r\n                                }\r\n                                else -> return@launch\r\n                            }\r\n                            launch(Dispatchers.Main) {\r\n                                addView(adView)\r\n                                this@implBannerMob.tag = \"AdView added\"\r\n                            }\r\n                        }\r\n                }\r\n            } else {\r\n                val adView = AdView(context)\r\n                adView.setAdSize(getAdSize(width.toFloat()))\r\n                adView.adUnitId = unitID\r\n                adView.adListener = object : AbsAdListener() {\r\n                    override fun onAdClicked() {\r\n                        FirebaseAnalytics.getInstance(App.context).logEvent(\"Ad_clicked\", Bundle())\r\n                    }\r\n                }\r\n                launch(Dispatchers.Main) {\r\n                    show(adView)\r\n                    adView.loadAd(AdsUtilsMob.adRequest)\r\n                    this@implBannerMob.tag = \"AdView added\"\r\n                }\r\n            }\r\n        }\r\n    }*/\r\n}\r\n\r\nfun getFAdLoaderRewardedMob(context: Activity, onUpdate: () -> Unit): FullscreenAdLoader = FAdLoaderRewardedMob(context, onUpdate)\r\nfun getFAdLoaderInterstitialMob(context: Activity, onUpdate: () -> Unit): FullscreenAdLoader = FAdLoaderInterstitialMob(context, onUpdate)\r\n\r\nclass FAdLoaderRewardedMob(val context: Activity, private val onUpdate: () -> Unit) : FullscreenAdLoader {\r\n\r\n    /*private var rewardedAd: RewardedAd? = null\r\n\r\n    private fun createAndLoadRewardAd() {\r\n        rewardedAd = null\r\n        RewardedAd.load(context, AdsUtilsMob.REWARDED, AdsUtilsMob.adRequest, object : RewardedAdLoadCallback() {\r\n            override fun onAdLoaded(p0: RewardedAd) {\r\n                rewardedAd = p0\r\n            }\r\n\r\n            override fun onAdFailedToLoad(p0: LoadAdError) {\r\n                Log.e(\"Ad\", \"Ad failed to load, code: ${p0.code}\")\r\n                GlobalScope.launch(Dispatchers.Main) {\r\n                    delay(2000)\r\n                    if (!context.isFinishing) {\r\n                        createAndLoadRewardAd()\r\n                    }\r\n                }\r\n            }\r\n        })\r\n    }*/\r\n\r\n    private fun showRewarded() {\r\n        /*rewardedAd?.fullScreenContentCallback = object : FullScreenContentCallback() {\r\n            override fun onAdDismissedFullScreenContent() {\r\n                createAndLoadRewardAd()\r\n            }\r\n        }\r\n        rewardedAd?.show(context) {\r\n            FirebaseAnalytics.getInstance(App.context).logEvent(\"Rewarded_Ad_watched\", Bundle())\r\n            Economy.reward(baseReward = 2)\r\n            onUpdate()\r\n        }*/\r\n    }\r\n\r\n    override fun load() {\r\n        //if (rewardedAd == null) createAndLoadRewardAd()\r\n    }\r\n\r\n    override fun show() {\r\n        /*when {\r\n            !AdsUtils.isRemoteAdsEnabled || !AdsUtils.isRemoteFullEnabled -> return\r\n            rewardedAd != null -> showRewarded()\r\n            Network.isAdsBlocked -> toast(\"Anuncios bloqueados por host\")\r\n            else -> toast(\"Anuncio aún cargando...\")\r\n        }*/\r\n    }\r\n}\r\n\r\nclass FAdLoaderInterstitialMob(val context: Activity, private val onUpdate: () -> Unit) : FullscreenAdLoader {\r\n    /*private var interstitialAd: InterstitialAd? = null\r\n\r\n    private fun createAndLoad() {\r\n        interstitialAd = null\r\n        InterstitialAd.load(context, AdsUtilsMob.INTERSTITIAL, AdsUtilsMob.adRequest, object : InterstitialAdLoadCallback() {\r\n            override fun onAdLoaded(p0: InterstitialAd) {\r\n                interstitialAd = p0\r\n            }\r\n\r\n            override fun onAdFailedToLoad(p0: LoadAdError) {\r\n                Log.e(\"Ad\", \"Ad failed to load, code: ${p0.code}\")\r\n                GlobalScope.launch(Dispatchers.Main) {\r\n                    delay(2000)\r\n                    if (!context.isFinishing) {\r\n                        createAndLoad()\r\n                    }\r\n                }\r\n            }\r\n        })\r\n    }*/\r\n\r\n    override fun load() {\r\n        //if (interstitialAd == null) createAndLoad()\r\n    }\r\n\r\n    override fun show() {\r\n        /* when {\r\n             !AdsUtils.isRemoteAdsEnabled || !AdsUtils.isRemoteFullEnabled -> return\r\n             interstitialAd != null -> {\r\n                 interstitialAd?.fullScreenContentCallback = object : FullScreenContentCallback() {\r\n                     override fun onAdDismissedFullScreenContent() {\r\n                         FirebaseAnalytics.getInstance(App.context).logEvent(\"Interstitial_Ad_watched\", Bundle())\r\n                         createAndLoad()\r\n                         Economy.reward(false)\r\n                         onUpdate()\r\n                     }\r\n                 }\r\n                 interstitialAd?.show(context)\r\n             }\r\n             Network.isAdsBlocked -> toast(\"Anuncios bloqueados por host\")\r\n             else -> toast(\"Anuncio aún cargando...\")\r\n         }*/\r\n    }\r\n}\r\n\r\nclass FAdLoaderInterstitialLazyMob(val context: AppCompatActivity) : FullscreenAdLoader {\r\n    //private var interstitialAd: InterstitialAd? = null\r\n\r\n    init {\r\n        //createAndLoad()\r\n    }\r\n\r\n    /*private fun createAndLoad() {\r\n        interstitialAd = null\r\n        InterstitialAd.load(context, AdsUtilsMob.INTERSTITIAL, AdsUtilsMob.adRequest, object : InterstitialAdLoadCallback() {\r\n            override fun onAdLoaded(p0: InterstitialAd) {\r\n                interstitialAd = p0\r\n            }\r\n\r\n            override fun onAdFailedToLoad(p0: LoadAdError) {\r\n                Log.e(\"Ad\", \"Ad failed to load, code: ${p0.code}\")\r\n                GlobalScope.launch(Dispatchers.Main) {\r\n                    delay(3000)\r\n                    if (!context.isFinishing) {\r\n                        createAndLoad()\r\n                    }\r\n                }\r\n            }\r\n        })\r\n    }*/\r\n\r\n    override fun load() {\r\n        //if (interstitialAd == null) createAndLoad()\r\n    }\r\n\r\n    override fun show() {\r\n        /*when {\r\n            interstitialAd != null -> {\r\n                interstitialAd?.fullScreenContentCallback = object : FullScreenContentCallback() {\r\n                    override fun onAdDismissedFullScreenContent() {\r\n                        FirebaseAnalytics.getInstance(App.context).logEvent(\"Interstitial_Ad_watched\", Bundle())\r\n                        createAndLoad()\r\n                        Economy.reward(false)\r\n                    }\r\n                }\r\n                interstitialAd?.show(context)\r\n            }\r\n            Network.isAdsBlocked -> toast(\"Anuncios bloqueados por host\")\r\n            else -> context.lifecycleScope.launch(Dispatchers.Main) {\r\n                var tryCount = 11\r\n                while (interstitialAd == null && tryCount > 0) {\r\n                    delay(250)\r\n                    tryCount--\r\n                }\r\n                if (interstitialAd != null)\r\n                    show()\r\n            }\r\n        }*/\r\n    }\r\n}\r\n\r\n/*fun getAdSize(width: Float): AdSize {\r\n    val metrics = App.context.resources.displayMetrics\r\n    val density = metrics.density\r\n    var adWidthPixels = width\r\n    if (adWidthPixels == 0f) {\r\n        adWidthPixels = metrics.widthPixels.toFloat()\r\n    }\r\n\r\n    val adWidth = (adWidthPixels / density).toInt()\r\n    return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(App.context, adWidth)\r\n\r\n}*/\r\n\r\n//abstract class AbsAdListener : AdListener()\r\n\r\nobject AdmobID {\r\n    const val RECENT_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val RECENT_BANNER2 = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val FAVORITE_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val FAVORITE_BANNER2 = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val DIRECTORY_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val HOME_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val HOME_BANNER2 = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val EMISSION_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val SEEING_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val RECOMMEND_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val QUEUE_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val RECORD_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val RANDOM_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val NEWS_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val INFO_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val ACHIEVEMENT_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val EXPLORER_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val CAST_BANNER = \"ca-app-pub-8896186846999141/5663284088\"\r\n    const val LIST_NATIVE = \"ca-app-pub-8896186846999141/5113437989\"\r\n    const val REWARDED = \"ca-app-pub-8896186846999141/9219385713\"\r\n    const val INTERSTITIAL = \"ca-app-pub-8896186846999141/7231764047\"\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/NativeManager.kt",
    "content": "package knf.kuma.ads\r\n\r\n/*import com.google.android.gms.ads.AdListener\r\nimport com.google.android.gms.ads.AdLoader\r\nimport com.google.android.gms.ads.LoadAdError\r\nimport com.google.android.gms.ads.nativead.NativeAd*/\r\n\r\n/*object NativeManager {\r\n    private var isLoading = false\r\n    private var internalSize = 0\r\n    private val adsChannel = Channel<NativeAd>(Int.MAX_VALUE)\r\n\r\n    init {\r\n        cacheAds()\r\n    }\r\n\r\n    suspend fun take(scope: CoroutineScope, size: Int, tryCount: Int = 0, callback: TakeCallback<NativeAd>) {\r\n        val operation = suspend {\r\n            scope.launch {\r\n                if (internalSize >= size) {\r\n                    launch(Dispatchers.Main) {\r\n                        callback(suspendCoroutine {\r\n                            launch {\r\n                                val pendingList = mutableListOf<NativeAd>()\r\n                                repeat(size) {\r\n                                    internalSize--\r\n                                    pendingList.add(adsChannel.receive())\r\n                                }\r\n                                it.resume(pendingList)\r\n                            }\r\n                        })\r\n                    }\r\n                    if (internalSize <= 5)\r\n                        cacheAds()\r\n                }else {\r\n                    take(scope, size, tryCount + 1, callback)\r\n                }\r\n            }\r\n            Unit\r\n        }\r\n        when {\r\n            withContext(Dispatchers.IO) {Network.isAdsBlocked } -> callback(emptyList())\r\n            internalSize >= size -> operation()\r\n            isLoading -> {\r\n                withContext(Dispatchers.IO) {\r\n                    while (isLoading)\r\n                        delay(500)\r\n                    if (tryCount > 3)\r\n                        callback(emptyList())\r\n                    else\r\n                        take(scope, size, tryCount + 1, callback)\r\n                }\r\n            }\r\n            else -> {\r\n                cacheAds(scope, size, operation)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun cacheAds(scope: CoroutineScope = GlobalScope, pendingSize: Int = 5, pending: PendingCallback = {}) {\r\n        if (isLoading) return\r\n        GlobalScope.launch(Dispatchers.Main) {\r\n            isLoading = true\r\n            var loader: AdLoader? = null\r\n            var isCallbackCalled = false\r\n            loader = AdLoader.Builder(App.context, AdsUtilsMob.LIST_NATIVE)\r\n                    .forNativeAd {\r\n                        GlobalScope.launch {\r\n                            internalSize++\r\n                            adsChannel.send(it)\r\n                            if (internalSize >= pendingSize) {\r\n                                isCallbackCalled = true\r\n                                scope.launch { pending() }\r\n                            }\r\n                            if (loader?.isLoading == false) {\r\n                                isLoading = false\r\n                                if (!isCallbackCalled)\r\n                                    scope.launch { pending() }\r\n                            }\r\n                        }\r\n                    }\r\n                    .withAdListener(object : AdListener() {\r\n                        override fun onAdFailedToLoad(p0: LoadAdError) {\r\n                            super.onAdFailedToLoad(p0)\r\n                            if (loader?.isLoading == false) {\r\n                                isLoading = false\r\n                                launch {\r\n                                    if (!isCallbackCalled)\r\n                                        scope.launch { pending() }\r\n                                }\r\n                            }\r\n                        }\r\n                    }).build()\r\n            loader.loadAds(AdsUtilsMob.adRequest, 5)\r\n        }\r\n    }\r\n}*/\r\n\r\ntypealias PendingCallback = suspend () -> Unit\r\ntypealias TakeCallback<T> = (List<T>) -> Unit"
  },
  {
    "path": "app/src/main/java/knf/kuma/ads/SubscriptionReceiver.kt",
    "content": "package knf.kuma.ads\r\n\r\nimport android.content.Intent\r\nimport knf.kuma.App\r\nimport knf.kuma.backup.firestore.FirestoreManager\r\nimport knf.kuma.commons.Network\r\nimport knf.kuma.commons.PrefsUtil\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport org.json.JSONObject\r\nimport java.net.URL\r\n\r\nobject SubscriptionReceiver {\r\n\r\n    data class VerifyStatus(val isVerified: Boolean = false, val isActive: Boolean = false)\r\n\r\n    data class SubscriptionInfo(\r\n            val token: String = \"\",\r\n            val purchaseTime: Long = 0L\r\n    )\r\n\r\n    fun check(intent: Intent) {\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            if (intent.hasExtra(\"token\"))\r\n                check(intent.getStringExtra(\"token\"))\r\n            else\r\n                check(PrefsUtil.subscriptionToken)\r\n        }\r\n    }\r\n\r\n    private suspend fun check(token: String?) {\r\n        if (token == null || !Network.isConnected) return\r\n        val status = checkStatus(token)\r\n        if (status.isVerified) {\r\n            PrefsUtil.subscriptionToken = token\r\n        } else {\r\n            PrefsUtil.subscriptionToken = null\r\n            if (!PrefsUtil.isAdsEnabled)\r\n                FirestoreManager.doSignOut(App.context)\r\n        }\r\n    }\r\n\r\n    suspend fun checkStatus(token: String): VerifyStatus = withContext(Dispatchers.IO) {\r\n        try {\r\n            val json = JSONObject(URL(\"https://us-central1-nu-client.cloudfunctions.net/checkSub?token=${token}\").readText())\r\n            VerifyStatus(json.getBoolean(\"isVerified\"), json.getBoolean(\"isActive\"))\r\n        } catch (e: Exception) {\r\n            e.printStackTrace()\r\n            VerifyStatus(isVerified = true, isActive = true)\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/ActivityAnime.kt",
    "content": "package knf.kuma.animeinfo\n\nimport androidx.activity.addCallback\nimport android.app.Activity\nimport android.content.ActivityNotFoundException\nimport android.content.Context\nimport android.content.Intent\nimport android.net.Uri\nimport android.os.Bundle\nimport android.view.InflateException\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.ImageView\nimport androidx.activity.viewModels\nimport androidx.core.app.ActivityOptionsCompat\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.animeinfo.img.ActivityImgFull\nimport knf.kuma.animeinfo.viewholders.AnimeActivityHolder\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.DesignUtils\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.noCrash\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport knf.kuma.directory.DirObject\nimport knf.kuma.directory.DirObjectCompact\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.ExplorerObject\nimport knf.kuma.pojos.FavoriteObject\nimport knf.kuma.pojos.NotificationObj\nimport knf.kuma.pojos.QueueObject\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeeingObject\nimport knf.kuma.recommended.AnimeShortObject\nimport knf.kuma.recommended.RankType\nimport knf.kuma.recommended.RecommendHelper\nimport knf.kuma.search.SearchObject\nimport knf.kuma.search.SearchObjectFav\nimport knf.kuma.widgets.emision.WEListItem\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.sdk27.coroutines.onLongClick\nimport org.jetbrains.anko.toast\nimport xdroid.toaster.Toaster\nimport java.util.Locale\nimport kotlin.random.Random\n\nclass ActivityAnime : GenericActivity(), AnimeActivityHolder.Interface {\n    private var isEdited = false\n    private val viewModel: AnimeViewModel by viewModels()\n    private val holder: AnimeActivityHolder by lazy { AnimeActivityHolder(this) }\n    private var favoriteObject: FavoriteObject? = null\n    private val dao = CacheDB.INSTANCE.favsDAO()\n    private var chapters: MutableList<AnimeObject.WebInfo.AnimeChapter> = ArrayList()\n    private var genres: MutableList<String> = ArrayList()\n    private val aidOnly get() = intent?.getBooleanExtra(keyAidOnly, false) ?: false\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getThemeNA())\n        super.onCreate(savedInstanceState)\n        try {\n            setContentView(R.layout.activity_anime_info)\n        } catch (e: InflateException) {\n            setContentView(R.layout.activity_anime_info_nwv)\n        }\n        setSupportActionBar(holder.toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        holder.toolbar.setNavigationOnClickListener { closeActivity() }\n        if (aidOnly)\n            viewModel.init(intent.getStringExtra(keyAid))\n        else\n            viewModel.init(this@ActivityAnime, intent.dataString, intent.getBooleanExtra(keyPersist, true))\n        if (intent.getBooleanExtra(keyNotification, false))\n            sendBroadcast(NotificationObj.fromIntent(intent).getBroadcast(this@ActivityAnime))\n        onBackPressedDispatcher.addCallback(this) { closeActivity() }\n        load()\n        checkBypass()\n        showRandomInterstitial(this)\n    }\n\n    private fun load() {\n        viewModel.liveData.observe(this, Observer { animeObject ->\n            if (animeObject != null) {\n                doOnUI {\n                    chapters = animeObject.chapters ?: mutableListOf()\n                    genres = animeObject.genres ?: mutableListOf()\n                    if (PrefsUtil.isFamilyFriendly && genres.map { it.lowercase(Locale.getDefault()) }.contains(\"ecchi\")) {\n                        toast(\"Anime no familiar\")\n                        onBackPressedDispatcher.onBackPressed()\n                    }\n                    favoriteObject = FavoriteObject(animeObject)\n                    favoriteObject?.let { fav ->\n                        holder.imageView.onLongClick(returnValue = true) {\n                            doAsync {\n                                val isFav = dao.isFav(fav.key)\n                                if (isFav) {\n                                    holder.setFABState(false)\n                                    dao.deleteFav(fav)\n                                    RecommendHelper.registerAll(genres, RankType.UNFAV)\n                                    doOnUI { toast(\"Removido de favoritos\") }\n                                } else {\n                                    holder.setFABState(true)\n                                    dao.addFav(fav)\n                                    RecommendHelper.registerAll(genres, RankType.FAV)\n                                    AchievementManager.onFavAdded(fav)\n                                    doOnUI { toast(\"Añadido a favoritos\") }\n                                }\n                                syncData { favs() }\n                            }\n                        }\n                        dao.isFavLive(fav.key).observe(this, Observer { holder.setFABState(it) })\n                    }\n                    holder.setTitle(animeObject.name)\n                    holder.loadImg(PatternUtil.getCover(animeObject.aid), View.OnClickListener {\n                        startActivity(\n                                Intent(this@ActivityAnime, ActivityImgFull::class.java)\n                                        .setData(Uri.parse(PatternUtil.getCover(animeObject.aid)))\n                                        .putExtra(keyTitle, animeObject.name), ActivityOptionsCompat.makeSceneTransitionAnimation(this@ActivityAnime, holder.imageView, \"img\")\n                                .toBundle()\n                        )\n                    })\n                    lifecycleScope.launch(Dispatchers.Main){\n                        holder.setFABState(withContext(Dispatchers.IO) { dao.isFav(favoriteObject?.key ?: 0) })\n                        holder.showFAB()\n                    }\n                    invalidateOptionsMenu()\n                    RecommendHelper.registerAll(genres, RankType.CHECK)\n                }\n            } else {\n                Toaster.toast(\"Error al cargar información del anime\")\n                onBackPressedDispatcher.onBackPressed()\n            }\n        })\n    }\n\n    private fun setResult() {\n        isEdited = true\n    }\n\n    override fun onFabClicked(actionButton: FloatingActionButton) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            setResult()\n            favoriteObject?.let {\n                val isFav = withContext(Dispatchers.IO) { dao.isFav(it.key) }\n                if (isFav) {\n                    holder.setFABState(false)\n                    withContext(Dispatchers.IO) { dao.deleteFav(it) }\n                    RecommendHelper.registerAll(genres, RankType.UNFAV)\n                } else {\n                    holder.setFABState(true)\n                    withContext(Dispatchers.IO) { dao.addFav(it) }\n                    RecommendHelper.registerAll(genres, RankType.FAV)\n                    AchievementManager.onFavAdded(it)\n                }\n                syncData { favs() }\n            }\n        }\n    }\n\n    override fun onImgClicked(imageView: ImageView) {\n\n    }\n\n    override fun onBypassUpdated() {\n        try {\n            if (!aidOnly)\n                viewModel.reload(this, intent.dataString, intent.getBooleanExtra(keyPersist, true))\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }\n\n    override fun getSnackbarAnchor(): View? {\n        return findViewById(R.id.coordinator)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        if (favoriteObject != null) {\n            menuInflater.inflate(R.menu.menu_anime_info, menu)\n            CastUtil.registerActivity(this, menu, R.id.castMenu)\n        }\n        return true\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_share -> share()\n        }\n        return true\n    }\n\n    private fun share() {\n        try {\n            startActivity(Intent.createChooser(Intent(Intent.ACTION_SEND)\n                    .setType(\"text/plain\")\n                    .putExtra(Intent.EXTRA_TEXT, favoriteObject?.name + \"\\n\" + favoriteObject?.link), \"Compartir\"))\n            AchievementManager.onShare()\n        } catch (e: ActivityNotFoundException) {\n            Toaster.toast(\"No se encontraron aplicaciones para enviar\")\n        }\n\n    }\n\n    private fun closeActivity() {\n        holder.hideFABForce()\n        if (intent.getBooleanExtra(keyFromFav, false) && isEdited) {\n            finish()\n        } else if (intent.getBooleanExtra(keyNoTransition, false)) {\n            finish()\n        } else {\n            supportFinishAfterTransition()\n        }\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        noCrash {\n            if (requestCode == FileAccessHelper.SD_REQUEST && resultCode == RESULT_OK) {\n                val validation = FileAccessHelper.isUriValid(data?.data)\n                if (!validation.isValid) {\n                    Toaster.toast(\"Directorio invalido: $validation\")\n                    FileAccessHelper.openTreeChooser(this)\n                }\n            }\n        }\n    }\n\n    companion object {\n        private var REQUEST_CODE = 558\n        private const val keyTitle = \"title\"\n        private const val keyAid = \"aid\"\n        private const val keyImg = \"img\"\n        private const val keyPosition = \"persist\"\n        private const val keyPersist = \"persist\"\n        private const val keyNoTransition = \"noTransition\"\n        private const val keyIsRecord = \"isRecord\"\n        private const val keyFromFav = \"from_fav\"\n        private const val keyAidOnly = \"aid_only\"\n        private const val keyNotification = \"notification\"\n        private const val sharedImg = \"img\"\n\n        fun open(fragment: Fragment, animeObject: SearchObject, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeObject: SearchObjectFav, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, recentObject: RecentObject, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(recentObject.url)\n            intent.putExtra(keyTitle, recentObject.name)\n            intent.putExtra(keyAid, recentObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(recentObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeObject: DirObjectCompact, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeObject: DirObject, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            try {\n                val intent = Intent(fragment.context, DesignUtils.infoClass)\n                intent.data = Uri.parse(animeObject.link)\n                intent.putExtra(keyTitle, animeObject.name)\n                intent.putExtra(keyAid, animeObject.aid)\n                intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n                intent.putExtra(keyPersist, persist)\n                intent.putExtra(keyNoTransition, !animate)\n                fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n\n        fun open(activity: Activity, animeObject: SearchObject, view: ImageView, persist: Boolean, animate: Boolean) {\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            activity.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(activity: Activity?, animeObject: AnimeShortObject, view: ImageView, persist: Boolean, animate: Boolean) {\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            activity?.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, explorerObject: ExplorerObject, view: ImageView) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(explorerObject.link)\n            intent.putExtra(keyTitle, explorerObject.name)\n            intent.putExtra(keyAid, explorerObject.key.toString())\n            intent.putExtra(keyImg, PatternUtil.getCover(explorerObject.aid))\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(activity: Activity, recordObject: RecordObject, view: ImageView) {\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.data = Uri.parse(recordObject.animeObject.link)\n            intent.putExtra(keyTitle, recordObject.name)\n            intent.putExtra(keyAid, recordObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(recordObject.animeObject.aid))\n            intent.putExtra(keyPersist, true)\n            intent.putExtra(keyIsRecord, true)\n            activity.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(activity: Activity?, seeingObject: SeeingObject) {\n            activity ?: return\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.data = Uri.parse(seeingObject.link)\n            intent.putExtra(keyTitle, seeingObject.title)\n            //intent.putExtra(keyAid, seeingObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(seeingObject.aid))\n            intent.putExtra(keyPersist, true)\n            intent.putExtra(keyNoTransition, true)\n            intent.putExtra(keyIsRecord, true)\n            activity.startActivity(intent)\n        }\n\n        fun open(context: Context, animeObject: SearchObject) {\n            val intent = Intent(context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            context.startActivity(intent)\n        }\n\n        fun open(fragment: Fragment, favoriteObject: FavoriteObject, view: ImageView) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(favoriteObject.link)\n            intent.putExtra(keyTitle, favoriteObject.name)\n            intent.putExtra(keyAid, favoriteObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(favoriteObject.aid))\n            intent.putExtra(keyFromFav, true)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(activity: Activity, queueObject: QueueObject, view: ImageView) {\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.putExtra(keyTitle, queueObject.chapter.name)\n            intent.putExtra(keyAid, queueObject.chapter.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(queueObject.chapter.aid))\n            intent.putExtra(keyAidOnly, true)\n            activity.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeRelated: AnimeObject.WebInfo.AnimeRelated) {\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(\"https://www3.animeflv.net/\" + animeRelated.link)\n            intent.putExtra(keyTitle, animeRelated.name)\n            intent.putExtra(keyAid, animeRelated.aid)\n            fragment.startActivityForResult(intent, REQUEST_CODE)\n        }\n\n        fun open(fragment: Fragment, animeObject: AnimeObject.WebInfo.AnimeRelated, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(\"https://www3.animeflv.net/\" + animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(context: Context, url: String) {\n            val intent = Intent(context, DesignUtils.infoClass)\n            intent.data = Uri.parse(url)\n            context.startActivity(intent)\n        }\n\n        fun getSimpleIntent(context: Context, item: WEListItem): Intent {\n            val intent = Intent(context, DesignUtils.infoClass)\n            intent.data = Uri.parse(item.link)\n            intent.action = \"${Random.nextInt(1, 9000)}\"\n            intent.putExtra(keyTitle, item.title)\n            intent.putExtra(keyAid, item.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(item.aid))\n            return intent\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/ActivityAnimeMaterial.kt",
    "content": "package knf.kuma.animeinfo\n\nimport androidx.activity.addCallback\nimport android.app.Activity\nimport android.content.ActivityNotFoundException\nimport android.content.Context\nimport android.content.Intent\nimport android.net.Uri\nimport android.os.Bundle\nimport android.view.InflateException\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.ImageView\nimport androidx.activity.viewModels\nimport androidx.core.app.ActivityOptionsCompat\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.animeinfo.img.ActivityImgFull\nimport knf.kuma.animeinfo.viewholders.AnimeActivityMaterialHolder\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.DesignUtils\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.noCrash\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport knf.kuma.directory.DirObject\nimport knf.kuma.directory.DirObjectCompact\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.ExplorerObject\nimport knf.kuma.pojos.FavoriteObject\nimport knf.kuma.pojos.NotificationObj\nimport knf.kuma.pojos.QueueObject\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeeingObject\nimport knf.kuma.recommended.AnimeShortObject\nimport knf.kuma.recommended.RankType\nimport knf.kuma.recommended.RecommendHelper\nimport knf.kuma.search.SearchAdvObject\nimport knf.kuma.search.SearchObject\nimport knf.kuma.search.SearchObjectFav\nimport knf.kuma.widgets.emision.WEListItem\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.sdk27.coroutines.onLongClick\nimport org.jetbrains.anko.toast\nimport xdroid.toaster.Toaster\nimport java.util.Locale\nimport kotlin.random.Random\n\nclass ActivityAnimeMaterial : GenericActivity(), AnimeActivityMaterialHolder.Interface {\n    private var isEdited = false\n    private val viewModel: AnimeViewModel by viewModels()\n    private val holder: AnimeActivityMaterialHolder by lazy { AnimeActivityMaterialHolder(this) }\n    private var favoriteObject: FavoriteObject? = null\n    private val dao = CacheDB.INSTANCE.favsDAO()\n    private var chapters: MutableList<AnimeObject.WebInfo.AnimeChapter> = ArrayList()\n    private var genres: MutableList<String> = ArrayList()\n    private val aidOnly get() = intent?.getBooleanExtra(keyAidOnly, false) ?: false\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getThemeNA())\n        super.onCreate(savedInstanceState)\n        try {\n            setContentView(R.layout.activity_anime_info_material)\n        } catch (e: InflateException) {\n            setContentView(R.layout.activity_anime_info_nwv)\n        }\n        setSupportActionBar(holder.toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        holder.toolbar.setNavigationOnClickListener { closeActivity() }\n        if (aidOnly)\n            viewModel.init(intent.getStringExtra(keyAid))\n        else\n            viewModel.init(this@ActivityAnimeMaterial, intent.dataString, intent.getBooleanExtra(keyPersist, true))\n        if (intent.getBooleanExtra(keyNotification, false))\n            sendBroadcast(NotificationObj.fromIntent(intent).getBroadcast(this@ActivityAnimeMaterial))\n        onBackPressedDispatcher.addCallback(this) { closeActivity() }\n        load()\n        checkBypass()\n        showRandomInterstitial(this)\n    }\n\n    private fun load() {\n        viewModel.liveData.observe(this, Observer { animeObject ->\n            if (animeObject != null) {\n                doOnUI {\n                    chapters = animeObject.chapters ?: mutableListOf()\n                    genres = animeObject.genres ?: mutableListOf()\n                    if (PrefsUtil.isFamilyFriendly && genres.map { it.lowercase(Locale.getDefault()) }.contains(\"ecchi\")) {\n                        toast(\"Anime no familiar\")\n                        onBackPressedDispatcher.onBackPressed()\n                    }\n                    favoriteObject = FavoriteObject(animeObject)\n                    favoriteObject?.let { fav ->\n                        holder.imageView.onLongClick(returnValue = true) {\n                            doAsync {\n                                val isFav = dao.isFav(fav.key)\n                                if (isFav) {\n                                    holder.setFABState(false)\n                                    dao.deleteFav(fav)\n                                    RecommendHelper.registerAll(genres, RankType.UNFAV)\n                                    doOnUI { toast(\"Removido de favoritos\") }\n                                } else {\n                                    holder.setFABState(true)\n                                    dao.addFav(fav)\n                                    RecommendHelper.registerAll(genres, RankType.FAV)\n                                    AchievementManager.onFavAdded(fav)\n                                    doOnUI { toast(\"Añadido a favoritos\") }\n                                }\n                                syncData { favs() }\n                            }\n                        }\n                        dao.isFavLive(fav.key).observe(this, Observer { holder.setFABState(it) })\n                    }\n                    holder.setTitle(animeObject.name)\n                    holder.loadImg(PatternUtil.getCover(animeObject.aid), View.OnClickListener {\n                        startActivity(\n                                Intent(this@ActivityAnimeMaterial, ActivityImgFull::class.java)\n                                        .setData(Uri.parse(PatternUtil.getCover(animeObject.aid)))\n                                        .putExtra(keyTitle, animeObject.name), ActivityOptionsCompat.makeSceneTransitionAnimation(this@ActivityAnimeMaterial, holder.imageView, \"img\")\n                                .toBundle()\n                        )\n                    })\n                    lifecycleScope.launch(Dispatchers.Main) {\n                        holder.setFABState(withContext(Dispatchers.IO) { dao.isFav(favoriteObject?.key ?: 0) })\n                        holder.showFAB()\n                    }\n                    invalidateOptionsMenu()\n                    RecommendHelper.registerAll(genres, RankType.CHECK)\n                }\n            } else {\n                Toaster.toast(\"Error al cargar información del anime\")\n                onBackPressedDispatcher.onBackPressed()\n            }\n        })\n    }\n\n    private fun setResult() {\n        isEdited = true\n    }\n\n    override fun onFabClicked(actionButton: FloatingActionButton) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            setResult()\n            favoriteObject?.let {\n                val isFav = withContext(Dispatchers.IO) { dao.isFav(it.key) }\n                if (isFav) {\n                    holder.setFABState(false)\n                    withContext(Dispatchers.IO) { dao.deleteFav(it) }\n                    RecommendHelper.registerAll(genres, RankType.UNFAV)\n                } else {\n                    holder.setFABState(true)\n                    withContext(Dispatchers.IO) { dao.addFav(it) }\n                    RecommendHelper.registerAll(genres, RankType.FAV)\n                    AchievementManager.onFavAdded(it)\n                }\n                syncData { favs() }\n            }\n        }\n    }\n\n    override fun onImgClicked(imageView: ImageView) {\n\n    }\n\n    override fun onBypassUpdated() {\n        try {\n            if (!aidOnly)\n                viewModel.reload(this, intent.dataString, intent.getBooleanExtra(keyPersist, true))\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }\n\n    override fun getSnackbarAnchor(): View? {\n        return findViewById(R.id.coordinator)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        if (favoriteObject != null) {\n            menuInflater.inflate(R.menu.menu_anime_info, menu)\n            CastUtil.registerActivity(this, menu, R.id.castMenu)\n        }\n        return true\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_share -> share()\n        }\n        return true\n    }\n\n    private fun share() {\n        try {\n            startActivity(Intent.createChooser(Intent(Intent.ACTION_SEND)\n                    .setType(\"text/plain\")\n                    .putExtra(Intent.EXTRA_TEXT, favoriteObject?.name + \"\\n\" + favoriteObject?.link), \"Compartir\"))\n            AchievementManager.onShare()\n        } catch (e: ActivityNotFoundException) {\n            Toaster.toast(\"No se encontraron aplicaciones para enviar\")\n        }\n\n    }\n\n    private fun closeActivity() {\n        holder.hideFABForce()\n        if (intent.getBooleanExtra(keyFromFav, false) && isEdited) {\n            finish()\n        } else if (intent.getBooleanExtra(keyNoTransition, false)) {\n            finish()\n        } else {\n            supportFinishAfterTransition()\n        }\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        noCrash {\n            if (requestCode == FileAccessHelper.SD_REQUEST && resultCode == RESULT_OK) {\n                val validation = FileAccessHelper.isUriValid(data?.data)\n                if (!validation.isValid) {\n                    Toaster.toast(\"Directorio invalido: $validation\")\n                    FileAccessHelper.openTreeChooser(this)\n                }\n            }\n        }\n    }\n\n    companion object {\n        private var REQUEST_CODE = 558\n        private const val keyTitle = \"title\"\n        private const val keyAid = \"aid\"\n        private const val keyImg = \"img\"\n        private const val keyPosition = \"persist\"\n        private const val keyPersist = \"persist\"\n        private const val keyNoTransition = \"noTransition\"\n        private const val keyIsRecord = \"isRecord\"\n        private const val keyFromFav = \"from_fav\"\n        private const val keyAidOnly = \"aid_only\"\n        private const val keyNotification = \"notification\"\n        private const val sharedImg = \"img\"\n\n        fun open(fragment: Fragment, recentObject: RecentObject, view: ImageView, position: Int) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(recentObject.anime)\n            intent.putExtra(keyTitle, recentObject.name)\n            intent.putExtra(keyAid, recentObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(recentObject.aid))\n            intent.putExtra(keyPosition, position)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        @JvmOverloads\n        fun open(fragment: Fragment, animeObject: AnimeObject, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeObject: SearchObject, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeObject: SearchAdvObject, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun openGeneric(fragment: Fragment, animeObject: SearchAdvObject, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeObject: SearchObjectFav, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeObject: AnimeObject.WebInfo.AnimeRelated, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(\"https://www3.animeflv.net/\" + animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, recentObject: RecentObject, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(recentObject.url)\n            intent.putExtra(keyTitle, recentObject.name)\n            intent.putExtra(keyAid, recentObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(recentObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun openGeneric(fragment: Fragment, recentObject: RecentObject, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(recentObject.url)\n            intent.putExtra(keyTitle, recentObject.name)\n            intent.putExtra(keyAid, recentObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(recentObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeObject: DirObjectCompact, view: ImageView, persist: Boolean = true, animate: Boolean = true) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeObject: DirObject, persist: Boolean = false) {\n            fragment.startActivity(Intent(fragment.requireContext(),DesignUtils.infoClass).apply {\n                data = Uri.parse(animeObject.link)\n                putExtra(keyTitle, animeObject.name)\n                putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n                putExtra(keyPersist, persist)\n            })\n        }\n\n        fun open(fragment: Fragment, dirObject: DirObjectCompact, persist: Boolean = false) {\n            fragment.startActivity(Intent(fragment.requireContext(),DesignUtils.infoClass).apply {\n                data = Uri.parse(dirObject.link)\n                putExtra(keyTitle, dirObject.name)\n                putExtra(keyImg, PatternUtil.getCover(dirObject.aid))\n                putExtra(keyPersist, persist)\n            })\n        }\n\n        fun open(activity: Activity, animeObject: AnimeObject, view: ImageView, persist: Boolean, animate: Boolean) {\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            activity.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(activity: Activity, animeObject: SearchObject, view: ImageView, persist: Boolean, animate: Boolean) {\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            activity.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(activity: Activity?, animeObject: AnimeShortObject, view: ImageView, persist: Boolean, animate: Boolean) {\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            intent.putExtra(keyPersist, persist)\n            intent.putExtra(keyNoTransition, !animate)\n            activity?.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, explorerObject: ExplorerObject, view: ImageView) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(explorerObject.link)\n            intent.putExtra(keyTitle, explorerObject.name)\n            intent.putExtra(keyAid, explorerObject.key.toString())\n            intent.putExtra(keyImg, PatternUtil.getCover(explorerObject.aid))\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(activity: Activity, recordObject: RecordObject, view: ImageView) {\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.data = Uri.parse(\"https://www3.animeflv.net/\" + recordObject.animeObject.link)\n            intent.putExtra(keyTitle, recordObject.name)\n            intent.putExtra(keyAid, recordObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(recordObject.animeObject.aid))\n            intent.putExtra(keyPersist, true)\n            intent.putExtra(keyIsRecord, true)\n            activity.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(activity: Activity?, seeingObject: SeeingObject) {\n            activity ?: return\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.data = Uri.parse(seeingObject.link)\n            intent.putExtra(keyTitle, seeingObject.title)\n            //intent.putExtra(keyAid, seeingObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(seeingObject.aid))\n            intent.putExtra(keyPersist, true)\n            intent.putExtra(keyNoTransition, true)\n            intent.putExtra(keyIsRecord, true)\n            activity.startActivity(intent)\n        }\n\n        fun open(context: Context, animeObject: SearchObject) {\n            val intent = Intent(context, DesignUtils.infoClass)\n            intent.data = Uri.parse(animeObject.link)\n            intent.putExtra(keyTitle, animeObject.name)\n            intent.putExtra(keyAid, animeObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(animeObject.aid))\n            context.startActivity(intent)\n        }\n\n        fun open(fragment: Fragment, favoriteObject: FavoriteObject, view: ImageView) {\n            val activity = fragment.activity ?: return\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(favoriteObject.link)\n            intent.putExtra(keyTitle, favoriteObject.name)\n            //intent.putExtra(keyAid, favoriteObject.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(favoriteObject.aid))\n            intent.putExtra(keyFromFav, true)\n            fragment.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(activity: Activity, queueObject: QueueObject, view: ImageView) {\n            val intent = Intent(activity, DesignUtils.infoClass)\n            intent.putExtra(keyTitle, queueObject.chapter.name)\n            intent.putExtra(keyAid, queueObject.chapter.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(queueObject.chapter.aid))\n            intent.putExtra(keyAidOnly, true)\n            activity.startActivity(intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, view, sharedImg).toBundle())\n        }\n\n        fun open(fragment: Fragment, animeRelated: AnimeObject.WebInfo.AnimeRelated) {\n            val intent = Intent(fragment.context, DesignUtils.infoClass)\n            intent.data = Uri.parse(\"https://www3.animeflv.net/\" + animeRelated.link)\n            intent.putExtra(keyTitle, animeRelated.name)\n            intent.putExtra(keyAid, animeRelated.aid)\n            fragment.startActivityForResult(intent, REQUEST_CODE)\n        }\n\n        fun open(context: Context, url: String) {\n            val intent = Intent(context, DesignUtils.infoClass)\n            intent.data = Uri.parse(url)\n            context.startActivity(intent)\n        }\n\n        fun getSimpleIntent(context: Context, item: WEListItem): Intent {\n            val intent = Intent(context, DesignUtils.infoClass)\n            intent.data = Uri.parse(item.link)\n            intent.action = \"${Random.nextInt(1, 9000)}\"\n            intent.putExtra(keyTitle, item.title)\n            intent.putExtra(keyAid, item.aid)\n            intent.putExtra(keyImg, PatternUtil.getCover(item.aid))\n            return intent\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimeBroadcast.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.content.BroadcastReceiver\nimport android.content.Context\nimport android.content.Intent\n\nimport knf.kuma.database.CacheDB\n\nclass AnimeBroadcast : BroadcastReceiver() {\n    override fun onReceive(context: Context, intent: Intent) {\n        val animeObject = CacheDB.INSTANCE.animeDAO().getByAid(intent.getStringExtra(\"aid\") ?: \"\")\n        if (animeObject != null)\n            ActivityAnimeMaterial.open(context, animeObject)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimeChaptersAdapter.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.content.ActivityNotFoundException\nimport android.content.Context\nimport android.content.Intent\nimport android.content.pm.ActivityInfo\nimport android.net.Uri\nimport android.os.Build\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageButton\nimport android.widget.ImageView\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.appcompat.widget.PopupMenu\nimport androidx.core.content.ContextCompat\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.android.material.card.MaterialCardView\nimport com.michaelflisar.dragselectrecyclerview.DragSelectTouchListener\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport com.squareup.picasso.Callback\nimport knf.kuma.App\nimport knf.kuma.R\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.animeinfo.fragments.ChaptersFragment\nimport knf.kuma.animeinfo.ktx.epTitle\nimport knf.kuma.animeinfo.ktx.fileName\nimport knf.kuma.animeinfo.ktx.filePath\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.cast.CastMedia\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.FileWrapper\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.distinct\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.load\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.noCrashSuspend\nimport knf.kuma.commons.safeShow\nimport knf.kuma.database.CacheDB\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeeingObject\nimport knf.kuma.pojos.SeenObject\nimport knf.kuma.queue.QueueManager\nimport knf.kuma.videoservers.FileActions\nimport knf.kuma.videoservers.ServersFactory\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport xdroid.toaster.Toaster\nimport java.net.URL\nimport java.util.Locale\nimport java.util.concurrent.atomic.AtomicReference\n\nclass AnimeChaptersAdapter(private val fragment: Fragment, private val recyclerView: RecyclerView, val chapters: List<ChapterObjWrap>, private val touchListener: DragSelectTouchListener) : RecyclerView.Adapter<AnimeChaptersAdapter.ChapterImgHolder>(), FastScrollRecyclerView.SectionedAdapter {\n\n    private val context: Context? = fragment.context\n    private val chaptersDAO = CacheDB.INSTANCE.seenDAO()\n    private val recordsDAO = CacheDB.INSTANCE.recordsDAO()\n    private val seeingDAO = CacheDB.INSTANCE.seeingDAO()\n    private val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n    private val isNetworkAvailable = Network.isConnected\n    val selection = HashSet<Int>()\n    private var seeingObject: SeeingObject? = null\n    var isImporting = false\n    private var processingPosition = -1\n\n    init {\n        setHasStableIds(true)\n        if (chapters.isNotEmpty()) {\n            noCrash {\n                seeingObject = seeingDAO.getByAid(chapters[0].chapter.aid)\n                doAsync {\n                    if (CacheDB.INSTANCE.animeDAO().isCompleted(chapters[0].chapter.aid))\n                        DownloadedObserver.observe(fragment.lifecycleScope, chapters.size, chapters[0].chapter.fileWrapper())\n                }\n            }\n        }\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChapterImgHolder {\n        return ChapterImgHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_chapter_preview, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ChapterImgHolder, position: Int, payloads: MutableList<Any>) {\n        if (context != null && payloads.isNotEmpty() && chapters.isNotEmpty()) {\n            holder.setSeen(chapters[position].isSeen)\n            if (selection.contains(position)) {\n                holder.cardView.setBackgroundColor(ContextCompat.getColor(context, EAHelper.getThemeColorLight()))\n            } else {\n                holder.cardView.setBackgroundColor(ContextCompat.getColor(context, R.color.cardview_background))\n            }\n        }\n        if (payloads.isEmpty())\n            super.onBindViewHolder(holder, position, payloads)\n    }\n\n    override fun onBindViewHolder(holder: ChapterImgHolder, position: Int) {\n        if (context == null) return\n        val chapter = chapters[position]\n        if (selection.contains(position))\n            holder.cardView.setBackgroundColor(ContextCompat.getColor(context, EAHelper.getThemeColorLight()))\n        else\n            holder.cardView.setBackgroundColor(ContextCompat.getColor(context, R.color.cardview_background))\n        if (processingPosition == holder.adapterPosition) {\n            holder.progressBar.isIndeterminate = true\n            holder.progressBarRoot.visibility = View.VISIBLE\n        } else\n            holder.progressBarRoot.visibility = View.GONE\n        if (!Network.isConnected || chapter.chapter.img == null)\n            holder.imageView.visibility = View.GONE\n        if (chapter.chapter.img != null)\n            holder.imageView.load(chapter.chapter.img, object : Callback {\n                override fun onSuccess() {\n                    holder.imageView.visibility = View.VISIBLE\n                }\n                override fun onError(e: Exception?) {\n\n                }\n            })\n        val downloadObject = AtomicReference<DownloadObject>()\n        holder.apply {\n            fileWrapperJob?.cancel()\n            fileWrapperJob = fragment.lifecycleScope.launch(Dispatchers.Main) {\n                withContext(Dispatchers.IO) {\n                    chapter.chapter.fileWrapper()\n                    downloadObject.set(downloadsDAO.getByEid(chapter.chapter.eid))\n                }\n\n                if (!isActive)\n                    return@launch\n                setQueueObserver(CacheDB.INSTANCE.queueDAO().isInQueueLive(chapter.chapter.eid), fragment) {\n                    setQueue(\n                        it,\n                        isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject.get())\n                    )\n                }\n                setDownloadObserver(downloadsDAO.getLiveByEid(chapter.chapter.eid).distinct, fragment) { downloadObject1 ->\n                    setDownloadState(downloadObject1)\n                    val casting = CastUtil.get().casting.value\n                    val isCasting = casting != null && casting == chapter.chapter.eid\n                    if (!isCasting)\n                        fragment.lifecycleScope.launch(Dispatchers.IO) {\n                            setQueue(\n                                QueueManager.isInQueue(chapter.chapter.eid),\n                                isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject1)\n                            )\n                        }\n                    else\n                        setDownloaded(\n                            isPlayAvailable(\n                                chapter.chapter.fileWrapper(),\n                                downloadObject1\n                            ), true\n                        )\n                    downloadObject.set(downloadObject1)\n                }\n                setCastingObserver(fragment) { s ->\n                    if (chapter.chapter.eid != s)\n                        fragment.lifecycleScope.launch(Dispatchers.IO) {\n                            setQueue(\n                                QueueManager.isInQueue(chapter.chapter.eid),\n                                isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject.get())\n                            )\n                        }\n                    else\n                        setDownloaded(\n                            isPlayAvailable(\n                                chapter.chapter.fileWrapper(),\n                                downloadObject.get()\n                            ), chapter.chapter.eid == s\n                        )\n                }\n            }\n        }\n        holder.chapter.setTextColor(ContextCompat.getColor(context, if (chapter.isSeen) EAHelper.getThemeColor() else R.color.textPrimary))\n        holder.separator.visibility = if (position == 0) View.GONE else View.VISIBLE\n        holder.chapter.text = chapter.chapter.number\n        if (!isFullMode)\n            holder.actions.visibility = View.GONE\n        else\n            holder.actions.setOnClickListener { view ->\n                fragment.lifecycleScope.launch(Dispatchers.Main) {\n                    val menu = PopupMenu(context, view)\n                    if (CastUtil.get().casting.value == chapter.chapter.eid) {\n                        menu.inflate(R.menu.chapter_casting_menu)\n                        if (canPlay(chapter.chapter.fileWrapper()))\n                            menu.menu.findItem(R.id.download).isVisible = false\n                    } else if (isPlayAvailable(\n                            chapter.chapter.fileWrapper(),\n                            downloadObject.get()\n                        )\n                    ) {\n                        menu.inflate(R.menu.chapter_downloaded_menu)\n                        if (!CastUtil.get().connected())\n                            menu.menu.findItem(R.id.cast).isVisible = false\n                    } else if (isNetworkAvailable)\n                        menu.inflate(R.menu.chapter_menu)\n                    else\n                        menu.inflate(R.menu.chapter_menu_offline)\n                    if (QueueManager.isInQueue(chapter.chapter.eid) && menu.menu.findItem(R.id.queue) != null)\n                        menu.menu.findItem(R.id.queue).isVisible = false\n                    if (!PrefsUtil.showImport() || isImporting)\n                        menu.menu.findItem(R.id.import_file).isVisible = false\n                    menu.setOnMenuItemClickListener { item ->\n                        when (item.itemId) {\n                            R.id.play -> if (canPlay(chapter.chapter.fileWrapper())) {\n                                fragment.lifecycleScope.launch(Dispatchers.IO) {\n                                    chaptersDAO.addChapter(SeenObject.fromChapter(chapter.chapter))\n                                    recordsDAO.add(RecordObject.fromChapter(chapter.chapter))\n                                }\n                                chapter.isSeen = true\n                                updateSeeing(chapter.chapter.number)\n                                holder.setSeen(true)\n                                ServersFactory.startPlay(context, chapter.chapter.epTitle, chapter.chapter.fileWrapper().name())\n                                syncData {\n                                    history()\n                                    seen()\n                                }\n                            } else {\n                                Toaster.toast(\"Aun no se está descargando\")\n                            }\n                            R.id.cast -> if (canPlay(chapter.chapter.fileWrapper())) {\n                                CastUtil.get().play(recyclerView, CastMedia.create(chapter.chapter))\n                                fragment.lifecycleScope.launch(Dispatchers.IO) {\n                                    chaptersDAO.addChapter(SeenObject.fromChapter(chapter.chapter))\n                                    recordsDAO.add(RecordObject.fromChapter(chapter.chapter))\n                                }\n                                chapter.isSeen = true\n                                syncData {\n                                    history()\n                                    seen()\n                                }\n                                updateSeeing(chapter.chapter.number)\n                                holder.setSeen(true)\n                            }\n                            R.id.casting -> CastUtil.get().openControls()\n                            R.id.delete -> MaterialDialog(context).safeShow {\n                                message(\n                                    text = \"¿Eliminar el ${\n                                        chapter.chapter.number.lowercase(\n                                            Locale.getDefault()\n                                        )\n                                    }?\"\n                                )\n                                positiveButton(text = \"CONFIRMAR\") {\n                                    fragment.lifecycleScope.launch(Dispatchers.Main) {\n                                        withContext(Dispatchers.IO) {\n                                            FileAccessHelper.deletePath(\n                                                chapter.chapter.filePath,\n                                                false\n                                            )\n                                        }\n                                        downloadObject.get()?.state = -8\n                                        chapter.chapter.fileWrapper().exist = false\n                                        holder.setDownloaded(false, false)\n                                    }\n                                    DownloadManagerCentral.cancel(chapter.chapter.eid)\n                                    QueueManager.remove(chapter.chapter.eid)\n                                }\n                                negativeButton(text = \"CANCELAR\")\n                            }\n                            R.id.download -> {\n                                setOrientation(true)\n                                FileActions.download(fragment, chapter.chapter) { state, _ ->\n                                    when (state) {\n                                        FileActions.CallbackState.START_DOWNLOAD -> {\n                                            fragment.lifecycleScope.launch(Dispatchers.Main) {\n                                                holder.progressBar.isIndeterminate = true\n                                                holder.progressBarRoot.visibility = View.VISIBLE\n                                                holder.setQueue(withContext(Dispatchers.IO) { CacheDB.INSTANCE.queueDAO().isInQueue(chapter.chapter.eid) }, true)\n                                                chapter.chapter.fileWrapper().exist = true\n                                            }\n                                        }\n\n                                        else -> {\n                                            fragment.doOnUI {\n                                                holder.progressBarRoot.visibility = View.GONE\n                                            }\n                                        }\n                                    }\n                                    setOrientation(false)\n                                }\n                            }\n                            R.id.streaming -> {\n                                setOrientation(true)\n                                FileActions.stream(fragment, chapter.chapter) { state, extra ->\n                                    when (state) {\n                                        FileActions.CallbackState.START_STREAM, FileActions.CallbackState.START_CAST -> {\n                                            if (state == FileActions.CallbackState.START_CAST) {\n                                                CastUtil.get().play(recyclerView, CastMedia.create(chapter.chapter, extra as? String))\n                                            }\n                                            fragment.lifecycleScope.launch(Dispatchers.IO) {\n                                                chaptersDAO.addChapter(SeenObject.fromChapter(chapter.chapter))\n                                                recordsDAO.add(RecordObject.fromChapter(chapter.chapter))\n                                            }\n                                            chapter.isSeen = true\n                                            syncData {\n                                                history()\n                                                seen()\n                                            }\n                                            updateSeeing(chapter.chapter.number)\n                                            holder.setSeen(true)\n                                        }\n\n                                        else -> {\n                                            //\n                                        }\n                                    }\n                                    setOrientation(false)\n                                }\n                            }\n                            R.id.queue -> if (isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject.get())) {\n                                QueueManager.add(chapter.chapter.fileWrapper(), downloadObject.get(), true, chapter.chapter)\n                                holder.setQueue(true, true)\n                            } else {\n                                setOrientation(true)\n                                ServersFactory.start(context, chapter.chapter.link, chapter.chapter, true, true, object : ServersFactory.ServersInterface {\n                                    override fun onFinish(started: Boolean, success: Boolean) {\n                                        if (success) {\n                                            holder.setQueue(true, false)\n                                        }\n                                        setOrientation(false)\n                                    }\n\n                                    override fun onCast(url: String?) {}\n\n                                    override fun onProgressIndicator(boolean: Boolean) {\n                                        fragment.doOnUI {\n                                            if (boolean) {\n                                                holder.progressBar.isIndeterminate = true\n                                                holder.progressBarRoot.visibility = View.VISIBLE\n                                            } else\n                                                holder.progressBarRoot.visibility = View.GONE\n                                        }\n                                    }\n\n                                    override fun getView(): View {\n                                        return recyclerView\n                                    }\n                                })\n                            }\n                            R.id.share -> fragment.activity?.startActivity(Intent.createChooser(Intent(Intent.ACTION_SEND)\n                                    .setType(\"text/plain\")\n                                    .putExtra(Intent.EXTRA_TEXT, chapter.chapter.epTitle + \"\\n\" + chapter.chapter.link), \"Compartir\"))\n                            R.id.import_file -> (fragment as ChaptersFragment).onMove(chapter.chapter.fileName)\n                            R.id.commentaries -> {\n                                fragment.lifecycleScope.launch(Dispatchers.Main) {\n                                    try {\n                                        val version = withContext(Dispatchers.IO) {\n                                            try {\n                                                Regex(\"load\\\\.(\\\\w+)\\\\.js\").find(URL(\"https://https-myanimelist-net-2.disqus.com/embed.js\").readText())?.destructured?.component1()!!\n                                            } catch (e: Exception) {\n                                                e.printStackTrace()\n                                                AdsUtils.remoteConfigs.getString(\n                                                    \"disqus_version\"\n                                                )\n                                            }\n                                        }\n                                        CommentariesDialog.show(\n                                            fragment,\n                                            chapter.chapter.link,\n                                            version\n                                        )\n                                    } catch (_: ActivityNotFoundException) {\n                                        noCrashSuspend {\n                                            context.startActivity(\n                                                Intent(\n                                                    Intent.ACTION_VIEW,\n                                                    Uri.parse(withContext(Dispatchers.IO) {\n                                                        chapter.chapter.commentariesLink(\n                                                            AdsUtils.remoteConfigs.getString(\n                                                                \"disqus_version\"\n                                                            )\n                                                        )\n                                                    })\n                                                )\n                                            )\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        true\n                    }\n                    menu.show()\n                }\n            }\n        holder.cardView.setOnClickListener {\n            if (chapter.isSeen) {\n                fragment.lifecycleScope.launch(Dispatchers.IO) {\n                    chaptersDAO.deleteChapter(chapter.chapter.aid, chapter.chapter.number)\n                }\n                chapter.isSeen = false\n                holder.chapter.setTextColor(ContextCompat.getColor(context, R.color.textPrimary))\n            } else {\n                fragment.lifecycleScope.launch(Dispatchers.IO) {\n                    chaptersDAO.addChapter(SeenObject.fromChapter(chapter.chapter))\n                }\n                chapter.isSeen = true\n                holder.chapter.setTextColor(ContextCompat.getColor(context, EAHelper.getThemeColor()))\n            }\n            syncData { seen() }\n            updateSeeing(chapter.chapter.number)\n        }\n        holder.cardView.setOnLongClickListener {\n            touchListener.startDragSelection(holder.adapterPosition)\n            true\n        }\n    }\n\n    override fun getSectionName(position: Int): String {\n        return chapters[position].chapter.number.trim().substring(chapters[position].chapter.number.trim().lastIndexOf(\" \") + 1)\n    }\n\n    private fun updateSeeing(chapter: String) {\n        doAsync {\n            seeingObject?.let {\n                it.chapter = chapter\n                seeingDAO.update(it)\n                syncData { seeing() }\n            }\n        }\n    }\n\n    private fun setOrientation(block: Boolean) {\n        noCrash {\n            if (block)\n                (fragment.activity as? AppCompatActivity)?.requestedOrientation = when {\n                    fragment.context?.resources?.getBoolean(R.bool.isLandscape) == true -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE\n                    else -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT\n                }\n            else (fragment.activity as? AppCompatActivity)?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n        }\n    }\n\n    private fun isPlayAvailable(fileWrapper: FileWrapper<*>, downloadObject: DownloadObject?): Boolean {\n        return fileWrapper.exist || downloadObject != null && downloadObject.isDownloading\n    }\n\n    private fun canPlay(fileWrapper: FileWrapper<*>): Boolean {\n        return fileWrapper.exist\n    }\n\n    override fun getItemViewType(position: Int): Int {\n        return chapters[position].chapter.chapterType?.value ?: 0\n    }\n\n    override fun getItemCount(): Int {\n        return chapters.size\n    }\n\n    override fun getItemId(position: Int): Long {\n        return position.toLong()\n    }\n\n    fun select(pos: Int, sel: Boolean) {\n        if (sel) {\n            selection.add(pos)\n        } else {\n            selection.remove(pos)\n        }\n        notifyItemChanged(pos, 0)\n    }\n\n    fun selectRange(start: Int, end: Int, sel: Boolean) {\n        if (sel)\n            selection.add(start)\n        else\n            selection.remove(start)\n        fragment.doOnUI { notifyItemChanged(start, true) }\n    }\n\n    fun deselectAll() {\n        selection.clear()\n        notifyDataSetChanged()\n    }\n\n    override fun onViewRecycled(holder: ChapterImgHolder) {\n        holder.unsetCastingObserver()\n        holder.unsetDownloadObserver()\n        holder.unsetQueueObserver()\n        super.onViewRecycled(holder)\n    }\n\n    inner class ChapterImgHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val separator: View by itemView.bind(R.id.separator)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val chapter: TextView by itemView.bind(R.id.chapter)\n        private val inDown: ImageView by itemView.bind(R.id.in_down)\n        val actions: ImageButton by itemView.bind(R.id.actions)\n        val progressBar: ProgressBar by itemView.bind(R.id.progress)\n        val progressBarRoot: View by itemView.bind(R.id.progress_root)\n\n        private var downloadLiveData: LiveData<DownloadObject> = MutableLiveData()\n        private var queueLiveData: LiveData<Boolean> = MutableLiveData()\n\n        private var downloadObserver: Observer<DownloadObject>? = null\n        private var castingObserver: Observer<String>? = null\n        private var queueObserver: Observer<Boolean>? = null\n        var fileWrapperJob: Job? = null\n\n        fun setDownloadObserver(downloadLiveData: LiveData<DownloadObject>, owner: LifecycleOwner?, observer: Observer<DownloadObject>) {\n            if (owner == null) return\n            this.downloadLiveData = downloadLiveData\n            this.downloadObserver = observer\n            this.downloadLiveData.observe(owner, observer)\n        }\n\n        fun unsetDownloadObserver() {\n            downloadObserver?.let {\n                downloadLiveData.removeObserver(it)\n                downloadObserver = null\n            }\n        }\n\n        fun setCastingObserver(owner: LifecycleOwner?, observer: Observer<String>) {\n            if (owner == null) return\n            this.castingObserver = observer\n            CastUtil.get().casting.observe(owner, observer)\n        }\n\n        fun unsetCastingObserver() {\n            castingObserver?.let {\n                CastUtil.get().casting.removeObserver(it)\n                castingObserver = null\n            }\n        }\n\n        fun setQueueObserver(queueLivedata: LiveData<Boolean>, owner: LifecycleOwner?, observer: Observer<Boolean>) {\n            if (owner == null) return\n            this.queueLiveData = queueLivedata\n            this.queueObserver = observer\n            this.queueLiveData.observe(owner, observer)\n        }\n\n        fun unsetQueueObserver() {\n            queueObserver?.let {\n                queueLiveData.removeObserver(it)\n                queueObserver = null\n            }\n        }\n\n        fun setDownloaded(downloaded: Boolean, isCasting: Boolean) {\n            inDown.post {\n                if (downloaded)\n                    inDown.setImageResource(R.drawable.ic_chap_down)\n                if (isCasting)\n                    inDown.setImageResource(R.drawable.ic_casting)\n                inDown.visibility = if (downloaded || isCasting) View.VISIBLE else View.GONE\n            }\n        }\n\n        fun setQueue(isInQueue: Boolean, isDownloaded: Boolean) {\n            inDown.post {\n                if (!isInQueue)\n                    setDownloaded(isDownloaded, false)\n                else {\n                    inDown.setImageResource(if (isDownloaded) R.drawable.ic_queue_file else R.drawable.ic_queue_normal)\n                    inDown.visibility = View.VISIBLE\n                }\n            }\n        }\n\n        fun setSeen(seen: Boolean) {\n            chapter.post { chapter.setTextColor(ContextCompat.getColor(App.context, if (seen) EAHelper.getThemeColor() else R.color.textPrimary)) }\n        }\n\n        fun setDownloadState(downloadObject: DownloadObject?) {\n            progressBar.post {\n                if (downloadObject != null && PrefsUtil.showProgress())\n                    when (downloadObject.state) {\n                        DownloadObject.PENDING -> {\n                            progressBarRoot.visibility = View.VISIBLE\n                            progressBar.isIndeterminate = true\n                        }\n                        DownloadObject.PAUSED, DownloadObject.DOWNLOADING -> {\n                            progressBarRoot.visibility = View.VISIBLE\n                            progressBar.isIndeterminate = false\n                            if (downloadObject.getEta() == -2L || PrefsUtil.downloaderType == 0)\n                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)\n                                    progressBar.setProgress(downloadObject.progress, true)\n                                else\n                                    progressBar.progress = downloadObject.progress\n                            else {\n                                progressBar.progress = 0\n                                progressBar.secondaryProgress = downloadObject.progress\n                            }\n                        }\n                        else -> progressBarRoot.visibility = View.GONE\n                    }\n                else\n                    progressBarRoot.visibility = View.GONE\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimeChaptersAdapterMaterial.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.content.Context\nimport android.content.Intent\nimport android.content.pm.ActivityInfo\nimport android.net.Uri\nimport android.os.Build\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageButton\nimport android.widget.ImageView\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.appcompat.widget.PopupMenu\nimport androidx.core.content.ContextCompat\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.michaelflisar.dragselectrecyclerview.DragSelectTouchListener\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport com.squareup.picasso.Callback\nimport knf.kuma.App\nimport knf.kuma.R\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.animeinfo.fragments.ChaptersFragmentMaterial\nimport knf.kuma.animeinfo.ktx.epTitle\nimport knf.kuma.animeinfo.ktx.fileName\nimport knf.kuma.animeinfo.ktx.filePath\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.cast.CastMedia\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.FileWrapper\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.distinct\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.getSurfaceColor\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.load\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.noCrashSuspend\nimport knf.kuma.commons.safeShow\nimport knf.kuma.database.CacheDB\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeeingObject\nimport knf.kuma.pojos.SeenObject\nimport knf.kuma.queue.QueueManager\nimport knf.kuma.videoservers.FileActions\nimport knf.kuma.videoservers.ServersFactory\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport xdroid.toaster.Toaster\nimport java.net.URL\nimport java.util.Locale\nimport java.util.concurrent.atomic.AtomicReference\n\nclass AnimeChaptersAdapterMaterial(private val fragment: Fragment, private val recyclerView: RecyclerView, val chapters: List<ChapterObjWrap>, private val touchListener: DragSelectTouchListener) : RecyclerView.Adapter<AnimeChaptersAdapterMaterial.ChapterImgHolder>(), FastScrollRecyclerView.SectionedAdapter {\n\n    private val context: Context? = fragment.context\n    private val chaptersDAO = CacheDB.INSTANCE.seenDAO()\n    private val recordsDAO = CacheDB.INSTANCE.recordsDAO()\n    private val seeingDAO = CacheDB.INSTANCE.seeingDAO()\n    private val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n    private val isNetworkAvailable = Network.isConnected\n    val selection = HashSet<Int>()\n    private var seeingObject: SeeingObject? = null\n    var isImporting = false\n    private var processingPosition = -1\n\n    init {\n        setHasStableIds(true)\n        if (chapters.isNotEmpty()) {\n            noCrash {\n                doAsync {\n                    seeingObject = seeingDAO.getByAid(chapters[0].chapter.aid)\n                    if (CacheDB.INSTANCE.animeDAO().isCompleted(chapters[0].chapter.aid))\n                        DownloadedObserver.observe(fragment.lifecycleScope, chapters.size, chapters[0].chapter.fileWrapper())\n                }\n            }\n        }\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChapterImgHolder {\n        return ChapterImgHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_chapter_preview_material, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ChapterImgHolder, position: Int, payloads: MutableList<Any>) {\n        if (context != null)\n            if (selection.contains(position))\n                holder.cardView.setBackgroundColor(ContextCompat.getColor(context, EAHelper.getThemeColorLight()))\n            else\n                holder.cardView.setBackgroundColor(fragment.getSurfaceColor())\n        if (payloads.isEmpty())\n            super.onBindViewHolder(holder, position, payloads)\n    }\n\n    override fun onBindViewHolder(holder: ChapterImgHolder, position: Int) {\n        if (context == null) return\n        val chapter = chapters[position]\n        if (selection.contains(position))\n            holder.cardView.setBackgroundColor(ContextCompat.getColor(context, EAHelper.getThemeColorLight()))\n        else\n            holder.cardView.setBackgroundColor(fragment.getSurfaceColor())\n        if (processingPosition == holder.adapterPosition) {\n            holder.progressBar.isIndeterminate = true\n            holder.progressBarRoot.visibility = View.VISIBLE\n        } else\n            holder.progressBarRoot.visibility = View.GONE\n        if (!Network.isConnected || chapter.chapter.img == null)\n            holder.imageView.visibility = View.GONE\n        if (chapter.chapter.img != null) {\n            holder.imageView.load(chapter.chapter.img, object : Callback {\n                override fun onSuccess() {\n                    holder.imageView.visibility = View.VISIBLE\n                }\n                override fun onError(e: Exception?) {\n\n                }\n            })\n        }\n        val downloadObject = AtomicReference<DownloadObject>()\n        holder.apply {\n            fileWrapperJob?.cancel()\n            fileWrapperJob = fragment.lifecycleScope.launch(Dispatchers.Main) {\n                withContext(Dispatchers.IO) {\n                    chapter.chapter.fileWrapper()\n                    downloadObject.set(downloadsDAO.getByEid(chapter.chapter.eid))\n                }\n\n                if (!isActive)\n                    return@launch\n                setQueueObserver(CacheDB.INSTANCE.queueDAO().isInQueueLive(chapter.chapter.eid), fragment, Observer {\n                    setQueue(it, isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject.get()))\n                })\n                setDownloadObserver(downloadsDAO.getLiveByEid(chapter.chapter.eid).distinct, fragment, Observer { downloadObject1 ->\n                    setDownloadState(downloadObject1)\n                    val casting = CastUtil.get().casting.value\n                    val isCasting = casting != null && casting == chapter.chapter.eid\n                    if (!isCasting)\n                        fragment.lifecycleScope.launch(Dispatchers.IO){\n                            setQueue(QueueManager.isInQueue(chapter.chapter.eid), isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject1))\n                        }\n                    else\n                        setDownloaded(isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject1), true)\n                    downloadObject.set(downloadObject1)\n                })\n                setCastingObserver(fragment, Observer { s ->\n                    if (chapter.chapter.eid != s)\n                        fragment.lifecycleScope.launch(Dispatchers.IO){\n                            setQueue(QueueManager.isInQueue(chapter.chapter.eid), isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject.get()))\n                        }\n                    else\n                        setDownloaded(isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject.get()), chapter.chapter.eid == s)\n                })\n            }\n        }\n        holder.chapter.setTextColor(ContextCompat.getColor(context, if (chapter.isSeen) EAHelper.getThemeColor() else R.color.textPrimary))\n        holder.separator.visibility = if (position == 0) View.GONE else View.VISIBLE\n        holder.chapter.text = chapter.chapter.number\n        if (!isFullMode)\n            holder.actions.visibility = View.GONE\n        else\n            holder.actions.setOnClickListener { view ->\n                fragment.lifecycleScope.launch(Dispatchers.Main) {\n                    val menu = PopupMenu(context, view)\n                    if (CastUtil.get().casting.value == chapter.chapter.eid) {\n                        menu.inflate(R.menu.chapter_casting_menu)\n                        if (canPlay(chapter.chapter.fileWrapper()))\n                            menu.menu.findItem(R.id.download).isVisible = false\n                    } else if (isPlayAvailable(\n                            chapter.chapter.fileWrapper(),\n                            downloadObject.get()\n                        )\n                    ) {\n                        menu.inflate(R.menu.chapter_downloaded_menu)\n                        if (!CastUtil.get().connected())\n                            menu.menu.findItem(R.id.cast).isVisible = false\n                    } else if (isNetworkAvailable)\n                        menu.inflate(R.menu.chapter_menu)\n                    else\n                        menu.inflate(R.menu.chapter_menu_offline)\n                    if (QueueManager.isInQueue(chapter.chapter.eid) && menu.menu.findItem(R.id.queue) != null)\n                        menu.menu.findItem(R.id.queue).isVisible = false\n                    if (!PrefsUtil.showImport() || isImporting)\n                        menu.menu.findItem(R.id.import_file).isVisible = false\n                    menu.setOnMenuItemClickListener { item ->\n                        when (item.itemId) {\n                            R.id.play -> if (canPlay(chapter.chapter.fileWrapper())) {\n                                fragment.lifecycleScope.launch(Dispatchers.IO){\n                                    chaptersDAO.addChapter(SeenObject.fromChapter(chapter.chapter))\n                                    recordsDAO.add(RecordObject.fromChapter(chapter.chapter))\n                                }\n                                chapter.isSeen = true\n                                updateSeeing(chapter.chapter.number)\n                                holder.setSeen(true)\n                                ServersFactory.startPlay(context, chapter.chapter.epTitle, chapter.chapter.fileWrapper().name())\n                                syncData {\n                                    history()\n                                    seen()\n                                }\n                            } else {\n                                Toaster.toast(\"Aun no se está descargando\")\n                            }\n                            R.id.cast -> if (canPlay(chapter.chapter.fileWrapper())) {\n                                //CastUtil.get().play(fragment.activity as Activity, recyclerView, chapter.eid, SelfServer.start(chapter.fileName, true), chapter.name, chapter.number, if (chapter.img == null) chapter.aid else chapter.img, chapter.img == null)\n                                CastUtil.get().play(recyclerView, CastMedia.create(chapter.chapter))\n                                fragment.lifecycleScope.launch(Dispatchers.IO){\n                                    chaptersDAO.addChapter(SeenObject.fromChapter(chapter.chapter))\n                                    recordsDAO.add(RecordObject.fromChapter(chapter.chapter))\n                                }\n                                chapter.isSeen = true\n                                syncData {\n                                    history()\n                                    seen()\n                                }\n                                updateSeeing(chapter.chapter.number)\n                                holder.setSeen(true)\n                            }\n                            R.id.casting -> CastUtil.get().openControls()\n                            R.id.delete -> MaterialDialog(context).safeShow {\n                                message(\n                                    text = \"¿Eliminar el ${\n                                        chapter.chapter.number.lowercase(\n                                            Locale.getDefault()\n                                        )\n                                    }?\"\n                                )\n                                positiveButton(text = \"CONFIRMAR\") {\n                                    fragment.lifecycleScope.launch(Dispatchers.Main) {\n                                        withContext(Dispatchers.IO) {\n                                            FileAccessHelper.deletePath(\n                                                chapter.chapter.filePath,\n                                                false\n                                            )\n                                        }\n                                        downloadObject.get()?.state = -8\n                                        chapter.chapter.fileWrapper().exist = false\n                                        holder.setDownloaded(false, false)\n                                    }\n                                    DownloadManagerCentral.cancel(chapter.chapter.eid)\n                                    QueueManager.remove(chapter.chapter.eid)\n                                }\n                                negativeButton(text = \"CANCELAR\")\n                            }\n                            R.id.download -> {\n                                setOrientation(true)\n                                FileActions.download(fragment, chapter.chapter) { state, _ ->\n                                    when (state) {\n                                        FileActions.CallbackState.START_DOWNLOAD -> {\n                                            fragment.lifecycleScope.launch(Dispatchers.Main) {\n                                                holder.progressBar.isIndeterminate = true\n                                                holder.progressBarRoot.visibility = View.VISIBLE\n                                                holder.setQueue(withContext(Dispatchers.IO){ CacheDB.INSTANCE.queueDAO().isInQueue(chapter.chapter.eid) }, true)\n                                                chapter.chapter.fileWrapper().exist = true\n                                            }\n                                        }\n\n                                        else -> {\n                                            fragment.doOnUI {\n                                                holder.progressBarRoot.visibility = View.GONE\n                                            }\n                                        }\n                                    }\n                                    setOrientation(false)\n                                }\n                            }\n                            R.id.streaming -> {\n                                setOrientation(true)\n                                FileActions.stream(fragment, chapter.chapter) { state, extra ->\n                                    when (state) {\n                                        FileActions.CallbackState.START_STREAM, FileActions.CallbackState.START_CAST -> {\n                                            if (state == FileActions.CallbackState.START_CAST) {\n                                                CastUtil.get().play(recyclerView, CastMedia.create(chapter.chapter, extra as? String))\n                                            }\n                                            fragment.lifecycleScope.launch(Dispatchers.IO){\n                                                chaptersDAO.addChapter(SeenObject.fromChapter(chapter.chapter))\n                                                recordsDAO.add(RecordObject.fromChapter(chapter.chapter))\n                                            }\n                                            chapter.isSeen = true\n                                            syncData {\n                                                history()\n                                                seen()\n                                            }\n                                            updateSeeing(chapter.chapter.number)\n                                            holder.setSeen(true)\n                                        }\n\n                                        else -> {\n                                            //\n                                        }\n                                    }\n                                    setOrientation(false)\n                                }\n                            }\n                            R.id.queue -> if (isPlayAvailable(chapter.chapter.fileWrapper(), downloadObject.get())) {\n                                QueueManager.add(chapter.chapter.fileWrapper(), downloadObject.get(), true, chapter.chapter)\n                                holder.setQueue(true, true)\n                            } else {\n                                setOrientation(true)\n                                ServersFactory.start(context, chapter.chapter.link, chapter.chapter, true, true, object : ServersFactory.ServersInterface {\n                                    override fun onFinish(started: Boolean, success: Boolean) {\n                                        if (success) {\n                                            holder.setQueue(true, false)\n                                        }\n                                        setOrientation(false)\n                                    }\n\n                                    override fun onCast(url: String?) {}\n\n                                    override fun onProgressIndicator(boolean: Boolean) {\n                                        fragment.doOnUI {\n                                            if (boolean) {\n                                                holder.progressBar.isIndeterminate = true\n                                                holder.progressBarRoot.visibility = View.VISIBLE\n                                            } else\n                                                holder.progressBarRoot.visibility = View.GONE\n                                        }\n                                    }\n\n                                    override fun getView(): View {\n                                        return recyclerView\n                                    }\n                                })\n                            }\n                            R.id.share -> fragment.activity?.startActivity(Intent.createChooser(Intent(Intent.ACTION_SEND)\n                                    .setType(\"text/plain\")\n                                    .putExtra(Intent.EXTRA_TEXT, chapter.chapter.epTitle + \"\\n\" + chapter.chapter.link), \"Compartir\"))\n                            R.id.import_file -> (fragment as ChaptersFragmentMaterial).onMove(chapter.chapter.fileName)\n                            R.id.commentaries -> {\n                                fragment.lifecycleScope.launch(Dispatchers.Main){\n                                    try {\n                                        val version = withContext(Dispatchers.IO) {\n                                            Regex(\"load\\\\.(\\\\w+)\\\\.js\").find(URL(\"https://https-myanimelist-net-2.disqus.com/embed.js\").readText())?.destructured?.component1()!!\n                                        }\n                                        CommentariesDialog.show(\n                                            fragment,\n                                            chapter.chapter.link,\n                                            version\n                                        )\n                                    } catch (e: Exception) {\n                                        noCrashSuspend {\n                                            context.startActivity(\n                                                Intent(\n                                                    Intent.ACTION_VIEW,\n                                                    Uri.parse(withContext(Dispatchers.IO) {\n                                                        chapter.chapter.commentariesLink(\n                                                            AdsUtils.remoteConfigs.getString(\n                                                                \"disqus_version\"\n                                                            )\n                                                        )\n                                                    })\n                                                )\n                                            )\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        true\n                    }\n                    menu.show()\n                }\n            }\n        holder.cardView.setOnClickListener {\n            if (chapter.isSeen) {\n                fragment.lifecycleScope.launch(Dispatchers.IO){\n                    chaptersDAO.deleteChapter(chapter.chapter.aid, chapter.chapter.number)\n                }\n                chapter.isSeen = false\n                holder.chapter.setTextColor(ContextCompat.getColor(context, R.color.textPrimary))\n            } else {\n                fragment.lifecycleScope.launch(Dispatchers.IO){\n                    chaptersDAO.addChapter(SeenObject.fromChapter(chapter.chapter))\n                }\n                chapter.isSeen = true\n                holder.chapter.setTextColor(ContextCompat.getColor(context, EAHelper.getThemeColor()))\n            }\n            syncData { seen() }\n            updateSeeing(chapter.chapter.number)\n        }\n        holder.cardView.setOnLongClickListener {\n            touchListener.startDragSelection(holder.adapterPosition)\n            true\n        }\n    }\n\n    override fun getSectionName(position: Int): String {\n        return chapters[position].chapter.number.trim().substring(chapters[position].chapter.number.trim().lastIndexOf(\" \") + 1)\n    }\n\n    private fun updateSeeing(chapter: String) {\n        fragment.lifecycleScope.launch(Dispatchers.IO){\n            seeingObject?.let {\n                it.chapter = chapter\n                seeingDAO.update(it)\n                syncData { seeing() }\n            }\n        }\n    }\n\n    private fun setOrientation(block: Boolean) {\n        noCrash {\n            if (block)\n                (fragment.activity as? AppCompatActivity)?.requestedOrientation = when {\n                    fragment.context?.resources?.getBoolean(R.bool.isLandscape) == true -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE\n                    else -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT\n                }\n            else (fragment.activity as? AppCompatActivity)?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n        }\n    }\n\n    private fun isPlayAvailable(fileWrapper: FileWrapper<*>, downloadObject: DownloadObject?): Boolean {\n        return fileWrapper.exist || downloadObject != null && downloadObject.isDownloading\n    }\n\n    private fun canPlay(fileWrapper: FileWrapper<*>): Boolean {\n        return fileWrapper.exist\n    }\n\n    override fun getItemViewType(position: Int): Int {\n        return chapters[position].chapter.chapterType?.value ?: 0\n    }\n\n    override fun getItemCount(): Int {\n        return chapters.size\n    }\n\n    override fun getItemId(position: Int): Long {\n        return position.toLong()\n    }\n\n    fun select(pos: Int, sel: Boolean) {\n        if (sel) {\n            selection.add(pos)\n        } else {\n            selection.remove(pos)\n        }\n        notifyItemChanged(pos, 0)\n    }\n\n    fun selectRange(start: Int, end: Int, sel: Boolean) {\n        for (i in start..end) {\n            if (sel)\n                selection.add(i)\n            else\n                selection.remove(i)\n        }\n        notifyItemRangeChanged(start, end - start + 1, 0)\n    }\n\n    fun deselectAll() {\n        selection.clear()\n        notifyDataSetChanged()\n    }\n\n    override fun onViewRecycled(holder: ChapterImgHolder) {\n        holder.unsetCastingObserver()\n        holder.unsetDownloadObserver()\n        holder.unsetQueueObserver()\n        super.onViewRecycled(holder)\n    }\n\n    inner class ChapterImgHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val separator: View by itemView.bind(R.id.separator)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val chapter: TextView by itemView.bind(R.id.chapter)\n        private val inDown: ImageView by itemView.bind(R.id.in_down)\n        val actions: ImageButton by itemView.bind(R.id.actions)\n        val progressBar: ProgressBar by itemView.bind(R.id.progress)\n        val progressBarRoot: View by itemView.bind(R.id.progress_root)\n\n        private var downloadLiveData: LiveData<DownloadObject> = MutableLiveData()\n        private var queueLiveData: LiveData<Boolean> = MutableLiveData()\n\n        private var downloadObserver: Observer<DownloadObject>? = null\n        private var castingObserver: Observer<String>? = null\n        private var queueObserver: Observer<Boolean>? = null\n        var fileWrapperJob: Job? = null\n\n        fun setDownloadObserver(downloadLiveData: LiveData<DownloadObject>, owner: LifecycleOwner?, observer: Observer<DownloadObject>) {\n            if (owner == null) return\n            this.downloadLiveData = downloadLiveData\n            this.downloadObserver = observer\n            this.downloadLiveData.observe(owner, observer)\n        }\n\n        fun unsetDownloadObserver() {\n            downloadObserver?.let {\n                downloadLiveData.removeObserver(it)\n                downloadObserver = null\n            }\n        }\n\n        fun setCastingObserver(owner: LifecycleOwner?, observer: Observer<String>) {\n            if (owner == null) return\n            this.castingObserver = observer\n            CastUtil.get().casting.observe(owner, observer)\n        }\n\n        fun unsetCastingObserver() {\n            castingObserver?.let {\n                CastUtil.get().casting.removeObserver(it)\n                castingObserver = null\n            }\n        }\n\n        fun setQueueObserver(queueLivedata: LiveData<Boolean>, owner: LifecycleOwner?, observer: Observer<Boolean>) {\n            if (owner == null) return\n            this.queueLiveData = queueLivedata\n            this.queueObserver = observer\n            this.queueLiveData.observe(owner, observer)\n        }\n\n        fun unsetQueueObserver() {\n            queueObserver?.let {\n                queueLiveData.removeObserver(it)\n                queueObserver = null\n            }\n        }\n\n        fun setDownloaded(downloaded: Boolean, isCasting: Boolean) {\n            noCrash {\n                inDown.post {\n                    if (downloaded)\n                        inDown.setImageResource(R.drawable.ic_chap_down)\n                    if (isCasting)\n                        inDown.setImageResource(R.drawable.ic_casting)\n                    inDown.visibility = if (downloaded || isCasting) View.VISIBLE else View.GONE\n                }\n            }\n        }\n\n        fun setQueue(isInQueue: Boolean, isDownloaded: Boolean) {\n            noCrash {\n                inDown.post {\n                    if (!isInQueue)\n                        setDownloaded(isDownloaded, false)\n                    else {\n                        inDown.setImageResource(if (isDownloaded) R.drawable.ic_queue_file else R.drawable.ic_queue_normal)\n                        inDown.visibility = View.VISIBLE\n                    }\n                }\n            }\n        }\n\n        fun setSeen(seen: Boolean) {\n            chapter.post { chapter.setTextColor(ContextCompat.getColor(App.context, if (seen) EAHelper.getThemeColor() else R.color.textPrimary)) }\n        }\n\n        fun setDownloadState(downloadObject: DownloadObject?) {\n            progressBar.post {\n                if (downloadObject != null && PrefsUtil.showProgress())\n                    when (downloadObject.state) {\n                        DownloadObject.PENDING -> {\n                            progressBarRoot.visibility = View.VISIBLE\n                            progressBar.isIndeterminate = true\n                        }\n                        DownloadObject.PAUSED, DownloadObject.DOWNLOADING -> {\n                            progressBarRoot.visibility = View.VISIBLE\n                            progressBar.isIndeterminate = false\n                            if (downloadObject.getEta() == -2L || PrefsUtil.downloaderType == 0)\n                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)\n                                    progressBar.setProgress(downloadObject.progress, true)\n                                else\n                                    progressBar.progress = downloadObject.progress\n                            else {\n                                progressBar.progress = 0\n                                progressBar.secondaryProgress = downloadObject.progress\n                            }\n                        }\n                        else -> progressBarRoot.visibility = View.GONE\n                    }\n                else\n                    progressBarRoot.visibility = View.GONE\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimeInfo.kt",
    "content": "package knf.kuma.animeinfo\n\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.pojos.AnimeObject\nimport java.text.SimpleDateFormat\nimport java.util.Calendar\nimport java.util.Locale\nimport java.util.regex.Pattern\n\nclass AnimeInfo(code: String) {\n    var aid: String? = null\n    var title: String? = null\n    var sid: String? = null\n    var day: AnimeObject.Day? = null\n        get() {\n            try {\n                if (date == null)\n                    return AnimeObject.Day.NONE\n                val calendar = Calendar.getInstance()\n                calendar.time = SimpleDateFormat(\"yyyy-MM-dd\", Locale.getDefault()).parse(date)\n                return when (calendar.get(Calendar.DAY_OF_WEEK)) {\n                    2 -> AnimeObject.Day.MONDAY\n                    3 -> AnimeObject.Day.TUESDAY\n                    4 -> AnimeObject.Day.WEDNESDAY\n                    5 -> AnimeObject.Day.THURSDAY\n                    6 -> AnimeObject.Day.FRIDAY\n                    7 -> AnimeObject.Day.SATURDAY\n                    1 -> AnimeObject.Day.SUNDAY\n                    else -> AnimeObject.Day.NONE\n                }\n            } catch (e: Exception) {\n                //e.printStackTrace()\n                return AnimeObject.Day.NONE\n            }\n        }\n    var epMap: HashMap<String, String>\n    private var date: String? = null\n\n    init {\n        val matcher = Pattern.compile(\"\\\"([^\\\"\\\\\\\\]*(?:\\\\\\\\.[^\\\"\\\\\\\\]*)*)\\\",?\").matcher(code)\n        var i = 0\n        while (matcher.find()) {\n            when (i) {\n                0 -> this.aid = matcher.group(1)\n                1 -> this.title = PatternUtil.fromHtml(matcher.group(1)).replace(\"\\\\\", \"\")\n                2 -> this.sid = matcher.group(1)\n                3 -> this.date = matcher.group(1)\n            }\n            i++\n        }\n        this.day = day\n        this.epMap = PatternUtil.getEpListMap(code)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimePagerAdapter.kt",
    "content": "package knf.kuma.animeinfo\n\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.fragment.app.FragmentPagerAdapter\nimport knf.kuma.animeinfo.fragments.ChaptersFragment\nimport knf.kuma.animeinfo.fragments.DetailsFragment\n\nclass AnimePagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {\n\n    private val detailsFragment = DetailsFragment.get()\n    private val chaptersFragment = ChaptersFragment.get()\n\n    override fun getPageTitle(position: Int): CharSequence? {\n        return when (position) {\n            1 -> \"EPISODIOS\"\n            else -> \"INFO\"\n        }\n    }\n\n    fun onChaptersReselect() {\n        chaptersFragment.onReselect()\n    }\n\n    override fun getItem(position: Int): Fragment {\n        return when (position) {\n            1 -> chaptersFragment\n            else -> detailsFragment\n        }\n    }\n\n    override fun getCount(): Int {\n        return 2\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimePagerAdapterMaterial.kt",
    "content": "package knf.kuma.animeinfo\n\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.fragment.app.FragmentPagerAdapter\nimport knf.kuma.animeinfo.fragments.ChaptersFragmentMaterial\nimport knf.kuma.animeinfo.fragments.DetailsFragmentMaterial\n\nclass AnimePagerAdapterMaterial(fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {\n\n    private val detailsFragment = DetailsFragmentMaterial.get()\n    private val chaptersFragment = ChaptersFragmentMaterial.get()\n\n    override fun getPageTitle(position: Int): CharSequence? {\n        return when (position) {\n            0 -> \"INFO\"\n            1 -> \"EPISODIOS\"\n            else -> \"INFO\"\n        }\n    }\n\n    fun onChaptersReselect() {\n        chaptersFragment.onReselect()\n    }\n\n    override fun getItem(position: Int): Fragment {\n        return when (position) {\n            0 -> detailsFragment\n            1 -> chaptersFragment\n            else -> detailsFragment\n        }\n    }\n\n    override fun getCount(): Int {\n        return 2\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimeRelatedAdapter.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport androidx.fragment.app.Fragment\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.load\nimport knf.kuma.databinding.ItemRelatedBinding\nimport knf.kuma.pojos.AnimeObject\n\ninternal class AnimeRelatedAdapter(private val fragment: Fragment, private val list: MutableList<AnimeObject.WebInfo.AnimeRelated>) : RecyclerView.Adapter<AnimeRelatedAdapter.RelatedHolder>() {\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RelatedHolder {\n        return RelatedHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_related, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: RelatedHolder, position: Int) {\n        val related = list[position]\n        holder.textView.text = related.name\n        holder.relation.text = related.relation\n        if (related.aid != \"null\") {\n            holder.imageView.visibility = View.VISIBLE\n            holder.imageView.load(PatternUtil.getCover(related.aid))\n            holder.cardView.setOnClickListener { ActivityAnime.open(fragment, related, holder.imageView) }\n        } else {\n            holder.imageView.visibility = View.GONE\n            holder.cardView.setOnClickListener { ActivityAnime.open(fragment, related) }\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    internal class RelatedHolder(itemView: View, binding: ItemRelatedBinding = ItemRelatedBinding.bind(itemView)) : RecyclerView.ViewHolder(itemView) {\n        val cardView: LinearLayout = binding.card\n        val imageView: ImageView = binding.img\n        val textView: TextView = binding.title\n        val relation: TextView = binding.relation\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimeRelatedAdapterMaterial.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport androidx.fragment.app.Fragment\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.load\nimport knf.kuma.databinding.ItemRelatedBinding\nimport knf.kuma.pojos.AnimeObject\n\ninternal class AnimeRelatedAdapterMaterial(private val fragment: Fragment, private val list: MutableList<AnimeObject.WebInfo.AnimeRelated>) : RecyclerView.Adapter<AnimeRelatedAdapterMaterial.RelatedHolder>() {\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RelatedHolder {\n        return RelatedHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_related, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: RelatedHolder, position: Int) {\n        val related = list[position]\n        holder.textView.text = related.name\n        holder.relation.text = related.relation\n        if (related.aid != \"null\") {\n            holder.imageView.visibility = View.VISIBLE\n            holder.imageView.load(PatternUtil.getCover(related.aid))\n            holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(fragment, related, holder.imageView) }\n        } else {\n            holder.imageView.visibility = View.GONE\n            holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(fragment, related) }\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    internal class RelatedHolder(itemView: View, binding: ItemRelatedBinding = ItemRelatedBinding.bind(itemView)) : RecyclerView.ViewHolder(itemView) {\n        val cardView: LinearLayout = binding.card\n        val imageView: ImageView = binding.img\n        val textView: TextView = binding.title\n        val relation: TextView = binding.relation\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimeTagsAdapter.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.search.GenreActivity\nimport org.jetbrains.anko.find\n\ninternal class AnimeTagsAdapter(private val context: Context, private val list: MutableList<String>) : RecyclerView.Adapter<AnimeTagsAdapter.TagHolder>() {\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TagHolder {\n        return TagHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_chip, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: TagHolder, position: Int) {\n        holder.chip.text = list[position]\n        holder.chip.setOnClickListener { GenreActivity.open(context, list[holder.adapterPosition]) }\n\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    internal class TagHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        var chip: TextView = itemView.find(R.id.chip)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimeTagsAdapterMaterial.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.search.GenreActivityMaterial\nimport org.jetbrains.anko.find\n\ninternal class AnimeTagsAdapterMaterial(private val context: Context, private val list: MutableList<String>) : RecyclerView.Adapter<AnimeTagsAdapterMaterial.TagHolder>() {\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TagHolder {\n        return TagHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_chip, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: TagHolder, position: Int) {\n        holder.chip.text = list[position]\n        holder.chip.setOnClickListener { GenreActivityMaterial.open(context, list[holder.adapterPosition]) }\n\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    internal class TagHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        var chip: TextView = itemView.find(R.id.chip)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/AnimeViewModel.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.content.Context\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.commons.noCrashLet\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.retrofit.Repository\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\n\nclass AnimeViewModel : ViewModel() {\n    private val repository = Repository()\n    val liveData: MutableLiveData<AnimeObject?> = MutableLiveData()\n\n    fun init(context: Context, link: String?, persist: Boolean) {\n        link?.let {\n            if (it.contains(\"/ver/\")) {\n                viewModelScope.launch {\n                    val nLink = withContext(Dispatchers.IO) { \"https://www3.animeflv.net\" + noCrashLet { jsoupCookies(it).get().select(\"a[href~=/anime/]\").attr(\"href\") } }\n                    repository.getAnime(nLink, persist, liveData)\n                }\n            } else\n                repository.getAnime(link, persist, liveData)\n        }\n    }\n\n    fun init(aid: String?) {\n        doAsync {\n            aid?.let {\n                val animeObject = CacheDB.INSTANCE.animeDAO().getAnimeByAid(aid)\n                doOnUIGlobal { liveData.value = animeObject }\n            } ?: doOnUIGlobal { liveData.value = null }\n        }\n    }\n\n    fun reload(context: Context, link: String?, persist: Boolean) {\n        init(context, link, persist)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/BottomActionsDialog.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.app.Dialog\nimport android.content.DialogInterface\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.FragmentManager\nimport androidx.lifecycle.LifecycleObserver\nimport com.google.android.material.bottomsheet.BottomSheetBehavior\nimport com.google.android.material.bottomsheet.BottomSheetDialog\nimport com.google.android.material.bottomsheet.BottomSheetDialogFragment\nimport knf.kuma.R\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.databinding.LayBottomActionsBinding\nimport org.jetbrains.anko.sdk27.coroutines.onClick\nimport org.jetbrains.anko.support.v4.toast\n\nclass BottomActionsDialog : BottomSheetDialogFragment(), LifecycleObserver {\n    private var callback: ActionsCallback? = null\n    private var listSize: Int = 0\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(R.layout.lay_bottom_actions, container, false)\n        val binding = LayBottomActionsBinding.bind(view)\n        if (listSize <= 1) {\n            binding.actionSeen.text = \"Marcar como visto\"\n            binding.actionUnseen.text = \"Marcar como no visto\"\n            binding.actionImportAll.text = \"Importar archivo\"\n            binding.actionDownloadAll.text = \"Descargar\"\n        }\n        binding.actionSeen.onClick {\n            callback?.onSelect(STATE_SEEN)\n            safeDismiss()\n        }\n        binding.actionUnseen.onClick {\n            callback?.onSelect(STATE_UNSEEN)\n            safeDismiss()\n        }\n        binding.actionImportAll.onClick {\n            callback?.onSelect(STATE_IMPORT_MULTIPLE)\n            safeDismiss()\n        }\n        binding.actionDownloadAll.onClick {\n            if (!isFullMode) {\n                toast(\"Deshabilitado para esta version\")\n            } else {\n                callback?.onSelect(STATE_DOWNLOAD_MULTIPLE)\n            }\n            safeDismiss()\n        }\n        binding.actionQueueAll.onClick {\n            if (!isFullMode) {\n                toast(\"Deshabilitado para esta version\")\n            } else {\n                callback?.onSelect(STATE_QUEUE_MULTIPLE)\n            }\n            safeDismiss()\n        }\n        return view\n    }\n\n    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {\n        val dialog = super.onCreateDialog(savedInstanceState)\n        dialog.setOnShowListener { dialogInterface ->\n            try {\n                val d = dialogInterface as? BottomSheetDialog\n                d?.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)?.also {\n                    BottomSheetBehavior.from(it).setState(BottomSheetBehavior.STATE_EXPANDED)\n                }\n            } catch (e: Exception) {\n                //\n            }\n        }\n        return dialog\n    }\n\n    fun safeShow(manager: FragmentManager, tag: String) {\n        try {\n            show(manager, tag)\n        } catch (e: Exception) {\n            //\n        }\n\n    }\n\n    private fun safeDismiss() {\n        try {\n            dismiss()\n        } catch (e: Exception) {\n            //\n        }\n\n    }\n\n    /*override fun onDismiss(dialog: DialogInterface) {\n        try {\n            super.onDismiss(dialog)\n            callback?.onDismiss()\n        } catch (e: IllegalArgumentException) {\n            e.printStackTrace()\n        }\n    }*/\n\n    override fun onCancel(dialog: DialogInterface) {\n        try {\n            super.onDismiss(dialog)\n            callback?.onDismiss()\n        } catch (e: IllegalArgumentException) {\n            e.printStackTrace()\n        }\n    }\n\n    interface ActionsCallback {\n        fun onSelect(state: Int)\n\n        fun onDismiss()\n    }\n\n    companion object {\n        const val STATE_SEEN = 0\n        const val STATE_UNSEEN = 1\n        const val STATE_IMPORT_MULTIPLE = 2\n        const val STATE_DOWNLOAD_MULTIPLE = 3\n        const val STATE_QUEUE_MULTIPLE = 4\n\n        fun newInstance(listSize: Int, callback: ActionsCallback): BottomActionsDialog {\n            val actionsDialog = BottomActionsDialog()\n            actionsDialog.callback = callback\n            actionsDialog.listSize = listSize\n            return actionsDialog\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/ChapterObjWrap.kt",
    "content": "package knf.kuma.animeinfo\r\n\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.AnimeObject\r\n\r\nclass ChapterObjWrap(val chapter: AnimeObject.WebInfo.AnimeChapter) {\r\n    var isSeen = CacheDB.INSTANCE.seenDAO().chapterIsSeen(chapter.aid,chapter.number)\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/CommentariesDialog.kt",
    "content": "package knf.kuma.animeinfo\n\nimport android.annotation.SuppressLint\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.webkit.WebView\nimport android.webkit.WebViewClient\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleObserver\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.OnLifecycleEvent\nimport androidx.lifecycle.lifecycleScope\nimport com.google.android.material.bottomsheet.BottomSheetDialogFragment\nimport knf.kuma.R\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.commons.urlEncode\nimport knf.kuma.databinding.LayCommentsBinding\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass CommentariesDialog : BottomSheetDialogFragment(), LifecycleObserver {\n    private var link: String = \"about:blank\"\n    private var version: String = \"1.0\"\n\n    @SuppressLint(\"SetJavaScriptEnabled\")\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val rootView = inflater.inflate(R.layout.lay_comments, container, false)\n        val binding = LayCommentsBinding.bind(rootView)\n        lifecycleScope.launch {\n            val html = withContext(Dispatchers.IO) { jsoupCookies(link).execute().body() }\n            val regex = Regex(\"this.page.url = '([^']*)';\\\\s+this.page.identifier = '([^']*)\").find(html)\n            val (target, identifier) = regex!!.destructured\n            val url = \"https://disqus.com/embed/comments/?base=default&f=https-myanimelist-net-2&t_i=$identifier&t_u=${urlEncode(target)}&s_o=default#version=$version\"\n            binding.webview.apply {\n                setInitialScale(1)\n                settings.useWideViewPort = true\n                settings.loadWithOverviewMode = true\n                settings.javaScriptEnabled = true\n                webViewClient = object : WebViewClient() {\n                    override fun onPageFinished(view: WebView?, url: String?) {\n                        super.onPageFinished(view, url)\n                        binding.loading.visibility = View.GONE\n                    }\n                }\n                loadUrl(url)\n            }\n        }\n        return rootView\n    }\n\n    fun setUpOwner(owner: LifecycleOwner) {\n        owner.lifecycle.addObserver(this)\n    }\n\n    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)\n    fun onPaused() {\n        safeDismiss()\n    }\n\n    fun safeShow(manager: FragmentManager, tag: String) {\n        try {\n            show(manager, tag)\n        } catch (e: Exception) {\n            //\n        }\n\n    }\n\n    private fun safeDismiss() {\n        try {\n            dismiss()\n        } catch (e: Exception) {\n            //\n        }\n    }\n\n    companion object {\n\n        fun show(fragment: Fragment, link: String, version: String) {\n            CommentariesDialog().apply {\n                this.link = link\n                this.version = version\n                setUpOwner(fragment)\n            }.safeShow(fragment.childFragmentManager, \"BottomSheetDialog\")\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/DownloadedObserver.kt",
    "content": "package knf.kuma.animeinfo\r\n\r\nimport knf.kuma.achievements.AchievementManager\r\nimport knf.kuma.commons.FileWrapper\r\nimport kotlinx.coroutines.CoroutineScope\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.Job\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.isActive\r\nimport kotlinx.coroutines.launch\r\n\r\nobject DownloadedObserver {\r\n    private var observer: Job = Job()\r\n\r\n    fun observe(scope: CoroutineScope, size: Int, fileWrapper: FileWrapper<*>) {\r\n        observer.cancel()\r\n        observer = Job()\r\n        scope.launch(Dispatchers.IO + observer) {\r\n            if (AchievementManager.isUnlocked(35) || size == fileWrapper.parentSize()) {\r\n                unlock()\r\n                return@launch\r\n            }\r\n            while (isActive) {\r\n                if (size == fileWrapper.parentSize()) {\r\n                    unlock()\r\n                    return@launch\r\n                }\r\n                delay(1500)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun unlock() {\r\n        AchievementManager.unlock(listOf(35))\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/fragments/ChaptersFragment.kt",
    "content": "package knf.kuma.animeinfo.fragments\n\nimport android.app.Activity\nimport android.content.Intent\nimport android.net.Uri\nimport android.os.Bundle\nimport android.util.Pair\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.documentfile.provider.DocumentFile\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.ViewModelProvider\nimport androidx.lifecycle.lifecycleScope\nimport knf.kuma.App\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.animeinfo.AnimeViewModel\nimport knf.kuma.animeinfo.ktx.fileName\nimport knf.kuma.animeinfo.viewholders.AnimeChaptersHolder\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.FileUtil\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.noCrashLet\nimport knf.kuma.commons.toast\nimport knf.kuma.custom.snackbar.SnackProgressBar\nimport knf.kuma.custom.snackbar.SnackProgressBarManager\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.download.MultipleDownloadManager\nimport knf.kuma.jobscheduler.DirUpdateWork\nimport knf.kuma.pojos.AnimeObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport xdroid.toaster.Toaster\nimport java.util.regex.Pattern\n\nclass ChaptersFragment : BottomFragment(), AnimeChaptersHolder.ChapHolderCallback {\n    private var holder: AnimeChaptersHolder? = null\n    private var moveFile: String? = null\n    private var chapters: MutableList<AnimeObject.WebInfo.AnimeChapter> = ArrayList()\n    private lateinit var snackManager: SnackProgressBarManager\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        activity?.let { activity ->\n            ViewModelProvider(activity).get(AnimeViewModel::class.java).liveData.observe(viewLifecycleOwner, Observer { animeObject ->\n                if (animeObject != null) {\n                    val chapters = animeObject.chapters\n                    chapters?.let {\n                        viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {\n                            when {\n                                checkIntegrity(chapters) -> {\n                                    if (PrefsUtil.isChapsAsc)\n                                        chapters.reverse()\n                                    holder?.setAdapter(this@ChaptersFragment, chapters)\n                                    holder?.goToChapter()\n                                }\n                                Network.isConnected -> {\n                                    DirUpdateWork.runNow()\n                                    \"Integridad de directorio comprometida, actualizando directorio...\".toast()\n                                }\n                            }\n                        }\n                    }\n                }\n            })\n        }\n    }\n\n    private fun checkIntegrity(list: List<AnimeObject.WebInfo.AnimeChapter>): Boolean {\n        return try {\n            list.isEmpty() || (list[0].aid != null && list[0].eid != null)\n        } catch (e: Exception) {\n            false\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(R.layout.recycler_chapters, container, false)\n        holder = AnimeChaptersHolder(view, this, this).also {\n            snackManager = SnackProgressBarManager(it.recyclerView)\n                    .setProgressBarColor(EAHelper.getThemeColor())\n                    .setOverlayLayoutAlpha(0.4f)\n                    .setOverlayLayoutColor(android.R.color.background_dark)\n        }\n        return view\n    }\n\n    override fun onReselect() {\n        holder?.smoothGoToChapter()\n    }\n\n    fun onMove(to: String) {\n        try {\n            this.moveFile = to\n            startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT)\n                    .addCategory(Intent.CATEGORY_OPENABLE)\n                    .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)\n                    .setType(\"video/mp4\"), 55698)\n        } catch (e: Exception) {\n            Toaster.toast(\"Error al importar\")\n        }\n    }\n\n    override fun onImportMultiple(chapters: MutableList<AnimeObject.WebInfo.AnimeChapter>) {\n        when (chapters.size) {\n            0 -> Toaster.toast(\"No se puede importar ningun episodio\")\n            1 -> {\n                this.moveFile = chapters[0].fileName\n                onMove(chapters[0].fileName)\n            }\n            else -> {\n                try {\n                    this.chapters = chapters\n                    startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT)\n                            .addCategory(Intent.CATEGORY_OPENABLE)\n                            .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)\n                            .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)\n                            .setType(\"video/mp4\"), 55698)\n                } catch (e: Exception) {\n                    Toaster.toast(\"Error al importar\")\n                }\n            }\n        }\n    }\n\n    override fun onDownloadMultiple(addQueue: Boolean, chapters: List<AnimeObject.WebInfo.AnimeChapter>) {\n        holder?.let { holder ->\n            MultipleDownloadManager.startDownload(this, holder.recyclerView, chapters.sortedBy { noCrashLet(9999) { \"(\\\\d+)\".toRegex().findAll(it.number).last().destructured.component1().toInt() } }, addQueue)\n        }\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        if (resultCode == Activity.RESULT_OK)\n            try {\n                holder?.adapter?.isImporting = true\n                if (data?.clipData == null || data.clipData?.itemCount ?: 0 == 0) {\n                    if (moveFile == null && chapters.size > 0) {\n                        val uri = data?.data\n                        val file = DocumentFile.fromSingleUri(App.context, uri ?: Uri.EMPTY)\n                        val last = getLastNumber(file?.name)\n                        moveFile = findChapter(last)?.fileName\n                    }\n                    val snackbar = SnackProgressBar(SnackProgressBar.TYPE_HORIZONTAL, \"Importando...\")\n                            .setIsIndeterminate(false)\n                            .setProgressMax(100)\n                            .setShowProgressPercentage(true)\n                    snackManager.show(snackbar, SnackProgressBarManager.LENGTH_INDEFINITE)\n                    FileUtil.moveFile(App.context.contentResolver, data?.data, FileAccessHelper.getOutputStream(moveFile)).observe(this, Observer { pair ->\n                        try {\n                            if (pair != null) {\n                                if (pair.second) {\n                                    if (pair.first == -1) {\n                                        Toaster.toast(\"Error al importar\")\n                                        FileAccessHelper.delete(moveFile)\n                                    } else\n                                        Toaster.toast(\"Importado exitosamente\")\n                                    holder?.adapter?.notifyDataSetChanged()\n                                    moveFile = null\n                                    snackManager.dismiss()\n                                    holder?.adapter?.isImporting = false\n                                } else\n                                    snackManager.setProgress(pair.first)\n                            }\n                        } catch (e: Exception) {\n                            Toaster.toast(\"Error al importar\")\n                        }\n                    })\n                } else {\n                    val snackbar = SnackProgressBar(SnackProgressBar.TYPE_HORIZONTAL, \"Importando...\")\n                            .setIsIndeterminate(false)\n                            .setProgressMax(100)\n                            .setShowProgressPercentage(true)\n                    snackManager.show(snackbar, SnackProgressBarManager.LENGTH_INDEFINITE)\n                    val moveRequests = ArrayList<Pair<Uri, String>>()\n                    val count = data.clipData?.itemCount ?: 0\n                    for (i in 0 until count) {\n                        try {\n                            val uri = data.clipData?.getItemAt(i)?.uri ?: Uri.EMPTY\n                            val file = DocumentFile.fromSingleUri(App.context, uri)\n                            val last = getLastNumber(file?.name)\n                            moveRequests.add(Pair(uri, findChapter(last)?.fileName ?: \"\"))\n                        } catch (e: Exception) {\n                            //\n                        }\n                    }\n                    if (moveRequests.size == 0) {\n                        Toaster.toast(\"No se pudo inferir el numero de los episodios\")\n                        snackManager.dismiss()\n                    } else {\n                        FileUtil.moveFiles(App.context.contentResolver, moveRequests).observe(this@ChaptersFragment, Observer { pairBooleanPair ->\n                            try {\n                                if (pairBooleanPair != null) {\n                                    if (pairBooleanPair.second) {\n                                        Toaster.toast(\"Importados ${pairBooleanPair.first.second} archivos exitosamente\")\n                                        holder?.adapter?.notifyDataSetChanged()\n                                        chapters = ArrayList()\n                                        snackManager.dismiss()\n                                        holder?.adapter?.isImporting = false\n                                    } else {\n                                        snackbar.setMessage(pairBooleanPair.first.first)\n                                        snackManager.updateTo(snackbar)\n                                        snackManager.setProgress(pairBooleanPair.first.second)\n                                    }\n                                }\n                            } catch (e: Exception) {\n                                Toaster.toast(\"Error al importar\")\n                            }\n                        })\n                    }\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                Toaster.toast(\"Error al importar\")\n            }\n\n    }\n\n    private fun findChapter(num: String?): AnimeObject.WebInfo.AnimeChapter? {\n        for (c in ArrayList<AnimeObject.WebInfo.AnimeChapter>(chapters)) {\n            if (c.number == \"Episodio $num\") {\n                chapters.remove(c)\n                return c\n            }\n        }\n        return null\n    }\n\n    private fun getLastNumber(name: String?): String? {\n        if (name.isNullOrEmpty()) return null\n        val matcher = Pattern.compile(\".*[_ ]0?(\\\\d+)[_ ].*$|0?(\\\\d+)$\").matcher(name.replace(\".mp4\", \"\"))\n        var last: String? = null\n        while (matcher.find()) {\n            try {\n                last = matcher.group(1)\n                if (last == null)\n                    last = matcher.group(2)\n            } catch (e: Exception) {\n                try {\n                    last = matcher.group(2)\n                } catch (e1: Exception) {\n                    e1.printStackTrace()\n                }\n            }\n        }\n        return last\n    }\n\n    companion object {\n\n        fun get(): ChaptersFragment {\n            return ChaptersFragment()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/fragments/ChaptersFragmentMaterial.kt",
    "content": "package knf.kuma.animeinfo.fragments\n\nimport android.app.Activity\nimport android.content.Intent\nimport android.net.Uri\nimport android.os.Bundle\nimport android.util.Pair\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.documentfile.provider.DocumentFile\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.ViewModelProvider\nimport androidx.lifecycle.lifecycleScope\nimport knf.kuma.App\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.animeinfo.AnimeViewModel\nimport knf.kuma.animeinfo.ktx.fileName\nimport knf.kuma.animeinfo.viewholders.AnimeChaptersMaterialHolder\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.FileUtil\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.noCrashLet\nimport knf.kuma.commons.toast\nimport knf.kuma.custom.snackbar.SnackProgressBar\nimport knf.kuma.custom.snackbar.SnackProgressBarManager\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.download.MultipleDownloadManager\nimport knf.kuma.jobscheduler.DirUpdateWork\nimport knf.kuma.pojos.AnimeObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport xdroid.toaster.Toaster\nimport java.util.regex.Pattern\n\nclass ChaptersFragmentMaterial : BottomFragment(), AnimeChaptersMaterialHolder.ChapHolderCallback {\n    private var holder: AnimeChaptersMaterialHolder? = null\n    private var moveFile: String? = null\n    private var chapters: MutableList<AnimeObject.WebInfo.AnimeChapter> = ArrayList()\n    private lateinit var snackManager: SnackProgressBarManager\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        activity?.let { activity ->\n            ViewModelProvider(activity).get(AnimeViewModel::class.java).liveData.observe(viewLifecycleOwner, Observer { animeObject ->\n                if (animeObject != null) {\n                    val chapters = animeObject.chapters\n                    chapters?.let {\n                        viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {\n                            when {\n                                checkIntegrity(chapters) -> {\n                                    if (PrefsUtil.isChapsAsc)\n                                        chapters.reverse()\n                                    holder?.setAdapter(this@ChaptersFragmentMaterial, chapters)\n                                    delay(1000)\n                                    holder?.goToChapter()\n                                }\n                                Network.isConnected -> {\n                                    DirUpdateWork.runNow()\n                                    \"Integridad de directorio comprometida, actualizando directorio...\".toast()\n                                }\n                            }\n                        }\n                    }\n                }\n            })\n        }\n    }\n\n    private fun checkIntegrity(list: List<AnimeObject.WebInfo.AnimeChapter>): Boolean {\n        return try {\n            list.isEmpty() || (list[0].aid != null && list[0].eid != null)\n        } catch (e: Exception) {\n            false\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(R.layout.recycler_chapters, container, false)\n        holder = AnimeChaptersMaterialHolder(view, this, this).also {\n            snackManager = SnackProgressBarManager(it.recyclerView)\n                    .setProgressBarColor(EAHelper.getThemeColor())\n                    .setOverlayLayoutAlpha(0.4f)\n                    .setOverlayLayoutColor(android.R.color.background_dark)\n        }\n        return view\n    }\n\n    override fun onReselect() {\n        holder?.smoothGoToChapter()\n    }\n\n    fun onMove(to: String) {\n        this.moveFile = to\n        startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT)\n                .addCategory(Intent.CATEGORY_OPENABLE)\n                .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)\n                .setType(\"video/mp4\"), 55698)\n    }\n\n    override fun onImportMultiple(chapters: MutableList<AnimeObject.WebInfo.AnimeChapter>) {\n        when (chapters.size) {\n            0 -> Toaster.toast(\"No se puede importar ningun episodio\")\n            1 -> {\n                this.moveFile = chapters[0].fileName\n                onMove(chapters[0].fileName)\n            }\n            else -> {\n                this.chapters = chapters\n                startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT)\n                        .addCategory(Intent.CATEGORY_OPENABLE)\n                        .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)\n                        .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)\n                        .setType(\"video/mp4\"), 55698)\n            }\n        }\n    }\n\n    override fun onDownloadMultiple(addQueue: Boolean, chapters: List<AnimeObject.WebInfo.AnimeChapter>) {\n        holder?.let { holder ->\n            MultipleDownloadManager.startDownload(this, holder.recyclerView, chapters.sortedBy { noCrashLet(9999) { \"(\\\\d+)\".toRegex().findAll(it.number).last().destructured.component1().toInt() } }, addQueue)\n        }\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        if (resultCode == Activity.RESULT_OK)\n            try {\n                holder?.adapter?.isImporting = true\n                if (data?.clipData == null || data.clipData?.itemCount ?: 0 == 0) {\n                    if (moveFile == null && chapters.size > 0) {\n                        val uri = data?.data\n                        val file = DocumentFile.fromSingleUri(App.context, uri ?: Uri.EMPTY)\n                        val last = getLastNumber(file?.name)\n                        moveFile = findChapter(last)?.fileName\n                    }\n                    val snackbar = SnackProgressBar(SnackProgressBar.TYPE_HORIZONTAL, \"Importando...\")\n                            .setIsIndeterminate(false)\n                            .setProgressMax(100)\n                            .setShowProgressPercentage(true)\n                    snackManager.show(snackbar, SnackProgressBarManager.LENGTH_INDEFINITE)\n                    FileUtil.moveFile(App.context.contentResolver, data?.data, FileAccessHelper.getOutputStream(moveFile)).observe(this, Observer { pair ->\n                        try {\n                            if (pair != null) {\n                                if (pair.second) {\n                                    if (pair.first == -1) {\n                                        Toaster.toast(\"Error al importar\")\n                                        FileAccessHelper.delete(moveFile)\n                                    } else\n                                        Toaster.toast(\"Importado exitosamente\")\n                                    holder?.adapter?.notifyDataSetChanged()\n                                    moveFile = null\n                                    snackManager.dismiss()\n                                    holder?.adapter?.isImporting = false\n                                } else\n                                    snackManager.setProgress(pair.first)\n                            }\n                        } catch (e: Exception) {\n                            Toaster.toast(\"Error al importar\")\n                        }\n                    })\n                } else {\n                    val snackbar = SnackProgressBar(SnackProgressBar.TYPE_HORIZONTAL, \"Importando...\")\n                            .setIsIndeterminate(false)\n                            .setProgressMax(100)\n                            .setShowProgressPercentage(true)\n                    snackManager.show(snackbar, SnackProgressBarManager.LENGTH_INDEFINITE)\n                    val moveRequests = ArrayList<Pair<Uri, String>>()\n                    val count = data.clipData?.itemCount ?: 0\n                    for (i in 0 until count) {\n                        try {\n                            val uri = data.clipData?.getItemAt(i)?.uri ?: Uri.EMPTY\n                            val file = DocumentFile.fromSingleUri(App.context, uri)\n                            val last = getLastNumber(file?.name)\n                            moveRequests.add(Pair(uri, findChapter(last)?.fileName ?: \"\"))\n                        } catch (e: Exception) {\n                            //\n                        }\n                    }\n                    if (moveRequests.size == 0) {\n                        Toaster.toast(\"No se pudo inferir el numero de los episodios\")\n                        snackManager.dismiss()\n                    } else {\n                        FileUtil.moveFiles(App.context.contentResolver, moveRequests).observe(this@ChaptersFragmentMaterial, Observer { pairBooleanPair ->\n                            try {\n                                if (pairBooleanPair != null) {\n                                    if (pairBooleanPair.second) {\n                                        Toaster.toast(\"Importados ${pairBooleanPair.first.second} archivos exitosamente\")\n                                        holder?.adapter?.notifyDataSetChanged()\n                                        chapters = ArrayList()\n                                        snackManager.dismiss()\n                                        holder?.adapter?.isImporting = false\n                                    } else {\n                                        snackbar.setMessage(pairBooleanPair.first.first)\n                                        snackManager.updateTo(snackbar)\n                                        snackManager.setProgress(pairBooleanPair.first.second)\n                                    }\n                                }\n                            } catch (e: Exception) {\n                                Toaster.toast(\"Error al importar\")\n                            }\n                        })\n                    }\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                Toaster.toast(\"Error al importar\")\n            }\n\n    }\n\n    private fun findChapter(num: String?): AnimeObject.WebInfo.AnimeChapter? {\n        for (c in ArrayList<AnimeObject.WebInfo.AnimeChapter>(chapters)) {\n            if (c.number == \"Episodio $num\") {\n                chapters.remove(c)\n                return c\n            }\n        }\n        return null\n    }\n\n    private fun getLastNumber(name: String?): String? {\n        if (name.isNullOrEmpty()) return null\n        val matcher = Pattern.compile(\".*[_ ]0?(\\\\d+)[_ ].*$|0?(\\\\d+)$\").matcher(name.replace(\".mp4\", \"\"))\n        var last: String? = null\n        while (matcher.find()) {\n            try {\n                last = matcher.group(1)\n                if (last == null)\n                    last = matcher.group(2)\n            } catch (e: Exception) {\n                try {\n                    last = matcher.group(2)\n                } catch (e1: Exception) {\n                    e1.printStackTrace()\n                }\n            }\n        }\n        return last\n    }\n\n    companion object {\n\n        fun get(): ChaptersFragmentMaterial {\n            return ChaptersFragmentMaterial()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/fragments/DetailsFragment.kt",
    "content": "package knf.kuma.animeinfo.fragments\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.Observer\nimport knf.kuma.R\nimport knf.kuma.animeinfo.AnimeViewModel\nimport knf.kuma.animeinfo.viewholders.AnimeDetailsHolder\n\nclass DetailsFragment : Fragment() {\n    private var holder: AnimeDetailsHolder? = null\n    private val viewModel: AnimeViewModel by activityViewModels()\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        viewModel.liveData.observe(viewLifecycleOwner, Observer { animeObject ->\n            if (animeObject != null)\n                holder?.populate(this@DetailsFragment, animeObject)\n        })\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return try {\n            val view = inflater.inflate(R.layout.fragment_anime_details, container, false)\n            holder = AnimeDetailsHolder(view)\n            view\n        } catch (e: ExceptionInInitializerError) {\n            null\n        }\n    }\n\n    companion object {\n\n        fun get(): DetailsFragment {\n            return DetailsFragment()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/fragments/DetailsFragmentMaterial.kt",
    "content": "package knf.kuma.animeinfo.fragments\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.Observer\nimport knf.kuma.R\nimport knf.kuma.animeinfo.AnimeViewModel\nimport knf.kuma.animeinfo.viewholders.AnimeDetailsMaterialHolder\n\nclass DetailsFragmentMaterial : Fragment() {\n    private var holder: AnimeDetailsMaterialHolder? = null\n    private val viewModel: AnimeViewModel by activityViewModels()\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        viewModel.liveData.observe(viewLifecycleOwner, Observer { animeObject ->\n            if (animeObject != null)\n                holder?.populate(this@DetailsFragmentMaterial, animeObject)\n        })\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return try {\n            val view = inflater.inflate(R.layout.fragment_anime_details_material, container, false)\n            holder = AnimeDetailsMaterialHolder(view)\n            view\n        } catch (e: ExceptionInInitializerError) {\n            null\n        }\n    }\n\n    companion object {\n\n        fun get(): DetailsFragmentMaterial {\n            return DetailsFragmentMaterial()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/img/ActivityImgFull.kt",
    "content": "package knf.kuma.animeinfo.img\n\nimport androidx.activity.addCallback\nimport android.os.Bundle\nimport android.view.ViewGroup\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updateLayoutParams\nimport androidx.preference.PreferenceManager\nimport com.google.android.material.snackbar.Snackbar\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.httpJsoup\nimport knf.kuma.commons.iterator\nimport knf.kuma.commons.safeDismiss\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.databinding.LayoutImgBigBaseBinding\nimport org.jetbrains.anko.doAsync\nimport org.json.JSONObject\nimport java.net.URLEncoder\nimport java.util.Locale\n\nclass ActivityImgFull : GenericActivity() {\n\n    private val keyTitle = \"title\"\n    private val binding by lazy { LayoutImgBigBaseBinding.inflate(layoutInflater) }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(binding.root)\n        binding.pager.adapter = ImgPagerAdapter(supportFragmentManager, intent.getStringExtra(keyTitle)\n                ?: \"\", listOf(intent.dataString ?: \"\"))\n        binding.indicator.setViewPager(binding.pager)\n        ViewCompat.setOnApplyWindowInsetsListener(binding.indicator) { _, insets ->\n            binding.indicator.updateLayoutParams<ViewGroup.MarginLayoutParams> {\n                topMargin = topMargin + insets.getInsets(WindowInsetsCompat.Type.statusBars()).top\n            }\n            WindowInsetsCompat.CONSUMED\n        }\n        searchInMAL()\n        onBackPressedDispatcher.addCallback(this) { supportFinishAfterTransition() }\n    }\n\n    private fun searchInMAL() {\n        if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(\"scale_img\", true))\n            doAsync {\n                val snackbar = binding.pager.showSnackbar(\"Buscando mejores imagenes...\", Snackbar.LENGTH_INDEFINITE)\n                try {\n                    val title = intent.getStringExtra(keyTitle)\n                    val response = httpJsoup(\"https://api.jikan.moe/v4/anime?q=${URLEncoder.encode(title, \"utf-8\")}&page=1\")\n                    if (response.statusCode() != 200)\n                        throw IllegalStateException(\"Response code: ${response.statusCode()}\")\n                    val results = JSONObject(\n                        response.body()\n                            ?: \"{}\"\n                    ).getJSONArray(\"data\")\n                    for (i in 0 until results.length()) {\n                        val json = results.getJSONObject(i)\n                        val name = json.getJSONArray(\"titles\").getJSONObject(0).getString(\"title\").lowercase(Locale.getDefault())\n                        if (title?.lowercase(Locale.getDefault()) == name) {\n                            val list = mutableListOf<String>()\n                            //list.add(json.getString(\"image_url\"))\n                            try {\n                                val picturesResponse = httpJsoup(\"https://api.jikan.moe/v4/anime/${json.getString(\"mal_id\")}/pictures\")\n                                if (picturesResponse.statusCode() != 200)\n                                    throw IllegalStateException(\"Response code: ${picturesResponse.statusCode()}\")\n                                val picturesArray = JSONObject(\n                                    picturesResponse.body()\n                                        ?: \"{}\"\n                                ).getJSONArray(\"data\")\n                                for (item in picturesArray) {\n                                    list.add(item.getJSONObject(\"jpg\").getString(\"large_image_url\"))\n                                }\n                            } catch (e: Exception) {\n                                e.printStackTrace()\n                            }\n                            doOnUI {\n                                binding.pager.adapter = ImgPagerAdapter(supportFragmentManager, intent.getStringExtra(keyTitle)\n                                        ?: \"\", list)\n                                binding.indicator.setViewPager(binding.pager)\n                            }\n                            break\n                        }\n                    }\n                    snackbar.safeDismiss()\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                    snackbar.safeDismiss()\n                }\n            }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/img/ImgFullFragment.kt",
    "content": "package knf.kuma.animeinfo.img\r\n\r\nimport android.content.Intent\r\nimport android.graphics.Bitmap\r\nimport android.net.Uri\r\nimport android.os.Bundle\r\nimport android.provider.MediaStore\r\nimport android.view.MenuItem\r\nimport android.view.View\r\nimport android.widget.ProgressBar\r\nimport androidx.appcompat.widget.PopupMenu\r\nimport androidx.fragment.app.Fragment\r\nimport com.bumptech.glide.Glide\r\nimport com.bumptech.glide.load.DataSource\r\nimport com.bumptech.glide.load.engine.GlideException\r\nimport com.bumptech.glide.request.RequestListener\r\nimport com.bumptech.glide.request.target.Target\r\nimport com.google.android.material.snackbar.Snackbar\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.createSnackbar\r\nimport knf.kuma.commons.safeDismiss\r\nimport knf.kuma.commons.showSnackbar\r\nimport knf.kuma.databinding.LayoutImgBigBinding\r\nimport org.jetbrains.anko.doAsync\r\nimport xdroid.toaster.Toaster\r\nimport java.io.FileOutputStream\r\n\r\nclass ImgFullFragment : Fragment(R.layout.layout_img_big), PopupMenu.OnMenuItemClickListener {\r\n\r\n    private var bitmap: Bitmap? = null\r\n    private val keyTitle = \"title\"\r\n    private lateinit var binding: LayoutImgBigBinding\r\n\r\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\r\n        super.onViewCreated(view, savedInstanceState)\r\n        binding = LayoutImgBigBinding.bind(view)\r\n        Glide.with(this).asBitmap().load(arguments?.getString(\"img\")).listener(\r\n            object : RequestListener<Bitmap> {\r\n                override fun onLoadFailed(\r\n                    e: GlideException?,\r\n                    model: Any?,\r\n                    target: Target<Bitmap?>,\r\n                    isFirstResource: Boolean\r\n                ): Boolean {\r\n                    binding.error.visibility = View.VISIBLE\r\n                    return false\r\n                }\r\n\r\n                override fun onResourceReady(\r\n                    resource: Bitmap,\r\n                    model: Any,\r\n                    target: Target<Bitmap?>?,\r\n                    dataSource: DataSource,\r\n                    isFirstResource: Boolean\r\n                ): Boolean {\r\n                    bitmap = resource\r\n                    return false\r\n                }\r\n            }\r\n        ).into(binding.img)\r\n        binding.img.setOnLongClickListener {\r\n            if (bitmap != null) {\r\n                context?.let {\r\n                    val popupMenu = PopupMenu(it, binding.anchor)\r\n                    popupMenu.inflate(R.menu.menu_img)\r\n                    popupMenu.setOnMenuItemClickListener(this@ImgFullFragment)\r\n                    popupMenu.show()\r\n                }\r\n            }\r\n            true\r\n        }\r\n    }\r\n\r\n    override fun onMenuItemClick(item: MenuItem): Boolean {\r\n        when (item.itemId) {\r\n            R.id.download -> {\r\n                try {\r\n                    val i = Intent(Intent.ACTION_CREATE_DOCUMENT)\r\n                            .addCategory(Intent.CATEGORY_OPENABLE)\r\n                            .setType(\"image/jpg\")\r\n                            .putExtra(Intent.EXTRA_TITLE, arguments?.getString(keyTitle) + \".jpg\")\r\n                    startActivityForResult(i, 556)\r\n                } catch (e: Exception) {\r\n                    Toaster.toast(\"Error al descargar\")\r\n                }\r\n            }\r\n            R.id.share -> try {\r\n                val intent = Intent(Intent.ACTION_SEND)\r\n                        .setType(\"image/*\")\r\n                        .putExtra(Intent.EXTRA_TEXT, arguments?.getString(keyTitle))\r\n                        .putExtra(Intent.EXTRA_STREAM, Uri.parse(MediaStore.Images.Media.insertImage(context?.contentResolver, bitmap, \"\", \"\")))\r\n                startActivity(Intent.createChooser(intent, \"Compartir...\"))\r\n            } catch (e: Exception) {\r\n                Toaster.toast(\"Error al compartir\")\r\n            }\r\n        }\r\n        return true\r\n    }\r\n\r\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\r\n        super.onActivityResult(requestCode, resultCode, data)\r\n        val snackbar = binding.img.createSnackbar(\"Guardando...\", Snackbar.LENGTH_INDEFINITE)\r\n        val progressBar = ProgressBar(context).also {\r\n            it.isIndeterminate = true\r\n        }\r\n        (snackbar.view as Snackbar.SnackbarLayout).addView(progressBar)\r\n        snackbar.show()\r\n        doAsync {\r\n            try {\r\n                val pfd = context?.contentResolver?.openFileDescriptor(data?.data ?: Uri.EMPTY, \"w\")\r\n                pfd?.let {\r\n                    val fileOutputStream = FileOutputStream(it.fileDescriptor)\r\n                    bitmap?.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream)\r\n                    fileOutputStream.close()\r\n                    it.close()\r\n                    snackbar.safeDismiss()\r\n                    binding.img.showSnackbar(\"Imagen guardada!\")\r\n                }\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n                snackbar.safeDismiss()\r\n                binding.img.showSnackbar(\"Error al guardar imagen\")\r\n            }\r\n        }\r\n    }\r\n\r\n\r\n    companion object {\r\n        fun create(img: String, title: String): ImgFullFragment {\r\n            val fragment = ImgFullFragment()\r\n            fragment.arguments = Bundle().apply {\r\n                putString(\"img\", img)\r\n                putString(\"title\", title)\r\n            }\r\n            return fragment\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/img/ImgPagerAdapter.kt",
    "content": "package knf.kuma.animeinfo.img\r\n\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.fragment.app.FragmentManager\r\nimport androidx.fragment.app.FragmentPagerAdapter\r\n\r\nclass ImgPagerAdapter(fm: FragmentManager, private val title: String, private val list: List<String>) : FragmentPagerAdapter(fm) {\r\n    override fun getItem(position: Int): Fragment = ImgFullFragment.create(list[position], title)\r\n\r\n    override fun getCount(): Int = list.size\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/ktx/Extensions.kt",
    "content": "package knf.kuma.animeinfo.ktx\r\n\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.pojos.AnimeObject\r\n\r\nval AnimeObject.WebInfo.AnimeChapter.epTitle: String get() = name + number.substring(number.lastIndexOf(\" \"))\r\n\r\nval AnimeObject.WebInfo.AnimeChapter.fileName: String\r\n    get() = if (PrefsUtil.saveWithName)\r\n        eid + \"$\" + PatternUtil.getFileName(link)\r\n    else\r\n        eid + \"$\" + aid + \"-\" + number.substring(number.lastIndexOf(\" \") + 1) + \".mp4\"\r\n\r\nval AnimeObject.WebInfo.AnimeChapter.filePath: String\r\n    get() = if (PrefsUtil.saveWithName)\r\n        \"$\" + PatternUtil.getFileName(link)\r\n    else\r\n        \"$\" + aid + \"-\" + number.substring(number.lastIndexOf(\" \") + 1) + \".mp4\""
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/viewholders/AnimeActivityHolder.kt",
    "content": "package knf.kuma.animeinfo.viewholders\n\nimport android.content.Intent\nimport android.graphics.drawable.Drawable\nimport android.net.Uri\nimport android.view.View\nimport android.widget.ImageView\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.appcompat.widget.Toolbar\nimport androidx.core.app.ActivityOptionsCompat\nimport androidx.viewpager.widget.ViewPager\nimport com.google.android.material.appbar.AppBarLayout\nimport com.google.android.material.appbar.CollapsingToolbarLayout\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\nimport com.google.android.material.tabs.TabLayout\nimport knf.kuma.R\nimport knf.kuma.animeinfo.AnimePagerAdapter\nimport knf.kuma.animeinfo.img.ActivityImgFull\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.forceHide\nimport knf.kuma.commons.load\nimport org.jetbrains.anko.sdk27.coroutines.onClick\n\n\nclass AnimeActivityHolder(val activity: AppCompatActivity) {\n    val appBarLayout: AppBarLayout by bind(activity, R.id.appBar)\n    private val collapsingToolbarLayout: CollapsingToolbarLayout by bind(activity, R.id.collapsingToolbar)\n    val imageView: ImageView by bind(activity, R.id.img)\n    val toolbar: Toolbar by bind(activity, R.id.toolbar)\n    private val tabLayout: TabLayout by bind(activity, R.id.tabs)\n    val pager: ViewPager by bind(activity, R.id.pager)\n    private val fab: FloatingActionButton by bind(activity, R.id.fab)\n\n    private val intent: Intent = activity.intent\n    private val animePagerAdapter: AnimePagerAdapter = AnimePagerAdapter(activity.supportFragmentManager)\n    private val innerInterface: Interface = activity as Interface\n\n    private val drawableHeartFull: Drawable by lazy { activity.getDrawable(R.drawable.heart_full) as Drawable }\n    private val drawableHeartEmpty: Drawable by lazy { activity.getDrawable(R.drawable.heart_empty) as Drawable }\n\n    init {\n        //fab.visibility = View.INVISIBLE\n        fab.isEnabled = false\n        populate(activity)\n        pager.offscreenPageLimit = 2\n        pager.adapter = animePagerAdapter\n        tabLayout.setupWithViewPager(pager)\n        pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {\n            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {\n\n            }\n\n            override fun onPageSelected(position: Int) {\n                appBarLayout.setExpanded(position == 0, true)\n            }\n\n            override fun onPageScrollStateChanged(state: Int) {\n\n            }\n        })\n        if (activity.intent.getBooleanExtra(\"isRecord\", false))\n            pager.setCurrentItem(1, true)\n        tabLayout.addOnTabSelectedListener(object : TabLayout.ViewPagerOnTabSelectedListener(pager) {\n            override fun onTabReselected(tab: TabLayout.Tab?) {\n                if (tab?.position == 1) {\n                    appBarLayout.setExpanded(false, true)\n                    animePagerAdapter.onChaptersReselect()\n                }\n            }\n        })\n        fab.onClick { innerInterface.onFabClicked(fab) }\n        imageView.onClick { innerInterface.onImgClicked(imageView) }\n    }\n\n    fun setTitle(title: String) {\n        collapsingToolbarLayout.post { collapsingToolbarLayout.title = title }\n    }\n\n    fun loadImg(link: String, listener: View.OnClickListener) {\n        imageView.post {\n            imageView.load(link)\n            imageView.setOnClickListener(listener)\n        }\n    }\n\n    fun setFABState(isFav: Boolean) {\n        activity.doOnUI {\n            fab.setImageDrawable(if (isFav) drawableHeartFull else drawableHeartEmpty)\n            fab.invalidate()\n        }\n    }\n\n    fun showFAB() {\n        activity.doOnUI {\n            fab.isEnabled = true\n            //fab.show()\n        }\n    }\n\n    fun hideFABForce() {\n        fab.isEnabled = false\n        fab.forceHide()\n    }\n\n    private fun populate(activity: AppCompatActivity) {\n        val title = intent.getStringExtra(\"title\")\n        if (title != null)\n            collapsingToolbarLayout.title = title\n        val img = intent.getStringExtra(\"img\")\n        if (img != null) {\n            imageView.load(img)\n            imageView.setOnClickListener { activity.startActivity(Intent(activity, ActivityImgFull::class.java).setData(Uri.parse(img)).putExtra(\"title\", title), ActivityOptionsCompat.makeSceneTransitionAnimation(activity, imageView, \"img\").toBundle()) }\n        }\n    }\n\n    interface Interface {\n        fun onFabClicked(actionButton: FloatingActionButton)\n\n        fun onImgClicked(imageView: ImageView)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/viewholders/AnimeActivityMaterialHolder.kt",
    "content": "package knf.kuma.animeinfo.viewholders\n\nimport android.content.Intent\nimport android.graphics.drawable.Drawable\nimport android.net.Uri\nimport android.view.View\nimport android.widget.ImageView\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.appcompat.widget.Toolbar\nimport androidx.core.app.ActivityOptionsCompat\nimport androidx.viewpager.widget.ViewPager\nimport com.google.android.material.appbar.AppBarLayout\nimport com.google.android.material.appbar.CollapsingToolbarLayout\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\nimport com.google.android.material.tabs.TabLayout\nimport knf.kuma.R\nimport knf.kuma.animeinfo.AnimePagerAdapterMaterial\nimport knf.kuma.animeinfo.img.ActivityImgFull\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.forceHide\nimport knf.kuma.commons.load\nimport org.jetbrains.anko.sdk27.coroutines.onClick\n\n\nclass AnimeActivityMaterialHolder(val activity: AppCompatActivity) {\n    val appBarLayout: AppBarLayout by bind(activity, R.id.appBar)\n    private val collapsingToolbarLayout: CollapsingToolbarLayout by bind(activity, R.id.collapsingToolbar)\n    val imageView: ImageView by bind(activity, R.id.img)\n    val toolbar: Toolbar by bind(activity, R.id.toolbar)\n    private val tabLayout: TabLayout by bind(activity, R.id.tabs)\n    val pager: ViewPager by bind(activity, R.id.pager)\n    private val fab: FloatingActionButton by bind(activity, R.id.fab)\n\n    private val intent: Intent = activity.intent\n    private val animePagerAdapter: AnimePagerAdapterMaterial = AnimePagerAdapterMaterial(activity.supportFragmentManager)\n    private val innerInterface: Interface = activity as Interface\n\n    private val drawableHeartFull: Drawable by lazy { activity.getDrawable(R.drawable.heart_full) as Drawable }\n    private val drawableHeartEmpty: Drawable by lazy { activity.getDrawable(R.drawable.heart_empty) as Drawable }\n\n    init {\n        //fab.visibility = View.INVISIBLE\n        fab.isEnabled = false\n        populate(activity)\n        pager.offscreenPageLimit = 2\n        pager.adapter = animePagerAdapter\n        tabLayout.setupWithViewPager(pager)\n        pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {\n            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {\n\n            }\n\n            override fun onPageSelected(position: Int) {\n                appBarLayout.setExpanded(position == 0, true)\n            }\n\n            override fun onPageScrollStateChanged(state: Int) {\n\n            }\n        })\n        if (activity.intent.getBooleanExtra(\"isRecord\", false))\n            pager.setCurrentItem(1, true)\n        tabLayout.addOnTabSelectedListener(object : TabLayout.ViewPagerOnTabSelectedListener(pager) {\n            override fun onTabReselected(tab: TabLayout.Tab?) {\n                if (tab?.position == 1) {\n                    appBarLayout.setExpanded(false, true)\n                    animePagerAdapter.onChaptersReselect()\n                }\n            }\n        })\n        fab.onClick { innerInterface.onFabClicked(fab) }\n        imageView.onClick { innerInterface.onImgClicked(imageView) }\n    }\n\n    fun setTitle(title: String) {\n        collapsingToolbarLayout.post { collapsingToolbarLayout.title = title }\n    }\n\n    fun loadImg(link: String, listener: View.OnClickListener) {\n        imageView.post {\n            imageView.load(link)\n            imageView.setOnClickListener(listener)\n        }\n    }\n\n    fun setFABState(isFav: Boolean) {\n        activity.doOnUI {\n            fab.setImageDrawable(if (isFav) drawableHeartFull else drawableHeartEmpty)\n            fab.invalidate()\n        }\n    }\n\n    fun showFAB() {\n        activity.doOnUI {\n            fab.isEnabled = true\n            //fab.show()\n        }\n    }\n\n    fun hideFABForce() {\n        fab.isEnabled = false\n        fab.forceHide()\n    }\n\n    private fun populate(activity: AppCompatActivity) {\n        val title = intent.getStringExtra(\"title\")\n        if (title != null)\n            collapsingToolbarLayout.title = title\n        val img = intent.getStringExtra(\"img\")\n        if (img != null) {\n            imageView.load(img)\n            imageView.setOnClickListener { activity.startActivity(Intent(activity, ActivityImgFull::class.java).setData(Uri.parse(img)).putExtra(\"title\", title), ActivityOptionsCompat.makeSceneTransitionAnimation(activity, imageView, \"img\").toBundle()) }\n        }\n    }\n\n    interface Interface {\n        fun onFabClicked(actionButton: FloatingActionButton)\n\n        fun onImgClicked(imageView: ImageView)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/viewholders/AnimeChaptersHolder.kt",
    "content": "package knf.kuma.animeinfo.viewholders\n\nimport android.net.Uri\nimport android.view.View\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.snackbar.Snackbar\nimport com.michaelflisar.dragselectrecyclerview.DragSelectTouchListener\nimport com.michaelflisar.dragselectrecyclerview.DragSelectionProcessor\nimport knf.kuma.R\nimport knf.kuma.animeinfo.AnimeChaptersAdapter\nimport knf.kuma.animeinfo.BottomActionsDialog\nimport knf.kuma.animeinfo.ChapterObjWrap\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeDismiss\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.custom.CenterLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.SeenObject\nimport knf.kuma.queue.QueueManager\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\n\nclass AnimeChaptersHolder(view: View, private val fragment: Fragment, private val callback: ChapHolderCallback) {\n    val recyclerView: RecyclerView = view.find(R.id.recycler)\n    private val manager: LinearLayoutManager = CenterLayoutManager(view.context)\n    private var chapters: MutableList<AnimeObject.WebInfo.AnimeChapter> = ArrayList()\n    var adapter: AnimeChaptersAdapter? = null\n        private set\n    private val touchListener: DragSelectTouchListener\n\n    init {\n        manager.isSmoothScrollbarEnabled = true\n        recyclerView.layoutManager = manager\n        touchListener = DragSelectTouchListener()\n                .withSelectListener(DragSelectionProcessor(object : DragSelectionProcessor.ISelectionHandler {\n                    override fun getSelection(): Set<Int> {\n                        return adapter?.selection ?: setOf()\n                    }\n\n                    override fun isSelected(i: Int): Boolean {\n                        return adapter?.selection?.contains(i) ?: false\n                    }\n\n                    override fun updateSelection(i: Int, i1: Int, b: Boolean, b1: Boolean) {\n                        adapter?.selectRange(i, i1, b)\n                    }\n\n                }).withStartFinishedListener(object : DragSelectionProcessor.ISelectionStartFinishedListener {\n                    override fun onSelectionStarted(i: Int, b: Boolean) {\n\n                    }\n\n                    override fun onSelectionFinished(i: Int) {\n                        BottomActionsDialog.newInstance(\n                            adapter?.selection?.size ?: 0,\n                            object : BottomActionsDialog.ActionsCallback {\n                                override fun onSelect(state: Int) {\n                                    try {\n                                        val snackbar = recyclerView.showSnackbar(\n                                            \"Procesando...\",\n                                            duration = Snackbar.LENGTH_INDEFINITE\n                                        )\n                                        when (state) {\n                                            BottomActionsDialog.STATE_SEEN -> doAsync {\n                                                val dao = CacheDB.INSTANCE.seenDAO()\n                                                for (i13 in ArrayList(\n                                                    adapter?.selection\n                                                        ?: arrayListOf()\n                                                )) {\n                                                    dao.addChapter(SeenObject.fromChapter(chapters[i13]))\n                                                }\n                                            syncData { seen() }\n                                            val seeingDAO = CacheDB.INSTANCE.seeingDAO()\n                                            val seeingObject = seeingDAO.getByAid(chapters[0].aid)\n                                            if (seeingObject != null) {\n                                                seeingObject.chapter = chapters[0].number\n                                                seeingDAO.update(seeingObject)\n                                                syncData { seeing() }\n                                            }\n                                                fragment.doOnUI {\n                                                    adapter?.apply {\n                                                        if (selection.isNotEmpty()) {\n                                                            selection.forEach {\n                                                                this.chapters[it].isSeen = true\n                                                            }\n                                                            deselectAll()\n                                                        }\n                                                    }\n                                                }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                        }\n                                        BottomActionsDialog.STATE_UNSEEN -> doAsync {\n                                            try {\n                                                val dao = CacheDB.INSTANCE.seenDAO()\n                                                for (i12 in ArrayList(adapter?.selection\n                                                        ?: arrayListOf())) {\n                                                    dao.deleteChapter(chapters[i12].aid, chapters[i12].number)\n                                                }\n                                                syncData { seen() }\n                                                val seeingDAO = CacheDB.INSTANCE.seeingDAO()\n                                                val seeingObject = seeingDAO.getByAid(chapters[0].aid)\n                                                if (seeingObject != null) {\n                                                    seeingObject.chapter = chapters[0].number\n                                                    seeingDAO.update(seeingObject)\n                                                    syncData { seeing() }\n                                                }\n                                                fragment.doOnUI {\n                                                    adapter?.apply {\n                                                        if (selection.isNotEmpty()) {\n                                                            selection.forEach {\n                                                                this.chapters[it].isSeen = false\n                                                            }\n                                                            deselectAll()\n                                                        }\n                                                    }\n                                                }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            } catch (e: Exception) {\n                                                e.printStackTrace()\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            }\n                                        }\n                                        BottomActionsDialog.STATE_IMPORT_MULTIPLE -> doAsync {\n                                            try {\n                                                val cChapters = ArrayList<AnimeObject.WebInfo.AnimeChapter>()\n                                                val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n                                                for (i13 in ArrayList(adapter?.selection\n                                                        ?: arrayListOf())) {\n                                                    val chapter = chapters[i13]\n                                                    val downloadObject = downloadsDAO.getByEid(chapter.eid)\n                                                    if (!chapter.fileWrapper().exist && (downloadObject == null || !downloadObject.isDownloading))\n                                                        cChapters.add(chapter)\n                                                }\n                                                callback.onImportMultiple(cChapters)\n                                                recyclerView.post { adapter?.deselectAll() }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            } catch (e: Exception) {\n                                                e.printStackTrace()\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            }\n                                        }\n                                        BottomActionsDialog.STATE_DOWNLOAD_MULTIPLE -> doAsync {\n                                            try {\n                                                val cChapters = mutableListOf<AnimeObject.WebInfo.AnimeChapter>()\n                                                val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n                                                for (i13 in ArrayList(adapter?.selection\n                                                        ?: arrayListOf())) {\n                                                    val chapter = chapters[i13]\n                                                    val downloadObject = downloadsDAO.getByEid(chapter.eid)\n                                                    if (!chapter.fileWrapper().exist && (downloadObject == null || !downloadObject.isDownloading))\n                                                        cChapters.add(chapter)\n                                                }\n                                                recyclerView.post { adapter?.deselectAll() }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                                callback.onDownloadMultiple(false, cChapters)\n                                            } catch (e: Exception) {\n                                                e.printStackTrace()\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            }\n                                        }\n                                        BottomActionsDialog.STATE_QUEUE_MULTIPLE -> doAsync {\n                                            try {\n                                                val cChapters = mutableListOf<AnimeObject.WebInfo.AnimeChapter>()\n                                                val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n                                                for (i13 in ArrayList(adapter?.selection\n                                                        ?: arrayListOf())) {\n                                                    val chapter = chapters[i13]\n                                                    val downloadObject = downloadsDAO.getByEid(chapter.eid)\n                                                    if (!chapter.fileWrapper().exist && (downloadObject == null || !downloadObject.isDownloading))\n                                                        cChapters.add(chapter)\n                                                    else if (chapter.fileWrapper().exist || downloadObject?.isDownloading == true)\n                                                        QueueManager.add(Uri.fromFile(chapter.fileWrapper().file()), true, chapter)\n                                                }\n                                                recyclerView.post { adapter?.deselectAll() }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                                callback.onDownloadMultiple(true, cChapters)\n                                            } catch (e: Exception) {\n                                                e.printStackTrace()\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            }\n                                        }\n                                    }\n                                } catch (e: Exception) {\n                                    //\n                                }\n\n                            }\n\n                            override fun onDismiss() {\n                                recyclerView.post { adapter?.deselectAll() }\n                            }\n                        }).safeShow(fragment.childFragmentManager, \"actions_dialog\")\n                    }\n                }).withMode(DragSelectionProcessor.Mode.Simple))\n                .withMaxScrollDistance(32)\n    }\n\n    fun setAdapter(fragment: Fragment, chapters: MutableList<AnimeObject.WebInfo.AnimeChapter>?) {\n        if (chapters == null) return\n        fragment.lifecycleScope.launch(Dispatchers.IO) {\n            this@AnimeChaptersHolder.chapters = chapters\n            this@AnimeChaptersHolder.adapter = AnimeChaptersAdapter(fragment, recyclerView, chapters.map { ChapterObjWrap(it) }, touchListener)\n            recyclerView.post {\n                recyclerView.adapter = adapter\n                recyclerView.addOnItemTouchListener(touchListener)\n            }\n        }\n    }\n\n    fun refresh() {\n        if (adapter != null)\n            recyclerView.post { adapter?.notifyDataSetChanged() }\n    }\n\n    fun goToChapter() {\n        fragment.lifecycleScope.launch(Dispatchers.IO) {\n            if (chapters.isNotEmpty()) {\n                val eids =\n                    chapters.sortedBy { it.number.substringAfterLast(\" \").toFloat() }.map { it.eid }\n                eids.chunked(50).forEach { list ->\n                    val chapter = CacheDB.INSTANCE.seenDAO().getLast(list)\n                    if (chapter != null) {\n                        val position = chapters.indexOf(chapters.find { it.eid == chapter.eid })\n                        if (position >= 0)\n                            launch(Dispatchers.Main) {\n                                manager.scrollToPositionWithOffset(position, 150)\n                            }\n                        return@forEach\n                    }\n                }\n            }\n        }\n    }\n\n    fun smoothGoToChapter() {\n        fragment.lifecycleScope.launch(Dispatchers.IO) {\n            if (chapters.isNotEmpty()) {\n                val eids =\n                    chapters.sortedBy { it.number.substringAfterLast(\" \").toFloat() }.map { it.eid }\n                eids.chunked(50).forEach { list ->\n                    val chapter = CacheDB.INSTANCE.seenDAO().getLast(list)\n                    if (chapter != null) {\n                        val position = chapters.indexOf(chapters.find { it.eid == chapter.eid })\n                        if (position >= 0)\n                            recyclerView.post {\n                                manager.smoothScrollToPosition(\n                                    recyclerView,\n                                    null,\n                                    position\n                                )\n                            }\n                        return@forEach\n                    }\n                }\n            }\n        }\n    }\n\n    interface ChapHolderCallback {\n        fun onImportMultiple(chapters: MutableList<AnimeObject.WebInfo.AnimeChapter>)\n\n        fun onDownloadMultiple(addQueue: Boolean, chapters: List<AnimeObject.WebInfo.AnimeChapter>)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/viewholders/AnimeChaptersMaterialHolder.kt",
    "content": "package knf.kuma.animeinfo.viewholders\n\nimport android.net.Uri\nimport android.view.View\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.snackbar.Snackbar\nimport com.michaelflisar.dragselectrecyclerview.DragSelectTouchListener\nimport com.michaelflisar.dragselectrecyclerview.DragSelectionProcessor\nimport knf.kuma.R\nimport knf.kuma.animeinfo.AnimeChaptersAdapterMaterial\nimport knf.kuma.animeinfo.BottomActionsDialog\nimport knf.kuma.animeinfo.ChapterObjWrap\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeDismiss\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.custom.CenterLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.SeenObject\nimport knf.kuma.queue.QueueManager\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\n\nclass AnimeChaptersMaterialHolder(view: View, private val fragment: Fragment, private val callback: ChapHolderCallback) {\n    val recyclerView: RecyclerView = view.find(R.id.recycler)\n    private val manager: LinearLayoutManager = CenterLayoutManager(view.context)\n    private var chapters: MutableList<AnimeObject.WebInfo.AnimeChapter> = ArrayList()\n    var adapter: AnimeChaptersAdapterMaterial? = null\n        private set\n    private val touchListener: DragSelectTouchListener\n\n    init {\n        manager.isSmoothScrollbarEnabled = true\n        recyclerView.layoutManager = manager\n        touchListener = DragSelectTouchListener()\n                .withSelectListener(DragSelectionProcessor(object : DragSelectionProcessor.ISelectionHandler {\n                    override fun getSelection(): Set<Int> {\n                        return adapter?.selection ?: setOf()\n                    }\n\n                    override fun isSelected(i: Int): Boolean {\n                        return adapter?.selection?.contains(i) ?: false\n                    }\n\n                    override fun updateSelection(i: Int, i1: Int, b: Boolean, b1: Boolean) {\n                        adapter?.selectRange(i, i1, b)\n                    }\n\n                }).withStartFinishedListener(object : DragSelectionProcessor.ISelectionStartFinishedListener {\n                    override fun onSelectionStarted(i: Int, b: Boolean) {\n\n                    }\n\n                    override fun onSelectionFinished(i: Int) {\n                        BottomActionsDialog.newInstance(\n                            adapter?.selection?.size ?: 0,\n                            object : BottomActionsDialog.ActionsCallback {\n                                override fun onSelect(state: Int) {\n                                    try {\n                                        val snackbar = recyclerView.showSnackbar(\n                                            \"Procesando...\",\n                                            duration = Snackbar.LENGTH_INDEFINITE\n                                        )\n                                        when (state) {\n                                            BottomActionsDialog.STATE_SEEN -> doAsync {\n                                                val dao = CacheDB.INSTANCE.seenDAO()\n                                                for (i13 in ArrayList(\n                                                    adapter?.selection\n                                                        ?: arrayListOf()\n                                                )) {\n                                                    dao.addChapter(SeenObject.fromChapter(chapters[i13]))\n                                                }\n                                            syncData { seen() }\n                                            val seeingDAO = CacheDB.INSTANCE.seeingDAO()\n                                            val seeingObject = seeingDAO.getByAid(chapters[0].aid)\n                                            if (seeingObject != null) {\n                                                seeingObject.chapter = chapters[0].number\n                                                seeingDAO.update(seeingObject)\n                                                syncData { seeing() }\n                                            }\n                                                fragment.doOnUI {\n                                                    adapter?.apply {\n                                                        if (selection.isNotEmpty()) {\n                                                            selection.forEach {\n                                                                this.chapters[it].isSeen = true\n                                                            }\n                                                            deselectAll()\n                                                        }\n                                                    }\n                                                }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                        }\n                                        BottomActionsDialog.STATE_UNSEEN -> doAsync {\n                                            try {\n                                                val dao = CacheDB.INSTANCE.seenDAO()\n                                                for (i12 in ArrayList(adapter?.selection\n                                                        ?: arrayListOf())) {\n                                                    dao.deleteChapter(chapters[i12].aid, chapters[i12].number)\n                                                }\n                                                syncData { seen() }\n                                                val seeingDAO = CacheDB.INSTANCE.seeingDAO()\n                                                val seeingObject = seeingDAO.getByAid(chapters[0].aid)\n                                                if (seeingObject != null) {\n                                                    seeingObject.chapter = chapters[0].number\n                                                    seeingDAO.update(seeingObject)\n                                                    syncData { seeing() }\n                                                }\n                                                fragment.doOnUI {\n                                                    adapter?.apply {\n                                                        if (selection.isNotEmpty()) {\n                                                            selection.forEach {\n                                                                this.chapters[it].isSeen = false\n                                                            }\n                                                            deselectAll()\n                                                        }\n                                                    }\n                                                }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            } catch (e: Exception) {\n                                                e.printStackTrace()\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            }\n                                        }\n                                        BottomActionsDialog.STATE_IMPORT_MULTIPLE -> doAsync {\n                                            try {\n                                                val cChapters = ArrayList<AnimeObject.WebInfo.AnimeChapter>()\n                                                val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n                                                for (i13 in ArrayList(adapter?.selection\n                                                        ?: arrayListOf())) {\n                                                    val chapter = chapters[i13]\n                                                    val downloadObject = downloadsDAO.getByEid(chapter.eid)\n                                                    if (!chapter.fileWrapper().exist && (downloadObject == null || !downloadObject.isDownloading))\n                                                        cChapters.add(chapter)\n                                                }\n                                                callback.onImportMultiple(cChapters)\n                                                recyclerView.post { adapter?.deselectAll() }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            } catch (e: Exception) {\n                                                e.printStackTrace()\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            }\n                                        }\n                                        BottomActionsDialog.STATE_DOWNLOAD_MULTIPLE -> doAsync {\n                                            try {\n                                                val cChapters = mutableListOf<AnimeObject.WebInfo.AnimeChapter>()\n                                                val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n                                                for (i13 in ArrayList(adapter?.selection\n                                                        ?: arrayListOf())) {\n                                                    val chapter = chapters[i13]\n                                                    val downloadObject = downloadsDAO.getByEid(chapter.eid)\n                                                    if (!chapter.fileWrapper().exist && (downloadObject == null || !downloadObject.isDownloading))\n                                                        cChapters.add(chapter)\n                                                }\n                                                recyclerView.post { adapter?.deselectAll() }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                                callback.onDownloadMultiple(false, cChapters)\n                                            } catch (e: Exception) {\n                                                e.printStackTrace()\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            }\n                                        }\n                                        BottomActionsDialog.STATE_QUEUE_MULTIPLE -> doAsync {\n                                            try {\n                                                val cChapters = mutableListOf<AnimeObject.WebInfo.AnimeChapter>()\n                                                val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n                                                for (i13 in ArrayList(adapter?.selection\n                                                        ?: arrayListOf())) {\n                                                    val chapter = chapters[i13]\n                                                    val downloadObject = downloadsDAO.getByEid(chapter.eid)\n                                                    if (!chapter.fileWrapper().exist && (downloadObject == null || !downloadObject.isDownloading))\n                                                        cChapters.add(chapter)\n                                                    else if (chapter.fileWrapper().exist || downloadObject?.isDownloading == true)\n                                                        QueueManager.add(Uri.fromFile(chapter.fileWrapper().file()), true, chapter)\n                                                }\n                                                recyclerView.post { adapter?.deselectAll() }\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                                callback.onDownloadMultiple(true, cChapters)\n                                            } catch (e: Exception) {\n                                                e.printStackTrace()\n                                                fragment.doOnUI { snackbar.safeDismiss() }\n                                            }\n                                        }\n                                    }\n                                } catch (e: Exception) {\n                                    //\n                                }\n\n                            }\n\n                            override fun onDismiss() {\n                                adapter?.deselectAll()\n                            }\n                        }).safeShow(fragment.childFragmentManager, \"actions_dialog\")\n                    }\n                }).withMode(DragSelectionProcessor.Mode.Simple))\n                .withMaxScrollDistance(32)\n    }\n\n    fun setAdapter(fragment: Fragment, chapters: MutableList<AnimeObject.WebInfo.AnimeChapter>?) {\n        if (chapters == null) return\n        fragment.lifecycleScope.launch(Dispatchers.IO){\n            this@AnimeChaptersMaterialHolder.chapters = chapters\n            this@AnimeChaptersMaterialHolder.adapter = AnimeChaptersAdapterMaterial(fragment, recyclerView, chapters.map { ChapterObjWrap(it) }, touchListener)\n            recyclerView.post {\n                recyclerView.adapter = adapter\n                recyclerView.addOnItemTouchListener(touchListener)\n            }\n        }\n    }\n\n    fun refresh() {\n        if (adapter != null)\n            recyclerView.post { adapter?.notifyDataSetChanged() }\n    }\n\n    fun goToChapter() {\n        fragment.lifecycleScope.launch(Dispatchers.IO){\n            if (chapters.isNotEmpty()) {\n                val eids =\n                    chapters.sortedBy { it.number.substringAfterLast(\" \").toFloat() }.map { it.eid }\n                eids.chunked(50).forEach { list ->\n                    val chapter = CacheDB.INSTANCE.seenDAO().getLast(list)\n                    if (chapter != null) {\n                        val position = chapters.indexOf(chapters.find { it.eid == chapter.eid })\n                        if (position >= 0)\n                            launch(Dispatchers.Main) {\n                                manager.scrollToPositionWithOffset(position, 150)\n                            }\n                        return@forEach\n                    }\n                }\n            }\n        }\n    }\n\n    fun smoothGoToChapter() {\n        fragment.lifecycleScope.launch(Dispatchers.IO) {\n            if (chapters.isNotEmpty()) {\n                val eids =\n                    chapters.sortedBy { it.number.substringAfterLast(\" \").toFloat() }.map { it.eid }\n                eids.chunked(50).forEach { list ->\n                    val chapter = CacheDB.INSTANCE.seenDAO().getLast(list)\n                    if (chapter != null) {\n                        val position = chapters.indexOf(chapters.find { it.eid == chapter.eid })\n                        if (position >= 0)\n                            recyclerView.post {\n                                manager.smoothScrollToPosition(\n                                    recyclerView,\n                                    null,\n                                    position\n                                )\n                            }\n                        return@forEach\n                    }\n                }\n            }\n        }\n    }\n\n    interface ChapHolderCallback {\n        fun onImportMultiple(chapters: MutableList<AnimeObject.WebInfo.AnimeChapter>)\n\n        fun onDownloadMultiple(addQueue: Boolean, chapters: List<AnimeObject.WebInfo.AnimeChapter>)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/viewholders/AnimeDetailsHolder.kt",
    "content": "package knf.kuma.animeinfo.viewholders\n\nimport android.annotation.SuppressLint\nimport android.content.ClipData\nimport android.view.View\nimport android.view.animation.AnimationUtils\nimport android.widget.AdapterView\nimport android.widget.ArrayAdapter\nimport android.widget.ImageButton\nimport android.widget.LinearLayout\nimport android.widget.Spinner\nimport android.widget.TextView\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.DividerItemDecoration\nimport androidx.recyclerview.widget.RecyclerView\nimport ir.mahdiparastesh.chlm.ChipsLayoutManager\nimport ir.mahdiparastesh.chlm.SpacingItemDecoration\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.animeinfo.AnimeRelatedAdapter\nimport knf.kuma.animeinfo.AnimeTagsAdapter\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.removeAllDecorations\nimport knf.kuma.custom.ExpandableTV\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.FragmentAnimeDetailsBinding\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.SeeingObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.clipboardManager\nimport org.jetbrains.anko.doAsync\nimport uz.jamshid.library.ExactRatingBar\nimport xdroid.toaster.Toaster\nimport androidx.core.view.isVisible\n\nclass AnimeDetailsHolder(val view: View) {\n    private val binding = FragmentAnimeDetailsBinding.bind(view)\n    private var cardViews: MutableList<View> = arrayListOf(binding.cardTitle, binding.cardDesc, binding.adContainer, binding.cardDetails, binding.cardGenres, binding.cardList, binding.cardRelated)\n    internal val title: TextView = binding.title\n    private val expandIcon: ImageButton = binding.expandIcon\n    private val desc: ExpandableTV = binding.expandableDesc\n    internal val type: TextView = binding.type\n    internal val state: TextView = binding.state\n    internal val id: TextView = binding.aid\n    internal val followers: TextView = binding.followers\n    private val layScore: LinearLayout = binding.layScore\n    private val ratingCount: TextView = binding.ratingCount\n    private val ratingBar: ExactRatingBar = binding.ratingBar\n    private val recyclerViewGenres: RecyclerView = binding.recyclerGenres\n    private val spinnerList: Spinner = binding.spinnerList\n    private val recyclerViewRelated: RecyclerView = binding.recyclerRelated\n    private val clipboardManager = view.context.applicationContext.clipboardManager\n    private var retard = 0\n    private var needAnimation = true\n\n    init {\n        recyclerViewGenres.layoutManager = ChipsLayoutManager.newBuilder(view.context).build()\n        recyclerViewGenres.addItemDecoration(SpacingItemDecoration(5, 5))\n        recyclerViewRelated.layoutManager = VariantLinearLayoutManager(view.context)\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    fun populate(fragment: Fragment, animeObject: AnimeObject) {\n        fragment.lifecycleScope.launch(Dispatchers.Main) {\n            title.text = animeObject.name\n            noCrash {\n                cardViews[0].setOnLongClickListener {\n                    try {\n                        val clip = ClipData.newPlainText(\"Anime title\", animeObject.name)\n                        clipboardManager.setPrimaryClip(clip)\n                        Toaster.toast(\"Título copiado\")\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                        Toaster.toast(\"Error al copiar título\")\n                    }\n                    true\n                }\n                showCard(cardViews[0])\n            }\n            noCrash {\n                if (animeObject.description != null && animeObject.description?.trim() != \"\") {\n                    desc.setTextAndIndicator(animeObject.description?.trim() ?: \"\", expandIcon)\n                    desc.setAnimationDuration(300)\n                    val onClickListener = View.OnClickListener {\n                        expandIcon.setImageResource(if (desc.isExpanded) R.drawable.action_expand else R.drawable.action_shrink)\n                        desc.toggle()\n                    }\n                    desc.setOnClickListener(onClickListener)\n                    expandIcon.setOnClickListener(onClickListener)\n                    showCard(cardViews[1])\n                }\n            }\n            noCrash {\n                if (PrefsUtil.isAdsEnabled) {\n                    showCard(cardViews[2])\n                }\n            }\n            noCrash {\n                type.text = animeObject.type\n                state.text = getStateString(animeObject.state, animeObject.day)\n                id.text = animeObject.aid\n                followers.text = animeObject.followers\n                if (animeObject.rate_stars == null || animeObject.rate_stars == \"0.0\")\n                    layScore.visibility = View.GONE\n                else {\n                    ratingCount.text = \"${animeObject.rate_count} (${animeObject.rate_stars\n                            ?: \"?.?\"})\"\n                    ratingBar.setStar(animeObject.rate_stars?.toFloat() ?: 0f)\n                }\n                showCard(cardViews[3])\n            }\n            noCrash {\n                fragment.context?.let { context ->\n                    if (animeObject.genres?.isNotEmpty() == true &&\n                            animeObject.genresString.trim().let { it != \"\" && it != \"Sin generos\" }) {\n                        recyclerViewGenres.adapter = AnimeTagsAdapter(context, animeObject.genres)\n                        showCard(cardViews[4])\n                    }\n                }\n            }\n            noCrash {\n                spinnerList.adapter = ArrayAdapter<String>(view.context, android.R.layout.simple_spinner_dropdown_item, view.context.resources.getStringArray(R.array.list_states))\n                fragment.lifecycleScope.launch(Dispatchers.Main){\n                    spinnerList.setSelection(withContext(Dispatchers.IO){\n                        CacheDB.INSTANCE.seeingDAO().getByAid(animeObject.aid)\n                    }?.state ?: 0)\n                    spinnerList.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {\n                        override fun onNothingSelected(parent: AdapterView<*>?) {\n\n                        }\n\n                        override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {\n                            doAsync {\n                                if (position == 0)\n                                    CacheDB.INSTANCE.seeingDAO().remove(SeeingObject.fromAnime(animeObject, position))\n                                else\n                                    CacheDB.INSTANCE.seeingDAO().add(SeeingObject.fromAnime(animeObject, position))\n                                syncData { seeing() }\n                            }\n                        }\n                    }\n                }\n                showCard(cardViews[5])\n            }\n            noCrash {\n                if (animeObject.related?.isNotEmpty() == true) {\n                    recyclerViewRelated.removeAllDecorations()\n                    if (animeObject.related.size > 1)\n                        recyclerViewRelated.addItemDecoration(DividerItemDecoration(view.context, LinearLayout.VERTICAL))\n                    recyclerViewRelated.adapter = AnimeRelatedAdapter(fragment, animeObject.related)\n                    showCard(cardViews[6])\n                } else {\n                    launch(Dispatchers.Main) { cardViews[6].visibility = View.GONE }\n                }\n            }\n            needAnimation = false\n            if (PrefsUtil.isAdsEnabled) {\n                fragment.lifecycleScope.launch(Dispatchers.IO) {\n                    retard += 300\n                    delay(retard.toLong())\n                    binding.adContainer.implBanner(AdsType.INFO_BANNER, true)\n                }\n            }\n        }\n    }\n\n    private fun showCard(view: View) {\n        if (view.isVisible || !needAnimation) return\n        retard += 100\n        GlobalScope.launch(Dispatchers.Main) {\n            delay(retard.toLong())\n            view.visibility = View.VISIBLE\n            val animation = AnimationUtils.makeInChildBottomAnimation(view.context)\n            animation.duration = 250\n            view.startAnimation(animation)\n            if (cardViews.indexOf(view) == 1)\n                desc.checkIndicator()\n        }\n    }\n\n    private fun getStateString(state: String?, day: AnimeObject.Day): String {\n        return when (day) {\n            AnimeObject.Day.MONDAY -> \"$state - Lunes\"\n            AnimeObject.Day.TUESDAY -> \"$state - Martes\"\n            AnimeObject.Day.WEDNESDAY -> \"$state - Miércoles\"\n            AnimeObject.Day.THURSDAY -> \"$state - Jueves\"\n            AnimeObject.Day.FRIDAY -> \"$state - Viernes\"\n            AnimeObject.Day.SATURDAY -> \"$state - Sábado\"\n            AnimeObject.Day.SUNDAY -> \"$state - Domingo\"\n            else -> state ?: \"\"\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/animeinfo/viewholders/AnimeDetailsMaterialHolder.kt",
    "content": "package knf.kuma.animeinfo.viewholders\n\n//import knf.kuma.ads.NativeManager\nimport android.annotation.SuppressLint\nimport android.content.ClipData\nimport android.view.View\nimport android.widget.AdapterView\nimport android.widget.ArrayAdapter\nimport android.widget.ImageButton\nimport android.widget.LinearLayout\nimport android.widget.Spinner\nimport android.widget.TextView\nimport androidx.core.view.isVisible\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport ir.mahdiparastesh.chlm.ChipsLayoutManager\nimport ir.mahdiparastesh.chlm.SpacingItemDecoration\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.ads.implBanner\nimport knf.kuma.animeinfo.AnimeRelatedAdapterMaterial\nimport knf.kuma.animeinfo.AnimeTagsAdapterMaterial\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.isVisibleAnimate\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.noCrashSuspend\nimport knf.kuma.commons.removeAllDecorations\nimport knf.kuma.custom.ExpandableTV\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.FragmentAnimeDetailsMaterialBinding\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.SeeingObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.clipboardManager\nimport org.jetbrains.anko.doAsync\nimport uz.jamshid.library.ExactRatingBar\nimport xdroid.toaster.Toaster\n\nclass AnimeDetailsMaterialHolder(val view: View) {\n    private val binding = FragmentAnimeDetailsMaterialBinding.bind(view)\n    private var layouts: MutableList<View> = arrayListOf(binding.layTitle, binding.layDescription, binding.adContainer, binding.layDetails, binding.layGenres, binding.layFollow, binding.layRelated)\n    internal val title: TextView = binding.title\n    private val expandIcon: ImageButton = binding.expandIcon\n    private val desc: ExpandableTV = binding.expandableDesc\n    internal val type: TextView = binding.type\n    internal val state: TextView = binding.state\n    internal val id: TextView = binding.aid\n    internal val followers: TextView = binding.followers\n    private val layScore: LinearLayout = binding.layScore\n    private val ratingCount: TextView = binding.ratingCount\n    private val ratingBar: ExactRatingBar = binding.ratingBar\n    private val recyclerViewGenres: RecyclerView = binding.recyclerGenres\n    private val spinnerList: Spinner = binding.spinnerList\n    private val recyclerViewRelated: RecyclerView = binding.recyclerRelated\n    private val clipboardManager = view.context.applicationContext.clipboardManager\n    private var needAnimation = true\n\n    init {\n        recyclerViewGenres.layoutManager = ChipsLayoutManager.newBuilder(view.context).build()\n        recyclerViewGenres.addItemDecoration(SpacingItemDecoration(5, 5))\n        recyclerViewRelated.layoutManager = VariantLinearLayoutManager(view.context)\n        binding.layAd.isVisible = PrefsUtil.isAdsEnabled\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    fun populate(fragment: Fragment, animeObject: AnimeObject) {\n        fragment.lifecycleScope.launch(Dispatchers.Main) {\n            title.text = animeObject.name\n            noCrash {\n                layouts[0].setOnLongClickListener {\n                    try {\n                        val clip = ClipData.newPlainText(\"Anime title\", animeObject.name)\n                        clipboardManager.setPrimaryClip(clip)\n                        Toaster.toast(\"Título copiado\")\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                        Toaster.toast(\"Error al copiar título\")\n                    }\n                    true\n                }\n                showLayout(layouts[0])\n            }\n            noCrash {\n                if (animeObject.description != null && animeObject.description?.isBlank() == false) {\n                    desc.setTextAndIndicator(animeObject.description?.trim() ?: \"\", expandIcon)\n                    desc.setAnimationDuration(300)\n                    val onClickListener = View.OnClickListener {\n                        expandIcon.setImageResource(if (desc.isExpanded) R.drawable.action_expand else R.drawable.action_shrink)\n                        desc.toggle()\n                    }\n                    desc.setOnClickListener(onClickListener)\n                    expandIcon.setOnClickListener(onClickListener)\n                    showLayout(layouts[1])\n                } else {\n                    binding.layDescriptionSeparator.isVisible = false\n                }\n            }\n            if (PrefsUtil.isAdsEnabled) {\n                launch {\n                    noCrashSuspend {\n                        binding.adContainer.isVisible = false\n                        binding.layAd.implBanner(AdsType.INFO_BANNER)\n                    }\n                }\n                showLayout(layouts[2])\n            }\n            noCrash {\n                type.text = animeObject.type\n                state.text = getStateString(animeObject.state, animeObject.day)\n                id.text = animeObject.aid\n                followers.text = animeObject.followers\n                if (animeObject.rate_stars == null || animeObject.rate_stars == \"0.0\")\n                    layScore.visibility = View.GONE\n                else {\n                    ratingCount.text = \"${animeObject.rate_count} (${\n                        animeObject.rate_stars\n                                ?: \"?.?\"\n                    })\"\n                    ratingBar.setStar(animeObject.rate_stars?.toFloat() ?: 0f)\n                }\n                showLayout(layouts[3])\n            }\n            noCrash {\n                fragment.context?.let { context ->\n                    if (animeObject.genres?.isNotEmpty() == true &&\n                            animeObject.genresString.trim().let { it != \"\" && it != \"Sin generos\" }) {\n                        recyclerViewGenres.adapter = AnimeTagsAdapterMaterial(context, animeObject.genres)\n                        showLayout(layouts[4])\n                    }\n                }\n            }\n            if (!layouts[5].isVisible)\n                noCrash {\n                    spinnerList.adapter = ArrayAdapter(view.context, android.R.layout.simple_spinner_dropdown_item, view.context.resources.getStringArray(R.array.list_states))\n                    fragment.lifecycleScope.launch(Dispatchers.Main) {\n                        spinnerList.onItemSelectedListener = null\n                        spinnerList.setSelection(withContext(Dispatchers.IO) {\n                            CacheDB.INSTANCE.seeingDAO().getByAid(animeObject.aid)\n                        }?.state ?: 0)\n                        spinnerList.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {\n                            override fun onNothingSelected(parent: AdapterView<*>?) {\n\n                            }\n\n                            override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {\n                                doAsync {\n                                    if (position == 0)\n                                        CacheDB.INSTANCE.seeingDAO().remove(SeeingObject.fromAnime(animeObject, position))\n                                    else\n                                        CacheDB.INSTANCE.seeingDAO().add(SeeingObject.fromAnime(animeObject, position))\n                                    syncData { seeing() }\n                                }\n                            }\n                        }\n                    }\n                    showLayout(layouts[5])\n                }\n            noCrash {\n                if (animeObject.related?.isNotEmpty() == true) {\n                    recyclerViewRelated.removeAllDecorations()\n                    recyclerViewRelated.adapter = AnimeRelatedAdapterMaterial(fragment, animeObject.related)\n                    showLayout(layouts[6])\n                } else {\n                    launch(Dispatchers.Main) { layouts[6].visibility = View.GONE }\n                }\n            }\n            needAnimation = false\n        }\n    }\n\n    private fun showLayout(view: View) {\n        if (view.visibility == View.VISIBLE || !needAnimation) return\n        view.isVisibleAnimate = true\n        if (layouts.indexOf(view) == 1)\n            desc.checkIndicator()\n    }\n\n    private fun getStateString(state: String?, day: AnimeObject.Day): String {\n        return when (day) {\n            AnimeObject.Day.MONDAY -> \"$state - Lunes\"\n            AnimeObject.Day.TUESDAY -> \"$state - Martes\"\n            AnimeObject.Day.WEDNESDAY -> \"$state - Miércoles\"\n            AnimeObject.Day.THURSDAY -> \"$state - Jueves\"\n            AnimeObject.Day.FRIDAY -> \"$state - Viernes\"\n            AnimeObject.Day.SATURDAY -> \"$state - Sábado\"\n            AnimeObject.Day.SUNDAY -> \"$state - Domingo\"\n            else -> state ?: \"\"\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/BackUpActivity.kt",
    "content": "package knf.kuma.backup\n\nimport android.animation.Animator\nimport android.content.Context\nimport android.content.Intent\nimport android.content.pm.ActivityInfo\nimport android.graphics.Rect\nimport android.os.Bundle\nimport android.view.View\nimport android.view.ViewAnimationUtils\nimport android.view.animation.AccelerateDecelerateInterpolator\nimport androidx.annotation.ColorInt\nimport androidx.core.content.ContextCompat\nimport androidx.preference.PreferenceManager\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.dropbox.core.android.Auth\nimport knf.kuma.BuildConfig\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.backup.firestore.FirestoreManager\nimport knf.kuma.backup.framework.BackupService\nimport knf.kuma.backup.framework.DropBoxService\nimport knf.kuma.backup.framework.LocalService\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.admFile\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.custom.SyncItemView\nimport knf.kuma.databinding.ActivityLoginBinding\nimport kotlin.math.max\n\nclass BackUpActivity : GenericActivity(), SyncItemView.OnClick {\n    val binding by lazy { ActivityLoginBinding.inflate(layoutInflater) }\n    private val syncItems: MutableList<SyncItemView> by lazy {\n        with(binding.layButtons) {\n            arrayListOf(syncFavs, syncHistory, syncFollowing, syncSeen, syncSeenNew)\n        }\n    }\n    private var service: BackupService? = null\n    private var waitingLogin = false\n\n    private val backColor: Int\n        @ColorInt\n        get() {\n            return when (Backups.type) {\n                Backups.Type.NONE -> ContextCompat.getColor(this, android.R.color.transparent)\n                Backups.Type.LOCAL -> ContextCompat.getColor(this, EAHelper.getThemeColorLight())\n                Backups.Type.DROPBOX -> ContextCompat.getColor(this, R.color.dropbox)\n                Backups.Type.FIRESTORE -> ContextCompat.getColor(this, R.color.firestore)\n            }\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        if (!resources.getBoolean(R.bool.isTablet))\n            requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT\n        setContentView(binding.root)\n        service = Backups.createService()\n        binding.layMain.loginDropbox.setOnClickListener { onDropBoxLogin() }\n        if (!PrefsUtil.isAdsEnabled && !BuildConfig.DEBUG && !admFile.exists() && !PrefsUtil.isSubscriptionEnabled) {\n            binding.layMain.loginFirestore.isEnabled = false\n            binding.layMain.adsRequired.visibility = View.VISIBLE\n        } else if (PrefsUtil.isAdsEnabled && Network.isAdsBlocked && !BuildConfig.DEBUG && !admFile.exists() && !PrefsUtil.isSubscriptionEnabled) {\n            binding.layMain.loginFirestore.isEnabled = false\n            binding.layMain.adsRequired.text = \"Anuncios bloqueados por host\"\n            binding.layMain.adsRequired.visibility = View.VISIBLE\n        } else if (!PrefsUtil.isSecurityUpdated && PrefsUtil.spProtectionEnabled && PrefsUtil.spErrorType != null) {\n            binding.layMain.loginFirestore.isEnabled = false\n            binding.layMain.adsRequired.text =\n                \"Proveedor de seguridad no pudo ser actualizado (${PrefsUtil.spErrorType})\"\n            binding.layMain.adsRequired.visibility = View.VISIBLE\n        }\n        FirestoreManager.start()\n        binding.layMain.loginFirestore.setOnClickListener { onFirestoreLogin() }\n        binding.layMain.loginLocal.setOnClickListener { onLocalLogin() }\n        binding.layButtons.logOut.setOnClickListener { onLogOut() }\n        binding.layFirestore.logOutFirestore.setOnClickListener { onLogOut() }\n        when {\n            service?.isLoggedIn == true -> {\n                setState(true)\n                showColor(savedInstanceState == null)\n                initSyncButtons()\n            }\n            FirestoreManager.isLoggedIn -> {\n                setState(true)\n                showColor(savedInstanceState == null)\n                initFirestoreSync()\n            }\n            else -> setState(false)\n        }\n    }\n\n    private fun initSyncButtons() {\n        for (itemView in syncItems) {\n            itemView.init(service, this)\n        }\n    }\n\n    private fun initFirestoreSync() {\n        AchievementManager.onBackup()\n        binding.layFirestore.staticSyncAchievements.suscribe(this, FirestoreManager.achievementsLiveData)\n        binding.layFirestore.staticSyncEA.suscribe(this, FirestoreManager.eaLiveData)\n        binding.layFirestore.staticSyncFavs.suscribe(this, FirestoreManager.favsLiveData)\n        binding.layFirestore.staticSyncGenres.suscribe(this, FirestoreManager.genresLiveData)\n        binding.layFirestore.staticSyncHistory.suscribe(this, FirestoreManager.historyLiveData)\n        binding.layFirestore.staticSyncQueue.suscribe(this, FirestoreManager.queueLiveData)\n        binding.layFirestore.staticSyncSeeing.suscribe(this, FirestoreManager.seeingLiveData)\n        binding.layFirestore.staticSyncSeen.suscribe(this, FirestoreManager.seenLiveData)\n    }\n\n    private fun clearSyncButtons() {\n        for (itemView in syncItems) {\n            itemView.clear()\n        }\n    }\n\n    private fun onDropBoxLogin() {\n        waitingLogin = true\n        service = DropBoxService().also { it.logIn() }\n    }\n\n    private fun onFirestoreLogin() {\n        FirestoreManager.doLogin(this)\n    }\n\n    private fun onLocalLogin() {\n        MaterialDialog(this).safeShow {\n            message(text = \"Los datos se quedarán en la memoria, no se podrá sincronizar datos entre dispositivos, usar este método?\")\n            positiveButton(text = \"usar\") {\n                service = LocalService().also {\n                    it.start()\n                    it.logIn()\n                }\n                onLogin()\n            }\n            negativeButton(text = \"cancelar\")\n        }\n    }\n\n    override fun onAction(syncItemView: SyncItemView, id: String, isBackup: Boolean) {\n        noCrash {\n            if (isBackup)\n                Backups.backup(binding.colorChanger, service, id) {\n                    noCrash {\n                        if (it == null)\n                            binding.colorChanger.showSnackbar(\"Error al respaldar\")\n                        syncItemView.enableBackup(it, this@BackUpActivity)\n                    }\n                }\n            else\n                Backups.restoreDialog(this, binding.colorChanger, id, syncItemView.backupObj)\n        }\n    }\n\n    private fun onLogOut() {\n        MaterialDialog(this).safeShow {\n            message(text = \"Los datos no respaldados podrian ser perdidos al borrar la app, ¿desea continuar?\")\n            positiveButton(text = \"continuar\") {\n                if (Backups.type == Backups.Type.FIRESTORE) {\n                    FirestoreManager.doSignOut(this@BackUpActivity)\n                    Backups.type = Backups.Type.NONE\n                    revertColor()\n                    setState(false)\n                } else {\n                    PreferenceManager.getDefaultSharedPreferences(this@BackUpActivity).edit().putString(\"auto_backup\", \"0\").apply()\n                    service?.logOut()\n                    service = null\n                    Backups.type = Backups.Type.NONE\n                    revertColor()\n                    setState(false)\n                    clearSyncButtons()\n                }\n            }\n            negativeButton(text = \"cancelar\")\n        }\n    }\n\n    private fun onLogin() {\n        if (service?.isLoggedIn == true || FirestoreManager.isLoggedIn) {\n            setState(true)\n            showColor(true)\n            initSyncButtons()\n        } else if (waitingLogin) {\n            binding.colorChanger.showSnackbar(\"Error al iniciar sesión\")\n        }\n        waitingLogin = false\n    }\n\n    private fun showColor(animate: Boolean) {\n        binding.colorChanger.post {\n            try {\n                binding.colorChanger.setBackgroundColor(backColor)\n                if (animate) {\n                    val bounds = Rect()\n                    binding.colorChanger.getDrawingRect(bounds)\n                    val centerX = bounds.centerX()\n                    val centerY = bounds.centerY()\n                    val finalRadius = max(bounds.width(), bounds.height())\n                    val animator = ViewAnimationUtils.createCircularReveal(binding.colorChanger, centerX, centerY, 0f, finalRadius.toFloat())\n                    animator.duration = 1000\n                    animator.interpolator = AccelerateDecelerateInterpolator()\n                    binding.colorChanger.visibility = View.VISIBLE\n                    animator.start()\n                } else {\n                    binding.colorChanger.visibility = View.VISIBLE\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n    }\n\n    private fun revertColor() {\n        binding.colorChanger.post {\n            val bounds = Rect()\n            binding.colorChanger.getDrawingRect(bounds)\n            val centerX = bounds.centerX()\n            val centerY = bounds.centerY()\n            val finalRadius = max(bounds.width(), bounds.height())\n            val animator = ViewAnimationUtils.createCircularReveal(binding.colorChanger, centerX, centerY, finalRadius.toFloat(), 0f)\n            animator.duration = 1000\n            animator.interpolator = AccelerateDecelerateInterpolator()\n            animator.addListener(object : Animator.AnimatorListener {\n                override fun onAnimationStart(animation: Animator) {\n\n                }\n\n                override fun onAnimationEnd(animation: Animator) {\n                    binding.colorChanger.visibility = View.INVISIBLE\n                }\n\n                override fun onAnimationCancel(animation: Animator) {\n\n                }\n\n                override fun onAnimationRepeat(animation: Animator) {\n\n                }\n            })\n            animator.start()\n        }\n    }\n\n    private fun setState(isLoggedIn: Boolean) {\n        runOnUiThread {\n            binding.layMain.root.visibility = if (isLoggedIn) View.GONE else View.VISIBLE\n            when (Backups.type) {\n                Backups.Type.LOCAL, Backups.Type.DROPBOX -> {\n                    binding.layButtons.root.visibility = if (isLoggedIn) View.VISIBLE else View.GONE\n                    binding.layFirestore.root.visibility = View.GONE\n                }\n                Backups.Type.FIRESTORE -> {\n                    binding.layFirestore.root.visibility = if (isLoggedIn) View.VISIBLE else View.GONE\n                    binding.layButtons.root.visibility = View.GONE\n                }\n                Backups.Type.NONE -> {\n                    binding.layButtons.root.visibility = if (isLoggedIn) View.VISIBLE else View.GONE\n                    binding.layFirestore.root.visibility = if (isLoggedIn) View.VISIBLE else View.GONE\n                }\n            }\n        }\n    }\n\n    override fun onResume() {\n        super.onResume()\n        if (waitingLogin) {\n            val token = Auth.getOAuth2Token()\n            if (service is DropBoxService && service?.logIn(token) == true) {\n                Backups.type = Backups.Type.DROPBOX\n            }\n            onLogin()\n        }\n    }\n\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        if (FirestoreManager.handleLogin(this, requestCode, resultCode, data)) {\n            initFirestoreSync()\n        }\n        onLogin()\n    }\n\n    companion object {\n\n        fun start(context: Context) {\n            context.startActivity(Intent(context, BackUpActivity::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/Backups.kt",
    "content": "package knf.kuma.backup\r\n\r\nimport android.content.Context\r\nimport android.view.View\r\nimport androidx.preference.PreferenceManager\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.google.android.material.snackbar.Snackbar\r\nimport com.google.gson.reflect.TypeToken\r\nimport knf.kuma.App\r\nimport knf.kuma.achievements.AchievementManager\r\nimport knf.kuma.backup.framework.BackupService\r\nimport knf.kuma.backup.framework.DropBoxService\r\nimport knf.kuma.backup.framework.LocalService\r\nimport knf.kuma.backup.objects.BackupObject\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.safeDismiss\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.commons.showSnackbar\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.Achievement\r\nimport knf.kuma.pojos.AnimeObject\r\nimport knf.kuma.pojos.AutoBackupObject\r\nimport knf.kuma.pojos.FavoriteObject\r\nimport knf.kuma.pojos.RecordObject\r\nimport knf.kuma.pojos.SeeingObject\r\nimport knf.kuma.pojos.SeenObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\nimport org.jetbrains.anko.doAsync\r\nimport java.text.SimpleDateFormat\r\nimport java.util.Calendar\r\nimport java.util.Locale\r\n\r\nobject Backups {\r\n\r\n    private const val keyFavs = \"favs\"\r\n    private const val keyHistory = \"history\"\r\n    private const val keyFollowing = \"following\"\r\n    private const val keySeen = \"seen\"\r\n    private const val keySeenNew = \"seencompact\"\r\n    const val keyAchievements = \"achievements\"\r\n    const val keyAutoBackup = \"autobackup\"\r\n\r\n    var type: Type\r\n        get() = when (PreferenceManager.getDefaultSharedPreferences(App.context).getInt(\"backup_type\", -1)) {\r\n            2 -> Type.FIRESTORE\r\n            1 -> Type.DROPBOX\r\n            0 -> Type.LOCAL\r\n            else -> Type.NONE\r\n        }\r\n        set(type) = PreferenceManager.getDefaultSharedPreferences(App.context).edit().putInt(\"backup_type\", type.value).apply()\r\n\r\n    fun createService(): BackupService? =\r\n            when (type) {\r\n                Type.DROPBOX -> DropBoxService()\r\n                Type.LOCAL -> LocalService()\r\n                else -> null\r\n            }?.also { it.start() }\r\n\r\n    fun search(backupService: BackupService? = null, id: String, onFound: (backupObject: BackupObject<*>?) -> Unit = {}) {\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            val service = backupService ?: createService()\r\n            service?.search(id)?.let { onFound(it) } ?: onFound(null)\r\n        }\r\n    }\r\n\r\n    fun backup(view: View? = null, backupService: BackupService? = null, id: String, onBackup: (backupObject: BackupObject<*>?) -> Unit = {}) {\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            val snackbar = view?.showSnackbar(\"Respaldando...\", Snackbar.LENGTH_INDEFINITE)\r\n            val service = backupService ?: createService()\r\n            service?.backup(BackupObject(getList(id)), id)?.let { onBackup(it) } ?: onBackup(null)\r\n            doOnUIGlobal { snackbar?.safeDismiss() }\r\n        }\r\n    }\r\n\r\n    fun backupAll() {\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            val service = createService()\r\n            service?.backup(BackupObject(getList(keyFavs)), keyFavs)\r\n            service?.backup(BackupObject(getList(keyHistory)), keyHistory)\r\n            service?.backup(BackupObject(getList(keyFollowing)), keyFollowing)\r\n            service?.backup(BackupObject(getList(keySeen)), keySeen)\r\n            service?.backup(BackupObject(getList(keySeenNew)), keySeenNew)\r\n        }\r\n    }\r\n\r\n    fun restoreDialog(context: Context?, view: View, id: String, backupObject: BackupObject<*>?) {\r\n        if (backupObject != null)\r\n            context?.let {\r\n                MaterialDialog(it).safeShow {\r\n                    message(text = \"¿Como desea restaurar?\")\r\n                    positiveButton(text = \"mezclar\") { restore(view, false, id, backupObject) }\r\n                    negativeButton(text = \"reemplazar\") { restore(view, true, id, backupObject) }\r\n                }\r\n            }\r\n    }\r\n\r\n    fun restoreAll() {\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            val service = createService()\r\n            service?.search(keyFavs)?.let { restore(null, false, keyFavs, it) }\r\n            service?.search(keyHistory)?.let { restore(null, false, keyHistory, it) }\r\n            service?.search(keyFollowing)?.let { restore(null, false, keyFollowing, it) }\r\n            service?.search(keySeen)?.let { restore(null, false, keySeen, it) }\r\n            service?.search(keySeenNew)?.let { restore(null, false, keySeenNew, it) }\r\n        }\r\n    }\r\n\r\n    private fun restore(view: View? = null, replace: Boolean, id: String, backupObject: BackupObject<*>) {\r\n        val snackbar = view?.showSnackbar(\"Restaurando...\", Snackbar.LENGTH_INDEFINITE)\r\n        doAsync {\r\n            try {\r\n                when (id) {\r\n                    keyFavs -> {\r\n                        if (replace)\r\n                            CacheDB.INSTANCE.favsDAO().clear()\r\n                        (backupObject.data?.filterIsInstance<FavoriteObject>() as? MutableList<FavoriteObject>)?.let { CacheDB.INSTANCE.favsDAO().addAll(it) }\r\n                    }\r\n                    keyHistory -> {\r\n                        if (replace)\r\n                            CacheDB.INSTANCE.recordsDAO().clear()\r\n                        (backupObject.data?.filterIsInstance<RecordObject>() as? MutableList<RecordObject>)?.let { CacheDB.INSTANCE.recordsDAO().addAll(it) }\r\n                    }\r\n                    keyFollowing -> {\r\n                        if (replace)\r\n                            CacheDB.INSTANCE.seeingDAO().clear()\r\n                        (backupObject.data?.filterIsInstance<SeeingObject>() as? MutableList<SeeingObject>)?.let { CacheDB.INSTANCE.seeingDAO().addAll(it) }\r\n                    }\r\n                    keySeen -> {\r\n                        if (replace) {\r\n                            CacheDB.INSTANCE.chaptersDAO().clear()\r\n                            CacheDB.INSTANCE.seenDAO().clear()\r\n                        }\r\n                        (backupObject.data?.filterIsInstance<AnimeObject.WebInfo.AnimeChapter>() as? MutableList<AnimeObject.WebInfo.AnimeChapter>)?.let { CacheDB.INSTANCE.seenDAO().addAll(it.map { SeenObject.fromChapter(it) }) }\r\n                    }\r\n                    keySeenNew -> {\r\n                        if (replace)\r\n                            CacheDB.INSTANCE.seenDAO().clear()\r\n                        (backupObject.data?.filterIsInstance<SeenObject>() as? MutableList<SeenObject>)?.let { CacheDB.INSTANCE.seenDAO().addAll(it) }\r\n                    }\r\n                }\r\n                snackbar?.safeDismiss()\r\n                view?.showSnackbar(\"Restauración completada\")\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n                snackbar?.safeDismiss()\r\n                view?.showSnackbar(\"Error al restaurar\")\r\n            }\r\n        }\r\n    }\r\n\r\n    val isAnimeflvInstalled: Boolean\r\n        get() =\r\n            try {\r\n                App.context.packageManager.getPackageInfo(\"knf.animeflv\", 0)\r\n                AchievementManager.unlock(listOf(7))\r\n                true\r\n            } catch (e: Exception) {\r\n                false\r\n            }\r\n\r\n    val isKeyInstalled: Boolean\r\n        get() =\r\n            try {\r\n                App.context.packageManager.getPackageInfo(\"knf.kuma.key\", 0)\r\n                true\r\n            } catch (e: Exception) {\r\n                false\r\n            }\r\n\r\n    private fun getList(id: String): List<*> {\r\n        return when (id) {\r\n            keyFavs -> CacheDB.INSTANCE.favsDAO().allRaw\r\n            keyHistory -> CacheDB.INSTANCE.recordsDAO().allRaw\r\n            keyFollowing -> CacheDB.INSTANCE.seeingDAO().allRaw\r\n            keySeenNew -> CacheDB.INSTANCE.seenDAO().all\r\n            keyAchievements -> CacheDB.INSTANCE.achievementsDAO().all\r\n            else -> mutableListOf<RecordObject>()\r\n        }\r\n    }\r\n\r\n    fun getType(id: String): java.lang.reflect.Type {\r\n        return when (id) {\r\n            keyFavs -> object : TypeToken<BackupObject<FavoriteObject>>() {\r\n\r\n            }.type\r\n            keyHistory -> object : TypeToken<BackupObject<RecordObject>>() {\r\n\r\n            }.type\r\n            keyFollowing -> object : TypeToken<BackupObject<SeeingObject>>() {\r\n\r\n            }.type\r\n            keySeenNew -> object : TypeToken<BackupObject<SeenObject>>() {\r\n\r\n            }.type\r\n            keySeen -> object : TypeToken<BackupObject<AnimeObject.WebInfo.AnimeChapter>>() {\r\n\r\n            }.type\r\n            keyAchievements -> object : TypeToken<BackupObject<Achievement>>() {\r\n\r\n            }.type\r\n            keyAutoBackup -> object : TypeToken<AutoBackupObject>() {\r\n\r\n            }.type\r\n            else -> object : TypeToken<BackupObject<*>>() {\r\n\r\n            }.type\r\n        }\r\n    }\r\n\r\n    fun saveLastBackup() {\r\n        PrefsUtil.lastBackup = SimpleDateFormat(\"dd/MM/yyyy kk:mm\", Locale.getDefault()).format(Calendar.getInstance().time)\r\n    }\r\n\r\n    enum class Type(var value: Int) {\r\n        NONE(-1),\r\n        LOCAL(0),\r\n        DROPBOX(1),\r\n        FIRESTORE(2)\r\n    }\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/MigrationActivity.kt",
    "content": "package knf.kuma.backup\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport androidx.fragment.app.Fragment\nimport knf.kuma.R\nimport knf.kuma.backup.screens.MigrateDirectoryFragment\nimport knf.kuma.backup.screens.MigrateSuccessFragment\nimport knf.kuma.backup.screens.MigrateVersionFragment\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.directory.DirectoryService\n\nclass MigrationActivity : GenericActivity(), DirectoryService.OnDirStatus {\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_migrate)\n    }\n\n    override fun onResume() {\n        super.onResume()\n        if (MigrateVersionFragment.installedCode < 252)\n            setFragment(MigrateVersionFragment())\n        else if (!PrefsUtil.isDirectoryFinished) {\n            DirectoryService.run(this)\n            setFragment(MigrateDirectoryFragment[this])\n        } else\n            setFragment(MigrateSuccessFragment())\n    }\n\n    private fun setFragment(fragment: Fragment) {\n        val transaction = supportFragmentManager.beginTransaction()\n        transaction.replace(R.id.root, fragment)\n        transaction.commit()\n    }\n\n    override fun onFinished() {\n        setFragment(MigrateSuccessFragment())\n    }\n\n    companion object {\n\n        fun start(context: Context) {\n            context.startActivity(Intent(context, MigrationActivity::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/FirestoreManager.kt",
    "content": "package knf.kuma.backup.firestore\r\n\r\nimport android.app.Activity\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.os.Build\r\nimport android.util.Log\r\nimport androidx.lifecycle.MutableLiveData\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.firebase.ui.auth.AuthUI\r\nimport com.firebase.ui.auth.IdpResponse\r\nimport com.google.firebase.Firebase\r\nimport com.google.firebase.auth.FirebaseAuth\r\nimport com.google.firebase.auth.FirebaseUser\r\nimport com.google.firebase.auth.UserProfileChangeRequest\r\nimport com.google.firebase.firestore.CollectionReference\r\nimport com.google.firebase.firestore.DocumentSnapshot\r\nimport com.google.firebase.firestore.ListenerRegistration\r\nimport com.google.firebase.firestore.QuerySnapshot\r\nimport com.google.firebase.firestore.firestore\r\nimport com.google.firebase.firestore.toObject\r\nimport knf.kuma.App\r\nimport knf.kuma.BuildConfig\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.SubscriptionReceiver\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.backup.firestore.data.AchievementsData\r\nimport knf.kuma.backup.firestore.data.EAData\r\nimport knf.kuma.backup.firestore.data.FavsData\r\nimport knf.kuma.backup.firestore.data.GenresData\r\nimport knf.kuma.backup.firestore.data.HistoryData\r\nimport knf.kuma.backup.firestore.data.QueueData\r\nimport knf.kuma.backup.firestore.data.SeeingData\r\nimport knf.kuma.backup.firestore.data.SeenData\r\nimport knf.kuma.backup.firestore.data.TopData\r\nimport knf.kuma.commons.Network\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.admFile\r\nimport knf.kuma.commons.currentTime\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.noCrashExec\r\nimport knf.kuma.commons.noCrashLet\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.database.EADB\r\nimport knf.kuma.pojos.SeenObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport org.jetbrains.anko.doAsync\r\nimport xdroid.toaster.Toaster.toast\r\nimport kotlin.contracts.ExperimentalContracts\r\nimport kotlin.contracts.contract\r\nimport kotlin.coroutines.resume\r\nimport kotlin.coroutines.suspendCoroutine\r\n\r\nobject FirestoreManager {\r\n    enum class State { IDLE, UPLOAD, SYNC }\r\n\r\n    val firestoreDB by lazy { Firebase.firestore }\r\n    val user: FirebaseUser? get() = FirebaseAuth.getInstance().currentUser\r\n    val uid: String? get() = user?.uid\r\n\r\n    private val listeners = mutableListOf<ListenerRegistration>()\r\n\r\n    val isLoggedIn: Boolean get() = uid != null\r\n\r\n    val favsLiveData = MutableLiveData(State.IDLE)\r\n    val seenLiveData = MutableLiveData(State.IDLE)\r\n    val eaLiveData = MutableLiveData(State.IDLE)\r\n    val achievementsLiveData = MutableLiveData(State.IDLE)\r\n    val genresLiveData = MutableLiveData(State.IDLE)\r\n    val historyLiveData = MutableLiveData(State.IDLE)\r\n    val queueLiveData = MutableLiveData(State.IDLE)\r\n    val seeingLiveData = MutableLiveData(State.IDLE)\r\n\r\n    private var isUpdateBlocked = false\r\n    var isFirestoreEnabled = false\r\n\r\n\r\n    @OptIn(ExperimentalContracts::class)\r\n    fun start() {\r\n        if (!isGPlayServicesEnabled() || isFirestoreEnabled) return\r\n        if (isLoggedIn && ((PrefsUtil.isAdsEnabled && !Network.isAdsBlocked) || BuildConfig.DEBUG || admFile.exists() || PrefsUtil.isSubscriptionEnabled)) {\r\n            isFirestoreEnabled = true\r\n            QueueManager.open()\r\n            doAsync {\r\n                firestoreDB.document(\"users/$uid/backups/history\").addSnapshotListener { documentSnapshot, firebaseFirestoreException ->\r\n                    doAsync {\r\n                        if (documentSnapshot.needsUpdate() && !isUpdateBlocked) {\r\n                            runBlocking(Dispatchers.Main) { historyLiveData.value = State.SYNC }\r\n                            documentSnapshot.toObject<HistoryData>()?.list?.let {\r\n                                CacheDB.INSTANCE.recordsDAO().apply {\r\n                                    clear()\r\n                                    addAll(it)\r\n                                }\r\n                                PrefsUtil.lsHistory = currentTime()\r\n                                Log.e(\"Firestore\", \"History updated\")\r\n                            }\r\n                            runBlocking(Dispatchers.Main) { historyLiveData.value = State.IDLE }\r\n                        } else firebaseFirestoreException?.printStackTrace()\r\n                    }\r\n                }.also { listeners.add(it) }\r\n                firestoreDB.document(\"users/$uid/backups/achievements\").addSnapshotListener { documentSnapshot, firebaseFirestoreException ->\r\n                    doAsync {\r\n                        if (documentSnapshot.needsUpdate() && !isUpdateBlocked) {\r\n                            runBlocking(Dispatchers.Main) { achievementsLiveData.value = State.SYNC }\r\n                            documentSnapshot.toObject<AchievementsData>()?.list?.let {\r\n                                CacheDB.INSTANCE.achievementsDAO().apply {\r\n                                    update(it)\r\n                                }\r\n                                PrefsUtil.lsAchievements = currentTime()\r\n                                Log.e(\"Firestore\", \"Achievements updated\")\r\n                            }\r\n                            runBlocking(Dispatchers.Main) { achievementsLiveData.value = State.IDLE }\r\n                        } else firebaseFirestoreException?.printStackTrace()\r\n                    }\r\n                }.also { listeners.add(it) }\r\n                firestoreDB.document(\"users/$uid/backups/ea\").addSnapshotListener { documentSnapshot, firebaseFirestoreException ->\r\n                    doAsync {\r\n                        if (documentSnapshot.needsUpdate() && !isUpdateBlocked) {\r\n                            runBlocking(Dispatchers.Main) { eaLiveData.value = State.SYNC }\r\n                            documentSnapshot.toObject<EAData>()?.list?.let {\r\n                                EADB.INSTANCE.eaDAO().apply {\r\n                                    unlock(it)\r\n                                }\r\n                                PrefsUtil.lsEa = currentTime()\r\n                                Log.e(\"Firestore\", \"EA Updated\")\r\n                            }\r\n                            runBlocking(Dispatchers.Main) { eaLiveData.value = State.IDLE }\r\n                        } else firebaseFirestoreException?.printStackTrace()\r\n                    }\r\n                }.also { listeners.add(it) }\r\n                firestoreDB.document(\"users/$uid/backups/favs\").addSnapshotListener { documentSnapshot, firebaseFirestoreException ->\r\n                    doAsync {\r\n                        if (documentSnapshot.needsUpdate() && !isUpdateBlocked) {\r\n                            runBlocking(Dispatchers.Main) { favsLiveData.value = State.SYNC }\r\n                            documentSnapshot.toObject<FavsData>()?.list?.let {\r\n                                CacheDB.INSTANCE.favsDAO().apply {\r\n                                    clear()\r\n                                    addAll(it)\r\n                                }\r\n                                PrefsUtil.lsFavs = currentTime()\r\n                                Log.e(\"Firestore\", \"Favs updated\")\r\n                            }\r\n                            runBlocking(Dispatchers.Main) { favsLiveData.value = State.IDLE }\r\n                        } else firebaseFirestoreException?.printStackTrace()\r\n                    }\r\n                }.also { listeners.add(it) }\r\n                firestoreDB.document(\"users/$uid/backups/genres\").addSnapshotListener { documentSnapshot, firebaseFirestoreException ->\r\n                    doAsync {\r\n                        if (documentSnapshot.needsUpdate() && !isUpdateBlocked) {\r\n                            runBlocking(Dispatchers.Main) { genresLiveData.value = State.SYNC }\r\n                            documentSnapshot.toObject<GenresData>()?.list?.let {\r\n                                CacheDB.INSTANCE.genresDAO().apply {\r\n                                    reset()\r\n                                    insertStatus(it)\r\n                                }\r\n                                PrefsUtil.lsGenres = currentTime()\r\n                                Log.e(\"Firestore\", \"Genres updated\")\r\n                            }\r\n                            runBlocking(Dispatchers.Main) { genresLiveData.value = State.IDLE }\r\n                        } else firebaseFirestoreException?.printStackTrace()\r\n                    }\r\n                }.also { listeners.add(it) }\r\n                firestoreDB.document(\"users/$uid/backups/queue\").addSnapshotListener { documentSnapshot, firebaseFirestoreException ->\r\n                    doAsync {\r\n                        if (documentSnapshot.needsUpdate() && !isUpdateBlocked) {\r\n                            runBlocking(Dispatchers.Main) { queueLiveData.value = State.SYNC }\r\n                            documentSnapshot.toObject<QueueData>()?.list?.let {\r\n                                CacheDB.INSTANCE.queueDAO().apply {\r\n                                    nuke()\r\n                                    add(it)\r\n                                }\r\n                                PrefsUtil.lsQueue = currentTime()\r\n                                Log.e(\"Firestore\", \"Queue updated\")\r\n                            }\r\n                            runBlocking(Dispatchers.Main) { queueLiveData.value = State.IDLE }\r\n                        } else firebaseFirestoreException?.printStackTrace()\r\n                    }\r\n                }.also { listeners.add(it) }\r\n                firestoreDB.document(\"users/$uid/backups/seeing\").addSnapshotListener { documentSnapshot, firebaseFirestoreException ->\r\n                    doAsync {\r\n                        if (documentSnapshot.needsUpdate() && !isUpdateBlocked) {\r\n                            runBlocking(Dispatchers.Main) { seeingLiveData.value = State.SYNC }\r\n                            documentSnapshot.toObject<SeeingData>()?.list?.let {\r\n                                CacheDB.INSTANCE.seeingDAO().apply {\r\n                                    clear()\r\n                                    addAll(it)\r\n                                }\r\n                                PrefsUtil.lsSeeing = currentTime()\r\n                                Log.e(\"Firestore\", \"Seeing updated\")\r\n                            }\r\n                            runBlocking(Dispatchers.Main) { seeingLiveData.value = State.IDLE }\r\n                        } else firebaseFirestoreException?.printStackTrace()\r\n                    }\r\n                }.also { listeners.add(it) }\r\n                firestoreDB.collection(\"users/$uid/backups/seen/data\").addSnapshotListener { querySnapshot, firebaseFirestoreException ->\r\n                    doAsync {\r\n                        if (querySnapshot.needsUpdate() && !isUpdateBlocked) {\r\n                            runBlocking(Dispatchers.Main) { seenLiveData.value = State.SYNC }\r\n                            val nList = mutableListOf<SeenObject>()\r\n                            querySnapshot.documents.forEach {\r\n                                it.toObject<SeenData>()?.list?.let { seenList ->\r\n                                    nList.addAll(seenList)\r\n                                }\r\n                            }\r\n                            CacheDB.INSTANCE.seenDAO().apply {\r\n                                clear()\r\n                                addAll(nList)\r\n                            }\r\n                            PrefsUtil.lsSeen = currentTime()\r\n                            Log.e(\"Firestore\", \"Seen updated\")\r\n                            runBlocking(Dispatchers.Main) { seenLiveData.value = State.IDLE }\r\n                        } else firebaseFirestoreException?.printStackTrace()\r\n                    }\r\n                }.also { listeners.add(it) }\r\n                firestoreDB.document(\"subscriptions/$uid\").get().addOnSuccessListener {\r\n                    if (it.exists() && PrefsUtil.subscriptionToken == null) {\r\n                        noCrash {\r\n                            it.toObject<SubscriptionReceiver.SubscriptionInfo>()?.let {\r\n                                GlobalScope.launch(Dispatchers.IO) {\r\n                                    val info = SubscriptionReceiver.checkStatus(it.token)\r\n                                    if (info.isVerified) {\r\n                                        PrefsUtil.subscriptionToken = it.token\r\n                                        toast(\"Suscripción restaurada\")\r\n                                    } else {\r\n                                        firestoreDB.document(\"subscriptions/$uid\").delete()\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        } else if (isLoggedIn) {\r\n            doSignOut(App.context)\r\n            Backups.type = Backups.Type.NONE\r\n            toast(\"Firestore deshabilitado\")\r\n        }\r\n        doAsync {\r\n            firestoreDB.document(\"top/${uid\r\n                    ?: PrefsUtil.instanceUuid}\").addSnapshotListener { documentSnapshot, _ ->\r\n                doAsync {\r\n                    if (documentSnapshot.needsUpdate() && !isUpdateBlocked) {\r\n                        documentSnapshot.toObject<TopData>()?.let {\r\n                            if (it.forced) {\r\n                                user?.updateProfile(UserProfileChangeRequest.Builder().setDisplayName(it.name).build())\r\n                                        ?: { PrefsUtil.instanceName = it.name }()\r\n                            }\r\n                            PrefsUtil.userRewardedVideoCount = it.number\r\n                            Log.e(\"Firestore\", \"Top updated\")\r\n                        }\r\n                    }\r\n                }\r\n            }.also { listeners.add(it) }\r\n        }\r\n    }\r\n\r\n    fun stop() {\r\n        QueueManager.close()\r\n        listeners.forEach { it.remove() }\r\n    }\r\n\r\n    private fun uploadAllData(checkForFiles: Boolean, activity: Activity) {\r\n        if (!isFirestoreEnabled) return\r\n        if (checkForFiles)\r\n            firestoreDB.collection(\"users/$uid/backups\").get()\r\n                    .addOnSuccessListener {\r\n                        if (it.isEmpty) {\r\n                            MaterialDialog(activity).safeShow {\r\n                                title(text = \"¿Nuevo usuario?\")\r\n                                message(text = \"Este parece ser tu primer inicio de sesion, tus datos necesitan ser subidos a la nube, primero asegurate que éste sea tu dispositivo principal!\")\r\n                                cancelable(false)\r\n                                positiveButton(text = \"Subir\") {\r\n                                    setDefaultDevice()\r\n                                    uploadAllData(false, activity)\r\n                                }\r\n                                negativeButton(text = \"Cerrar sesion\") {\r\n                                    doSignOut(activity)\r\n                                }\r\n                            }\r\n                            firestoreDB.document(\"top/${PrefsUtil.instanceUuid}\").delete()\r\n                        } else {\r\n                            firestoreDB.document(\"users/$uid/backups/info\")\r\n                                    .get().addOnCompleteListener { document ->\r\n                                        val data = document.result?.data\r\n                                        if (data != null && data[\"uuid\"] == PrefsUtil.instanceUuid) {\r\n                                            MaterialDialog(activity).safeShow {\r\n                                                title(text = \"Bienvenido de nuevo\")\r\n                                                message(text = \"Actualmente tienes datos en la nube y este es tu dispositivo principal, ¿que datos quieres usar?\\n(Usar tus datos locales sobreescribirá lo que haya en la nube)\")\r\n                                                cancelable(false)\r\n                                                positiveButton(text = \"Datos locales\") {\r\n                                                    uploadAllData(false, activity)\r\n                                                }\r\n                                                negativeButton(text = \"Descargar de la nube\") {\r\n                                                    start()\r\n                                                }\r\n                                            }\r\n                                        } else {\r\n                                            toast(\"Se descargarán tus datos de la nube\")\r\n                                            start()\r\n                                        }\r\n                                    }\r\n                        }\r\n                    }\r\n        else {\r\n            stop()\r\n            isUpdateBlocked = true\r\n            QueueManager.open()\r\n            Log.e(\"Firestore\", \"On upload all data\")\r\n            syncData {\r\n                history()\r\n                seen()\r\n                achievements()\r\n                ea()\r\n                favs()\r\n                genres()\r\n                queue()\r\n                seeing()\r\n                top()\r\n            }\r\n            GlobalScope.launch(Dispatchers.IO) {\r\n                delay(10000)\r\n                isUpdateBlocked = false\r\n                start()\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun setDefaultDevice() {\r\n        if (!isFirestoreEnabled) return\r\n        firestoreDB.document(\"users/$uid/backups/info\").set(mapOf(\"uuid\" to PrefsUtil.instanceUuid))\r\n    }\r\n\r\n    fun updateHistory(collection: CollectionReference) =\r\n            noCrash {\r\n                doOnUIGlobal { historyLiveData.value = State.SYNC }\r\n                collection.document(\"history\").set(HistoryData.create()).addOnSuccessListener {\r\n                    Log.e(\"Firestore\", \"History upload success\")\r\n                    PrefsUtil.lsHistory = currentTime()\r\n                    doOnUIGlobal { historyLiveData.value = State.IDLE }\r\n                }.addOnFailureListener {\r\n                    Log.e(\"Firestore\", \"History upload error\", it)\r\n                    doOnUIGlobal { historyLiveData.value = State.IDLE }\r\n                }\r\n            }\r\n\r\n    fun updateSeen(collection: CollectionReference) =\r\n            noCrash {\r\n                doOnUIGlobal { seenLiveData.value = State.SYNC }\r\n                val data = SeenData.create()\r\n                val segments = data.list.chunked(10000).map { SeenData(it) }\r\n                collection.document(\"seen\").set(mapOf(\"size\" to segments.size))\r\n                val subcollection = collection.document(\"seen\").collection(\"data\")\r\n                segments.forEachIndexed { index, seenData ->\r\n                    subcollection.document(\"seen_$index\").set(seenData).addOnSuccessListener {\r\n                        Log.e(\"Firestore\", \"Seen_$index upload success\")\r\n                    }.addOnFailureListener {\r\n                        Log.e(\"Firestore\", \"Seen_$index upload error\", it)\r\n                    }\r\n                }\r\n                runBlocking {\r\n                    var nextIndex = data.list.size\r\n                    var needsNext = true\r\n                    while (needsNext) {\r\n                        needsNext = suspendCoroutine {\r\n                            noCrashLet(false) {\r\n                                val reference = subcollection.document(\"seen_$needsNext\")\r\n                                reference.get().addOnCompleteListener { subDocument ->\r\n                                    noCrashExec(exec = { it.resume(false) }) {\r\n                                        if (subDocument.result?.exists() == true) {\r\n                                            reference.delete()\r\n                                            it.resume(true)\r\n                                        } else\r\n                                            it.resume(false)\r\n                                    }\r\n                                }\r\n                            }\r\n                        }\r\n                        nextIndex++\r\n                    }\r\n                }\r\n                PrefsUtil.lsSeen = currentTime()\r\n                doOnUIGlobal { seenLiveData.value = State.IDLE }\r\n            }\r\n\r\n    fun updateAchievements(collection: CollectionReference) =\r\n            noCrash {\r\n                doOnUIGlobal { achievementsLiveData.value = State.SYNC }\r\n                collection.document(\"achievements\").set(AchievementsData.create()).addOnSuccessListener {\r\n                    Log.e(\"Firestore\", \"Achievements upload success\")\r\n                    PrefsUtil.lsAchievements = currentTime()\r\n                    doOnUIGlobal { achievementsLiveData.value = State.IDLE }\r\n                }.addOnFailureListener {\r\n                    Log.e(\"Firestore\", \"Achievements upload error\", it)\r\n                    doOnUIGlobal { achievementsLiveData.value = State.IDLE }\r\n                }\r\n            }\r\n\r\n    fun updateEA(collection: CollectionReference) =\r\n            noCrash {\r\n                doOnUIGlobal { eaLiveData.value = State.SYNC }\r\n                collection.document(\"ea\").set(EAData.create()).addOnSuccessListener {\r\n                    Log.e(\"Firestore\", \"EA upload success\")\r\n                    PrefsUtil.lsEa = currentTime()\r\n                    doOnUIGlobal { eaLiveData.value = State.IDLE }\r\n                }.addOnFailureListener {\r\n                    Log.e(\"Firestore\", \"EA upload error\", it)\r\n                    doOnUIGlobal { eaLiveData.value = State.IDLE }\r\n                }\r\n            }\r\n\r\n    fun updateFavs(collection: CollectionReference) =\r\n            noCrash {\r\n                doOnUIGlobal { favsLiveData.value = State.SYNC }\r\n                collection.document(\"favs\").set(FavsData.create()).addOnSuccessListener {\r\n                    Log.e(\"Firestore\", \"Favs upload success\")\r\n                    PrefsUtil.lsFavs = currentTime()\r\n                    doOnUIGlobal { favsLiveData.value = State.IDLE }\r\n                }.addOnFailureListener {\r\n                    Log.e(\"Firestore\", \"Favs upload error\", it)\r\n                    doOnUIGlobal { favsLiveData.value = State.IDLE }\r\n                }\r\n            }\r\n\r\n    fun updateGenres(collection: CollectionReference) =\r\n            noCrash {\r\n                doOnUIGlobal { genresLiveData.value = State.SYNC }\r\n                collection.document(\"genres\").set(GenresData.create()).addOnSuccessListener {\r\n                    Log.e(\"Firestore\", \"Genres upload success\")\r\n                    PrefsUtil.lsGenres = currentTime()\r\n                    doOnUIGlobal { genresLiveData.value = State.IDLE }\r\n                }.addOnFailureListener {\r\n                    Log.e(\"Firestore\", \"Genres upload error\", it)\r\n                    doOnUIGlobal { genresLiveData.value = State.IDLE }\r\n                }\r\n            }\r\n\r\n    fun updateQueue(collection: CollectionReference) =\r\n            noCrash {\r\n                doOnUIGlobal { queueLiveData.value = State.SYNC }\r\n                collection.document(\"queue\").set(QueueData.create()).addOnSuccessListener {\r\n                    Log.e(\"Firestore\", \"Queue upload success\")\r\n                    PrefsUtil.lsQueue = currentTime()\r\n                    doOnUIGlobal { queueLiveData.value = State.IDLE }\r\n                }.addOnFailureListener {\r\n                    Log.e(\"Firestore\", \"Queue upload error\", it)\r\n                    doOnUIGlobal { queueLiveData.value = State.IDLE }\r\n                }\r\n            }\r\n\r\n    fun updateSeeing(collection: CollectionReference) =\r\n            noCrash {\r\n                doOnUIGlobal { seeingLiveData.value = State.SYNC }\r\n                collection.document(\"seeing\").set(SeeingData.create()).addOnSuccessListener {\r\n                    Log.e(\"Firestore\", \"Seeing upload success\")\r\n                    PrefsUtil.lsSeeing = currentTime()\r\n                    doOnUIGlobal { seeingLiveData.value = State.IDLE }\r\n                }.addOnFailureListener {\r\n                    Log.e(\"Firestore\", \"Seeing upload error\", it)\r\n                    doOnUIGlobal { seeingLiveData.value = State.IDLE }\r\n                }\r\n            }\r\n\r\n    fun updateTop() =\r\n            doAsync {\r\n                noCrash {\r\n                    firestoreDB.document(\"top/${uid\r\n                            ?: PrefsUtil.instanceUuid}\").set(TopData.create())\r\n                    Log.e(\"Firestore\", \"Top upload success\")\r\n                }\r\n            }\r\n\r\n    fun updateTopSync() =\r\n            noCrash {\r\n                firestoreDB.document(\"top/${uid\r\n                        ?: PrefsUtil.instanceUuid}\").set(TopData.create())\r\n                Log.e(\"Firestore\", \"Top upload success\")\r\n            }\r\n\r\n    @ExperimentalContracts\r\n    fun listenTop(callback: (list: List<TopData>) -> Unit): ListenerRegistration {\r\n        var lastUpdate = 0L\r\n        return firestoreDB.collection(\"top\").addSnapshotListener { querySnapshot, exception ->\r\n            exception?.let { Log.e(\"Firestore\", \"Top Query Error\", it) }\r\n            if (System.currentTimeMillis() >= lastUpdate + 5000) {\r\n                lastUpdate = System.currentTimeMillis()\r\n                Log.e(\"Firestore\", \"On tops update\")\r\n                querySnapshot?.let { callback(it.documents.mapNotNull { document -> document.toObject<TopData>() }) }\r\n            }\r\n        }\r\n    }\r\n\r\n\r\n    fun doLogin(activity: Activity) {\r\n        if (isLoggedIn) {\r\n            MaterialDialog(activity).safeShow {\r\n                message(text = \"Deseas cerrar sesión?\")\r\n                positiveButton(text = \"Cerrar sesion\") {\r\n                    doSignOut(activity)\r\n                }\r\n            }\r\n        } else {\r\n            val providers = arrayListOf(\r\n                    AuthUI.IdpConfig.EmailBuilder().build(),\r\n                    AuthUI.IdpConfig.GoogleBuilder().build(),\r\n                //AuthUI.IdpConfig.TwitterBuilder().build()\r\n            )\r\n            /*if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(activity) != ConnectionResult.SUCCESS) {\r\n                providers.removeAt(1)\r\n            }*/\r\n            activity.startActivityForResult(\r\n                    AuthUI.getInstance()\r\n                        .createSignInIntentBuilder()\r\n                        .setAvailableProviders(providers)\r\n                        .setTheme(R.style.AppTheme_FirebaseUI)\r\n                        .setLogo(R.drawable.ic_launcher_login)\r\n                        .setCredentialManagerEnabled(false)\r\n                        .build()\r\n                    , 5548\r\n            )\r\n        }\r\n    }\r\n\r\n    fun doSignOut(context: Context) = AuthUI.getInstance().signOut(context)\r\n\r\n\r\n    @OptIn(ExperimentalContracts::class)\r\n    fun handleLogin(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?): Boolean {\r\n        if (requestCode == 5548) {\r\n            val response = IdpResponse.fromResultIntent(data)\r\n            if (resultCode == Activity.RESULT_OK) {\r\n                Backups.type = Backups.Type.FIRESTORE\r\n                uploadAllData(true, activity)\r\n                return true\r\n            } else if (response != null) {\r\n                val error = response.error\r\n                error?.printStackTrace()\r\n                toast(\"Error al iniciar sesion: ${error?.message}\")\r\n            }\r\n        }\r\n        return false\r\n    }\r\n\r\n    private fun isGPlayServicesEnabled(): Boolean =\r\n            Build.VERSION.SDK_INT < Build.VERSION_CODES.R ||\r\n                    PrefsUtil.isSecurityUpdated || !PrefsUtil.spProtectionEnabled\r\n\r\n}\r\n\r\n@ExperimentalContracts\r\nfun DocumentSnapshot?.needsUpdate(): Boolean {\r\n    contract { returns(true) implies (this@needsUpdate != null) }\r\n    return this != null && !this.metadata.hasPendingWrites() && this.exists()\r\n}\r\n\r\n@ExperimentalContracts\r\nfun QuerySnapshot?.needsUpdate(): Boolean {\r\n    contract { returns(true) implies (this@needsUpdate != null) }\r\n    return this != null && !this.metadata.hasPendingWrites()\r\n}\r\n\r\nclass SyncRequest(private val collection: CollectionReference) {\r\n    private val syncList = mutableListOf<() -> Unit>()\r\n\r\n    fun history() = syncList.add { runBlocking(Dispatchers.IO) { FirestoreManager.updateHistory(collection) } }\r\n    fun seen() = syncList.add { runBlocking(Dispatchers.IO) { FirestoreManager.updateSeen(collection) } }\r\n    fun achievements() = syncList.add { runBlocking(Dispatchers.IO) { FirestoreManager.updateAchievements(collection) } }\r\n    fun ea() = syncList.add { runBlocking(Dispatchers.IO) { FirestoreManager.updateEA(collection) } }\r\n    fun favs() = syncList.add { runBlocking(Dispatchers.IO) { FirestoreManager.updateFavs(collection) } }\r\n    fun genres() = syncList.add { runBlocking(Dispatchers.IO) { FirestoreManager.updateGenres(collection) } }\r\n    fun queue() = syncList.add { runBlocking(Dispatchers.IO) { FirestoreManager.updateQueue(collection) } }\r\n    fun seeing() = syncList.add { runBlocking(Dispatchers.IO) { FirestoreManager.updateSeeing(collection) } }\r\n    fun top() = syncList.add { runBlocking(Dispatchers.IO) { FirestoreManager.updateTop() } }\r\n\r\n    fun sync() {\r\n        if (FirestoreManager.isLoggedIn)\r\n            QueueManager.add(syncList)\r\n    }\r\n}\r\n\r\nfun syncData(uploads: SyncRequest.() -> Unit) {\r\n    if (!FirestoreManager.isFirestoreEnabled) return\r\n    val syncRequest = SyncRequest(FirestoreManager.firestoreDB.collection(\"users/${FirestoreManager.uid}/backups\"))\r\n    uploads(syncRequest)\r\n    syncRequest.sync()\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/QueueManager.kt",
    "content": "package knf.kuma.backup.firestore\r\n\r\nimport knf.kuma.commons.noCrash\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\n\r\nobject QueueManager {\r\n    private var list = mutableListOf<() -> Unit>()\r\n    private var isRunning = false\r\n    private var isClosed = false\r\n\r\n    fun add(items: List<() -> Unit>) {\r\n        if (isClosed) return\r\n        if (isRunning)\r\n            list.addAll(items)\r\n        else\r\n            run(items)\r\n    }\r\n\r\n    fun open() {\r\n        isRunning = false\r\n        isClosed = false\r\n    }\r\n\r\n    fun close() {\r\n        isClosed = true\r\n    }\r\n\r\n    private fun run(items: List<() -> Unit> = list) {\r\n        val tlist = ArrayList(items)\r\n        list = mutableListOf()\r\n        isRunning = true\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            tlist.forEach {\r\n                if (isClosed) return@launch\r\n                noCrash { it() }\r\n            }\r\n            if (list.isNotEmpty())\r\n                run()\r\n            else\r\n                isRunning = false\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/data/AchievementsData.kt",
    "content": "package knf.kuma.backup.firestore.data\r\n\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.Achievement\r\n\r\n@Keep\r\ndata class AchievementsData(val list: List<Achievement> = emptyList()) {\r\n    companion object {\r\n        fun create(): AchievementsData = AchievementsData(CacheDB.INSTANCE.achievementsDAO().all)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/data/EAData.kt",
    "content": "package knf.kuma.backup.firestore.data\r\n\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.database.EADB\r\nimport knf.kuma.pojos.EAObject\r\n\r\n@Keep\r\ndata class EAData(val list: List<EAObject> = emptyList()) {\r\n    companion object {\r\n        fun create(): EAData = EAData(EADB.INSTANCE.eaDAO().all)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/data/FavsData.kt",
    "content": "package knf.kuma.backup.firestore.data\r\n\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.FavoriteObject\r\n\r\n@Keep\r\ndata class FavsData(val list: List<FavoriteObject> = emptyList()) {\r\n    companion object {\r\n        fun create(): FavsData = FavsData(CacheDB.INSTANCE.favsDAO().allRaw)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/data/GenresData.kt",
    "content": "package knf.kuma.backup.firestore.data\r\n\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.GenreStatusObject\r\n\r\n@Keep\r\ndata class GenresData(val list: List<GenreStatusObject> = emptyList()) {\r\n    companion object {\r\n        fun create(): GenresData = GenresData(CacheDB.INSTANCE.genresDAO().all)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/data/HistoryData.kt",
    "content": "package knf.kuma.backup.firestore.data\r\n\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.RecordObject\r\n\r\n@Keep\r\ndata class HistoryData(val list: List<RecordObject> = emptyList()) {\r\n    companion object {\r\n        fun create(): HistoryData = HistoryData(CacheDB.INSTANCE.recordsDAO().allRaw)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/data/QueueData.kt",
    "content": "package knf.kuma.backup.firestore.data\r\n\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.QueueObject\r\n\r\n@Keep\r\ndata class QueueData(val list: List<QueueObject> = emptyList()) {\r\n    companion object {\r\n        fun create(): QueueData = QueueData(CacheDB.INSTANCE.queueDAO().allRaw)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/data/SeeingData.kt",
    "content": "package knf.kuma.backup.firestore.data\r\n\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.SeeingObject\r\n\r\n@Keep\r\ndata class SeeingData(val list: List<SeeingObject> = emptyList()) {\r\n    companion object {\r\n        fun create(): SeeingData = SeeingData(CacheDB.INSTANCE.seeingDAO().allRaw)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/data/SeenData.kt",
    "content": "package knf.kuma.backup.firestore.data\r\n\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.SeenObject\r\n\r\n@Keep\r\ndata class SeenData(val list: List<SeenObject> = emptyList()) {\r\n    companion object {\r\n        fun create(): SeenData = SeenData(CacheDB.INSTANCE.seenDAO().all)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/firestore/data/TopData.kt",
    "content": "package knf.kuma.backup.firestore.data\r\n\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.backup.firestore.FirestoreManager\r\nimport knf.kuma.commons.PrefsUtil\r\n\r\n@Keep\r\ndata class TopData(val uid: String = \"\", val name: String = \"\", val number: Int = 0, val forced: Boolean = false) {\r\n    companion object {\r\n        fun create() = FirestoreManager.user?.let {\r\n            TopData(it.uid, it.displayName ?: \"Anónimo\", PrefsUtil.userRewardedVideoCount)\r\n        }\r\n                ?: TopData(PrefsUtil.instanceUuid, PrefsUtil.instanceName, PrefsUtil.userRewardedVideoCount)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/framework/BackupService.kt",
    "content": "package knf.kuma.backup.framework\r\n\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.backup.objects.BackupObject\r\nimport knf.kuma.commons.decrypt\r\nimport knf.kuma.commons.encrypt\r\n\r\nabstract class BackupService {\r\n\r\n    abstract fun start()\r\n\r\n    abstract val isLoggedIn: Boolean\r\n\r\n    abstract fun logIn(token: String? = null): Boolean\r\n\r\n    abstract fun logOut()\r\n\r\n    abstract suspend fun search(id: String, manual: Boolean = false): BackupObject<*>?\r\n\r\n    abstract suspend fun backup(backupObject: BackupObject<*>, id: String): BackupObject<*>?\r\n\r\n    fun String.checkResponse(id: String): String =\r\n            if (id == Backups.keyAchievements)\r\n                this.decrypt() ?: this\r\n            else this\r\n\r\n    fun String.checkData(id: String): String =\r\n            if (id == Backups.keyAchievements)\r\n                this.encrypt() ?: this\r\n            else this\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/framework/DropBoxService.kt",
    "content": "package knf.kuma.backup.framework\r\n\r\nimport androidx.preference.PreferenceManager\r\nimport com.dropbox.core.DbxRequestConfig\r\nimport com.dropbox.core.android.Auth\r\nimport com.dropbox.core.http.OkHttp3Requestor\r\nimport com.dropbox.core.v2.DbxClientV2\r\nimport com.dropbox.core.v2.files.WriteMode\r\nimport com.google.gson.Gson\r\nimport knf.kuma.App\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.backup.objects.BackupObject\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.toast\r\nimport java.io.ByteArrayInputStream\r\nimport java.io.InputStreamReader\r\nimport java.nio.charset.StandardCharsets\r\n\r\nclass DropBoxService : BackupService() {\r\n\r\n    private var client: DbxClientV2? = null\r\n    private var dbToken: String?\r\n        get() = PreferenceManager.getDefaultSharedPreferences(App.context).getString(\"db_token\", null)\r\n        set(value) = PreferenceManager.getDefaultSharedPreferences(App.context).edit().putString(\"db_token\", value).apply()\r\n\r\n    override fun start() {\r\n        if (dbToken != null)\r\n            logIn(dbToken)\r\n    }\r\n\r\n    override val isLoggedIn: Boolean\r\n        get() = client != null\r\n\r\n    override fun logIn(token: String?): Boolean {\r\n        return if (token != null) {\r\n            dbToken = token\r\n            val requestConfig = DbxRequestConfig.newBuilder(\"dropbox_app\")\r\n                    .withHttpRequestor(OkHttp3Requestor(OkHttp3Requestor.defaultOkHttpClient()))\r\n                    .build()\r\n            client = DbxClientV2(requestConfig, token)\r\n            true\r\n        } else {\r\n            noCrash { Auth.startOAuth2Authentication(App.context, \"qtjow4hsk06vt19\") }?.let { \"Error al iniciar sesión en dropbox\".toast() }\r\n            false\r\n        }\r\n    }\r\n\r\n    override fun logOut() {\r\n        client = null\r\n        dbToken = null\r\n    }\r\n\r\n    override suspend fun search(id: String, manual: Boolean): BackupObject<*>? {\r\n        return if (isLoggedIn)\r\n            try {\r\n                val list = client?.files()?.searchV2(id)?.matches ?: arrayListOf()\r\n                if (list.size > 0) {\r\n                    val downloader = client?.files()?.download(\"/$id\")\r\n                    val backupObject = InputStreamReader(downloader?.inputStream).use {\r\n                        Gson().fromJson<Any>(it.readText().checkResponse(id), Backups.getType(id)) as BackupObject<*>\r\n                    }\r\n                    downloader?.close()\r\n                    backupObject\r\n                } else\r\n                    null\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n                null\r\n            }\r\n        else null\r\n    }\r\n\r\n    override suspend fun backup(backupObject: BackupObject<*>, id: String): BackupObject<*>? {\r\n        return if (isLoggedIn)\r\n            try {\r\n                client?.files()?.uploadBuilder(\"/$id\")\r\n                        ?.withMute(true)\r\n                        ?.withMode(WriteMode.OVERWRITE)\r\n                        ?.uploadAndFinish(ByteArrayInputStream(Gson().toJson(backupObject, Backups.getType(id)).checkData(id).toByteArray(StandardCharsets.UTF_8)))\r\n                Backups.saveLastBackup()\r\n                backupObject\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n                null\r\n            }\r\n        else null\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/framework/LocalService.kt",
    "content": "package knf.kuma.backup.framework\r\n\r\nimport android.os.Build\r\nimport android.os.Environment\r\nimport android.widget.Toast\r\nimport com.google.gson.Gson\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.backup.objects.BackupObject\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.noCrashLet\r\nimport knf.kuma.commons.safeContext\r\nimport java.io.File\r\n\r\nclass LocalService : BackupService() {\r\n\r\n    private val baseFile by lazy {\r\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\r\n            safeContext.getExternalFilesDir(\"backups\") ?: File(safeContext.filesDir, \"backups\")\r\n        } else {\r\n            File(Environment.getExternalStorageDirectory(), \"UKIKU/backups\")\r\n        }\r\n    }\r\n\r\n    override fun start() {\r\n        if (!baseFile.exists())\r\n            baseFile.mkdirs()\r\n    }\r\n\r\n    override val isLoggedIn: Boolean\r\n        get() = true\r\n\r\n    override fun logIn(token: String?): Boolean {\r\n        Backups.type = Backups.Type.LOCAL\r\n        return true\r\n    }\r\n\r\n    override fun logOut() {\r\n    }\r\n\r\n    override suspend fun search(id: String, manual: Boolean): BackupObject<*>? {\r\n        val file = File(baseFile, \"$id.backup\")\r\n        return if (file.exists()) {\r\n            noCrashLet { Gson().fromJson(file.readText().checkResponse(id), Backups.getType(id)) as BackupObject<*> }\r\n        } else {\r\n            if (manual && id != Backups.keyAutoBackup) {\r\n                doOnUIGlobal { Toast.makeText(safeContext, \"El archivo de respaldo necesita estar en ${file.path}\", Toast.LENGTH_LONG).show() }\r\n            }\r\n            null\r\n        }\r\n    }\r\n\r\n    override suspend fun backup(backupObject: BackupObject<*>, id: String): BackupObject<*>? {\r\n        val file = File(baseFile, \"$id.backup\")\r\n        return noCrashLet {\r\n            file.writeText(Gson().toJson(backupObject, Backups.getType(id)).checkData(id))\r\n            backupObject\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/objects/AnimeChapters.kt",
    "content": "package knf.kuma.backup.objects\r\n\r\nimport com.google.gson.Gson\r\nimport com.google.gson.reflect.TypeToken\r\nimport knf.kuma.pojos.AnimeObject\r\n\r\nclass AnimeChapters {\r\n    var aid = \"0\"\r\n    var chapters = \"[]\"\r\n\r\n    fun chaptersList(): List<AnimeObject.WebInfo.AnimeChapter> {\r\n        val type = object : TypeToken<List<AnimeObject.WebInfo.AnimeChapter>>() {\r\n\r\n        }.type\r\n        return Gson().fromJson<List<AnimeObject.WebInfo.AnimeChapter>>(chapters, type) ?: listOf()\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/objects/BackupObject.kt",
    "content": "package knf.kuma.backup.objects\n\nimport com.google.gson.annotations.SerializedName\nimport java.text.SimpleDateFormat\nimport java.util.Calendar\nimport java.util.Locale\n\nopen class BackupObject<T> {\n    @SerializedName(\"date\")\n    var date: String? = null\n    @SerializedName(\"data\")\n    var data: List<T>? = null\n\n    constructor()\n\n    constructor(data: List<T>) {\n        this.date = SimpleDateFormat(\"dd/MM/yyyy kk:mm\", Locale.getDefault()).format(Calendar.getInstance().time)\n        this.data = data\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/objects/FavList.kt",
    "content": "package knf.kuma.backup.objects\n\nimport com.google.gson.Gson\nimport com.google.gson.annotations.SerializedName\nimport com.google.gson.reflect.TypeToken\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.FavoriteObject\nimport xdroid.toaster.Toaster\nimport java.io.InputStream\nimport java.io.InputStreamReader\n\nclass FavList {\n    @SerializedName(\"response\")\n    internal var response: String? = null\n    @SerializedName(\"favs\")\n    internal var favs: MutableList<FavSection>? = null\n\n    internal class FavSection {\n        @SerializedName(\"name\")\n        var name: String? = null\n        @SerializedName(\"list\")\n        var list: MutableList<FavEntry>? = null\n    }\n\n    internal class FavEntry {\n        @SerializedName(\"title\")\n        var title: String? = null\n        @SerializedName(\"aid\")\n        var aid: String? = null\n        @SerializedName(\"section\")\n        var section: String? = null\n        @SerializedName(\"order\")\n        var order: Int = 0\n    }\n\n    companion object {\n\n        fun decode(inputStream: InputStream?): MutableList<FavoriteObject>? {\n            if (inputStream == null) return null\n            var totalCount = 0\n            var errorCount = 0\n            val dao = CacheDB.INSTANCE.animeDAO()\n            val favList = Gson().fromJson<FavList>(InputStreamReader(inputStream), object : TypeToken<FavList>() {\n\n            }.type)\n            val favs = ArrayList<FavoriteObject>()\n            for (section in favList.favs ?: listOf<FavSection>()) {\n                totalCount += section.list?.size ?: 0\n                for (favEntry in section.list ?: listOf<FavEntry>()) {\n                    val animeObject = dao.getByAid(favEntry.aid ?: \"\")\n                    if (animeObject != null) {\n                        val fav = FavoriteObject(animeObject)\n                        fav.category = favEntry.section\n                        favs.add(fav)\n                    } else\n                        errorCount++\n                }\n            }\n            Toaster.toast(\"Migrados correctamente \" + (totalCount - errorCount) + \"/\" + totalCount)\n            return favs\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/objects/SeenList.kt",
    "content": "package knf.kuma.backup.objects\n\nimport android.util.Log\nimport com.google.gson.Gson\nimport com.google.gson.annotations.SerializedName\nimport com.google.gson.reflect.TypeToken\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.SeenObject\nimport xdroid.toaster.Toaster\nimport java.io.InputStream\nimport java.io.InputStreamReader\n\n/**\n * Created by jordy on 01/03/2018.\n */\n\nclass SeenList {\n    @SerializedName(\"response\")\n    internal var response: String? = null\n    @SerializedName(\"vistos\")\n    internal var vistos: String? = null\n    internal var list: MutableList<SeenObj>? = null\n\n    private fun deserialize() {\n        list = ArrayList()\n        Log.e(\"Seen\", \"$vistos\")\n        val els = vistos?.replace(\"E\", \"\")?.split(\":::\".toRegex())?.dropLastWhile { it.isEmpty() }?.toTypedArray()\n        for (el in els ?: emptyArray()) {\n            if (el != \"\") {\n                val spl = el.split(\"_\".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()\n                list?.add(SeenObj(spl[0], spl[1]))\n            }\n        }\n        list?.sort()\n    }\n\n    internal inner class SeenObj(var aid: String, var num: String) : Comparable<SeenObj> {\n\n        override fun compareTo(other: SeenObj): Int {\n            val bname = aid.compareTo(other.aid)\n            return if (bname != 0) {\n                bname\n            } else {\n                num.compareTo(other.num)\n            }\n        }\n    }\n\n    companion object {\n\n        fun decode(inputStream: InputStream?): MutableList<SeenObject>? {\n            if (inputStream == null) return null\n            var errorCount = 0\n            val dao = CacheDB.INSTANCE.animeDAO()\n            val seenList = Gson().fromJson<SeenList>(InputStreamReader(inputStream), object : TypeToken<SeenList>() {\n\n            }.type)\n            seenList.deserialize()\n            val totalCount = seenList.list?.size ?: 0\n            val chapters = ArrayList<SeenObject>()\n            var animeObject: AnimeChapters? = null\n            for (obj in seenList.list ?: listOf<SeenObj>()) {\n                try {\n                    if (animeObject == null || animeObject.aid != obj.aid)\n                        animeObject = dao.getChaptersByAid(obj.aid)\n                    val chapterList = animeObject.chaptersList()\n                    var found = false\n                    for (chapter in chapterList) {\n                        try {\n                            if (chapter.number.endsWith(\" \" + obj.num)) {\n                                chapters.add(SeenObject.fromChapter(chapter))\n                                found = true\n                                break\n                            }\n                        } catch (e: Exception) {\n                            e.printStackTrace()\n                        }\n                    }\n                    if (!found)\n                        errorCount++\n                } catch (e: Exception) {\n                    errorCount++\n                }\n            }\n            Toaster.toast(\"Migrados correctamente \" + (totalCount - errorCount) + \"/\" + totalCount)\n            return chapters\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/screens/MigrateDirectoryFragment.kt",
    "content": "package knf.kuma.backup.screens\n\nimport android.os.Bundle\nimport android.util.Log\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.Fragment\nimport knf.kuma.R\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.LayMigrateDirectoryBinding\nimport knf.kuma.directory.DirectoryService\nimport knf.kuma.directory.DirectoryService.Companion.STATE_FINISHED\nimport knf.kuma.directory.DirectoryService.Companion.STATE_FULL\nimport knf.kuma.directory.DirectoryService.Companion.STATE_INTERRUPTED\nimport knf.kuma.directory.DirectoryService.Companion.STATE_PARTIAL\n\nclass MigrateDirectoryFragment : Fragment() {\n\n    private var onDirStatus: DirectoryService.OnDirStatus? = null\n    private lateinit var binding: LayMigrateDirectoryBinding\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return inflater.inflate(R.layout.lay_migrate_directory, container, false)\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        binding = LayMigrateDirectoryBinding.bind(view)\n        CacheDB.INSTANCE.animeDAO().countLive.observe(viewLifecycleOwner) { count -> binding.tvDirectoryCount.text = count.toString() }\n        DirectoryService.getLiveStatus().observe(viewLifecycleOwner) { integer ->\n            if (integer != null)\n                when (integer) {\n                    STATE_PARTIAL -> Log.e(\"Dir\", \"Partial search\")\n                    STATE_FULL -> Log.e(\"Dir\", \"Full search\")\n                    STATE_INTERRUPTED -> {\n                        Log.e(\"Dir\", \"Interrupted\")\n                        binding.loading.visibility = View.GONE\n                        binding.tvError.text = \"Error: Creacion interrumpida\"\n                        binding.tvError.visibility = View.VISIBLE\n                    }\n                    STATE_FINISHED -> {\n                        Log.e(\"Dir\", \"Finished\")\n                        onDirStatus?.onFinished()\n                    }\n                }\n        }\n    }\n\n    fun setOnDirStatus(onDirStatus: DirectoryService.OnDirStatus) {\n        this.onDirStatus = onDirStatus\n    }\n\n    companion object {\n\n        operator fun get(dirStatus: DirectoryService.OnDirStatus): MigrateDirectoryFragment {\n            val fragment = MigrateDirectoryFragment()\n            fragment.setOnDirStatus(dirStatus)\n            return fragment\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/screens/MigrateSuccessFragment.kt",
    "content": "package knf.kuma.backup.screens\n\nimport android.content.ActivityNotFoundException\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.Fragment\nimport com.google.android.material.snackbar.Snackbar\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport knf.kuma.App\nimport knf.kuma.R\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.backup.objects.FavList\nimport knf.kuma.backup.objects.SeenList\nimport knf.kuma.commons.safeDismiss\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.commons.toast\nimport knf.kuma.database.CacheDB\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster\n\nclass MigrateSuccessFragment : Fragment() {\n\n    private val REQUEST_FAVS = 5628\n    private val REQUEST_SEEN = 9986\n    private lateinit var root: View\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(R.layout.lay_migrate_success, container, false)\n        root = view.find(R.id.root)\n        view.find<View>(R.id.migrate_favs).setOnClickListener { onMigrateFavs() }\n        view.find<View>(R.id.migrate_seen).setOnClickListener { onMigrateSeen() }\n        return view\n    }\n\n    private fun onMigrateFavs() {\n        try {\n            startActivityForResult(Intent().setAction(\"knf.kuma.MIGRATE\").putExtra(\"type\", 0), REQUEST_FAVS)\n        } catch (e: ActivityNotFoundException) {\n            \"No se encontró Animeflv App o la version es incorrecta!\".toast()\n        }\n    }\n\n    private fun onMigrateSeen() {\n        try {\n            startActivityForResult(Intent().setAction(\"knf.kuma.MIGRATE\").putExtra(\"type\", 1), REQUEST_SEEN)\n        } catch (e: ActivityNotFoundException) {\n            \"No se encontró Animeflv App o la version es incorrecta!\".toast()\n        }\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        val snackbar = root.showSnackbar(\"Migrando...\", Snackbar.LENGTH_INDEFINITE)\n        doAsync {\n            try {\n                data?.data?.let {\n                    when (requestCode) {\n                        REQUEST_FAVS -> {\n                            val list = FavList.decode(App.context.contentResolver.openInputStream(it))\n                                    ?: return@let null\n                            CacheDB.INSTANCE.favsDAO().addAll(list)\n                            syncData { favs() }\n                        }\n                        REQUEST_SEEN -> {\n                            val chapters = SeenList.decode(App.context.contentResolver.openInputStream(it))\n                                    ?: return@let null\n                            CacheDB.INSTANCE.seenDAO().addAll(chapters)\n                            syncData { seen() }\n                        }\n                        else -> null\n                    }\n                } ?: throw IllegalStateException(\"Data or IS is null!\")\n            } catch (e: Exception) {\n                e.printStackTrace()\n                FirebaseCrashlytics.getInstance().recordException(e)\n                Toaster.toast(\"Error al migrar datos\")\n            }\n            snackbar.safeDismiss()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/backup/screens/MigrateVersionFragment.kt",
    "content": "package knf.kuma.backup.screens\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.TextView\nimport androidx.core.content.pm.PackageInfoCompat\nimport androidx.fragment.app.Fragment\nimport knf.kuma.App\nimport knf.kuma.R\nimport org.jetbrains.anko.find\n\nclass MigrateVersionFragment : Fragment() {\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return inflater.inflate(R.layout.lay_migrate_version, container, false)\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        view.find<TextView>(R.id.tv_version_bad).text = installedCode.toString()\n    }\n\n    companion object {\n\n        val installedCode: Long\n            get() {\n            return try {\n                val info = App.context.packageManager.getPackageInfo(\"knf.animeflv\", 0)\n                PackageInfoCompat.getLongVersionCode(info)\n            } catch (e: Exception) {\n                -1\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/cast/CastCustom.kt",
    "content": "package knf.kuma.cast\r\n\r\nimport android.app.Dialog\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.view.View\r\nimport android.widget.ImageView\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.customview.customView\r\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\r\nimport es.munix.multidisplaycast.CastManager\r\nimport es.munix.multidisplaycast.helpers.NotificationsHelper\r\nimport es.munix.multidisplaycast.interfaces.DialogCallback\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.custom.ThemedControlsActivity\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass CastCustom : CastManager() {\r\n\r\n    private val notificationHelper = CastNotificationHelper()\r\n\r\n    override fun onLoadImage(context: Context, image: String, imageView: ImageView) {\r\n        imageView.apply {\r\n            load(image)\r\n            onClick { context.startActivity(Intent(context, controlsClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) }\r\n        }\r\n    }\r\n\r\n    override fun getControlsClass(): Class<*> {\r\n        return ThemedControlsActivity::class.java\r\n    }\r\n\r\n    override fun getNotificationsHelper(): NotificationsHelper {\r\n        return notificationHelper\r\n    }\r\n\r\n    override fun getPairingDialog(context: Context, title: String, message: String, positiveText: String?, negativeText: String?, dialogCallback: DialogCallback): Dialog {\r\n        return createDialog(context, null, title, message, positiveText, negativeText, dialogCallback)\r\n                ?: super.getPairingDialog(context, title, message, positiveText, negativeText, dialogCallback)\r\n    }\r\n\r\n    override fun getDisconnectDialog(context: Context, customView: View, positiveText: String?, dialogCallback: DialogCallback): Dialog {\r\n        return createDialog(context, customView, null, null, positiveText, null, dialogCallback)\r\n                ?: super.getDisconnectDialog(context, customView, positiveText, dialogCallback)\r\n    }\r\n\r\n    override fun getPairingCodeDialog(context: Context, view: View, title: String, positiveText: String?, negativeText: String?, callback: DialogCallback): Dialog {\r\n        return createDialog(context, view, title, null, positiveText, negativeText, callback)\r\n                ?: super.getPairingCodeDialog(context, view, title, positiveText, negativeText, callback)\r\n    }\r\n\r\n    private fun createDialog(context: Context, view: View?, title: String?, message: String?, positiveText: String?, negativeText: String?, callback: DialogCallback): Dialog? {\r\n        return try {\r\n            MaterialDialog(context).apply {\r\n                lifecycleOwner()\r\n                if (!title.isNullOrEmpty()) title(text = title)\r\n                if (!title.isNullOrEmpty()) message(text = message)\r\n                if (view != null) customView(view = view)\r\n                if (!positiveText.isNullOrEmpty())\r\n                    positiveButton(text = positiveText) {\r\n                        callback.onPositive()\r\n                    }\r\n                if (!negativeText.isNullOrEmpty())\r\n                    negativeButton(text = negativeText) {\r\n                        callback.onNegative()\r\n                    }\r\n            }\r\n        } catch (e: Exception) {\r\n            null\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/cast/CastMedia.kt",
    "content": "package knf.kuma.cast\r\n\r\nimport android.net.Uri\r\nimport com.google.android.gms.cast.MediaInfo\r\nimport com.google.android.gms.cast.MediaMetadata\r\nimport com.google.android.gms.common.images.WebImage\r\nimport knf.kuma.animeinfo.ktx.filePath\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.SelfServer\r\nimport knf.kuma.pojos.AnimeObject\r\nimport knf.kuma.pojos.ExplorerObject\r\nimport knf.kuma.pojos.RecentObject\r\nimport knf.kuma.recents.RecentModel\r\n\r\ndata class CastMedia(val url: String, val eid: String, val mediaInfo: MediaInfo) {\r\n\r\n    val title: String get() = mediaInfo.metadata?.getString(MediaMetadata.KEY_TITLE)!!\r\n    val subTitle: String get() = mediaInfo.metadata?.getString(MediaMetadata.KEY_SUBTITLE)!!\r\n    val image: String get() = mediaInfo.metadata?.images!![0].url.toString()\r\n    val type: String get() = mediaInfo.contentType!!\r\n\r\n    companion object {\r\n        fun create(chapter: AnimeObject.WebInfo.AnimeChapter?, url: String? = null): CastMedia? {\r\n            if (chapter == null) return null\r\n            val metadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE).apply {\r\n                putString(MediaMetadata.KEY_TITLE, chapter.name)\r\n                putString(MediaMetadata.KEY_SUBTITLE, chapter.number)\r\n                addImage(WebImage(Uri.parse(if (chapter.img.isNullOrBlank()) \"https://www3.animeflv.net/uploads/animes/thumbs/${chapter.aid}.jpg\" else chapter.img)))\r\n            }\r\n            val fUrl = when {\r\n                url.isNullOrBlank() -> SelfServer.start(chapter.filePath, true)\r\n                PrefsUtil.isProxyCastEnabled -> ProxyCache.start(url)\r\n                else -> url\r\n            }\r\n            val mediaInfo = MediaInfo.Builder(fUrl!!).apply {\r\n                setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)\r\n                setContentType(\"video/mp4\")\r\n                setMetadata(metadata)\r\n            }\r\n            return CastMedia(fUrl, chapter.eid, mediaInfo.build())\r\n        }\r\n\r\n        fun create(recent: RecentObject?, url: String? = null): CastMedia? {\r\n            if (recent == null) return null\r\n            val metadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE).apply {\r\n                putString(MediaMetadata.KEY_TITLE, recent.name)\r\n                putString(MediaMetadata.KEY_SUBTITLE, recent.chapter)\r\n                addImage(WebImage(Uri.parse(\"https://www3.animeflv.net/uploads/animes/thumbs/${recent.aid}.jpg\")))\r\n            }\r\n            val fUrl = when {\r\n                url.isNullOrBlank() -> SelfServer.start(recent.filePath, true)\r\n                PrefsUtil.isProxyCastEnabled -> ProxyCache.start(url)\r\n                else -> url\r\n            }\r\n            val mediaInfo = MediaInfo.Builder(fUrl!!).apply {\r\n                setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)\r\n                setContentType(\"video/mp4\")\r\n                setMetadata(metadata)\r\n            }\r\n            return CastMedia(fUrl, recent.eid, mediaInfo.build())\r\n        }\r\n\r\n        fun create(recent: RecentModel?, url: String? = null): CastMedia? {\r\n            if (recent == null) return null\r\n            val metadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE).apply {\r\n                putString(MediaMetadata.KEY_TITLE, recent.name)\r\n                putString(MediaMetadata.KEY_SUBTITLE, recent.chapter)\r\n                addImage(WebImage(Uri.parse(\"https://www3.animeflv.net/uploads/animes/thumbs/${recent.aid}.jpg\")))\r\n            }\r\n            val fUrl = when {\r\n                url.isNullOrBlank() -> SelfServer.start(recent.extras.filePath, true)\r\n                PrefsUtil.isProxyCastEnabled -> ProxyCache.start(url)\r\n                else -> url\r\n            }\r\n            val mediaInfo = MediaInfo.Builder(fUrl!!).apply {\r\n                setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)\r\n                setContentType(\"video/mp4\")\r\n                setMetadata(metadata)\r\n            }\r\n            return CastMedia(fUrl, recent.extras.eid, mediaInfo.build())\r\n        }\r\n\r\n        fun create(fileDownObj: ExplorerObject.FileDownObj?): CastMedia? {\r\n            if (fileDownObj == null) return null\r\n            val metadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE).apply {\r\n                putString(MediaMetadata.KEY_TITLE, fileDownObj.title)\r\n                putString(MediaMetadata.KEY_SUBTITLE, \"Episodio ${fileDownObj.chapter}\")\r\n                addImage(WebImage(Uri.parse(fileDownObj.chapPreviewLink)))\r\n            }\r\n            val url = SelfServer.start(\r\n                fileDownObj.fileName.substring(fileDownObj.fileName.indexOf(\"$\")),\r\n                true\r\n            )\r\n            val mediaInfo = MediaInfo.Builder(url!!).apply {\r\n                setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)\r\n                setContentType(\"video/mp4\")\r\n                setMetadata(metadata)\r\n            }\r\n            return CastMedia(url, fileDownObj.eid, mediaInfo.build())\r\n        }\r\n    }\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/cast/CastNotificationHelper.kt",
    "content": "package knf.kuma.cast\r\n\r\nimport es.munix.multidisplaycast.helpers.NotificationsHelper\r\n\r\nclass CastNotificationHelper : NotificationsHelper()"
  },
  {
    "path": "app/src/main/java/knf/kuma/cast/ProxyCache.kt",
    "content": "package knf.kuma.cast\r\n\r\nimport knf.kuma.App\r\nimport knf.kuma.commons.SelfServer\r\nimport knf.libs.videocache.HttpProxyCacheServer\r\n\r\nobject ProxyCache {\r\n    private val cacheServer: HttpProxyCacheServer by lazy { HttpProxyCacheServer(App.context) }\r\n\r\n    fun start(url: String): String {\r\n        return if (cacheServer.isCached(url))\r\n            SelfServer.start(cacheServer.getProxyUrl(url), true) ?: \"\"\r\n        else\r\n            cacheServer.getProxyUrl(url, false)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/changelog/ChangeAdapter.kt",
    "content": "package knf.kuma.changelog\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\nimport knf.kuma.R\nimport knf.kuma.changelog.objects.Release\nimport org.jetbrains.anko.find\n\ninternal class ChangeAdapter(release: Release) : RecyclerView.Adapter<ChangeAdapter.ChangeItem>() {\n\n    private val changes = release.changes\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChangeItem {\n        return ChangeItem(LayoutInflater.from(parent.context).inflate(R.layout.item_release, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ChangeItem, position: Int) {\n        val change = changes[position]\n        setType(holder.type, change.type)\n        holder.description.text = change.text\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    private fun setType(textView: TextView?, type: String) {\n        if (textView == null) return\n        when (type) {\n            \"new\" -> {\n                textView.text = \"Nuevo\"\n                textView.setBackgroundResource(R.drawable.chip_new)\n            }\n            \"change\" -> {\n                textView.text = \"Cambio\"\n                textView.setBackgroundResource(R.drawable.chip_change)\n            }\n            \"fix\" -> {\n                textView.text = \"Arreglo\"\n                textView.setBackgroundResource(R.drawable.chip_error)\n            }\n            else -> {\n                textView.text = \"Cambio\"\n                textView.setBackgroundResource(R.drawable.chip_change)\n            }\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return changes.size\n    }\n\n    internal class ChangeItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        var type: TextView = itemView.find(R.id.type)\n        var description: TextView = itemView.find(R.id.description)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/changelog/ChangeAdapterMaterial.kt",
    "content": "package knf.kuma.changelog\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\nimport com.google.android.material.chip.Chip\nimport knf.kuma.R\nimport knf.kuma.changelog.objects.Release\nimport org.jetbrains.anko.find\n\ninternal class ChangeAdapterMaterial(release: Release) : RecyclerView.Adapter<ChangeAdapterMaterial.ChangeItem>() {\n\n    private val changes = release.changes\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChangeItem {\n        return ChangeItem(LayoutInflater.from(parent.context).inflate(R.layout.item_release_material, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ChangeItem, position: Int) {\n        val change = changes[position]\n        setType(holder.type, change.type)\n        holder.description.text = change.text\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    private fun setType(chip: Chip, type: String) {\n        when (type) {\n            \"new\" -> {\n                chip.text = \"Nuevo\"\n                chip.setChipBackgroundColorResource(R.color.release_new)\n            }\n            \"fix\" -> {\n                chip.text = \"Arreglo\"\n                chip.setChipBackgroundColorResource(R.color.release_error)\n            }\n            else -> {\n                chip.text = \"Cambio\"\n                chip.setChipBackgroundColorResource(R.color.release_change)\n            }\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return changes.size\n    }\n\n    internal class ChangeItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        var type: Chip = itemView.find(R.id.type)\n        var description: TextView = itemView.find(R.id.description)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/changelog/ChangelogActivity.kt",
    "content": "package knf.kuma.changelog\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.View\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.core.content.pm.PackageInfoCompat\nimport androidx.lifecycle.lifecycleScope\nimport androidx.preference.PreferenceManager\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport knf.kuma.changelog.objects.Changelog\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.databinding.RecyclerChangelogBinding\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport org.jsoup.Jsoup\nimport org.jsoup.parser.Parser\nimport xdroid.toaster.Toaster\nimport java.io.BufferedReader\nimport java.io.InputStreamReader\n\nclass ChangelogActivity : GenericActivity() {\n\n    private val binding by lazy { RecyclerChangelogBinding.inflate(layoutInflater) }\n    private val changelog: Changelog\n        @Throws(Exception::class)\n        get() = if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(\"changelog_load\", true)) {\n            Changelog(Jsoup.parse(xml, \"\", Parser.xmlParser()))\n        } else {\n            Changelog(Jsoup.connect(\"https://raw.githubusercontent.com/jordyamc/UKIKU/master/app/src/main/assets/changelog.xml\").parser(Parser.xmlParser()).get())\n        }\n\n    private val xml: String?\n        get() {\n            var xmlString: String? = null\n            val am = assets\n            try {\n                val reader = BufferedReader(InputStreamReader(am.open(\"changelog.xml\")))\n                val sb = StringBuilder()\n                var mLine: String? = reader.readLine()\n                while (mLine != null) {\n                    sb.append(mLine)\n                    mLine = reader.readLine()\n                }\n                reader.close()\n                xmlString = sb.toString()\n            } catch (e1: Exception) {\n                e1.printStackTrace()\n            }\n\n            return xmlString\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(binding.root)\n        binding.toolbar.title = \"Changelog\"\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        binding.toolbar.setNavigationOnClickListener { finish() }\n        doAsync {\n            try {\n                val changelog = changelog\n                binding.progress.post { binding.progress.visibility = View.GONE }\n                binding.recycler.post { binding.recycler.adapter = ReleaseAdapter(changelog) }\n            } catch (e: Exception) {\n                FirebaseCrashlytics.getInstance().recordException(e)\n                Toaster.toast(\"Error al cargar changelog\")\n                finish()\n            }\n        }\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, ChangelogActivity::class.java))\n        }\n\n        fun check(activity: AppCompatActivity) {\n            doAsync {\n                try {\n                    val cCode = PreferenceManager.getDefaultSharedPreferences(activity).getInt(\"version_code\", 0)\n                    val pCode = PackageInfoCompat.getLongVersionCode(activity.packageManager.getPackageInfo(activity.packageName, 0)).toInt()\n                    if (pCode > cCode && cCode != 0) {\n                        activity.lifecycleScope.launch(Dispatchers.Main) {\n                            delay(2000)\n                            MaterialDialog(activity).safeShow {\n                                message(text = \"Nueva versión, ¿Leer Changelog?\")\n                                positiveButton(text = \"Leer\") {\n                                    open(activity)\n                                    PreferenceManager.getDefaultSharedPreferences(activity).edit().putInt(\"version_code\", pCode).apply()\n                                }\n                                negativeButton(text = \"Omitir\") { PreferenceManager.getDefaultSharedPreferences(activity).edit().putInt(\"version_code\", pCode).apply() }\n                                setOnCancelListener { PreferenceManager.getDefaultSharedPreferences(activity).edit().putInt(\"version_code\", pCode).apply() }\n                            }\n                        }\n                    } else\n                        PreferenceManager.getDefaultSharedPreferences(activity).edit().putInt(\"version_code\", pCode).apply()\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/changelog/ChangelogActivityMaterial.kt",
    "content": "package knf.kuma.changelog\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.View\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.core.content.pm.PackageInfoCompat\nimport androidx.lifecycle.lifecycleScope\nimport androidx.preference.PreferenceManager\nimport androidx.recyclerview.widget.DividerItemDecoration\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport knf.kuma.changelog.objects.Changelog\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.databinding.RecyclerChangelogMaterialBinding\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport org.jsoup.Jsoup\nimport org.jsoup.parser.Parser\nimport xdroid.toaster.Toaster\nimport java.io.BufferedReader\nimport java.io.InputStreamReader\n\nclass ChangelogActivityMaterial : GenericActivity() {\n\n    private val binding by lazy { RecyclerChangelogMaterialBinding.inflate(layoutInflater) }\n    private val changelog: Changelog\n        @Throws(Exception::class)\n        get() = if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(\"changelog_load\", true)) {\n            Changelog(Jsoup.parse(xml, \"\", Parser.xmlParser()))\n        } else {\n            Changelog(Jsoup.connect(\"https://raw.githubusercontent.com/jordyamc/UKIKU/master/app/src/main/assets/changelog.xml\").parser(Parser.xmlParser()).get())\n        }\n\n    private val xml: String?\n        get() {\n            var xmlString: String? = null\n            val am = assets\n            try {\n                val reader = BufferedReader(InputStreamReader(am.open(\"changelog.xml\")))\n                val sb = StringBuilder()\n                var mLine: String? = reader.readLine()\n                while (mLine != null) {\n                    sb.append(mLine)\n                    mLine = reader.readLine()\n                }\n                reader.close()\n                xmlString = sb.toString()\n            } catch (e1: Exception) {\n                e1.printStackTrace()\n            }\n\n            return xmlString\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(binding.root)\n        binding.toolbar.title = \"Changelog\"\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        binding.toolbar.setNavigationOnClickListener { finish() }\n        binding.recycler.addItemDecoration(DividerItemDecoration(this,DividerItemDecoration.VERTICAL))\n        doAsync {\n            try {\n                val changelog = changelog\n                binding.progress.post { binding.progress.visibility = View.GONE }\n                binding.recycler.post { binding.recycler.adapter = ReleaseAdapterMaterial(changelog) }\n            } catch (e: Exception) {\n                FirebaseCrashlytics.getInstance().recordException(e)\n                Toaster.toast(\"Error al cargar changelog\")\n                finish()\n            }\n        }\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, ChangelogActivityMaterial::class.java))\n        }\n\n        fun check(activity: AppCompatActivity) {\n            doAsync {\n                try {\n                    val cCode = PreferenceManager.getDefaultSharedPreferences(activity).getInt(\"version_code\", 0)\n                    val pCode = PackageInfoCompat.getLongVersionCode(activity.packageManager.getPackageInfo(activity.packageName, 0)).toInt()\n                    if (pCode > cCode && cCode != 0) {\n                        activity.lifecycleScope.launch(Dispatchers.Main) {\n                            delay(2000)\n                            MaterialDialog(activity).safeShow {\n                                message(text = \"Nueva versión, ¿Leer Changelog?\")\n                                positiveButton(text = \"Leer\") {\n                                    open(activity)\n                                    PreferenceManager.getDefaultSharedPreferences(activity).edit().putInt(\"version_code\", pCode).apply()\n                                }\n                                negativeButton(text = \"Omitir\") { PreferenceManager.getDefaultSharedPreferences(activity).edit().putInt(\"version_code\", pCode).apply() }\n                                setOnCancelListener { PreferenceManager.getDefaultSharedPreferences(activity).edit().putInt(\"version_code\", pCode).apply() }\n                            }\n                        }\n                    } else\n                        PreferenceManager.getDefaultSharedPreferences(activity).edit().putInt(\"version_code\", pCode).apply()\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/changelog/ReleaseAdapter.kt",
    "content": "package knf.kuma.changelog\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.changelog.objects.Changelog\nimport org.jetbrains.anko.find\n\ninternal class ReleaseAdapter(changelog: Changelog) : RecyclerView.Adapter<ReleaseAdapter.ReleaseItem>() {\n\n    private val list = changelog.releases\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReleaseItem {\n        return ReleaseItem(LayoutInflater.from(parent.context).inflate(R.layout.item_changelog, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ReleaseItem, position: Int) {\n        val release = list[position]\n        holder.version.text = release.version\n        holder.code.text = release.code\n        holder.recyclerView.adapter = ChangeAdapter(release)\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    internal class ReleaseItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val version: TextView = itemView.find(R.id.version)\n        val code: TextView = itemView.find(R.id.code)\n        val recyclerView: RecyclerView = itemView.find(R.id.recycler)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/changelog/ReleaseAdapterMaterial.kt",
    "content": "package knf.kuma.changelog\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.changelog.objects.Changelog\nimport org.jetbrains.anko.find\n\ninternal class ReleaseAdapterMaterial(changelog: Changelog) : RecyclerView.Adapter<ReleaseAdapterMaterial.ReleaseItem>() {\n\n    private val list = changelog.releases\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReleaseItem {\n        return ReleaseItem(LayoutInflater.from(parent.context).inflate(R.layout.item_changelog_material, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ReleaseItem, position: Int) {\n        val release = list[position]\n        holder.version.text = release.version\n        holder.code.text = release.code\n        holder.recyclerView.adapter = ChangeAdapterMaterial(release)\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    internal class ReleaseItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val version: TextView = itemView.find(R.id.version)\n        val code: TextView = itemView.find(R.id.code)\n        val recyclerView: RecyclerView = itemView.find(R.id.recycler)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/changelog/objects/Change.kt",
    "content": "package knf.kuma.changelog.objects\n\nimport org.jsoup.nodes.Element\n\nclass Change(element: Element) {\n    var type: String = element.attr(\"type\")\n    var text: String = element.text()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/changelog/objects/Changelog.kt",
    "content": "package knf.kuma.changelog.objects\n\nimport org.jsoup.nodes.Document\n\nclass Changelog(document: Document) {\n    var releases: MutableList<Release>\n\n    init {\n        val list = ArrayList<Release>()\n        for (element in document.select(\"release\")) {\n            list.add(Release(element))\n        }\n        this.releases = list\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/changelog/objects/Release.kt",
    "content": "package knf.kuma.changelog.objects\n\nimport org.jsoup.nodes.Element\n\nclass Release(element: Element) {\n    var version: String = element.attr(\"version\")\n    var code: String = element.attr(\"code\")\n    var changes: MutableList<Change>\n\n    init {\n        val list = ArrayList<Change>()\n        for (e in element.select(\"change\")) {\n            list.add(Change(e))\n        }\n        this.changes = list\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/AllSSLOkHttpClient.kt",
    "content": "package knf.kuma.commons\r\n\r\nimport okhttp3.ConnectionSpec\r\nimport okhttp3.OkHttpClient\r\nimport org.conscrypt.Conscrypt\r\nimport java.security.Security\r\nimport javax.net.ssl.SSLContext\r\n\r\nobject AllSSLOkHttpClient {\r\n    fun get() = OkHttpClient.Builder()\r\n        .connectionSpecs(\r\n            listOf(\r\n                ConnectionSpec.CLEARTEXT,\r\n                ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)\r\n                    .allEnabledTlsVersions()\r\n                    .allEnabledCipherSuites()\r\n                    .build()\r\n            )\r\n        ).build()\r\n\r\n    fun enableTLS() {\r\n        try {\r\n            Security.insertProviderAt(Conscrypt.newProvider(), 1)\r\n            SSLContext.getInstance(\"TLSv1.3\").apply {\r\n                init(null, null, null)\r\n                createSSLEngine()\r\n            }\r\n        } catch (e: Exception) {\r\n            e.printStackTrace()\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/BypassUtil.kt",
    "content": "package knf.kuma.commons\n\nimport android.content.Context\nimport android.webkit.CookieManager\nimport android.webkit.WebSettings\nimport android.webkit.WebView\nimport androidx.preference.PreferenceManager\nimport com.bumptech.glide.load.model.LazyHeaders\nimport knf.kuma.App\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.uagen.UAGenerator\nimport knf.kuma.uagen.randomUA\nimport knf.tools.bypass.DisplayType\nimport knf.tools.bypass.Request\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport org.jsoup.HttpStatusException\nimport org.jsoup.Jsoup\n\n/**\n * Created by jordy on 17/03/2018.\n */\n\nclass BypassUtil {\n\n    interface BypassListener {\n        fun onNeedRecreate()\n    }\n\n    companion object {\n        val userAgent: String\n            get() = if (PrefsUtil.useDefaultUserAgent && !PrefsUtil.alwaysGenerateUA) noCrashLet { WebSettings.getDefaultUserAgent(App.context) }\n                ?: PrefsUtil.userAgent else PrefsUtil.userAgent\n        var isLoading = false\n        var isChecking = false\n\n        private const val keyCfClearance = \"cf_clearance\"\n        private const val keyCfDuid = \"__cfduid\"\n        private const val keyCookiesBypass = \"bypass_cookies\"\n        private const val defaultValue = \"\"\n        const val testLink = \"https://www3.animeflv.net/\"\n\n        fun createRequest(): Request {\n            return Request(\n                testLink,\n                lastUA = PrefsUtil.userAgent,\n                showReload = AdsUtils.remoteConfigs.getBoolean(\"bypass_show_reload\"),\n                useFocus = isTV,\n                maxTryCount = AdsUtils.remoteConfigs.getLong(\"bypass_max_tries\").toInt(),\n                useLatestUA = true,\n                reloadOnCaptcha = false,\n                waitCaptcha = true,\n                clearCookiesAtStart = true,\n                displayType = DisplayType.DIALOG,\n                dialogStyle = 0\n            )\n        }\n\n        suspend fun clearCookiesIfNeeded() {\n            if (!withContext(Dispatchers.IO) { isCloudflareActive() })\n                clearCookies(null)\n        }\n\n        fun saveCookies(context: Context, cookies: String): Boolean =\n            noCrashLet(false) {\n                bypassCookies = cookies\n                if (cookies.contains(keyCfClearance)) {\n                        val parts = cookies.split(\";\").dropLastWhile { it.isEmpty() }.toTypedArray()\n                        for (cookie in parts) {\n                            if (cookie.contains(keyCfDuid))\n                                setCFDuid(context, cookie.trim().substring(cookie.trim().indexOf(\"=\") + 1))\n                            if (cookie.contains(keyCfClearance)) {\n                                val clearance = cookie.trim().substring(cookie.trim().indexOf(\"=\") + 1)\n                                if (clearance.isBlank())\n                                    return@noCrashLet false\n                                setClearance(context, clearance)\n                            }\n                        }\n                        return@noCrashLet true\n                    }\n                    false\n                }\n\n        fun clearCookies(webView: WebView?) {\n            noCrash {\n                val cookieManager = CookieManager.getInstance()\n                cookieManager.removeAllCookies(null)\n                webView?.clearCache(true)\n                bypassCookies = null\n                setCFDuid(App.context)\n                setClearance(App.context)\n                PrefsUtil.userAgent = UAGenerator.getRandomUserAgent()\n            }\n        }\n\n        fun isNeeded(url: String = testLink): Boolean {\n            return try {\n                val response = jsoupCookies(url).execute()\n                response.statusCode().let { it == 503 || it == 403 }\n            } catch (e: HttpStatusException) {\n                e.statusCode.let { it == 503 || it == 403 }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                false\n            }\n        }\n\n        fun isCloudflareActive(url: String = testLink): Boolean {\n            return try {\n                val response = Jsoup.connect(url).followRedirects(true).execute()\n                response.statusCode().let { it == 503 || it == 403 }\n            } catch (e: HttpStatusException) {\n                e.statusCode.let { it == 503 || it == 403 }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                false\n            }\n        }\n\n        fun isCloudflareActiveRandom(url: String = testLink): Boolean {\n            return try {\n                val response = Jsoup.connect(url).followRedirects(true).userAgent(randomUA()).execute()\n                response.statusCode().let { it == 503 || it == 403 }\n            } catch (e: HttpStatusException) {\n                e.statusCode.let { it == 503 || it == 403 }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                false\n            }\n        }\n\n        fun isNeededFlag(): Int {\n            return try {\n                val response = jsoupCookies(testLink).execute()\n                when (response.statusCode()) {\n                    503 -> 1\n                    403 -> 2\n                    else -> 0\n                }\n            } catch (e: HttpStatusException) {\n                when (e.statusCode) {\n                    503 -> 1\n                    403 -> 2\n                    else -> 0\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                0\n            }\n        }\n\n        fun getMapCookie(context: Context): Map<String, String> {\n            val map = LinkedHashMap<String, String>()\n            map[\"device\"] = \"computer\"\n            map[\"InstiSession\"] =\n                \"eyJpZCI6IjRlNGYwNWYxLTg4NDMtNGQwOS05ODlmLWM1OWQ5N2NmNjVlYyIsInJlZmVycmVyIjoiIiwiY2FtcGFpZ24iOnsic291cmNlIjpudWxsLCJtZWRpdW0iOm51bGwsImNhbXBhaWduIjpudWxsLCJ0ZXJtIjpudWxsLCJjb250ZW50IjpudWxsfX0=\"\n            bypassCookies?.split(\";\")?.forEach {\n                if (it.contains(\"=\")) {\n                    val split = it.split(\"=\")\n                    map[split[0]] = split[1]\n                }\n            }\n            //getClearance(context).let { if (it != defaultValue) map[keyCfClearance] = it }\n            //getCFDuid(context).let { if (it != defaultValue) map[keyCfDuid] = it }\n            return map\n        }\n\n        fun getLazyHeaders(): LazyHeaders {\n            return LazyHeaders.Builder().apply {\n                addHeader(\"Cookie\", getStringCookie(App.context))\n                addHeader(\"User-Agent\", userAgent)\n            }.build()\n        }\n\n        fun getMapHeaders(): Map<String, String> {\n            return mapOf(\n                \"Cookie\" to getStringCookie(App.context),\n                \"User-Agent\" to userAgent\n            )\n        }\n\n        fun getStringCookie(context: Context): String {\n            val builder = StringBuilder()\n            for ((key, value) in getMapCookie(context))\n                builder.append(\"$key=$value;\")\n            return builder.toString().dropLastWhile { it == ' ' || it == ';' }\n        }\n\n        var bypassCookies: String?\n            set(value) = PreferenceManager.getDefaultSharedPreferences(App.context).edit().putString(keyCookiesBypass, value).apply()\n            get() = PreferenceManager.getDefaultSharedPreferences(App.context).getString(keyCookiesBypass, null)\n\n        fun getClearance(context: Context): String {\n            return PreferenceManager.getDefaultSharedPreferences(context).getString(keyCfClearance, defaultValue)\n                ?: defaultValue\n        }\n\n        private fun setClearance(context: Context, value: String = defaultValue) {\n            PreferenceManager.getDefaultSharedPreferences(context).edit().putString(keyCfClearance, value).apply()\n        }\n\n        fun getCFDuid(context: Context): String {\n            return PreferenceManager.getDefaultSharedPreferences(context).getString(keyCfDuid, defaultValue)\n                    ?: defaultValue\n        }\n\n        private fun setCFDuid(context: Context, value: String = defaultValue) {\n            PreferenceManager.getDefaultSharedPreferences(context).edit().putString(keyCfDuid, value).apply()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/CastUtil.kt",
    "content": "package knf.kuma.commons\n\nimport android.app.Activity\nimport android.content.Context\nimport android.content.Intent\nimport android.util.Log\nimport android.view.Menu\nimport android.view.View\nimport androidx.lifecycle.MutableLiveData\nimport com.google.android.material.snackbar.Snackbar\nimport es.munix.multidisplaycast.CastManager\nimport es.munix.multidisplaycast.interfaces.CastListener\nimport es.munix.multidisplaycast.interfaces.PlayStatusListener\nimport knf.kuma.App\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.cast.CastCustom\nimport knf.kuma.cast.CastMedia\nimport knf.kuma.custom.ThemedControlsActivity\nimport org.jetbrains.annotations.Contract\nimport xdroid.toaster.Toaster\n\nclass CastUtil private constructor(private val context: Context) : CastListener, PlayStatusListener {\n    val casting = MutableLiveData<String>()\n\n    private var loading: Snackbar? = null\n\n    init {\n        CastManager.setInstance(CastCustom())\n        CastManager.getInstance().setDiscoveryManager()\n        CastManager.getInstance().setPlayStatusListener(javaClass.simpleName, this)\n        CastManager.getInstance().setCastListener(javaClass.simpleName, this)\n        casting.value = NO_PLAYING\n    }\n\n    fun registerActivity(activity: Activity, menu: Menu, menuId: Int) = CastManager.getInstance().registerForActivity(activity, menu, menuId)\n\n    fun connected(): Boolean {\n        return CastManager.getInstance().isConnected\n        //return isConnected;\n    }\n\n    fun play(view: View, castMedia: CastMedia?) {\n        try {\n            if (castMedia == null) throw IllegalStateException(\"CastMedia must not be null\")\n            if (connected()) {\n                if (!castMedia.url.endsWith(\":\" + SelfServer.HTTP_PORT))\n                    SelfServer.stop()\n                Log.e(\"Cast\", castMedia.url)\n                CastManager.getInstance().playMedia(castMedia.url, \"video/mp4\", castMedia.title, castMedia.subTitle, castMedia.image)\n                startLoading(view)\n                setEid(castMedia.eid)\n                AchievementManager.unlock(listOf(6))\n            } else {\n                Toaster.toast(\"No hay dispositivo seleccionado\")\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            stopLoading()\n            Toaster.toast(\"Error al reproducir\")\n        }\n    }\n\n    fun stop() {\n        CastManager.getInstance().stop()\n    }\n\n    fun onDestroy() {\n        loading?.safeDismiss()\n        loading = null\n        CastManager.getInstance().onDestroy()\n    }\n\n    override fun isConnected() {\n    }\n\n    override fun isDisconnected() {\n        stopLoading()\n        setEid(NO_PLAYING)\n        SelfServer.stop()\n    }\n\n    private fun getLoading(view: View): Snackbar {\n        return view.showSnackbar(\"Cargando...\", duration = Snackbar.LENGTH_INDEFINITE)\n    }\n\n    private fun startLoading(view: View) {\n        doOnUIGlobal {\n            loading = getLoading(view)\n        }\n    }\n\n    private fun stopLoading() {\n        doOnUIGlobal {\n            loading?.safeDismiss()\n            loading = null\n        }\n    }\n\n    private fun setEid(eid: String) {\n        doOnUIGlobal {\n            casting.value = eid\n        }\n    }\n\n    fun openControls() {\n        context.startActivity(Intent(context, ThemedControlsActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))\n    }\n\n    override fun onPlayStatusChanged(playStatus: Int) {\n        when (playStatus) {\n            PlayStatusListener.STATUS_START_PLAYING -> {\n                stopLoading()\n                openControls()\n            }\n            PlayStatusListener.STATUS_FINISHED, PlayStatusListener.STATUS_STOPPED -> {\n                stopLoading()\n                setEid(NO_PLAYING)\n            }\n            PlayStatusListener.STATUS_NOT_SUPPORT_LISTENER -> {\n                stopLoading()\n                setEid(NO_PLAYING)\n                Toaster.toast(\"Video no soportado por dispositivo\")\n            }\n        }\n    }\n\n    override fun onPositionChanged(currentPosition: Long) {\n\n    }\n\n    override fun onTotalDurationObtained(totalDuration: Long) {\n\n    }\n\n    override fun onSuccessSeek() {\n\n    }\n\n    companion object {\n        var NO_PLAYING = \"no_play\"\n        private val ourInstance: CastUtil by lazy { CastUtil(App.context) }\n\n        @Contract(pure = true)\n        fun get(): CastUtil {\n            return ourInstance\n        }\n\n        fun registerActivity(activity: Activity, menu: Menu, menuId: Int) = get().registerActivity(activity, menu, menuId)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/ChannelTools.kt",
    "content": "package knf.kuma.commons\n\nimport java.io.IOException\nimport java.nio.ByteBuffer\nimport java.nio.channels.ReadableByteChannel\nimport java.nio.channels.WritableByteChannel\n\nobject ChannelTools {\n    @Throws(IOException::class)\n    fun fastChannelCopy(src: ReadableByteChannel, dest: WritableByteChannel) {\n        val buffer = ByteBuffer.allocateDirect(16 * 1024)\n        while (src.read(buffer) != -1) {\n            // prepare the buffer to be drained\n            buffer.flip()\n            // write to the channel, may block\n            dest.write(buffer)\n            // If partial transfer, shift remainder down\n            // If buffer is empty, same as doing clear()\n            buffer.compact()\n        }\n        // EOF will leave buffer in fill state\n        buffer.flip()\n        // make sure the buffer is fully drained.\n        while (buffer.hasRemaining()) {\n            dest.write(buffer)\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/CipherExt.kt",
    "content": "package knf.kuma.commons\r\n\r\nimport android.util.Base64\r\nimport knf.kuma.BuildConfig\r\nimport javax.crypto.Cipher\r\nimport javax.crypto.spec.GCMParameterSpec\r\nimport javax.crypto.spec.IvParameterSpec\r\nimport javax.crypto.spec.SecretKeySpec\r\n\r\nobject CipherContainer {\r\n    val encryption = Encryption.getDefault(BuildConfig.CIPHER_PWD_16, BuildConfig.CIPHER_PWD_12, ByteArray(16))\r\n}\r\n\r\nfun String.encrypt(): String? = CipherContainer.encryption.encryptOrNull(this)\r\nfun String.encryptOrThrow(): String = CipherContainer.encryption.encrypt(this)\r\n\r\nfun String.decrypt(): String? = CipherContainer.encryption.decryptOrNull(this)\r\nfun String.decryptOrThrow(): String = CipherContainer.encryption.decrypt(this)\r\n\r\nfun String.encrypt12(password: String): String {\r\n    val secretKeySpec = SecretKeySpec(password.toByteArray(), \"AES\")\r\n    val iv = ByteArray(12)\r\n    val charArray = password.toCharArray()\r\n    for (i in charArray.indices) {\r\n        iv[i] = charArray[i].toByte()\r\n    }\r\n    val gcmParameterSpec = GCMParameterSpec(128, iv)\r\n\r\n    val cipher = Cipher.getInstance(\"AES/GCM/NoPadding\")\r\n    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec)\r\n\r\n    val encryptedValue = cipher.doFinal(this.toByteArray())\r\n    return Base64.encodeToString(encryptedValue, Base64.DEFAULT)\r\n}\r\n\r\nfun String.encrypt16(password: String): String {\r\n    val secretKeySpec = SecretKeySpec(password.toByteArray(), \"AES\")\r\n    val iv = ByteArray(16)\r\n    val charArray = password.toCharArray()\r\n    for (i in charArray.indices) {\r\n        iv[i] = charArray[i].toByte()\r\n    }\r\n    val ivParameterSpec = IvParameterSpec(iv)\r\n\r\n    val cipher = Cipher.getInstance(\"AES/GCM/NoPadding\")\r\n    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec)\r\n\r\n    val encryptedValue = cipher.doFinal(this.toByteArray())\r\n    return Base64.encodeToString(encryptedValue, Base64.DEFAULT)\r\n}\r\n\r\nfun String.encrypt32(password: String): String {\r\n    val secretKeySpec = SecretKeySpec(password.toByteArray(), \"AES\")\r\n    val iv = ByteArray(12)\r\n    val charArray = password.toCharArray()\r\n    for (i in charArray.indices) {\r\n        iv[i] = charArray[i].toByte()\r\n    }\r\n    val ivParameterSpec = IvParameterSpec(iv)\r\n\r\n    val cipher = Cipher.getInstance(\"AES/GCM/NoPadding\")\r\n    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec)\r\n\r\n    val encryptedValue = cipher.doFinal(this.toByteArray())\r\n    return Base64.encodeToString(encryptedValue, Base64.DEFAULT)\r\n}\r\n\r\nfun String.decrypt12(password: String): String {\r\n    val secretKeySpec = SecretKeySpec(password.toByteArray(), \"AES\")\r\n    val iv = ByteArray(12)\r\n    val charArray = password.toCharArray()\r\n    for (i in charArray.indices) {\r\n        iv[i] = charArray[i].toByte()\r\n    }\r\n    val gcmParameterSpec = GCMParameterSpec(128, iv)\r\n\r\n    val cipher = Cipher.getInstance(\"AES/GCM/NoPadding\")\r\n    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec)\r\n\r\n    val decryptedByteValue = cipher.doFinal(Base64.decode(this, Base64.DEFAULT))\r\n    return String(decryptedByteValue)\r\n}\r\n\r\nfun String.decrypt16(password: String): String {\r\n    val secretKeySpec = SecretKeySpec(password.toByteArray(), \"AES\")\r\n    val iv = ByteArray(16)\r\n    val charArray = password.toCharArray()\r\n    for (i in charArray.indices) {\r\n        iv[i] = charArray[i].toByte()\r\n    }\r\n    val ivParameterSpec = IvParameterSpec(iv)\r\n\r\n    val cipher = Cipher.getInstance(\"AES/GCM/NoPadding\")\r\n    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec)\r\n\r\n    val decryptedByteValue = cipher.doFinal(Base64.decode(this, Base64.DEFAULT))\r\n    return String(decryptedByteValue)\r\n}\r\n\r\nfun String.decrypt32(password: String): String {\r\n    val secretKeySpec = SecretKeySpec(password.toByteArray(), \"AES\")\r\n    val iv = ByteArray(12)\r\n    val charArray = password.toCharArray()\r\n    for (i in charArray.indices) {\r\n        iv[i] = charArray[i].toByte()\r\n    }\r\n    val ivParameterSpec = IvParameterSpec(iv)\r\n\r\n    val cipher = Cipher.getInstance(\"AES/GCM/NoPadding\")\r\n    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec)\r\n\r\n    val decryptedByteValue = cipher.doFinal(Base64.decode(this, Base64.DEFAULT))\r\n    return String(decryptedByteValue)\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/DesignUtils.kt",
    "content": "package knf.kuma.commons\r\n\r\nimport android.content.ComponentName\r\nimport android.content.Intent\r\nimport android.content.pm.PackageManager\r\nimport androidx.fragment.app.FragmentActivity\r\nimport knf.kuma.App\r\nimport knf.kuma.Main\r\nimport knf.kuma.MainMaterial\r\nimport knf.kuma.animeinfo.ActivityAnime\r\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\r\nimport knf.kuma.emision.EmissionActivity\r\nimport knf.kuma.emision.EmissionActivityMaterial\r\nimport knf.kuma.explorer.ExplorerActivity\r\nimport knf.kuma.explorer.ExplorerActivityMaterial\r\n\r\nobject DesignUtils {\r\n    private const val nameMainFlat = \"knf.kuma.MainMaterial\"\r\n    private const val nameMainClassic = \"knf.kuma.Main\"\r\n    private const val nameInfoFlat = \"knf.kuma.animeinfo.ActivityAnimeMaterial\"\r\n    private const val nameInfoClassic = \"knf.kuma.animeinfo.ActivityAnime\"\r\n    private var lastPref = PrefsUtil.designStyle\r\n\r\n    val isFlat get() = PrefsUtil.designStyle == \"0\"\r\n\r\n    val mainClass: Class<*> get() = if (isFlat) MainMaterial::class.java else Main::class.java\r\n    val infoClass: Class<*> get() = if (isFlat) ActivityAnimeMaterial::class.java else ActivityAnime::class.java\r\n    val explorerClass: Class<*> get() = if (isFlat) ExplorerActivityMaterial::class.java else ExplorerActivity::class.java\r\n    val emissionClass: Class<*> get() = if (isFlat) EmissionActivityMaterial::class.java else EmissionActivity::class.java\r\n\r\n    fun change(activity: FragmentActivity, to: String? = PrefsUtil.designStyle, start: Boolean = true) {\r\n        to ?: return\r\n        if (to == \"0\") {\r\n            enableComponent(nameMainFlat)\r\n            enableComponent(nameInfoFlat)\r\n            if (start){\r\n                activity.finish()\r\n                activity.startActivity(Intent(activity, MainMaterial::class.java).putExtra(\"start_position\", 3))\r\n            }\r\n            disableComponent(nameMainClassic)\r\n            disableComponent(nameInfoClassic)\r\n        } else {\r\n            enableComponent(nameMainClassic)\r\n            enableComponent(nameInfoClassic)\r\n            if (start){\r\n                activity.finish()\r\n                activity.startActivity(Intent(activity, Main::class.java).putExtra(\"start_position\", 3))\r\n            }\r\n            disableComponent(nameMainFlat)\r\n            disableComponent(nameInfoFlat)\r\n        }\r\n    }\r\n\r\n    private fun disableComponent(name: String) {\r\n        App.context.packageManager.apply {\r\n            setComponentEnabledSetting(ComponentName(App.context.packageName, name), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)\r\n        }\r\n    }\r\n\r\n    private fun enableComponent(name: String) {\r\n        App.context.packageManager.apply {\r\n            setComponentEnabledSetting(ComponentName(App.context.packageName, name), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)\r\n        }\r\n    }\r\n\r\n    fun listenDesignChange(activity: FragmentActivity){\r\n        PrefsUtil.getLiveDesignType().observe(activity) {\r\n            noCrash {\r\n                if (it != lastPref && it.toInt() >= 0) {\r\n                    lastPref = it\r\n                    change(activity, it)\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/EAHelper.kt",
    "content": "package knf.kuma.commons\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.TextView\nimport androidx.annotation.ColorRes\nimport androidx.annotation.DrawableRes\nimport androidx.annotation.StyleRes\nimport androidx.preference.PreferenceManager\nimport com.google.android.material.button.MaterialButton\nimport knf.kuma.App\nimport knf.kuma.BuildConfig\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.ads.FullscreenAdLoader\nimport knf.kuma.ads.getFAdLoaderInterstitial\nimport knf.kuma.ads.getFAdLoaderRewarded\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.EADB\nimport knf.kuma.databinding.ActivityEaBinding\nimport knf.kuma.pojos.EAObject\nimport moe.feng.common.stepperview.IStepperAdapter\nimport moe.feng.common.stepperview.VerticalStepperItemView\nimport org.jetbrains.anko.find\nimport org.jetbrains.anko.sdk27.coroutines.onClick\nimport xdroid.toaster.Toaster\nimport java.util.Random\nimport androidx.core.content.edit\n\nobject EAHelper {\n    private val CODE1: String by lazy {\n        PreferenceManager.getDefaultSharedPreferences(App.context).getString(\"ea_code1\", null)\n                ?: generate(App.context, \"ea_code1\", arrayOf(\"R\", \"F\", \"D\", \"C\"))\n    }\n    private val CODE2: String by lazy {\n        PreferenceManager.getDefaultSharedPreferences(App.context).getString(\"ea_code2\", null)\n                ?: generate(App.context, \"ea_code2\", arrayOf(\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\"))\n    }\n    private var CURRENT_1 = \"\"\n    private var CURRENT_2 = \"\"\n\n    val isPart0Unlocked: Boolean\n        get() = EADB.INSTANCE.eaDAO().isUnlocked(0)\n\n    val isPart1Unlocked: Boolean\n        get() = EADB.INSTANCE.eaDAO().isUnlocked(1)\n\n    val isPart2Unlocked: Boolean\n        get() = EADB.INSTANCE.eaDAO().isUnlocked(2)\n\n    val isPart3Unlocked: Boolean\n        get() = EADB.INSTANCE.eaDAO().isUnlocked(3)\n    val isAllUnlocked: Boolean\n        get() = isPart0Unlocked && isPart1Unlocked && isPart2Unlocked && isPart3Unlocked\n\n    val phase: Int\n        get() = when {\n            isPart3Unlocked -> 4\n            isPart2Unlocked -> 3\n            isPart1Unlocked -> 2\n            isPart0Unlocked -> 1\n            else -> 0\n        }\n\n    val eaMessage: String\n        get() = when {\n            isPart3Unlocked -> \"Disfruta de la recompensa\"\n            isPart2Unlocked -> \"El tesoro esta en Akihabara\"\n            isPart1Unlocked -> \"LMMJVSD \\u2192 US \\u2192 $CODE2\"\n            isPart0Unlocked -> CODE1\n            else -> \"\\u26B2 easteregg\"\n        }\n\n    fun getMessage(phase: Int): String {\n        return when (phase) {\n            4 -> \"Disfruta de la recompensa\"\n            3 -> \"El tesoro esta en Akihabara\"\n            2 -> \"LMMJVSD \\u2192 US \\u2192 $CODE2\"\n            1 -> CODE1\n            else -> \"\\u26B2 easteregg\"\n        }\n    }\n\n    fun checkStart(query: String) {\n        if (phase == 0 && query == BuildConfig.EASTER_SEARCH) {\n            Toaster.toastLong(CODE1)\n            setUnlocked(0)\n        }\n    }\n\n    private fun generate(context: Context, key: String, array: Array<String>): String {\n        val builder = StringBuilder()\n        for (i in 0..9) {\n            builder.append(array[Random().nextInt(array.size)])\n        }\n        PreferenceManager.getDefaultSharedPreferences(context).edit {\n            putString(\n                key,\n                builder.toString()\n            )\n        }\n        return builder.toString()\n    }\n\n    fun enter1(part: String) {\n        if (isPart0Unlocked && phase == 1) {\n            CURRENT_1 += part\n            if (CURRENT_1 == CODE1) {\n                setUnlocked(1)\n                Toaster.toastLong(\"LMMJVSD \\u2192 US \\u2192 $CODE2\")\n                clear1()\n            } else if (!CODE1.startsWith(CURRENT_1)) {\n                clear1()\n                CURRENT_1 += part\n            }\n        }\n    }\n\n    fun clear1() {\n        CURRENT_1 = \"\"\n    }\n\n    fun enter2(part: String) {\n        if (isPart1Unlocked && phase == 2) {\n            CURRENT_2 += part\n            if (CURRENT_2 == CODE2) {\n                setUnlocked(2)\n                Toaster.toastLong(\"El tesoro esta en Akihabara\")\n                clear2()\n            } else if (!CODE2.startsWith(CURRENT_2)) {\n                clear2()\n                CURRENT_2 += part\n            }\n        }\n    }\n\n    fun clear2() {\n        CURRENT_2 = \"\"\n    }\n\n    internal fun enter3() {\n        if (isPart2Unlocked && phase == 3) {\n            setUnlocked(3)\n        }\n    }\n\n    fun setUnlocked(phase: Int) {\n        EADB.INSTANCE.eaDAO().unlock(EAObject(phase))\n        AchievementManager.onPhaseUnlocked(phase)\n        syncData { ea() }\n    }\n\n    @StyleRes\n    fun getTheme(): Int {\n        return noCrashLet(R.style.AppTheme_NoActionBar) {\n            if (!isPart0Unlocked || !isPart1Unlocked || !isPart2Unlocked or !isPart3Unlocked)\n                R.style.AppTheme_DayNight\n            when (PrefsUtil.themeColor) {\n                \"0\" -> R.style.AppTheme_DayNight\n                \"1\" -> R.style.AppTheme_Pink\n                \"2\" -> R.style.AppTheme_Purple\n                \"3\" -> R.style.AppTheme_DeepPurple\n                \"4\" -> R.style.AppTheme_Indigo\n                \"5\" -> R.style.AppTheme_Blue\n                \"6\" -> R.style.AppTheme_LightBlue\n                \"7\" -> R.style.AppTheme_Cyan\n                \"8\" -> R.style.AppTheme_Teal\n                \"9\" -> R.style.AppTheme_Green\n                \"10\" -> R.style.AppTheme_LightGreen\n                \"11\" -> R.style.AppTheme_Lime\n                \"12\" -> R.style.AppTheme_Yellow\n                \"13\" -> R.style.AppTheme_Amber\n                \"14\" -> R.style.AppTheme_Orange\n                \"15\" -> R.style.AppTheme_DeepOrange\n                \"16\" -> R.style.AppTheme_Brown\n                \"17\" -> R.style.AppTheme_Gray\n                \"18\" -> R.style.AppTheme_BlueGray\n                else -> R.style.AppTheme_DayNight\n            }\n        }\n    }\n\n    @StyleRes\n    fun getThemeNA(): Int {\n        return noCrashLet(R.style.AppTheme_NoActionBar) {\n            if (!isPart0Unlocked || !isPart1Unlocked || !isPart2Unlocked or !isPart3Unlocked)\n                R.style.AppTheme_NoActionBar\n            when (PrefsUtil.themeColor) {\n                \"0\" -> R.style.AppTheme_NoActionBar\n                \"1\" -> R.style.AppTheme_NoActionBar_Pink\n                \"2\" -> R.style.AppTheme_NoActionBar_Purple\n                \"3\" -> R.style.AppTheme_NoActionBar_DeepPurple\n                \"4\" -> R.style.AppTheme_NoActionBar_Indigo\n                \"5\" -> R.style.AppTheme_NoActionBar_Blue\n                \"6\" -> R.style.AppTheme_NoActionBar_LightBlue\n                \"7\" -> R.style.AppTheme_NoActionBar_Cyan\n                \"8\" -> R.style.AppTheme_NoActionBar_Teal\n                \"9\" -> R.style.AppTheme_NoActionBar_Green\n                \"10\" -> R.style.AppTheme_NoActionBar_LightGreen\n                \"11\" -> R.style.AppTheme_NoActionBar_Lime\n                \"12\" -> R.style.AppTheme_NoActionBar_Yellow\n                \"13\" -> R.style.AppTheme_NoActionBar_Amber\n                \"14\" -> R.style.AppTheme_NoActionBar_Orange\n                \"15\" -> R.style.AppTheme_NoActionBar_DeepOrange\n                \"16\" -> R.style.AppTheme_NoActionBar_Brown\n                \"17\" -> R.style.AppTheme_NoActionBar_Gray\n                \"18\" -> R.style.AppTheme_NoActionBar_BlueGray\n                else -> R.style.AppTheme_NoActionBar\n            }\n        }\n    }\n\n    @StyleRes\n    fun getThemeDialog(): Int {\n        return noCrashLet(R.style.AppTheme_Dialog_Base) {\n            if (!isPart0Unlocked || !isPart1Unlocked || !isPart2Unlocked or !isPart3Unlocked)\n                R.style.AppTheme_Dialog_Base\n            when (PrefsUtil.themeColor) {\n                \"0\" -> R.style.AppTheme_Dialog_Base\n                \"1\" -> R.style.AppTheme_Dialog_Pink\n                \"2\" -> R.style.AppTheme_Dialog_Purple\n                \"3\" -> R.style.AppTheme_Dialog_DeepPurple\n                \"4\" -> R.style.AppTheme_Dialog_Indigo\n                \"5\" -> R.style.AppTheme_Dialog_Blue\n                \"6\" -> R.style.AppTheme_Dialog_LightBlue\n                \"7\" -> R.style.AppTheme_Dialog_Cyan\n                \"8\" -> R.style.AppTheme_Dialog_Teal\n                \"9\" -> R.style.AppTheme_Dialog_Green\n                \"10\" -> R.style.AppTheme_Dialog_LightGreen\n                \"11\" -> R.style.AppTheme_Dialog_Lime\n                \"12\" -> R.style.AppTheme_Dialog_Yellow\n                \"13\" -> R.style.AppTheme_Dialog_Amber\n                \"14\" -> R.style.AppTheme_Dialog_Orange\n                \"15\" -> R.style.AppTheme_Dialog_DeepOrange\n                \"16\" -> R.style.AppTheme_Dialog_Brown\n                \"17\" -> R.style.AppTheme_Dialog_Gray\n                \"18\" -> R.style.AppTheme_Dialog_BlueGray\n                else -> R.style.AppTheme_Dialog_Base\n            }\n        }\n    }\n\n    @DrawableRes\n    fun getThemeImg(): Int {\n        return noCrashLet(getThemeImg(\"0\")) {\n            if (!isPart0Unlocked || !isPart1Unlocked || !isPart2Unlocked or !isPart3Unlocked)\n                getThemeImg(\"0\")\n            getThemeImg(PrefsUtil.themeColor)\n        }\n    }\n\n    @DrawableRes\n    fun getThemeImg(value: String): Int {\n        when (value) {\n            \"0\" -> return R.drawable.side_nav_bar\n            \"1\" -> return R.drawable.side_nav_bar_pink\n            \"2\" -> return R.drawable.side_nav_bar_purple\n            \"3\" -> return R.drawable.side_nav_bar_deep_purple\n            \"4\" -> return R.drawable.side_nav_bar_indigo\n            \"5\" -> return R.drawable.side_nav_bar_blue\n            \"6\" -> return R.drawable.side_nav_bar_light_blue\n            \"7\" -> return R.drawable.side_nav_bar_cyan\n            \"8\" -> return R.drawable.side_nav_bar_teal\n            \"9\" -> return R.drawable.side_nav_bar_green\n            \"10\" -> return R.drawable.side_nav_bar_light_green\n            \"11\" -> return R.drawable.side_nav_bar_lime\n            \"12\" -> return R.drawable.side_nav_bar_yellow\n            \"13\" -> return R.drawable.side_nav_bar_amber\n            \"14\" -> return R.drawable.side_nav_bar_orange\n            \"15\" -> return R.drawable.side_nav_bar_deep_orange\n            \"16\" -> return R.drawable.side_nav_bar_brown\n            \"17\" -> return R.drawable.side_nav_bar_gray\n            \"18\" -> return R.drawable.side_nav_bar_blue_gray\n            else -> return R.drawable.side_nav_bar\n        }\n    }\n\n    @ColorRes\n    fun getThemeColor(): Int {\n        return noCrashLet(getThemeColor(\"0\")) {\n            if (!isPart0Unlocked || !isPart1Unlocked || !isPart2Unlocked or !isPart3Unlocked)\n                getThemeColor(\"0\")\n            getThemeColor(PrefsUtil.themeColor)\n        }\n    }\n\n    @ColorRes\n    fun getThemeColor(value: String): Int {\n        when (value) {\n            \"0\" -> return R.color.colorAccent\n            \"1\" -> return R.color.colorAccentPink\n            \"2\" -> return R.color.colorAccentPurple\n            \"3\" -> return R.color.colorAccentDeepPurple\n            \"4\" -> return R.color.colorAccentIndigo\n            \"5\" -> return R.color.colorAccentBlue\n            \"6\" -> return R.color.colorAccentLightBlue\n            \"7\" -> return R.color.colorAccentCyan\n            \"8\" -> return R.color.colorAccentTeal\n            \"9\" -> return R.color.colorAccentGreen\n            \"10\" -> return R.color.colorAccentLightGreen\n            \"11\" -> return R.color.colorAccentLime\n            \"12\" -> return R.color.colorAccentYellow\n            \"13\" -> return R.color.colorAccentAmber\n            \"14\" -> return R.color.colorAccentOrange\n            \"15\" -> return R.color.colorAccentDeepOrange\n            \"16\" -> return R.color.colorAccentBrown\n            \"17\" -> return R.color.colorAccentGray\n            \"18\" -> return R.color.colorAccentBlueGrey\n            else -> return R.color.colorAccent\n        }\n    }\n\n    @ColorRes\n    fun getThemeColorLight(): Int {\n        return noCrashLet(getThemeColorLight(\"0\")) {\n            if (!isPart0Unlocked || !isPart1Unlocked || !isPart2Unlocked or !isPart3Unlocked)\n                getThemeColorLight(\"0\")\n            getThemeColorLight(PrefsUtil.themeColor)\n        }\n    }\n\n    @ColorRes\n    fun getThemeColorLight(value: String): Int {\n        when (value) {\n            \"0\" -> return R.color.colorAccentLight\n            \"1\" -> return R.color.colorAccentPinkLight\n            \"2\" -> return R.color.colorAccentPurpleLight\n            \"3\" -> return R.color.colorAccentDeepPurpleLight\n            \"4\" -> return R.color.colorAccentIndigoLight\n            \"5\" -> return R.color.colorAccentBlueLight\n            \"6\" -> return R.color.colorAccentLightBlueLight\n            \"7\" -> return R.color.colorAccentCyanLight\n            \"8\" -> return R.color.colorAccentTealLight\n            \"9\" -> return R.color.colorAccentGreenLight\n            \"10\" -> return R.color.colorAccentLightGreenLight\n            \"11\" -> return R.color.colorAccentLimeLight\n            \"12\" -> return R.color.colorAccentYellowLight\n            \"13\" -> return R.color.colorAccentAmberLight\n            \"14\" -> return R.color.colorAccentOrangeLight\n            \"15\" -> return R.color.colorAccentDeepOrangeLight\n            \"16\" -> return R.color.colorAccentBrownLight\n            \"17\" -> return R.color.colorAccentGrayLight\n            \"18\" -> return R.color.colorAccentBlueGreyLight\n            else -> return R.color.colorAccentLight\n        }\n    }\n}\n\nclass EAUnlockActivity : GenericActivity(), IStepperAdapter {\n\n    private val binding by lazy { ActivityEaBinding.inflate(layoutInflater) }\n    private val rewardedAd: FullscreenAdLoader by lazy { getFAdLoaderRewarded(this) }\n    private var interstitial: FullscreenAdLoader = getFAdLoaderInterstitial(this)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(binding.root)\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.title = \"Easter egg\"\n        binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\n        rewardedAd.load()\n        interstitial.load()\n    }\n\n    override fun onResume() {\n        super.onResume()\n        doOnUI {\n            binding.progress.visibility = View.GONE\n            binding.verticalStepperView.stepperAdapter = this@EAUnlockActivity\n            binding.verticalStepperView.currentStep = checkPurchases()\n        }\n    }\n\n    private fun showAd() {\n        diceOf<() -> Unit> {\n            put({ rewardedAd.show() }, AdsUtils.remoteConfigs.getDouble(\"rewarded_percent\"))\n            put({ interstitial.show() }, AdsUtils.remoteConfigs.getDouble(\"interstitial_percent\"))\n        }()\n    }\n\n    private fun checkPurchases(): Int {\n        return EAHelper.phase\n    }\n\n    override fun getTitle(index: Int): CharSequence {\n        return \"Paso ${index + 1}\"\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onCreateCustomView(index: Int, context: Context?, view: VerticalStepperItemView?): View {\n        val inflateView = LayoutInflater.from(context).inflate(R.layout.item_ea_step, view, false)\n        val hint = inflateView.find<TextView>(R.id.hint)\n        hint.text = EAHelper.getMessage(index)\n        val unlockCoinsButton = inflateView.find<MaterialButton>(R.id.unlockCoins)\n        if (index == 0 || index == 4) {\n            inflateView.find<View>(R.id.layBuy).visibility = View.GONE\n        } else {\n            unlockCoinsButton.text = getPurchaseCost(index).toString()\n            unlockCoinsButton.onClick {\n                doOnUI {\n                    if (Economy.buy(getPurchaseCost(index))) {\n                        unlock(index)\n                        Toaster.toast(\"Compra realizada\")\n                    } else\n                        Toaster.toast(\"No tienes suficientes loli-coins!!\")\n                }\n            }\n        }\n        return inflateView\n    }\n\n    private fun getSkuCode(index: Int): String {\n        return when (index) {\n            1 -> \"ee_2\"\n            2 -> \"ee_3\"\n            3 -> \"ee_4\"\n            else -> \"ee_all\"\n        }\n    }\n\n    private fun getPurchaseCost(index: Int): Int {\n        return when (index) {\n            1 -> 700\n            2 -> 1300\n            3 -> 500\n            else -> 9999\n        }\n    }\n\n    private fun unlock(index: Int) {\n        unlock(getSkuCode(index))\n    }\n\n    private fun unlock(sku: String?) {\n        when (sku) {\n            \"ee_2\" -> {\n                EAHelper.setUnlocked(1)\n                binding.verticalStepperView.nextStep()\n            }\n            \"ee_3\" -> {\n                EAHelper.setUnlocked(2)\n                binding.verticalStepperView.nextStep()\n            }\n            \"ee_4\" -> {\n                EAHelper.setUnlocked(3)\n                binding.verticalStepperView.nextStep()\n            }\n            \"ee_all\" -> {\n                EAHelper.setUnlocked(1)\n                EAHelper.setUnlocked(2)\n                EAHelper.setUnlocked(3)\n                binding.verticalStepperView.currentStep = 4\n                invalidateOptionsMenu()\n            }\n        }\n    }\n\n    override fun getSummary(index: Int): CharSequence? {\n        return null\n    }\n\n    override fun size(): Int {\n        return 5\n    }\n\n    override fun onShow(index: Int) {\n\n    }\n\n    override fun onHide(index: Int) {\n\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        if (EAHelper.phase != 4)\n            menuInflater.inflate(R.menu.menu_ea, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.coins -> {\n                Economy.showWallet(this) {\n                    showAd()\n                }\n            }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        binding.blockView.visibility = View.GONE\n    }\n\n    companion object {\n        fun start(context: Context) {\n            context.startActivity(Intent(context, EAUnlockActivity::class.java))\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/EAMapActivity.kt",
    "content": "package knf.kuma.commons\r\n\r\nimport android.app.Activity\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.graphics.Bitmap\r\nimport android.graphics.Canvas\r\nimport android.graphics.Color\r\nimport android.os.Bundle\r\nimport androidx.core.content.ContextCompat\r\nimport com.google.android.gms.maps.GoogleMap\r\nimport com.google.android.gms.maps.OnMapReadyCallback\r\nimport com.google.android.gms.maps.SupportMapFragment\r\nimport com.google.android.gms.maps.model.BitmapDescriptorFactory\r\nimport com.google.android.gms.maps.model.LatLng\r\nimport com.google.android.gms.maps.model.MarkerOptions\r\nimport knf.kuma.R\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.databinding.ActivityEamapBinding\r\nimport nl.dionsegijn.konfetti.models.Shape\r\nimport nl.dionsegijn.konfetti.models.Size\r\n\r\nclass EAMapActivity : GenericActivity(), OnMapReadyCallback {\r\n\r\n    private val binding by lazy { ActivityEamapBinding.inflate(layoutInflater) }\r\n    private lateinit var mMap: GoogleMap\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(binding.root)\r\n        // Obtain the SupportMapFragment and get notified when the map is ready to be used.\r\n        val mapFragment = supportFragmentManager\r\n                .findFragmentById(R.id.map) as? SupportMapFragment\r\n        mapFragment?.getMapAsync(this)\r\n    }\r\n\r\n    /**\r\n     * Manipulates the map once available.\r\n     * This callback is triggered when the map is ready to be used.\r\n     * This is where we can add markers or lines, add listeners or move the camera. In this case,\r\n     * we just add a marker near Sydney, Australia.\r\n     * If Google Play services is not installed on the device, the user will be prompted to install\r\n     * it inside the SupportMapFragment. This method will only be triggered once the user has\r\n     * installed Google Play services and returned to the app.\r\n     */\r\n    override fun onMapReady(googleMap: GoogleMap) {\r\n        mMap = googleMap\r\n        mMap.uiSettings.apply {\r\n            isMapToolbarEnabled = false\r\n            isZoomControlsEnabled = false\r\n        }\r\n        val point = LatLng(35.702067, 139.774528)\r\n        val marker = mMap.addMarker(MarkerOptions().apply {\r\n            position(point)\r\n            title(\"Easter Egg completado!\")\r\n            icon(BitmapDescriptorFactory.fromBitmap(getBitmapFromVD(this@EAMapActivity, R.drawable.ic_treasure)))\r\n\r\n        })\r\n        googleMap.setOnCameraMoveListener { marker?.isVisible = mMap.cameraPosition.zoom >= 13 }\r\n        googleMap.setOnMarkerClickListener { m ->\r\n            if (m == marker) {\r\n                EAHelper.enter3()\r\n                binding.konfetti.build()\r\n                        .addColors(Color.BLUE, Color.RED, Color.YELLOW, Color.GREEN, Color.MAGENTA)\r\n                        .setDirection(0.0, 359.0)\r\n                        .setSpeed(4f, 7f)\r\n                        .setFadeOutEnabled(true)\r\n                        .setTimeToLive(2000)\r\n                        .addShapes(Shape.RECT, Shape.CIRCLE)\r\n                        .addSizes(Size(12, 6f), Size(16, 6f))\r\n                        .setPosition(-50f, binding.konfetti.width + 50f, -50f, -50f)\r\n                        .streamFor(300, 10000L)\r\n            }\r\n            false\r\n        }\r\n    }\r\n\r\n    private fun getBitmapFromVD(context: Context, drawableId: Int): Bitmap {\r\n        val drawable = ContextCompat.getDrawable(context, drawableId)\r\n        val bitmap = Bitmap.createBitmap(drawable?.intrinsicWidth ?: 0,\r\n                drawable?.intrinsicHeight ?: 0, Bitmap.Config.ARGB_8888)\r\n        val canvas = Canvas(bitmap)\r\n        drawable?.setBounds(0, 0, canvas.width, canvas.height)\r\n        drawable?.draw(canvas)\r\n        return bitmap\r\n    }\r\n\r\n    companion object {\r\n\r\n        fun start(context: Activity) {\r\n            context.startActivityForResult(Intent(context, EAMapActivity::class.java), 5698)\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/Economy.kt",
    "content": "package knf.kuma.commons\r\n\r\nimport androidx.appcompat.app.AlertDialog\r\nimport androidx.core.content.ContextCompat\r\nimport androidx.fragment.app.FragmentActivity\r\nimport androidx.lifecycle.MutableLiveData\r\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\r\nimport knf.kuma.R\r\nimport knf.kuma.achievements.AchievementManager\r\nimport knf.kuma.backup.firestore.FirestoreManager\r\nimport knf.kuma.databinding.DialogWalletBinding\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\nimport xdroid.toaster.Toaster.toast\r\n\r\nval Int.coins: String get() = \"$this loli-coin${if (this == 1) \"\" else \"s\"}\"\r\n\r\nobject Economy {\r\n\r\n    private val coinsLiveData = MutableLiveData(PrefsUtil.userCoins)\r\n    val rewardedVideoLiveData = MutableLiveData(PrefsUtil.userRewardedVideoCount)\r\n\r\n    fun reward(isAdClicked: Boolean = false, baseReward: Int = 1) {\r\n        doOnUIException(onLog = { FirebaseCrashlytics.getInstance().recordException(it);toast(\"Error al obtener loli-coins\\n${it.message}\") }) {\r\n            val reward = diceOf<Int> {\r\n                put(baseReward, if (isAdClicked) 80.0 else 90.0)\r\n                put(baseReward + 1, if (isAdClicked) 15.0 else 8.0)\r\n                put(baseReward + 2, if (isAdClicked) 5.0 else 2.0)\r\n            }\r\n            PrefsUtil.userCoins = (PrefsUtil.userCoins + reward).also { coinsLiveData.value = it }\r\n            PrefsUtil.userRewardedVideoCount = (PrefsUtil.userRewardedVideoCount + 1).also { rewardedVideoLiveData.value = it }\r\n            FirestoreManager.updateTop()\r\n            AchievementManager.incrementCount(reward, listOf(46, 47, 48, 49, 50, 51))\r\n            toast(\"Has ganado ${reward.coins}!!!!!\")\r\n        }\r\n    }\r\n\r\n    fun buy(price: Int): Boolean {\r\n        val total = PrefsUtil.userCoins\r\n        return if (total >= price) {\r\n            PrefsUtil.userCoins = (total - price).also { doOnUIGlobal { coinsLiveData.value = it } }\r\n            true\r\n        } else false\r\n    }\r\n\r\n    fun showWallet(activity: FragmentActivity, themed: Boolean = false, onShow: () -> Unit) {\r\n        activity.doOnUI {\r\n            val view = activity.layoutInflater.inflate(R.layout.dialog_wallet, null)\r\n            val binding = DialogWalletBinding.bind(view)\r\n            if (themed) {\r\n                binding.coinsCount.setTextColor(ContextCompat.getColor(activity, EAHelper.getThemeColorLight()))\r\n                binding.backgroundTop.setBackgroundColor(ContextCompat.getColor(activity, EAHelper.getThemeColorLight()))\r\n                binding.backgroundBottom.setBackgroundColor(ContextCompat.getColor(activity, EAHelper.getThemeColor()))\r\n            }\r\n            binding.coinsCount.text = PrefsUtil.userCoins.toString()\r\n            coinsLiveData.observe(activity) {\r\n                activity.doOnUI {\r\n                    binding.coinsCount.text = it.toString()\r\n                }\r\n            }\r\n            binding.showAdButton.onClick { onShow() }\r\n            AlertDialog.Builder(activity).apply {\r\n                setView(view)\r\n            }.show()\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/Encryption.java",
    "content": "package knf.kuma.commons;\r\n\r\nimport android.util.Base64;\r\n\r\nimport java.io.UnsupportedEncodingException;\r\nimport java.security.InvalidAlgorithmParameterException;\r\nimport java.security.InvalidKeyException;\r\nimport java.security.MessageDigest;\r\nimport java.security.NoSuchAlgorithmException;\r\nimport java.security.SecureRandom;\r\nimport java.security.spec.InvalidKeySpecException;\r\nimport java.security.spec.KeySpec;\r\n\r\nimport javax.crypto.BadPaddingException;\r\nimport javax.crypto.Cipher;\r\nimport javax.crypto.IllegalBlockSizeException;\r\nimport javax.crypto.NoSuchPaddingException;\r\nimport javax.crypto.SecretKey;\r\nimport javax.crypto.SecretKeyFactory;\r\nimport javax.crypto.spec.IvParameterSpec;\r\nimport javax.crypto.spec.PBEKeySpec;\r\nimport javax.crypto.spec.SecretKeySpec;\r\n\r\n/**\r\n * A class to make more easy and simple the encrypt routines, this is the core of Encryption library\r\n */\r\npublic class Encryption {\r\n\r\n    /**\r\n     * The Builder used to create the Encryption instance and that contains the information about\r\n     * encryption specifications, this instance need to be private and careful managed\r\n     */\r\n    private final Builder mBuilder;\r\n\r\n    /**\r\n     * The private and unique constructor, you should use the Encryption.Builder to build your own\r\n     * instance or get the default proving just the sensible information about encryption\r\n     */\r\n    private Encryption(Builder builder) {\r\n        mBuilder = builder;\r\n    }\r\n\r\n    /**\r\n     * @return an default encryption instance or {@code null} if occur some Exception, you can\r\n     * create yur own Encryption instance using the Encryption.Builder\r\n     */\r\n    public static Encryption getDefault(String key, String salt, byte[] iv) {\r\n        try {\r\n            return Builder.getDefaultBuilder(key, salt, iv).build();\r\n        } catch (NoSuchAlgorithmException e) {\r\n            e.printStackTrace();\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Encrypt a String\r\n     *\r\n     * @param data the String to be encrypted\r\n     * @return the encrypted String or {@code null} if you send the data as {@code null}\r\n     * @throws UnsupportedEncodingException       if the Builder charset name is not supported or if\r\n     *                                            the Builder charset name is not supported\r\n     * @throws NoSuchAlgorithmException           if the Builder digest algorithm is not available\r\n     *                                            or if this has no installed provider that can\r\n     *                                            provide the requested by the Builder secret key\r\n     *                                            type or it is {@code null}, empty or in an invalid\r\n     *                                            format\r\n     * @throws NoSuchPaddingException             if no installed provider can provide the padding\r\n     *                                            scheme in the Builder digest algorithm\r\n     * @throws InvalidAlgorithmParameterException if the specified parameters are inappropriate for\r\n     *                                            the cipher\r\n     * @throws InvalidKeyException                if the specified key can not be used to initialize\r\n     *                                            the cipher instance\r\n     * @throws InvalidKeySpecException            if the specified key specification cannot be used\r\n     *                                            to generate a secret key\r\n     * @throws BadPaddingException                if the padding of the data does not match the\r\n     *                                            padding scheme\r\n     * @throws IllegalBlockSizeException          if the size of the resulting bytes is not a\r\n     *                                            multiple of the cipher block size\r\n     * @throws NullPointerException               if the Builder digest algorithm is {@code null} or\r\n     *                                            if the specified Builder secret key type is\r\n     *                                            {@code null}\r\n     * @throws IllegalStateException              if the cipher instance is not initialized for\r\n     *                                            encryption or decryption\r\n     */\r\n    public String encrypt(String data) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException {\r\n        if (data == null) return null;\r\n        SecretKey secretKey = getSecretKey(hashTheKey(mBuilder.getKey()));\r\n        byte[] dataBytes = data.getBytes(mBuilder.getCharsetName());\r\n        Cipher cipher = Cipher.getInstance(mBuilder.getAlgorithm());\r\n        cipher.init(Cipher.ENCRYPT_MODE, secretKey, mBuilder.getIvParameterSpec(), mBuilder.getSecureRandom());\r\n        return Base64.encodeToString(cipher.doFinal(dataBytes), mBuilder.getBase64Mode());\r\n    }\r\n\r\n    /**\r\n     * This is a sugar method that calls encrypt method and catch the exceptions returning\r\n     * {@code null} when it occurs and logging the error\r\n     *\r\n     * @param data the String to be encrypted\r\n     * @return the encrypted String or {@code null} if you send the data as {@code null}\r\n     */\r\n    public String encryptOrNull(String data) {\r\n        try {\r\n            return encrypt(data);\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This is a sugar method that calls encrypt method in background, it is a good idea to use this\r\n     * one instead the default method because encryption can take several time and with this method\r\n     * the process occurs in a AsyncTask, other advantage is the Callback with separated methods,\r\n     * one for success and other for the exception\r\n     *\r\n     * @param data     the String to be encrypted\r\n     * @param callback the Callback to handle the results\r\n     */\r\n    public void encryptAsync(final String data, final Callback callback) {\r\n        if (callback == null) return;\r\n        new Thread(new Runnable() {\r\n            @Override\r\n            public void run() {\r\n                try {\r\n                    String encrypt = encrypt(data);\r\n                    if (encrypt == null) {\r\n                        callback.onError(new Exception(\"Encrypt return null, it normally occurs when you send a null data\"));\r\n                    }\r\n                    callback.onSuccess(encrypt);\r\n                } catch (Exception e) {\r\n                    callback.onError(e);\r\n                }\r\n            }\r\n        }).start();\r\n    }\r\n\r\n    /**\r\n     * Decrypt a String\r\n     *\r\n     * @param data the String to be decrypted\r\n     * @return the decrypted String or {@code null} if you send the data as {@code null}\r\n     * @throws UnsupportedEncodingException       if the Builder charset name is not supported or if\r\n     *                                            the Builder charset name is not supported\r\n     * @throws NoSuchAlgorithmException           if the Builder digest algorithm is not available\r\n     *                                            or if this has no installed provider that can\r\n     *                                            provide the requested by the Builder secret key\r\n     *                                            type or it is {@code null}, empty or in an invalid\r\n     *                                            format\r\n     * @throws NoSuchPaddingException             if no installed provider can provide the padding\r\n     *                                            scheme in the Builder digest algorithm\r\n     * @throws InvalidAlgorithmParameterException if the specified parameters are inappropriate for\r\n     *                                            the cipher\r\n     * @throws InvalidKeyException                if the specified key can not be used to initialize\r\n     *                                            the cipher instance\r\n     * @throws InvalidKeySpecException            if the specified key specification cannot be used\r\n     *                                            to generate a secret key\r\n     * @throws BadPaddingException                if the padding of the data does not match the\r\n     *                                            padding scheme\r\n     * @throws IllegalBlockSizeException          if the size of the resulting bytes is not a\r\n     *                                            multiple of the cipher block size\r\n     * @throws NullPointerException               if the Builder digest algorithm is {@code null} or\r\n     *                                            if the specified Builder secret key type is\r\n     *                                            {@code null}\r\n     * @throws IllegalStateException              if the cipher instance is not initialized for\r\n     *                                            encryption or decryption\r\n     */\r\n    public String decrypt(String data) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {\r\n        if (data == null) return null;\r\n        byte[] dataBytes = Base64.decode(data, mBuilder.getBase64Mode());\r\n        SecretKey secretKey = getSecretKey(hashTheKey(mBuilder.getKey()));\r\n        Cipher cipher = Cipher.getInstance(mBuilder.getAlgorithm());\r\n        cipher.init(Cipher.DECRYPT_MODE, secretKey, mBuilder.getIvParameterSpec(), mBuilder.getSecureRandom());\r\n        byte[] dataBytesDecrypted = (cipher.doFinal(dataBytes));\r\n        return new String(dataBytesDecrypted);\r\n    }\r\n\r\n    /**\r\n     * This is a sugar method that calls decrypt method and catch the exceptions returning\r\n     * {@code null} when it occurs and logging the error\r\n     *\r\n     * @param data the String to be decrypted\r\n     * @return the decrypted String or {@code null} if you send the data as {@code null}\r\n     */\r\n    public String decryptOrNull(String data) {\r\n        try {\r\n            return decrypt(data);\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n            return null;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * This is a sugar method that calls decrypt method in background, it is a good idea to use this\r\n     * one instead the default method because decryption can take several time and with this method\r\n     * the process occurs in a AsyncTask, other advantage is the Callback with separated methods,\r\n     * one for success and other for the exception\r\n     *\r\n     * @param data     the String to be decrypted\r\n     * @param callback the Callback to handle the results\r\n     */\r\n    public void decryptAsync(final String data, final Callback callback) {\r\n        if (callback == null) return;\r\n        new Thread(new Runnable() {\r\n            @Override\r\n            public void run() {\r\n                try {\r\n                    String decrypt = decrypt(data);\r\n                    if (decrypt == null) {\r\n                        callback.onError(new Exception(\"Decrypt return null, it normally occurs when you send a null data\"));\r\n                    }\r\n                    callback.onSuccess(decrypt);\r\n                } catch (Exception e) {\r\n                    callback.onError(e);\r\n                }\r\n            }\r\n        }).start();\r\n    }\r\n\r\n    /**\r\n     * creates a 128bit salted aes key\r\n     *\r\n     * @param key encoded input key\r\n     * @return aes 128 bit salted key\r\n     * @throws NoSuchAlgorithmException     if no installed provider that can provide the requested\r\n     *                                      by the Builder secret key type\r\n     * @throws UnsupportedEncodingException if the Builder charset name is not supported\r\n     * @throws InvalidKeySpecException      if the specified key specification cannot be used to\r\n     *                                      generate a secret key\r\n     * @throws NullPointerException         if the specified Builder secret key type is {@code null}\r\n     */\r\n    private SecretKey getSecretKey(char[] key) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException {\r\n        SecretKeyFactory factory = SecretKeyFactory.getInstance(mBuilder.getSecretKeyType());\r\n        KeySpec spec = new PBEKeySpec(key, mBuilder.getSalt().getBytes(mBuilder.getCharsetName()), mBuilder.getIterationCount(), mBuilder.getKeyLength());\r\n        SecretKey tmp = factory.generateSecret(spec);\r\n        return new SecretKeySpec(tmp.getEncoded(), mBuilder.getKeyAlgorithm());\r\n    }\r\n\r\n    /**\r\n     * takes in a simple string and performs an sha1 hash\r\n     * that is 128 bits long...we then base64 encode it\r\n     * and return the char array\r\n     *\r\n     * @param key simple inputted string\r\n     * @return sha1 base64 encoded representation\r\n     * @throws UnsupportedEncodingException if the Builder charset name is not supported\r\n     * @throws NoSuchAlgorithmException     if the Builder digest algorithm is not available\r\n     * @throws NullPointerException         if the Builder digest algorithm is {@code null}\r\n     */\r\n    private char[] hashTheKey(String key) throws UnsupportedEncodingException, NoSuchAlgorithmException {\r\n        MessageDigest messageDigest = MessageDigest.getInstance(mBuilder.getDigestAlgorithm());\r\n        messageDigest.update(key.getBytes(mBuilder.getCharsetName()));\r\n        return Base64.encodeToString(messageDigest.digest(), Base64.NO_PADDING).toCharArray();\r\n    }\r\n\r\n    /**\r\n     * When you encrypt or decrypt in callback mode you get noticed of result using this interface\r\n     */\r\n    public interface Callback {\r\n\r\n        /**\r\n         * Called when encrypt or decrypt job ends and the process was a success\r\n         *\r\n         * @param result the encrypted or decrypted String\r\n         */\r\n        void onSuccess(String result);\r\n\r\n        /**\r\n         * Called when encrypt or decrypt job ends and has occurred an error in the process\r\n         *\r\n         * @param exception the Exception related to the error\r\n         */\r\n        void onError(Exception exception);\r\n\r\n    }\r\n\r\n    /**\r\n     * This class is used to create an Encryption instance, you should provide ALL data or start\r\n     * with the Default Builder provided by the getDefaultBuilder method\r\n     */\r\n    public static class Builder {\r\n\r\n        private byte[] mIv;\r\n        private int mKeyLength;\r\n        private int mBase64Mode;\r\n        private int mIterationCount;\r\n        private String mSalt;\r\n        private String mKey;\r\n        private String mAlgorithm;\r\n        private String mKeyAlgorithm;\r\n        private String mCharsetName;\r\n        private String mSecretKeyType;\r\n        private String mDigestAlgorithm;\r\n        private String mSecureRandomAlgorithm;\r\n        private SecureRandom mSecureRandom;\r\n        private IvParameterSpec mIvParameterSpec;\r\n\r\n        /**\r\n         * @return an default builder with the follow defaults:\r\n         * the default char set is UTF-8\r\n         * the default base mode is Base64\r\n         * the Secret Key Type is the PBKDF2WithHmacSHA1\r\n         * the default salt is \"some_salt\" but can be anything\r\n         * the default length of key is 128\r\n         * the default iteration count is 65536\r\n         * the default algorithm is AES in CBC mode and PKCS 5 Padding\r\n         * the default secure random algorithm is SHA1PRNG\r\n         * the default message digest algorithm SHA1\r\n         */\r\n        public static Builder getDefaultBuilder(String key, String salt, byte[] iv) {\r\n            return new Builder()\r\n                    .setIv(iv)\r\n                    .setKey(key)\r\n                    .setSalt(salt)\r\n                    .setKeyLength(128)\r\n                    .setKeyAlgorithm(\"AES\")\r\n                    .setCharsetName(\"UTF8\")\r\n                    .setIterationCount(1)\r\n                    .setDigestAlgorithm(\"SHA1\")\r\n                    .setBase64Mode(Base64.DEFAULT)\r\n                    .setAlgorithm(\"AES/CBC/PKCS5Padding\")\r\n                    .setSecureRandomAlgorithm(\"SHA1PRNG\")\r\n                    .setSecretKeyType(\"PBKDF2WithHmacSHA1\");\r\n        }\r\n\r\n        /**\r\n         * Build the Encryption with the provided information\r\n         *\r\n         * @return a new Encryption instance with provided information\r\n         * @throws NoSuchAlgorithmException if the specified SecureRandomAlgorithm is not available\r\n         * @throws NullPointerException     if the SecureRandomAlgorithm is {@code null} or if the\r\n         *                                  IV byte array is null\r\n         */\r\n        public Encryption build() throws NoSuchAlgorithmException {\r\n            setSecureRandom(SecureRandom.getInstance(getSecureRandomAlgorithm()));\r\n            setIvParameterSpec(new IvParameterSpec(getIv()));\r\n            return new Encryption(this);\r\n        }\r\n\r\n        /**\r\n         * @return the charset name\r\n         */\r\n        private String getCharsetName() {\r\n            return mCharsetName;\r\n        }\r\n\r\n        /**\r\n         * @param charsetName the new charset name\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setCharsetName(String charsetName) {\r\n            mCharsetName = charsetName;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the algorithm\r\n         */\r\n        private String getAlgorithm() {\r\n            return mAlgorithm;\r\n        }\r\n\r\n        /**\r\n         * @param algorithm the algorithm to be used\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setAlgorithm(String algorithm) {\r\n            mAlgorithm = algorithm;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the key algorithm\r\n         */\r\n        private String getKeyAlgorithm() {\r\n            return mKeyAlgorithm;\r\n        }\r\n\r\n        /**\r\n         * @param keyAlgorithm the keyAlgorithm to be used in keys\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setKeyAlgorithm(String keyAlgorithm) {\r\n            mKeyAlgorithm = keyAlgorithm;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the Base 64 mode\r\n         */\r\n        private int getBase64Mode() {\r\n            return mBase64Mode;\r\n        }\r\n\r\n        /**\r\n         * @param base64Mode set the base 64 mode\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setBase64Mode(int base64Mode) {\r\n            mBase64Mode = base64Mode;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the type of aes key that will be created, on KITKAT+ the API has changed, if you\r\n         * are getting problems please @see <a href=\"http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html\">http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html</a>\r\n         */\r\n        private String getSecretKeyType() {\r\n            return mSecretKeyType;\r\n        }\r\n\r\n        /**\r\n         * @param secretKeyType the type of AES key that will be created, on KITKAT+ the API has\r\n         *                      changed, if you are getting problems please @see <a href=\"http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html\">http://android-developers.blogspot.com.br/2013/12/changes-to-secretkeyfactory-api-in.html</a>\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setSecretKeyType(String secretKeyType) {\r\n            mSecretKeyType = secretKeyType;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the value used for salting\r\n         */\r\n        private String getSalt() {\r\n            return mSalt;\r\n        }\r\n\r\n        /**\r\n         * @param salt the value used for salting\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setSalt(String salt) {\r\n            mSalt = salt;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the key\r\n         */\r\n        private String getKey() {\r\n            return mKey;\r\n        }\r\n\r\n        /**\r\n         * @param key the key.\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setKey(String key) {\r\n            mKey = key;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the length of key\r\n         */\r\n        private int getKeyLength() {\r\n            return mKeyLength;\r\n        }\r\n\r\n        /**\r\n         * @param keyLength the length of key\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setKeyLength(int keyLength) {\r\n            mKeyLength = keyLength;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the number of times the password is hashed\r\n         */\r\n        private int getIterationCount() {\r\n            return mIterationCount;\r\n        }\r\n\r\n        /**\r\n         * @param iterationCount the number of times the password is hashed\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setIterationCount(int iterationCount) {\r\n            mIterationCount = iterationCount;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the algorithm used to generate the secure random\r\n         */\r\n        private String getSecureRandomAlgorithm() {\r\n            return mSecureRandomAlgorithm;\r\n        }\r\n\r\n        /**\r\n         * @param secureRandomAlgorithm the algorithm to generate the secure random\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setSecureRandomAlgorithm(String secureRandomAlgorithm) {\r\n            mSecureRandomAlgorithm = secureRandomAlgorithm;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the IvParameterSpec bytes array\r\n         */\r\n        private byte[] getIv() {\r\n            return mIv;\r\n        }\r\n\r\n        /**\r\n         * @param iv the byte array to create a new IvParameterSpec\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setIv(byte[] iv) {\r\n            mIv = iv;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the SecureRandom\r\n         */\r\n        private SecureRandom getSecureRandom() {\r\n            return mSecureRandom;\r\n        }\r\n\r\n        /**\r\n         * @param secureRandom the Secure Random\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setSecureRandom(SecureRandom secureRandom) {\r\n            mSecureRandom = secureRandom;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the IvParameterSpec\r\n         */\r\n        private IvParameterSpec getIvParameterSpec() {\r\n            return mIvParameterSpec;\r\n        }\r\n\r\n        /**\r\n         * @param ivParameterSpec the IvParameterSpec\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setIvParameterSpec(IvParameterSpec ivParameterSpec) {\r\n            mIvParameterSpec = ivParameterSpec;\r\n            return this;\r\n        }\r\n\r\n        /**\r\n         * @return the message digest algorithm\r\n         */\r\n        private String getDigestAlgorithm() {\r\n            return mDigestAlgorithm;\r\n        }\r\n\r\n        /**\r\n         * @param digestAlgorithm the algorithm to be used to get message digest instance\r\n         * @return this instance to follow the Builder patter\r\n         */\r\n        public Builder setDigestAlgorithm(String digestAlgorithm) {\r\n            mDigestAlgorithm = digestAlgorithm;\r\n            return this;\r\n        }\r\n\r\n    }\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/ExtensionUtils.kt",
    "content": "package knf.kuma.commons\r\n\r\nimport android.annotation.SuppressLint\r\nimport android.app.Activity\r\nimport android.content.ComponentName\r\nimport android.content.Context\r\nimport android.content.ContextWrapper\r\nimport android.content.Intent\r\nimport android.content.pm.PackageManager\r\nimport android.content.res.Resources\r\nimport android.graphics.drawable.AnimationDrawable\r\nimport android.graphics.drawable.Drawable\r\nimport android.net.Uri\r\nimport android.os.Build\r\nimport android.os.Environment\r\nimport android.util.Log\r\nimport android.util.TypedValue\r\nimport android.view.LayoutInflater\r\nimport android.view.MenuItem\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.view.animation.AnimationUtils\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.annotation.ColorInt\r\nimport androidx.annotation.DrawableRes\r\nimport androidx.annotation.FontRes\r\nimport androidx.annotation.IdRes\r\nimport androidx.annotation.LayoutRes\r\nimport androidx.annotation.MenuRes\r\nimport androidx.annotation.UiThread\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.appcompat.widget.PopupMenu\r\nimport androidx.appcompat.widget.Toolbar\r\nimport androidx.asynclayoutinflater.view.AsyncLayoutInflater\r\nimport androidx.coordinatorlayout.widget.CoordinatorLayout\r\nimport androidx.core.app.NotificationCompat\r\nimport androidx.core.content.ContextCompat\r\nimport androidx.core.content.res.ResourcesCompat\r\nimport androidx.core.view.isVisible\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.fragment.app.FragmentActivity\r\nimport androidx.lifecycle.LifecycleOwner\r\nimport androidx.lifecycle.LiveData\r\nimport androidx.lifecycle.distinctUntilChanged\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.recyclerview.widget.GridLayoutManager\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\r\nimport com.bumptech.glide.Glide\r\nimport com.bumptech.glide.load.DataSource\r\nimport com.bumptech.glide.load.engine.DiskCacheStrategy\r\nimport com.bumptech.glide.load.engine.GlideException\r\nimport com.bumptech.glide.load.model.GlideUrl\r\nimport com.bumptech.glide.request.RequestListener\r\nimport com.bumptech.glide.request.target.Target\r\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\r\nimport com.google.android.material.snackbar.Snackbar\r\nimport com.squareup.picasso.Callback\r\nimport knf.kuma.App\r\nimport knf.kuma.BuildConfig\r\nimport knf.kuma.R\r\nimport knf.kuma.custom.snackbar.SnackProgressBar\r\nimport knf.kuma.custom.snackbar.SnackProgressBarManager\r\nimport knf.kuma.database.CacheDB\r\nimport knh.kuma.commons.cloudflarebypass.util.ConvertUtil\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport okhttp3.ConnectionSpec\r\nimport okhttp3.MediaType.Companion.toMediaType\r\nimport okhttp3.OkHttpClient\r\nimport okhttp3.Request\r\nimport okhttp3.RequestBody.Companion.toRequestBody\r\nimport okhttp3.Response\r\nimport org.json.JSONArray\r\nimport org.json.JSONObject\r\nimport org.jsoup.Connection\r\nimport org.jsoup.HttpStatusException\r\nimport org.jsoup.Jsoup\r\nimport org.jsoup.nodes.Document\r\nimport org.nield.kotlinstatistics.WeightedDice\r\nimport pl.droidsonroids.jspoon.Jspoon\r\nimport xdroid.toaster.Toaster\r\nimport java.io.File\r\nimport java.net.URLDecoder\r\nimport java.net.URLEncoder\r\nimport java.nio.charset.StandardCharsets\r\nimport kotlin.coroutines.resume\r\nimport kotlin.coroutines.suspendCoroutine\r\n\r\nfun Toolbar.changeToolbarFont(@FontRes res: Int) {\r\n    for (i in 0 until childCount) {\r\n        val view = getChildAt(i)\r\n        if (view is TextView && view.text == title) {\r\n            view.typeface = ResourcesCompat.getFont(context, res)\r\n            break\r\n        }\r\n    }\r\n}\r\n\r\nval String.urlFixed: String get() = if (!contains(\"animeflv.net\")) \"https://www3.animeflv.net$this\" else this\r\n\r\nval String.fixedHost: String get() = if (!startsWith(\"http\")) \"https:$this\" else this\r\n\r\nval <T>LiveData<T>.distinct: LiveData<T>\r\n    get() = this.distinctUntilChanged()\r\n\r\n\r\nfun getPackage(): String {\r\n    return if (BuildConfig.BUILD_TYPE == \"debug\" || BuildConfig.BUILD_TYPE == \"release\" || BuildConfig.BUILD_TYPE == \"playstore\" || BuildConfig.BUILD_TYPE == \"amazon\") \"knf.kuma\" else \"knf.kuma.${BuildConfig.BUILD_TYPE}\"\r\n}\r\n\r\nval getUpdateDir: String\r\n    get() = when (BuildConfig.BUILD_TYPE) {\r\n        \"debug\", \"release\" -> \"release\"\r\n        else -> BuildConfig.BUILD_TYPE\r\n    }\r\n\r\nfun currentTime(): Long = System.currentTimeMillis()\r\n\r\nval ffFile: File get() = File(baseDir, \"data.crypt\")\r\nval admFile: File get() = File(baseDir, BuildConfig.ADM_FILE)\r\nval baseDir: File\r\n    get() =\r\n        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q)\r\n            File(Environment.getExternalStorageDirectory(), \"UKIKU/backups\")\r\n        else\r\n            App.context.filesDir\r\n\r\nfun verifiyFF() {\r\n    try {\r\n        if (PrefsUtil.isFamilyFriendly && !ffFile.exists()) {\r\n            ffFile.parentFile?.mkdirs()\r\n            ffFile.createNewFile()\r\n            ffFile.writeText(PrefsUtil.ffPass)\r\n        } else if (!PrefsUtil.isFamilyFriendly && ffFile.exists()) {\r\n            PrefsUtil.isFamilyFriendly = true\r\n            PrefsUtil.ffPass = ffFile.readText()\r\n            CacheDB.INSTANCE.animeDAO().nukeEcchi()\r\n        }\r\n    } catch (e: Exception) {\r\n        //\r\n    }\r\n}\r\n\r\nfun MaterialDialog.safeShow(func: MaterialDialog.() -> Unit): MaterialDialog {\r\n    doOnUIGlobal {\r\n        try {\r\n            lifecycleOwner()\r\n            this.func()\r\n            this@safeShow.show()\r\n        } catch (e: Exception) {\r\n            //\r\n        }\r\n    }\r\n    return this\r\n}\r\n\r\nfun MaterialDialog.safeShow() {\r\n    doOnUIGlobal {\r\n        try {\r\n            lifecycleOwner()\r\n            this@safeShow.show()\r\n        } catch (e: Exception) {\r\n            //\r\n        }\r\n    }\r\n}\r\n\r\nfun MaterialDialog.safeDismiss() {\r\n    try {\r\n        dismiss()\r\n    } catch (exception: Exception) {\r\n        //\r\n    }\r\n}\r\n\r\nfun Snackbar.safeDismiss() {\r\n    try {\r\n        dismiss()\r\n    } catch (e: Exception) {\r\n        e.printStackTrace()\r\n    }\r\n}\r\n\r\noperator fun JSONArray.iterator(): Iterator<JSONObject> = (0 until length()).asSequence().map { get(it) as JSONObject }.iterator()\r\n\r\nfun RecyclerView.verifyManager(size: Int = 115) {\r\n    val manager = layoutManager\r\n    if (manager is GridLayoutManager) {\r\n        manager.spanCount = gridColumns(size)\r\n        layoutManager = manager\r\n    }\r\n    setHasFixedSize(true)\r\n}\r\n\r\nval canGroupNotifications: Boolean\r\n    get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N\r\n\r\nfun gridColumns(size: Int = 115): Int {\r\n    val metrics = App.context.resources.displayMetrics\r\n    val dpWidht = metrics.widthPixels / metrics.density\r\n    return (dpWidht / size).toInt().coerceAtLeast(1)\r\n}\r\n\r\nfun View.showSnackbar(text: String, duration: Int = Snackbar.LENGTH_SHORT, animation: Int = Snackbar.ANIMATION_MODE_FADE): Snackbar {\r\n    return Snackbar.make(this, text, duration).apply {\r\n        animationMode = animation\r\n    }.also { doOnUIGlobal { it.show() } }\r\n}\r\n\r\nfun View.showSnackbar(text: String, duration: Int = Snackbar.LENGTH_SHORT, button: String, onAction: (View) -> Unit): Snackbar {\r\n    return Snackbar.make(this, text, duration).apply {\r\n        animationMode = Snackbar.ANIMATION_MODE_SLIDE\r\n        setAction(button, onAction)\r\n    }.also { doOnUIGlobal { it.show() } }\r\n}\r\n\r\nfun SnackProgressBarManager.showProgressSnackbar(text: String, duration: Int = SnackProgressBarManager.LENGTH_SHORT) {\r\n    val snackbar = SnackProgressBar(SnackProgressBar.TYPE_HORIZONTAL, text)\r\n            .setIsIndeterminate(true)\r\n            .setProgressMax(100)\r\n            .setShowProgressPercentage(false)\r\n    doOnUIGlobal { show(snackbar, duration) }\r\n}\r\n\r\nfun View.createSnackbar(text: String, duration: Int = Snackbar.LENGTH_SHORT): Snackbar {\r\n    return Snackbar.make(this, text, duration)\r\n}\r\n\r\nval Int.asPx: Int\r\n    get() = (this * Resources.getSystem().displayMetrics.density).toInt()\r\n\r\nfun <T : View> Activity.bind(@IdRes res: Int): Lazy<T> {\r\n    @Suppress(\"UNCHECKED_CAST\")\r\n    return lazy { findViewById<T>(res) }\r\n}\r\n\r\nfun <T : View> View.bind(@IdRes res: Int): Lazy<T> {\r\n    @Suppress(\"UNCHECKED_CAST\")\r\n    return lazy { findViewById<T>(res) }\r\n}\r\n\r\nfun <T : View> View.optionalBind(@IdRes res: Int): Lazy<T?> {\r\n    @Suppress(\"UNCHECKED_CAST\")\r\n    return lazy { findViewById<T?>(res) }\r\n}\r\n\r\nfun <T : View> bind(activity: AppCompatActivity, @IdRes res: Int): Lazy<T> {\r\n    @Suppress(\"UNCHECKED_CAST\")\r\n    return lazy { activity.findViewById<T>(res) }\r\n}\r\n\r\nfun <T : View> optionalBind(activity: AppCompatActivity, @IdRes res: Int): Lazy<T?> {\r\n    @Suppress(\"UNCHECKED_CAST\")\r\n    return lazy { activity.findViewById<T?>(res) }\r\n}\r\n\r\nfun <T : View> Activity.optionalBind(@IdRes res: Int): Lazy<T?> {\r\n    @Suppress(\"UNCHECKED_CAST\")\r\n    return lazy { findViewById<T?>(res) }\r\n}\r\n\r\nfun Request.execute(followRedirects: Boolean = true): Response {\r\n    return OkHttpClient().newBuilder().apply {\r\n        followRedirects(followRedirects)\r\n        connectionSpecs(\r\n            listOf(\r\n                ConnectionSpec.CLEARTEXT, ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)\r\n                    .allEnabledTlsVersions()\r\n                    .allEnabledCipherSuites()\r\n                    .build()\r\n            )\r\n        )\r\n    }.build().newCall(this).execute()\r\n}\r\n\r\nfun Request.executeNoSSl(followRedirects: Boolean = true): Response {\r\n    return NoSSLOkHttpClient.get().newBuilder().apply {\r\n        followRedirects(followRedirects)\r\n        connectionSpecs(\r\n            listOf(\r\n                ConnectionSpec.CLEARTEXT, ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)\r\n                    .allEnabledTlsVersions()\r\n                    .allEnabledCipherSuites()\r\n                    .build()\r\n            )\r\n        )\r\n    }.build().newCall(this).execute()\r\n}\r\n\r\nval safeContext: Context\r\n    get() = App.context\r\n\r\nval isTV: Boolean get() = App.context.resources.getBoolean(R.bool.isTv)\r\n\r\n@ColorInt\r\nfun Int.toColor(): Int {\r\n    return ContextCompat.getColor(App.context, this)\r\n}\r\n\r\nfun ImageView.load(link: String?, callback: Callback? = null) {\r\n    try {\r\n        Glide.with(this).load(GlideUrl(link, BypassUtil.getLazyHeaders()))\r\n            .diskCacheStrategy(DiskCacheStrategy.ALL)\r\n            .listener(object : RequestListener<Drawable> {\r\n                override fun onLoadFailed(\r\n                    e: GlideException?,\r\n                    model: Any?,\r\n                    target: Target<Drawable?>,\r\n                    isFirstResource: Boolean\r\n                ): Boolean {\r\n                    callback?.onError(e)\r\n                    return false\r\n                }\r\n\r\n                override fun onResourceReady(\r\n                    resource: Drawable,\r\n                    model: Any,\r\n                    target: Target<Drawable?>?,\r\n                    dataSource: DataSource,\r\n                    isFirstResource: Boolean\r\n                ): Boolean {\r\n                    callback?.onSuccess()\r\n                    return false\r\n                }\r\n            }).into(this)\r\n    } catch (e: Exception) {\r\n        e.printStackTrace()\r\n    }\r\n}\r\n\r\nfun ImageView.loadGlide(link: String) {\r\n    Glide.with(safeContext).load(link).into(this)\r\n}\r\n\r\nfun ImageView.load(uri: Uri?, callback: Callback? = null) {\r\n    Glide.with(this).load(uri)\r\n        .listener(object : RequestListener<Drawable> {\r\n            override fun onLoadFailed(\r\n                e: GlideException?,\r\n                model: Any?,\r\n                target: Target<Drawable?>,\r\n                isFirstResource: Boolean\r\n            ): Boolean {\r\n                callback?.onError(e)\r\n                return false\r\n            }\r\n\r\n            override fun onResourceReady(\r\n                resource: Drawable,\r\n                model: Any,\r\n                target: Target<Drawable?>?,\r\n                dataSource: DataSource,\r\n                isFirstResource: Boolean\r\n            ): Boolean {\r\n                callback?.onSuccess()\r\n                return false\r\n            }\r\n        }).into(this)\r\n}\r\n\r\nfun <T> retry(numOfRetries: Int, block: () -> T): T {\r\n    var throwable: Throwable? = null\r\n    (1..numOfRetries).forEach {\r\n        try {\r\n            return block()\r\n        } catch (e: Throwable) {\r\n            throwable = e\r\n        }\r\n    }\r\n    throw throwable!!\r\n}\r\n\r\nfun noCrash(enableLog: Boolean = true, func: () -> Unit): String? {\r\n    return try {\r\n        func()\r\n        null\r\n    } catch (e: Exception) {\r\n        if (enableLog)\r\n            e.printStackTrace()\r\n        e.message\r\n    }\r\n}\r\n\r\nsuspend fun noCrashSuspend(enableLog: Boolean = true, func: suspend () -> Unit): String? {\r\n    return try {\r\n        func()\r\n        null\r\n    } catch (e: Exception) {\r\n        if (enableLog)\r\n            e.printStackTrace()\r\n        e.message\r\n    }\r\n}\r\n\r\nfun noCrashException(enableLog: Boolean = true, func: () -> Unit): Exception? {\r\n    return try {\r\n        func()\r\n        null\r\n    } catch (e: Exception) {\r\n        if (enableLog)\r\n            e.printStackTrace()\r\n        e\r\n    }\r\n}\r\n\r\nfun noCrashExec(exec: () -> Unit = {}, func: () -> Unit) {\r\n    try {\r\n        func()\r\n    } catch (e: Exception) {\r\n        e.printStackTrace()\r\n        exec()\r\n    }\r\n}\r\n\r\nfun <T> noCrashLet(onCrash: () -> Unit = {}, func: () -> T): T? {\r\n    return try {\r\n        func()\r\n    } catch (e: Exception) {\r\n        e.printStackTrace()\r\n        onCrash()\r\n        null\r\n    }\r\n}\r\n\r\nfun <T> noCrashLet(onCrash: T, func: () -> T): T {\r\n    return try {\r\n        func()\r\n    } catch (e: Exception) {\r\n        e.printStackTrace()\r\n        onCrash\r\n    }\r\n}\r\n\r\nfun <T> noCrashLetNullable(onCrash: T? = null, func: () -> T): T? {\r\n    return try {\r\n        func()\r\n    } catch (e: Exception) {\r\n        e.printStackTrace()\r\n        onCrash\r\n    }\r\n}\r\n\r\nfun String?.toast() {\r\n    if (!this.isNullOrEmpty())\r\n        Toaster.toast(this)\r\n}\r\n\r\nfun String?.toastLong() {\r\n    if (!this.isNullOrEmpty())\r\n        Toaster.toastLong(this)\r\n}\r\n\r\nfun LifecycleOwner.doOnUI(enableLog: Boolean = true, onLog: (text: String) -> Unit = {}, func: suspend () -> Unit) {\r\n    lifecycleScope.launch(Dispatchers.Main) {\r\n        noCrashSuspend(enableLog) {\r\n            func()\r\n        }?.also { onLog(it) }\r\n    }\r\n}\r\n\r\nfun doOnUIGlobal(enableLog: Boolean = true, onLog: (text: String) -> Unit = {}, func: suspend () -> Unit) {\r\n    GlobalScope.launch(Dispatchers.Main) {\r\n        noCrashSuspend(enableLog) {\r\n            func()\r\n        }?.also { onLog(it) }\r\n    }\r\n}\r\n\r\nfun doOnUIException(enableLog: Boolean = true, onLog: (e: Exception) -> Unit = {}, func: () -> Unit) {\r\n    GlobalScope.launch(Dispatchers.Main) {\r\n        noCrashException(enableLog) {\r\n            func()\r\n        }?.also { onLog(it) }\r\n    }\r\n}\r\n\r\nfun <T> List<Any>.transform(): List<T> = this.map { it as T }\r\n\r\nfun <T> MutableList<T>.removeAll(vararg elements: Collection<T>) {\r\n    elements.forEach {\r\n        removeAll(it)\r\n    }\r\n}\r\n\r\ninfix fun <T : Any> Collection<T>?.notSameContent(collection: Collection<T>?) = !isSameContent(collection)\r\n\r\ninfix fun <T : Any> Collection<T>?.isSameContent(collection: Collection<T>?) =\r\n        collection.let {\r\n            this != null && it != null && this.size == it.size && this.containsAll(it)\r\n        }\r\n\r\nfun NotificationCompat.Builder.create(func: NotificationCompat.Builder.() -> Unit): NotificationCompat.Builder {\r\n    this.func()\r\n    return this\r\n}\r\n\r\nfun ViewGroup.inflate(@LayoutRes layout: Int, attachToRoot: Boolean = false, context: Context = this.context): View = LayoutInflater.from(context).inflate(layout, this, attachToRoot)\r\n\r\nfun inflate(context: Context, @LayoutRes layout: Int, attachToRoot: Boolean = false): View = LayoutInflater.from(context).inflate(layout, null, attachToRoot)\r\n\r\nsuspend fun asyncInflate(context: Context, @LayoutRes layout: Int, attachToRoot: Boolean = false): View = withContext(Dispatchers.Main) {\r\n    suspendCoroutine<View> {\r\n        AsyncLayoutInflater(context).inflate(layout, null) { view, _, _ ->\r\n            it.resume(view)\r\n        }\r\n    }\r\n}\r\n\r\nfun File.safeDelete(log: Boolean = false) {\r\n    try {\r\n        delete()\r\n    } catch (e: Exception) {\r\n        if (log)\r\n            e.printStackTrace()\r\n    }\r\n}\r\n\r\nfun RecyclerView.removeAllDecorations() {\r\n    while (itemDecorationCount > 0)\r\n        removeItemDecorationAt(0)\r\n}\r\n\r\nfun Any?.isNull(): Boolean {\r\n    return this == null\r\n}\r\n\r\nfun Any?.notNull(): Boolean {\r\n    return this != null\r\n}\r\n\r\nfun String.r(from: String, to: String) = replace(from, to)\r\n\r\nfun Context.findActivity(): Activity? {\r\n    var context = this\r\n    while (context is ContextWrapper) {\r\n        if (context is Activity) {\r\n            return context\r\n        }\r\n        context = context.baseContext\r\n    }\r\n    return null\r\n}\r\n\r\nfun Context.findLifecycleOwner(): LifecycleOwner? {\r\n    var context = this\r\n    while (context is ContextWrapper) {\r\n        if (context is LifecycleOwner) {\r\n            return context\r\n        }\r\n        context = context.baseContext\r\n    }\r\n    return null\r\n}\r\n\r\n@UiThread\r\nfun ImageView.setAnimatedResource(@DrawableRes res: Int) {\r\n    setImageResource(res)\r\n    val animated = drawable as AnimationDrawable\r\n    animated.callback = this\r\n    animated.setVisible(true, true)\r\n    animated.start()\r\n}\r\n\r\nfun FloatingActionButton.forceHide() {\r\n    val params = layoutParams as? CoordinatorLayout.LayoutParams\r\n    params?.behavior = null\r\n    requestLayout()\r\n    visibility = View.GONE\r\n}\r\n\r\nfun httpRequest(url: String) =\r\n    NoSSLOkHttpClient.get().newCall(okHttpCookies(url)).execute()\r\n\r\nfun httpJsoup(url: String) =\r\n    Jsoup.connect(url)\r\n        .ignoreContentType(true)\r\n        .ignoreHttpErrors(true)\r\n        .execute()\r\n\r\nfun jsoupCookies(url: String?, followRedirects: Boolean = true): Connection =\r\n        Jsoup.connect(url)\r\n                .cookies(BypassUtil.getMapCookie(App.context))\r\n                .userAgent(BypassUtil.userAgent)\r\n                .timeout(PrefsUtil.timeoutTime.toInt() * 1000)\r\n                .followRedirects(followRedirects)\r\n\r\nfun <T> jsoupCookiesAdapter(url: String?, adapter: Class<T>, followRedirects: Boolean = true): T =\r\n    Jspoon.create().adapter(adapter).fromHtml(\r\n        Jsoup.connect(url)\r\n            .cookies(BypassUtil.getMapCookie(App.context))\r\n            .userAgent(BypassUtil.userAgent)\r\n            .timeout(PrefsUtil.timeoutTime.toInt() * 1000)\r\n            .followRedirects(followRedirects)\r\n            .get().outerHtml()\r\n    )\r\n\r\nfun jsoupCookiesDir(url: String?, useCookies: Boolean): Connection =\r\n        Jsoup.connect(url).apply {\r\n            if (useCookies)\r\n                if (PrefsUtil.useDefaultUserAgent && !PrefsUtil.alwaysGenerateUA) {\r\n                    cookies(ConvertUtil.List2Map(PrefsUtil.dirCookies))\r\n                } else {\r\n                    cookies(BypassUtil.getMapCookie(App.context))\r\n                }\r\n            if (PrefsUtil.useDefaultUserAgent && !PrefsUtil.alwaysGenerateUA)\r\n                userAgent(PrefsUtil.userAgentDir)\r\n            else\r\n                userAgent(PrefsUtil.userAgent)\r\n            timeout(PrefsUtil.timeoutTime.toInt() * 1000)\r\n            followRedirects(true)\r\n        }\r\n\r\nfun okHttpCookies(url: String, method: String = \"GET\"): Request = Request.Builder().apply {\r\n    url(url)\r\n    method(method, if (method == \"POST\") \"\".toRequestBody(\"text/plain\".toMediaType()) else null)\r\n    header(\"User-Agent\", BypassUtil.userAgent)\r\n    header(\"Cookie\", BypassUtil.getStringCookie(App.context))\r\n}.build()\r\n\r\nfun okHttpDocument(url: String): Document = Jsoup.parse(okHttpCookies(url).execute(true).use {\r\n    if (it.isSuccessful)\r\n        it.body?.string()\r\n    else\r\n        throw IllegalStateException(\"Response error Url: ${it.request.url}, code: ${it.code}\")\r\n})\r\n\r\nfun isHostValid(hostName: String): Boolean {\r\n    if (validateAds(hostName)) return true\r\n    return when (hostName) {\r\n        \"fex.net\",\r\n        \"api.crashlytics.com\",\r\n        \"e.crashlytics.com\",\r\n        \"reports.crashlytics.com\",\r\n        \"sdk-android.ad.smaato.net\",\r\n        \"cdn.myanimelist.net\",\r\n        \"myanimelist.cdn-dena.com\",\r\n        \"settings.crashlytics.com\",\r\n        \"somoskudasai.com\",\r\n        \"animeflv.net\",\r\n        \"m.animeflv.net\",\r\n        \"github.com\",\r\n        \"raw.githubusercontent.com\",\r\n        \"cdn.animeflv.net\",\r\n        \"s1.animeflv.net\",\r\n        \"streamango.com\",\r\n        \"ok.ru\",\r\n        \"www.rapidvideo.com\",\r\n        \"us-central1-nu-client.cloudfunctions.net\",\r\n        \"\",\r\n        \"worldvideodownload.com\",\r\n        \"okvid.download\",\r\n        \"www.yourupload.com\" -> true\r\n        else -> isVideoHostName(hostName)\r\n    }.also { if (!it) Log.e(\"Hostname\", \"Not verified: $hostName\") }\r\n}\r\n\r\nprivate fun validateAds(hostName: String): Boolean {\r\n    listOf(\r\n            \"android\",\r\n            \"doubleclick\",\r\n            \"invitemedia.com\",\r\n            \"media.admob.com\",\r\n            \"gstatic\",\r\n            \"google\",\r\n            \"goo.gl\",\r\n            \"gvtl\",\r\n            \"gvt2\",\r\n            \"urchin\",\r\n            \"gkecnapps\",\r\n            \"youtube\",\r\n            \"youtu.be\",\r\n            \"yt.be\",\r\n            \"ytimg\",\r\n            \"g.co\",\r\n            \"ggpht\",\r\n            \"gkecnapps\",\r\n            \"appbrain\",\r\n            \"apptornado\",\r\n            \"startappservice\",\r\n            \"criteo\",\r\n            \"appcoachs\"\r\n    ).forEach { if (hostName.contains(it)) return true }\r\n    return false\r\n}\r\n\r\nprivate fun isVideoHostName(hostName: String): Boolean {\r\n    return when {\r\n        hostName.contains(\"google.com\") -> true\r\n        hostName.contains(\"fex.net\") ||\r\n                hostName.contains(\"content-na.drive.amazonaws.com\") ||\r\n                hostName.contains(\"mediafire\") ||\r\n                hostName.contains(\"fruithosted.net\") ||\r\n                hostName.contains(\"mp4upload.com\") ||\r\n                hostName.contains(\"storage.googleapis.com\") ||\r\n                hostName.contains(\"playercdn.net\") ||\r\n                hostName.contains(\"vidcache.net\") ||\r\n                hostName.contains(\"fembed.com\") ||\r\n                hostName.contains(\"leasewebcdn.me\") ||\r\n                hostName.contains(\"fvs.io\") -> true\r\n        else -> false\r\n    }\r\n}\r\n\r\nfun <T> diceOf(default: T? = null, mapCreator: MutableMap<T, Double>.() -> Unit): T {\r\n    val map = mutableMapOf<T, Double>()\r\n    mapCreator(map)\r\n    if (default != null && map.isEmpty()) return default\r\n    return WeightedDice(map).roll()\r\n}\r\n\r\ninline var View.isVisibleAnimate: Boolean\r\n    get() = isVisible\r\n    set(value) {\r\n        isVisible = value\r\n        startAnimation(AnimationUtils.loadAnimation(context, if (value) R.anim.fadein else R.anim.fadeout))\r\n    }\r\n\r\nfun View.onClickMenu(\r\n        @MenuRes menu: Int, showIcons: Boolean = true,\r\n        hideItems: () -> List<Int> = { emptyList() },\r\n        onItemClicked: (item: MenuItem) -> Unit = {}\r\n) = this.setOnClickListener { popUpMenu(this@onClickMenu, menu, showIcons, hideItems, onItemClicked) }\r\n\r\n@SuppressLint(\"RestrictedApi\")\r\nfun popUpMenu(\r\n    view: View,\r\n    @MenuRes menu: Int, showIcons: Boolean = true,\r\n    hideItems: () -> List<Int> = { emptyList() },\r\n    onItemClicked: (item: MenuItem) -> Unit = {}\r\n) = doOnUIGlobal {\r\n    PopupMenu(view.context, view).apply {\r\n        inflate(menu)\r\n        setOnMenuItemClickListener {\r\n            onItemClicked.invoke(it)\r\n            true\r\n        }\r\n        hideItems().forEach {\r\n            getMenu().findItem(it).isVisible = false\r\n        }\r\n    }.show()\r\n}\r\n\r\nfun AppCompatActivity.setSurfaceBars() {\r\n    val surfaceColor = getSurfaceColor()\r\n    window.apply {\r\n        statusBarColor = surfaceColor\r\n        navigationBarColor = surfaceColor\r\n    }\r\n}\r\n\r\nfun AppCompatActivity.getSurfaceColor(): Int {\r\n    return TypedValue().apply {\r\n        theme.resolveAttribute(R.attr.colorSurface, this, true)\r\n    }.data\r\n}\r\n\r\nfun Fragment.getSurfaceColor(): Int {\r\n    return (requireActivity() as AppCompatActivity).getSurfaceColor()\r\n}\r\n\r\nfun String.resolveRedirection(tryCount: Int = 0): String =\r\n    try {\r\n        jsoupCookies(this).execute().url().toString()\r\n    } catch (e: HttpStatusException) {\r\n        if (tryCount >= 3)\r\n            this\r\n        else\r\n            resolveRedirection(tryCount + 1)\r\n    }\r\n\r\nfun List<Pair<String, String>>.toArray(): Array<String> {\r\n    val list = mutableListOf<String>()\r\n    forEach { e ->\r\n        list.add(e.first)\r\n        list.add(e.second)\r\n    }\r\n    return list.toTypedArray()\r\n}\r\n\r\nfun urlEncode(url: String): String {\r\n    return try {\r\n        if (Build.VERSION.SDK_INT >= 33) {\r\n            URLEncoder.encode(url, StandardCharsets.UTF_8)\r\n        } else {\r\n            URLEncoder.encode(url, \"utf-8\")\r\n        }\r\n    } catch (e: Exception) {\r\n        url\r\n    }\r\n}\r\n\r\nfun urlDecode(url: String): String {\r\n    return try {\r\n        if (Build.VERSION.SDK_INT >= 33) {\r\n            URLDecoder.decode(url, StandardCharsets.UTF_8)\r\n        } else {\r\n            URLDecoder.decode(url, \"utf-8\")\r\n        }\r\n    } catch (e: Exception) {\r\n        url\r\n    }\r\n}\r\n\r\nval isFullMode: Boolean get() = BuildConfig.DEBUG || BuildConfig.BUILD_TYPE != \"playstore\"\r\n\r\nprivate fun isIntentResolved(ctx: Context, intent: Intent): Boolean {\r\n    return ctx.packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null\r\n}\r\n\r\nfun <T : View> FragmentActivity.findView(@IdRes id: Int): Lazy<T> = object : Lazy<T> {\r\n\r\n    private var view: T? = null\r\n    override val value: T\r\n        get() = view ?: findViewById<T>(id).also { view = it }\r\n\r\n    override fun isInitialized(): Boolean {\r\n        return view != null\r\n    }\r\n}\r\n\r\nval isMIUI: Boolean by lazy {\r\n    Build.MANUFACTURER.lowercase().contains(\"huawei\") ||\r\n            Build.BRAND.contains(\"huawei\") ||\r\n            isIntentResolved(\r\n                safeContext,\r\n                Intent(\"miui.intent.action.OP_AUTO_START\").addCategory(Intent.CATEGORY_DEFAULT)\r\n            ) ||\r\n            isIntentResolved(\r\n                safeContext,\r\n                Intent().setComponent(\r\n                    ComponentName(\r\n                        \"com.miui.securitycenter\",\r\n                        \"com.miui.permcenter.autostart.AutoStartManagementActivity\"\r\n                    )\r\n                )\r\n            )\r\n            || isIntentResolved(\r\n        safeContext, Intent(\"miui.intent.action.POWER_HIDE_MODE_APP_LIST\").addCategory(Intent.CATEGORY_DEFAULT)\r\n    )\r\n            || isIntentResolved(\r\n        safeContext,\r\n        Intent().setComponent(\r\n            ComponentName(\"com.miui.securitycenter\", \"com.miui.powercenter.PowerSettings\")\r\n        )\r\n    )\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/FileUtil.kt",
    "content": "package knf.kuma.commons\n\nimport android.annotation.TargetApi\nimport android.content.ContentResolver\nimport android.content.Context\nimport android.net.Uri\nimport android.os.Build\nimport android.os.storage.StorageManager\nimport android.provider.DocumentsContract\nimport android.util.Pair\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport knf.kuma.download.FileAccessHelper\nimport org.jetbrains.anko.doAsync\nimport java.io.File\nimport java.io.OutputStream\nimport java.lang.reflect.Array\nimport java.util.Locale\n\nobject FileUtil {\n\n    private const val PRIMARY_VOLUME_NAME = \"primary\"\n    internal var TAG = \"TAG\"\n\n    val externalMounts: HashSet<String>\n        get() {\n\n            val out = HashSet<String>()\n            val reg = \"(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*\"\n            val s = StringBuilder()\n            try {\n                val process = ProcessBuilder().command(\"mount\").redirectErrorStream(true).start()\n                process.waitFor()\n                val inputStream = process.inputStream\n                val buffer = ByteArray(1024)\n                while (inputStream.read(buffer) != -1) {\n                    s.append(String(buffer))\n                }\n                inputStream.close()\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n\n            val lines = s.toString().split(\"\\n\".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()\n            for (line in lines) {\n                if (!line.lowercase(Locale.US).contains(\"asec\")) {\n                    if (line.matches(reg.toRegex())) {\n                        val parts = line.split(\" \".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()\n                        for (part in parts) {\n                            if (part.startsWith(\"/\")) {\n                                if (!part.lowercase(Locale.US).contains(\"vold\")) {\n                                    out.add(part)\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            return out\n        }\n\n    fun getFullPathFromTreeUri(treeUri: Uri?, con: Context): String? {\n        try {\n            treeUri ?: return null\n            var volumePath: String? = getVolumePath(getVolumeIdFromTreeUri(treeUri), con)\n                    ?: return File.separator\n            if (volumePath?.endsWith(File.separator) == true) {\n                volumePath = volumePath.substring(0, volumePath.length - 1)\n            }\n\n            var documentPath = getDocumentPathFromTreeUri(treeUri)\n            if (documentPath.endsWith(File.separator)) {\n                documentPath = documentPath.substring(0, documentPath.length - 1)\n            }\n\n            return if (documentPath.isNotEmpty()) {\n                if (documentPath.startsWith(File.separator)) {\n                    volumePath + documentPath\n                } else {\n                    volumePath + File.separator + documentPath\n                }\n            } else {\n                volumePath\n            }\n        } catch (e: Exception) {\n            return null\n        }\n    }\n\n\n    private fun getVolumePath(volumeId: String?, con: Context): String? {\n        try {\n            val mStorageManager = con.getSystemService(Context.STORAGE_SERVICE) as StorageManager\n\n            val storageVolumeClazz = Class.forName(\"android.os.storage.StorageVolume\")\n\n            val getVolumeList = mStorageManager.javaClass.getMethod(\"getVolumeList\")\n            val getUuid = storageVolumeClazz.getMethod(\"getUuid\")\n            val getPath = storageVolumeClazz.getMethod(\"getPath\")\n            val isPrimary = storageVolumeClazz.getMethod(\"isPrimary\")\n            val result = getVolumeList.invoke(mStorageManager)\n\n            val length = Array.getLength(result)\n            for (i in 0 until length) {\n                val storageVolumeElement = Array.get(result, i)\n                val uuid = getUuid.invoke(storageVolumeElement) as String?\n                val primary = isPrimary.invoke(storageVolumeElement) as Boolean\n\n                // primary volume?\n                if (primary && PRIMARY_VOLUME_NAME == volumeId) {\n                    return getPath.invoke(storageVolumeElement) as String\n                }\n\n                // other volumes?\n                if (uuid != null) {\n                    if (uuid == volumeId) {\n                        return getPath.invoke(storageVolumeElement) as String\n                    }\n                }\n            }\n\n            // not found.\n            return null\n        } catch (ex: Exception) {\n            return null\n        }\n\n    }\n\n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n    private fun getVolumeIdFromTreeUri(treeUri: Uri): String? {\n        val docId = DocumentsContract.getTreeDocumentId(treeUri)\n        val split = docId.split(\":\".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()\n\n        return if (split.isNotEmpty()) {\n            split[0]\n        } else {\n            null\n        }\n    }\n\n\n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n    private fun getDocumentPathFromTreeUri(treeUri: Uri): String {\n        val docId = DocumentsContract.getTreeDocumentId(treeUri)\n        val split = docId.split(\":\".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()\n        return if (split.size >= 2) {\n            split[1]\n        } else {\n            File.separator\n        }\n    }\n\n    fun moveFile(resolver: ContentResolver, uri: Uri?, outputStream: OutputStream?, delete: Boolean = true): LiveData<Pair<Int, Boolean>> {\n        val liveData = MutableLiveData<Pair<Int, Boolean>>()\n        if (uri == null || outputStream == null) {\n            doOnUIGlobal { liveData.value = Pair(-1, true) }\n            return liveData\n        }\n        doAsync {\n            try {\n                val inputStream = resolver.openInputStream(uri)\n                val total = inputStream?.available()?.toLong() ?: 0\n                val buffer = ByteArray(128 * 1024)\n                var read: Int = inputStream?.read(buffer) ?: 0\n                var current: Long = 0\n                while (read != -1) {\n                    outputStream.write(buffer, 0, read)\n                    current += read.toLong()\n                    val prog = (current * 100 / total).toInt()\n                    doOnUIGlobal { liveData.value = Pair(prog, false) }\n                    read = inputStream?.read(buffer) ?: 0\n                }\n                inputStream?.close()\n                outputStream.flush()\n                outputStream.close()\n                try {\n                    if (delete)\n                        DocumentsContract.deleteDocument(resolver, uri)\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n\n                doOnUIGlobal { liveData.value = Pair(100, true) }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                FirebaseCrashlytics.getInstance().recordException(e)\n                doOnUIGlobal { liveData.value = Pair(-1, true) }\n            }\n        }\n        return liveData\n    }\n\n    fun moveFiles(resolver: ContentResolver, pairs: MutableList<Pair<Uri, String>>): LiveData<Pair<Pair<String, Int>, Boolean>> {\n        val liveData = MutableLiveData<Pair<Pair<String, Int>, Boolean>>()\n        doAsync {\n            val ps = \"Importando archivos: %d/%d\"\n            val gTotal = pairs.size\n            var success = 0\n            for ((g_count, pair) in pairs.withIndex()) {\n                try {\n                    val inputStream = resolver.openInputStream(pair.first)\n                    val outputStream = FileAccessHelper.getOutputStream(pair.second)\n                    val total = inputStream?.available()?.toLong() ?: 0\n                    val buffer = ByteArray(128 * 1024)\n                    var read: Int = inputStream?.read(buffer) ?: 0\n                    var current: Long = 0\n                    while (read != -1) {\n                        outputStream?.write(buffer, 0, read)\n                        current += read.toLong()\n                        val prog = (current * 100 / total).toInt()\n                        doOnUIGlobal { liveData.value = Pair(Pair(String.format(Locale.US, ps, g_count, gTotal), prog), false) }\n                        read = inputStream?.read(buffer) ?: 0\n                    }\n                    inputStream?.close()\n                    outputStream?.flush()\n                    outputStream?.close()\n                    doOnUIGlobal { liveData.value = Pair(Pair(String.format(Locale.US, ps, g_count, gTotal), 100), false) }\n                    try {\n                        DocumentsContract.deleteDocument(resolver, pair.first)\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                    }\n\n                    success++\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                    FileAccessHelper.delete(pair.second)\n                }\n\n            }\n            val finalSuccess = success\n            doOnUIGlobal { liveData.value = Pair(Pair(String.format(Locale.US, ps, gTotal, gTotal), finalSuccess), true) }\n        }\n        return liveData\n    }\n\n    fun moveFile(file_name: String, callback: MoveCallback) {\n        doAsync {\n            try {\n                val inputStream = FileAccessHelper.getTmpInputStream(file_name)\n                val outputStream = FileAccessHelper.getOutputStream(file_name)\n                val total = inputStream?.available()?.toLong() ?: 0\n                val buffer = ByteArray(128 * 1024)\n                var read: Int = inputStream?.read(buffer) ?: 0\n                var current: Long = 0\n                while (read != -1) {\n                    outputStream?.write(buffer, 0, read)\n                    current += read.toLong()\n                    val prog = (current * 100 / total).toInt()\n                    callback.onProgress(Pair(prog, false))\n                    read = inputStream?.read(buffer) ?: 0\n                }\n                inputStream?.close()\n                outputStream?.flush()\n                outputStream?.close()\n                try {\n                    val file = FileAccessHelper.getTmpFile(file_name)\n                    file.delete()\n                    if (file.parentFile?.list()?.isEmpty() == true)\n                        file.parentFile?.delete()\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n\n                callback.onProgress(Pair(100, true))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                FileAccessHelper.getTmpFile(file_name).delete()\n                callback.onProgress(Pair(-1, true))\n            }\n        }\n    }\n\n    interface MoveCallback {\n        fun onProgress(pair: Pair<Int, Boolean>)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/FileWrapper.kt",
    "content": "package knf.kuma.commons\r\n\r\nimport android.os.Build\r\nimport android.os.Environment\r\nimport androidx.documentfile.provider.DocumentFile\r\nimport knf.kuma.App\r\nimport knf.kuma.download.FileAccessHelper\r\nimport java.io.File\r\nimport java.io.InputStream\r\n\r\nabstract class FileWrapper<T>(val path: String) {\r\n\r\n    abstract var exist: Boolean\r\n    abstract fun existForced(): Boolean\r\n    abstract fun file(): File?\r\n    abstract fun name(): String\r\n    abstract fun length(): Long?\r\n    abstract fun lastModified(): Long?\r\n    abstract fun inputStream(): InputStream?\r\n    abstract fun parentSize(): Int\r\n    abstract fun generate(): T\r\n    abstract fun reset()\r\n\r\n    companion object {\r\n        fun create(file_name: String?): FileWrapper<*> {\r\n            file_name ?: throw IllegalStateException(\"Path can't be null!\")\r\n            return when {\r\n                PrefsUtil.downloadType == \"0\" -> NormalFileWrapper(file_name)\r\n                Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> DocumentFileWrapper(file_name)\r\n                else -> NormalPreQFileWrapper(file_name)\r\n            }\r\n        }\r\n\r\n        fun fromFileName(file_name: String): File =\r\n                File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\r\n    }\r\n}\r\n\r\nclass NormalFileWrapper(path: String) : FileWrapper<File?>(path) {\r\n    private var mFile = generate()\r\n    override var exist = mFile?.exists() == true\r\n    override fun existForced(): Boolean {\r\n        reset()\r\n        return exist\r\n    }\r\n    override fun file(): File? = mFile\r\n    override fun name(): String = mFile?.name ?: path\r\n    override fun length(): Long? = mFile?.length()\r\n    override fun lastModified(): Long? = mFile?.lastModified()\r\n    override fun inputStream(): InputStream? = mFile?.inputStream()\r\n    override fun parentSize(): Int = mFile?.parentFile?.list()?.size ?: 0\r\n    override fun generate(): File? = File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(path)).listFiles { file -> file.name.contains(path) }?.let {\r\n        if (it.isNotEmpty())\r\n            it[0]\r\n        else\r\n            null\r\n    }\r\n\r\n    override fun reset() {\r\n        mFile = generate()\r\n        exist = mFile?.exists() == true\r\n    }\r\n}\r\n\r\nclass NormalPreQFileWrapper(path: String) : FileWrapper<File?>(path) {\r\n    private var mFile = generate()\r\n    override var exist = mFile?.exists() == true\r\n    override fun existForced(): Boolean {\r\n        reset()\r\n        return exist\r\n    }\r\n    override fun file(): File? = mFile\r\n    override fun name(): String = mFile?.name ?: path\r\n    override fun length(): Long? = mFile?.length()\r\n    override fun lastModified(): Long? = mFile?.lastModified()\r\n    override fun inputStream(): InputStream? = mFile?.inputStream()\r\n    override fun parentSize(): Int = mFile?.parentFile?.list()?.size ?: 0\r\n    override fun generate(): File? = File(FileUtil.getFullPathFromTreeUri(FileAccessHelper.treeUri, App.context), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(path)).listFiles { file -> file.name.contains(path) }?.let {\r\n        if (it.isNotEmpty())\r\n            it[0]\r\n        else\r\n            null\r\n    }\r\n\r\n    override fun reset() {\r\n        mFile = generate()\r\n        exist = mFile?.exists() == true\r\n    }\r\n}\r\n\r\nclass DocumentFileWrapper(path: String) : FileWrapper<DocumentFile?>(path) {\r\n    private var document = generate()\r\n    override var exist = document?.exists() == true\r\n    override fun existForced(): Boolean {\r\n        reset()\r\n        return exist\r\n    }\r\n    override fun file(): File? = FileUtil.getFullPathFromTreeUri(document?.uri, App.context)?.let { File(it) }\r\n    override fun name(): String = document?.name ?: path\r\n    override fun length(): Long? = document?.length()\r\n    override fun lastModified(): Long? = document?.lastModified()\r\n    override fun inputStream(): InputStream? = document?.let { App.context.contentResolver.openInputStream(it.uri) }\r\n    override fun parentSize(): Int = document?.parentFile?.listFiles()?.size ?: 0\r\n    override fun generate(): DocumentFile? = FileAccessHelper.treeUri?.let { uri ->\r\n        FileAccessHelper.find(DocumentFile.fromTreeUri(App.context, uri), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(path), false)?.listFiles()?.let { list ->\r\n            var file: DocumentFile? = null\r\n            list.forEach {\r\n                if (it.name?.contains(path) == true) {\r\n                    file = it\r\n                    return@forEach\r\n                }\r\n            }\r\n            file\r\n        }\r\n    }\r\n\r\n    override fun reset() {\r\n        document = generate()\r\n        exist = document?.exists() == true\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/Network.kt",
    "content": "package knf.kuma.commons\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.Context.WIFI_SERVICE\nimport android.net.ConnectivityManager\nimport android.net.wifi.WifiManager\nimport android.text.format.Formatter\nimport knf.kuma.App\nimport java.io.BufferedReader\nimport java.io.FileInputStream\nimport java.io.InputStreamReader\n\n@SuppressLint(\"StaticFieldLeak\")\nobject Network {\n\n    val isConnected: Boolean\n        get() {\n            return try {\n                val cm = App.context.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager\n                val activeNetwork = cm?.activeNetworkInfo\n                activeNetwork != null && activeNetwork.isConnected\n            } catch (e: Exception) {\n                false\n            }\n\n        }\n\n    val ipAddress: String\n        get() {\n            val wm = App.context.applicationContext.getSystemService(WIFI_SERVICE) as? WifiManager\n            return Formatter.formatIpAddress(wm?.connectionInfo?.ipAddress ?: 0)\n        }\n\n    val isAdsBlocked: Boolean by lazy {\n        return@lazy try {\n            BufferedReader(InputStreamReader(FileInputStream(\"/etc/hosts\"))).readLines().forEach {\n                if (it.contains(\"admob\") || it.contains(\"appbrains\"))\n                    return@lazy true\n            }\n            false\n        } catch (e: Exception) {\n            false\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/NoSSLOkHttpClient.kt",
    "content": "package knf.kuma.commons\n\nimport knf.kuma.custom.TlsOnlySocketFactory\nimport okhttp3.Cache\nimport okhttp3.OkHttpClient\nimport java.io.File\nimport java.security.cert.CertificateException\nimport java.util.concurrent.TimeUnit\nimport javax.net.ssl.SSLContext\nimport javax.net.ssl.TrustManager\nimport javax.net.ssl.X509TrustManager\n\n\nobject NoSSLOkHttpClient {\n    private val appCache by lazy { Cache(File(safeContext.cacheDir, \"okhttpcache\"), 10 * 1024 * 1024) }\n    fun get(): OkHttpClient {\n        try {\n            val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {\n                @Throws(CertificateException::class)\n                override fun checkClientTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {\n\n                }\n\n                @Throws(CertificateException::class)\n                override fun checkServerTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {\n\n                }\n\n                override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> {\n                    return arrayOf()\n                }\n            })\n            val sslContext = SSLContext.getInstance(\"SSL\").apply {\n                init(null, trustAllCerts, java.security.SecureRandom())\n            }\n            val sslSocketFactory = if (isMIUI) {\n                TlsOnlySocketFactory(sslContext.socketFactory)\n            } else {\n                sslContext.socketFactory\n            }\n            val builder = OkHttpClient.Builder().apply {\n                connectTimeout(PrefsUtil.timeoutTime, TimeUnit.SECONDS)\n                readTimeout(PrefsUtil.timeoutTime, TimeUnit.SECONDS)\n                sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)\n                cache(appCache)\n                hostnameVerifier { _, _ -> /*isHostValid(hostName)*/ true }\n            }\n            /*val dns = DnsOverHttps.Builder().client(builder).apply {\n                url(\"https://dns.google/dns-query\".toHttpUrl())\n                bootstrapDnsHosts(InetAddress.getByName(\"8.8.4.4\"), InetAddress.getByName(\"8.8.8.8\"))\n            }.build()\n            return builder.newBuilder().dns(dns).build()*/\n            return builder.build()\n        } catch (e: Exception) {\n            throw RuntimeException(e)\n        }\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/PatternUtil.kt",
    "content": "package knf.kuma.commons\n\nimport android.os.Build\nimport android.text.Html\nimport android.util.Log\nimport com.bumptech.glide.load.model.GlideUrl\nimport com.bumptech.glide.load.model.LazyHeaders\nimport knf.kuma.App\nimport knf.kuma.pojos.AnimeObject\nimport java.util.regex.Pattern\n\n\nobject PatternUtil {\n    @Suppress(\"DEPRECATION\")\n    fun fromHtml(html: String): String {\n        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)\n            Html.fromHtml(html.r(\"\\\\\\\\u\", \"\\\\u\").r(\"\\\\/\", \"/\"), Html.FROM_HTML_MODE_LEGACY).toString()\n        else\n            Html.fromHtml(html.r(\"\\\\\\\\u\", \"\\\\u\").r(\"\\\\/\", \"/\")).toString()\n    }\n\n    fun getLinkNumber(link: String): String {\n        val pattern = Pattern.compile(\"/(\\\\d+)[/.]\")\n        val matcher = pattern.matcher(link)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getRapidLink(link: String): String {\n        val pattern = Pattern.compile(\"value=([\\\\w#.]+)\")\n        val matcher = pattern.matcher(link)\n        matcher.find()\n        return \"https://www.rapidvideo.com/e/\" + matcher.group(1)\n    }\n\n    fun getRapidVideoLink(link: String): String {\n        val pattern = Pattern.compile(\"\\\"(http.*\\\\.mp4)\\\"\")\n        val matcher = pattern.matcher(link)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getYULink(link: String): String {\n        val pattern = Pattern.compile(\"\\\"(.*yourupload.*)\\\"\")\n        val matcher = pattern.matcher(link)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getYUvideoLink(link: String): String {\n        val pattern = Pattern.compile(\"file: ?'(.*vidcache.*mp4)'\")\n        val matcher = pattern.matcher(link)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getLinkId(link: String): String {\n        val matcher = Pattern.compile(\"^.*/(.*)-\\\\d+$\").matcher(link)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getLinkNum(link: String): String {\n        val matcher = Pattern.compile(\"^.*-(\\\\d+)$\").matcher(link)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getFileName(link: String): String {\n        return try {\n            val matcher = Pattern.compile(\"^.*/(.*-\\\\d+\\\\.?\\\\d*)$\").matcher(link)\n            matcher.find()\n            matcher.group(1) + \".mp4\"\n        } catch (e: Exception) {\n            Log.e(\"Pattern\", \"No name found in: $link\", e)\n            \"N-F.mp4\"\n        }\n\n    }\n\n    fun getRootFileName(link: String): String {\n        return try {\n            val matcher = Pattern.compile(\"^.*/([a-z\\\\-\\\\d]+).*$\").matcher(link)\n            matcher.find()\n            matcher.group(1)\n        } catch (e: Exception) {\n            Log.e(\"Pattern\", \"No name found in: $link\", e)\n            \"N-F\"\n        }\n\n    }\n\n    fun getNameFromFile(file: String?): String {\n        if (file.isNull()) return \"\"\n        val matcher = Pattern.compile(\"^.*\\\\$(.*)-\\\\d+\\\\.?\\\\d*\\\\.mp4$\").matcher(file)\n        matcher.find()\n        return noCrashLet(\"null/\") { matcher.group(1) + \"/\" }\n    }\n\n    fun getNumFromFile(file: String): String {\n        val matcher = Pattern.compile(\"^.*\\\\$[\\\\w-]+-(\\\\d+\\\\.?\\\\d*)\\\\.mp4$\").matcher(file)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getEidFromFile(file: String): String {\n        val matcher = Pattern.compile(\"^(-?\\\\d+)\\\\$.*$\").matcher(file)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun extractLink(html: String): String {\n        val matcher = Pattern.compile(\"https?://[a-zA-Z0-9.=?/!&#_\\\\-]+|/[a-zA-Z0-9.=?/!&#_\\\\-]+\").matcher(html)\n        matcher.find()\n        return matcher.group(0)\n    }\n\n    fun extractMangoLink(html: String): String {\n        val matcher = Pattern.compile(\"\\\"(https.*streamango\\\\.com[/a-z]+)\\\"\").matcher(html)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun extractMediaLink(html: String): String {\n        val matcher = Pattern.compile(\"www\\\\.mediafire[a-zA-Z0-a.=?/&%]+\").matcher(html)\n        matcher.find()\n        return \"https://\" + matcher.group().replace(\"%2F\", \"/\")\n    }\n\n    fun extractOkruLink(html: String): String {\n        val matcher = Pattern.compile(\"\\\"(https://ok\\\\.ru.*)\\\"\").matcher(html)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getAnimeUrl(chapter: String, aid: String): String {\n        return \"https://www3.animeflv.net/anime/\" + aid + chapter.substring(\n            chapter.lastIndexOf(\"/\"),\n            chapter.lastIndexOf(\"-\")\n        )\n    }\n\n    fun getCover(aid: String?): String {\n        return \"https://www3.animeflv.net/uploads/animes/covers/$aid.jpg\"\n    }\n\n    fun getThumb(aid: String?): String {\n        return \"https://ukiku.app/thumbs/$aid.jpg\"\n    }\n\n    fun getCoverGlide(aid: String?): GlideUrl {\n        return GlideUrl(\n            \"https://m.animeflv.net/uploads/animes/covers/$aid.jpg\",\n            LazyHeaders.Builder().apply {\n                addHeader(\"Cookie\", BypassUtil.getStringCookie(App.context))\n                addHeader(\"User-Agent\", BypassUtil.userAgent)\n            }.build()\n        )\n    }\n\n    fun getBanner(aid: String): String {\n        return \"https://www3.animeflv.net/uploads/animes/banners/$aid.jpg\"\n    }\n\n    fun getEpListMap(code: String): HashMap<String, String> {\n        val map = LinkedHashMap<String, String>()\n        val matcher = Pattern.compile(\"\\\\[(\\\\d+\\\\.?\\\\d?),(\\\\d+)]\").matcher(code)\n        while (matcher.find()) {\n            map[matcher.group(1)] = matcher.group(2)\n        }\n        return map\n    }\n\n    fun isCustomSearch(s: String): Boolean {\n        return s.matches(\"^:[a-z]+:.*$\".toRegex())\n    }\n\n    fun getCustomSearch(s: String): String {\n        val matcher = Pattern.compile(\"^:[a-z]+:(.*$)\").matcher(s)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getCustomAttr(s: String): String {\n        val matcher = Pattern.compile(\"^:([a-z]+):.*$\").matcher(s)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    fun getEids(chapters: MutableList<AnimeObject.WebInfo.AnimeChapter>): MutableList<String> =\n            chapters.map { it.eid }.toMutableList()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/PicassoSingle.kt",
    "content": "package knf.kuma.commons\n\nimport android.annotation.SuppressLint\nimport com.squareup.picasso.OkHttp3Downloader\nimport com.squareup.picasso.Picasso\nimport knf.kuma.App\nimport okhttp3.ConnectionSpec\nimport okhttp3.OkHttpClient\n\nobject PicassoSingle {\n    @SuppressLint(\"StaticFieldLeak\")\n    private lateinit var picasso: Picasso\n\n    fun get(): Picasso {\n        if (!::picasso.isInitialized)\n            picasso = create()\n        return picasso\n    }\n\n    private fun create(): Picasso = Picasso.Builder(App.context)\n        .downloader(\n            OkHttp3Downloader(\n                OkHttpClient().newBuilder()\n                    .connectionSpecs(\n                        listOf(\n                            ConnectionSpec.MODERN_TLS,\n                            ConnectionSpec.COMPATIBLE_TLS,\n                            ConnectionSpec.CLEARTEXT\n                        )\n                    )\n            .addInterceptor {\n                val nRequest = it.request().newBuilder().apply {\n                    addHeader(\"Cookie\", BypassUtil.getStringCookie(App.context))\n                    addHeader(\"User-Agent\", BypassUtil.userAgent)\n                }.build()\n                it.proceed(nRequest)\n            }.build()\n        )\n        ).build()\n\n    fun clear() {\n        picasso = create()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/PrefsUtil.kt",
    "content": "package knf.kuma.commons\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Build\nimport androidx.lifecycle.LiveData\nimport androidx.preference.PreferenceManager\nimport com.securepreferences.SecurePreferences\nimport knf.kuma.App\nimport knf.kuma.R\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.player.CustomExoPlayer\nimport knf.kuma.player.VideoActivity\nimport knf.kuma.uagen.randomUA\nimport knh.kuma.commons.cloudflarebypass.util.ConvertUtil\nimport java.net.HttpCookie\nimport java.util.UUID\n\n@SuppressLint(\"StaticFieldLeak\")\nobject PrefsUtil {\n    private var context: Context = App.context\n\n    val layType: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"lay_type\", context.getString(R.string.layType))\n                ?: \"0\"\n\n    val themeOption: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"theme_option\", context.getString(R.string.theme_default))\n                ?: context.getString(R.string.theme_default)\n\n    val themeColor: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"theme_color\", \"0\")\n                ?: \"0\"\n\n    var favsOrder: Int\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getInt(\"favs_order\", 0)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(\"favs_order\", value).apply()\n\n    var dirOrder: Int\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getInt(\"dir_order\", 0)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(\"dir_order\", value).apply()\n\n    var achievementsVersion: Int\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getInt(\"achievements_version\", 0)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(\"achievements_version\", value).apply()\n\n    val isChapsAsc: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"asc_chapters\", false)\n\n    var isDirectoryFinished: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"directory_finished\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"directory_finished\", value).apply()\n\n    var isFetchDBReset: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"fetch_db_reset\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"fetch_db_reset\", value).apply()\n\n    val isAdsEnabled: Boolean\n        get() = (!isSubscriptionEnabled && AdsUtils.remoteConfigs.getBoolean(\"ads_forced\")) ||\n                PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"ads_enabled_new\", true)\n\n    val downloaderType: Int\n        get() = Integer.parseInt(\n            PreferenceManager.getDefaultSharedPreferences(context)\n                .getString(\"downloader_type\", null)\n                ?: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && isMIUI) \"0\" else \"1\"\n        )\n\n    var autoBackupTime: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"auto_backup\", \"0\")\n                ?: \"0\"\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"auto_backup\", value).apply()\n\n    val showFavIndicator: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getBoolean(\"show_fav_count\", true)\n\n    var spProtectionEnabled: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getBoolean(\"security_blocking_firestore\", true)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit()\n            .putBoolean(\"security_blocking_firestore\", value).apply()\n\n    var tvRecentsChannelCreated: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getBoolean(\"tv_channel_recents_created\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit()\n            .putBoolean(\"tv_channel_recents_created\", value).apply()\n\n    var tvRecentsPreFilled: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getBoolean(\"tv_channel_recents_prefilled\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit()\n            .putBoolean(\"tv_channel_recents_prefilled\", value).apply()\n\n    var tvRecentsChannelId: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getLong(\"tv_channel_recents_id\", -1)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit()\n            .putLong(\"tv_channel_recents_id\", value).apply()\n\n    var tvRecentsChannelLastEid: String?\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getString(\"tv_channel_recents_last_eid\", null)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit()\n            .putString(\"tv_channel_recents_last_eid\", value).apply()\n\n    var tvRecentsChannelIds: Set<String>?\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getStringSet(\"tv_channel_recents_ids\", null)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit()\n            .putStringSet(\"tv_channel_recents_ids\", value).apply()\n\n    var spErrorType: String?\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getString(\"sp_error_type\", null)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit()\n            .putString(\"sp_error_type\", value).apply()\n\n    private val useExperimentalPlayer: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getBoolean(\"experimental_player\", false)\n\n    val collapseDirectoryNotification: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context)\n            .getBoolean(\"collapse_dir_nots\", true)\n\n    val showRecentImage: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"recent_image\", true)\n\n    val useSmoothAnimations: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"smooth_animations\", true)\n\n    var emissionBlacklist: MutableSet<String>\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getStringSet(\"emision_blacklist\", LinkedHashSet())\n                ?: LinkedHashSet()\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putStringSet(\"emision_blacklist\", value).apply()\n\n    var emissionShowHidden: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"show_hidden\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"show_hidden\", value).apply()\n\n    var isAchievementsOmitted: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"achievements_omited\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"achievements_omited\", value).apply()\n\n    var isSecurityUpdated: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"securityUpdated\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"securityUpdated\", value).apply()\n\n    var lastStart: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"last_start\", System.currentTimeMillis())\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"last_start\", value).apply()\n\n    var firstStart: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"first_start_new\", 0)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"first_start_new\", value).apply()\n\n    val saveWithName: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"save_type\", \"0\") == \"0\"\n\n    var emissionShowFavs: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"show_favs\", true)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"show_favs\", value).apply()\n\n    var timeoutTime: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"timeout_time\", if (context.resources.getBoolean(R.bool.isTv)) \"0\" else \"10\")?.toLong()\n                ?: 0\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"timeout_time\", value.toString()).apply()\n\n    var rememberServer: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"remember_server\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"remember_server\", value).apply()\n\n    var lastServer: String?\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"last_server\", null)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"last_server\", value).apply()\n\n    var lastBackup: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"last_backup\", \"Desconocido\")\n                ?: \"Desconocido\"\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"last_backup\", value).apply()\n\n    val notifyFavs: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"notify_favs\", false)\n\n    val isProxyCastEnabled: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"force_local_cast\", false)\n\n    val isGroupingEnabled: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"group_notifications\", true) && canGroupNotifications\n\n    var storageType: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"storage_type\", \"Sin almacenamiento\")\n                ?: \"Sin almacenamiento\"\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"storage_type\", value).apply()\n\n    var downloadType: String\n        get() = defaultDownloadType\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"download_type\", value).apply()\n\n    val maxParallelDownloads: Int\n        get() = Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context).getString(\"max_parallel_downloads\", \"3\")\n                ?: \"3\")\n\n    var userAgent: String\n        get() =\n            if (alwaysGenerateUA && mayUseRandomUA)\n                randomUA()\n            else\n                PreferenceManager.getDefaultSharedPreferences(context).getString(\"user_agent\", randomUA())\n                        ?: randomUA()\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"user_agent\", value).apply()\n\n    val mayUseRandomUA: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"may_use_random_useragent_1\", false)\n\n    var alwaysGenerateUA: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"alwaysGenerateUA\", true)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"alwaysGenerateUA\", value).apply()\n\n    var userAgentDir: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"user_agent_dir\", randomUA())\n                ?: randomUA()\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"user_agent_dir\", value).apply()\n\n    var randomLimit: Int\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getInt(\"random_limit\", 25)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(\"random_limit\", value).apply()\n\n    val useHome: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"recents_design\", \"0\") == \"1\"\n\n    var useDefaultUserAgent: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"use_device_useragent\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"use_device_useragent\", value).apply()\n\n    val usePlaceholders: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"list_placeholder\", false)\n\n    var instanceUuid: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"instance_uuid\", null)\n                ?: UUID.randomUUID().toString().also { instanceUuid = it }\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"instance_uuid\", value).apply()\n\n    var instanceName: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"instance_name\", \"Anónimo\")\n                ?: \"Anónimo\"\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"instance_name\", value).apply()\n\n    var recentLastHiddenNew: Int\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getInt(\"recent_last_hidden_new\", 0)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(\"recent_last_hidden_new\", value).apply()\n\n    private val rewardedVideoCount: Int\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getInt(\"rewarded_videos_seen\", 0)\n\n    var userRewardedVideoCount: Int\n        get() = SecurePreferences(context).getInt(\"user_rewarded_videos_seen\", rewardedVideoCount)\n        set(value) = SecurePreferences(context).edit().putInt(\"user_rewarded_videos_seen\", value).apply()\n\n    private val coins: Int\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"coinsNum\", null)?.decrypt()?.toInt()\n                ?: 0\n\n    var userCoins: Int\n        get() = noCrashLet(0) {\n            SecurePreferences(context).getInt(\"userCoins\", try {\n                coins\n            } catch (e: Exception) {\n                0\n            })\n        }\n        set(value) = SecurePreferences(context).edit().putInt(\"userCoins\", value).apply()\n\n    var lsAchievements: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"ls_achievements\", -1)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"ls_achievements\", value).apply()\n\n    var lsEa: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"ls_ea\", -1)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"ls_ea\", value).apply()\n\n    var lsFavs: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"ls_favs\", -1)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"ls_favs\", value).apply()\n\n    var lsGenres: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"ls_genres\", -1)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"ls_genres\", value).apply()\n\n    var lsHistory: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"ls_history\", -1)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"ls_history\", value).apply()\n\n    var lsQueue: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"ls_queue\", -1)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"ls_queue\", value).apply()\n\n    var lsSeeing: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"ls_seeing\", -1)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"ls_seeing\", value).apply()\n\n    var lsSeen: Long\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getLong(\"ls_seen\", -1)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(\"ls_seen\", value).apply()\n\n    var isFamilyFriendly: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"family_friendly_enabled\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"family_friendly_enabled\", value).apply()\n\n    var ffPass: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"ff_pass_cbc\", \"\")\n                ?: \"\"\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"ff_pass_cbc\", value).apply()\n\n    var topCount: Int\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getInt(\"top_count\", 25)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putInt(\"top_count\", value).apply()\n\n    var subscriptionToken: String?\n        get() = SecurePreferences(context).getString(\"subscription_token\", null)\n        set(value) = SecurePreferences(context).edit().putString(\"subscription_token\", value).apply()\n\n    var isPSWarned: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"isPSWarned1\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"isPSWarned1\", value).apply()\n\n    var isNativeAdsEnabled: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"isNativeAdsEnabled\", true)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"isNativeAdsEnabled\", value).apply()\n\n    var isFullAdsEnabled: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"isFullAdsEnabled\", true)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"isFullAdsEnabled\", value).apply()\n\n    var fullAdsProbability: Float\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getFloat(\"fullAdsProbability\", AdsUtils.remoteConfigs.getDouble(\"full_show_probability\").toFloat())\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putFloat(\"fullAdsProbability\", value).apply()\n\n    var fullAdsExtraProbability: Float\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getFloat(\"fullAdsExtraProbability\", AdsUtils.remoteConfigs.getDouble(\"full_show_extra_probability\").toFloat())\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putFloat(\"fullAdsExtraProbability\", value).apply()\n\n    val designStyle: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"designStyleType\", \"0\")\n                ?: \"0\"\n\n    val recentActionType: String\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getString(\"recentActionType\", \"0\")\n                ?: \"0\"\n\n    var dirCookies: List<HttpCookie>\n        get() = ConvertUtil.String2List(PreferenceManager.getDefaultSharedPreferences(context).getString(\"dirCookies\", \"\")\n                ?: \"\")\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putString(\"dirCookies\", ConvertUtil.listToString(value)).apply()\n\n    var isForbiddenTipShown: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"isForbiddenTipShown\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"isForbiddenTipShown\", value).apply()\n\n    var isBypassWarningShown: Boolean\n        get() = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"isBypassWarningShown\", false)\n        set(value) = PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(\"isBypassWarningShown\", value).apply()\n\n    fun showProgress(): Boolean {\n        return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"show_progress\", true)\n    }\n\n    fun showFavSections(): Boolean {\n        return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"fav_sections\", true)\n    }\n\n    fun showImport(): Boolean {\n        return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"show_import\", false)\n    }\n\n    fun bufferSize(): Int {\n        return Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context).getString(\"buffer_size\", \"32\")\n                ?: \"32\")\n    }\n\n    fun getLiveEmissionBlackList(): LiveData<Set<String>> {\n        return PreferenceManager.getDefaultSharedPreferences(context).stringSetLiveData(\"emision_blacklist\", LinkedHashSet())\n    }\n\n    fun getPlayerIntent(): Intent {\n        return if (useExperimentalPlayer)\n            Intent(context, VideoActivity::class.java)\n        else\n            Intent(context, CustomExoPlayer::class.java)\n    }\n\n    fun getLiveShowFavIndicator(): LiveData<Boolean> {\n        return PreferenceManager.getDefaultSharedPreferences(context).booleanLiveData(\"show_fav_count\", true)\n    }\n\n    fun getLiveDesignType(): LiveData<String> {\n        return PreferenceManager.getDefaultSharedPreferences(context).stringLiveData(\"designStyleType\", \"0\").distinct\n    }\n\n    fun getLiveEmissionVisibility(): LiveData<Boolean> =\n            PreferenceManager.getDefaultSharedPreferences(context).booleanLiveData(\"show_hidden\", false)\n\n    val isSubscriptionEnabled: Boolean get() = subscriptionToken != null\n\n    private val defaultDownloadType: String\n        get() {\n            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)\n                \"1\"\n            else\n                PreferenceManager.getDefaultSharedPreferences(context).getString(\"download_type\", \"0\")\n                        ?: \"0\"\n        }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/SSLSkipper.kt",
    "content": "package knf.kuma.commons\n\nimport java.security.GeneralSecurityException\nimport java.security.SecureRandom\nimport java.security.cert.CertificateException\nimport java.security.cert.X509Certificate\nimport javax.net.ssl.HostnameVerifier\nimport javax.net.ssl.HttpsURLConnection\nimport javax.net.ssl.SSLContext\nimport javax.net.ssl.TrustManager\nimport javax.net.ssl.X509TrustManager\n\nobject SSLSkipper {\n    fun skip() {\n        val trustAllCertificates = arrayOf<TrustManager>(object : X509TrustManager {\n            override fun getAcceptedIssuers(): Array<X509Certificate>? {\n                return null // Not relevant.\n            }\n\n            override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) {\n                noCrash {\n                    certs.forEach {\n                        it.checkValidity()\n                    }\n                }\n            }\n\n            override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) {\n                noCrash {\n                    certs.forEach {\n                        it.checkValidity()\n                    }\n                }\n            }\n        })\n\n        val trustAllHostnames = HostnameVerifier { hostName, _ -> /*isHostValid(hostName)*/ true }\n\n        try {\n            System.setProperty(\"jsse.enableSNIExtension\", \"false\")\n            val sc = SSLContext.getInstance(\"SSL\")\n            sc.init(null, trustAllCertificates, SecureRandom())\n            HttpsURLConnection.setDefaultSSLSocketFactory(sc.socketFactory)\n            HttpsURLConnection.setDefaultHostnameVerifier(trustAllHostnames)\n        } catch (e: GeneralSecurityException) {\n            throw ExceptionInInitializerError(e)\n        }\n\n        try {\n            val context = SSLContext.getInstance(\"TLS\")\n            context.init(null, arrayOf<X509TrustManager>(object : X509TrustManager {\n                @Throws(CertificateException::class)\n                override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {\n                    noCrash {\n                        chain.forEach {\n                            it.checkValidity()\n                        }\n                    }\n                }\n\n                @Throws(CertificateException::class)\n                override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {\n                    noCrash {\n                        chain.forEach {\n                            it.checkValidity()\n                        }\n                    }\n                }\n\n                override fun getAcceptedIssuers(): Array<X509Certificate?> {\n                    return arrayOfNulls(0)\n                }\n            }), SecureRandom())\n            HttpsURLConnection.setDefaultSSLSocketFactory(context.socketFactory)\n        } catch (e: Exception) {\n\n        }\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/SelfServer.kt",
    "content": "package knf.kuma.commons\n\nimport android.app.Notification\nimport android.app.PendingIntent\nimport android.app.Service\nimport android.content.BroadcastReceiver\nimport android.content.Context\nimport android.content.Intent\nimport android.content.IntentFilter\nimport android.net.Uri\nimport android.os.Build\nimport android.os.IBinder\nimport android.webkit.URLUtil\nimport androidx.core.app.NotificationCompat\nimport fi.iki.elonen.NanoHTTPD\nimport knf.kuma.App\nimport knf.kuma.R\nimport knf.kuma.download.DownloadManager\nimport knf.kuma.download.foreground\nimport knf.kuma.download.service\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport org.jetbrains.anko.doAsync\nimport xdroid.toaster.Toaster\nimport java.io.File\nimport java.io.FileInputStream\nimport java.io.IOException\nimport java.io.InputStream\nimport java.io.PipedInputStream\nimport java.io.PipedOutputStream\nimport java.net.HttpURLConnection\nimport java.net.URL\nimport androidx.core.net.toUri\n\nclass SelfServer : Service() {\n    private val receiver = object : BroadcastReceiver() {\n        override fun onReceive(context: Context?, intent: Intent?) {\n            CastUtil.get().stop()\n            stopForeground(STOP_FOREGROUND_REMOVE)\n            stopSelf()\n        }\n    }\n\n    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {\n        foreground(64587, foregroundNotification(), false)\n        return START_STICKY\n    }\n\n    override fun onCreate() {\n        super.onCreate()\n        foreground(64587, foregroundNotification(), false)\n        val filter = IntentFilter(\"knf.cast.stop.foreground\")\n        if (Build.VERSION.SDK_INT >= 33) {\n            registerReceiver(receiver, filter, RECEIVER_NOT_EXPORTED)\n        } else {\n            registerReceiver(receiver, filter)\n        }\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n        try {\n            unregisterReceiver(receiver)\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }\n\n    override fun onBind(intent: Intent?): IBinder? {\n        return null\n    }\n\n    private fun foregroundNotification(): Notification {\n        return NotificationCompat.Builder(App.context, DownloadManager.CHANNEL_FOREGROUND).apply {\n            setSmallIcon(R.drawable.ic_server_running)\n            setOngoing(true)\n            priority = NotificationCompat.PRIORITY_MIN\n            setGroup(\"manager\")\n            if (PrefsUtil.collapseDirectoryNotification)\n                setSubText(\"Servidor activo\")\n            else\n                setContentTitle(\"Servidor activo\")\n            addAction(R.drawable.ic_stop, \"Detener\",\n                PendingIntent.getBroadcast(\n                    App.context,\n                    4689,\n                    Intent(\"knf.cast.stop.foreground\"),\n                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\n                )\n            )\n        }.build()\n    }\n\n    companion object {\n        var HTTP_PORT = 6991\n        private var INSTANCE: Server? = null\n\n        fun start(data: String, isFile: Boolean = true): String? {\n            return try {\n                stop(true)\n                App.context.service(Intent(App.context, SelfServer::class.java))\n                INSTANCE = Server(data, isFile)\n                \"http://\" + Network.ipAddress + \":\" + HTTP_PORT\n            } catch (e: Exception) {\n                e.printStackTrace()\n                Toaster.toast(\"Error al iniciar server\")\n                null\n            }\n        }\n\n        fun stop(isRestart: Boolean = false) {\n            if (INSTANCE?.isAlive == true) {\n                INSTANCE?.stop()\n                if (!isRestart)\n                    App.context.sendBroadcast(Intent(\"knf.cast.stop.foreground\").apply {\n                        setPackage(\"knf.kuma\")\n                    })\n            }\n        }\n    }\n\n    private class Server @Throws(Exception::class)\n    constructor(private val data: String, private val isFile: Boolean) : NanoHTTPD(HTTP_PORT) {\n\n        init {\n            start(SOCKET_READ_TIMEOUT, false)\n        }\n\n        override fun serve(session: IHTTPSession): Response {\n            return if (isFile)\n                if (URLUtil.isFileUrl(data)) {\n                    var file = File(data.toUri().path)\n                    if (!file.exists())\n                        file = file.parentFile?.listFiles { f -> f.name.contains(data.toUri().path!!.substringAfterLast(\"$\")) }!![0]\n                    serveFile(session.headers, file)\n                } else\n                    serveFile(session.headers, data)\n            else\n                serveWeb(session.headers, data)\n        }\n\n        private fun getSize(url: String): Long {\n            return try {\n                val connection = URL(url).openConnection() as HttpURLConnection\n                connection.connect()\n                connection.contentLength.toLong()\n            } catch (e: Exception) {\n                0\n            }\n\n        }\n\n        private fun serveWeb(header: Map<String, String>, url: String): Response {\n            var res: Response? = null\n            val okHttpClient = OkHttpClient()\n            val request = Request.Builder().url(url)\n            val response = okHttpClient.newCall(request.build()).execute()\n            val body = response.body\n            val total = body?.contentLength() ?: 0\n            val inputStream = body?.byteStream()\n            val pipedIn = PipedInputStream()\n            val pipedOut = PipedOutputStream(pipedIn)\n            if (inputStream != null) {\n                doAsync {\n                    noCrash {\n                        val b = ByteArray(16 * 1024)\n                        var len = inputStream.read(b, 0, 16 * 1024)\n                        while (len != -1) {\n                            pipedOut.write(b, 0, len)\n                            len = inputStream.read(b, 0, 16 * 1024)\n                        }\n                        pipedOut.flush()\n                        response.close()\n                    }\n                }\n                Thread.sleep(400)\n                res = createResponse(Response.Status.OK, \"video/mp4\", pipedIn, total)\n            }\n            return res ?: getResponse(\"Error 404: File not found\")\n        }\n\n        private fun serveFile(header: Map<String, String>, file_name: String): Response {\n            var res: Response?\n            val mime = \"video/mp4\"\n            val fileWrapper = FileWrapper.create(file_name)\n            try {\n                if (!fileWrapper.exist)\n                    throw IllegalAccessException()\n                // Calculate etag\n                val etag = Integer.toHexString((fileWrapper.file()?.absolutePath +\n                        fileWrapper.lastModified() + \"\" + fileWrapper.length()).hashCode())\n\n                // Support (simple) skipping:\n                var startFrom: Long = 0\n                var endAt: Long = -1\n                var range = header[\"range\"]\n                if (range != null) {\n                    if (range.startsWith(\"bytes=\")) {\n                        range = range.substring(\"bytes=\".length)\n                        val minus = range.indexOf('-')\n                        try {\n                            if (minus > 0) {\n                                startFrom = java.lang.Long.parseLong(range.substring(0, minus))\n                                endAt = java.lang.Long.parseLong(range.substring(minus + 1))\n                            }\n                        } catch (ignored: NumberFormatException) {\n                        }\n\n                    }\n                }\n\n                // Change return code and add Content-Range header when skipping is requested\n                val fileLen = fileWrapper.length() ?: 0\n                if (range != null && startFrom >= 0) {\n                    if (startFrom >= fileLen) {\n                        res = createResponse(Response.Status.RANGE_NOT_SATISFIABLE, MIME_PLAINTEXT, \"\")\n                        res.addHeader(\"Content-Range\", \"bytes 0-0/$fileLen\")\n                        res.addHeader(\"ETag\", etag)\n                    } else {\n                        if (endAt < 0) {\n                            endAt = fileLen - 1\n                        }\n                        var newLen = endAt - startFrom + 1\n                        if (newLen < 0) {\n                            newLen = 0\n                        }\n\n                        val dataLen = newLen\n                        val fis = fileWrapper.inputStream()\n                        fis?.skip(startFrom)\n\n                        res = createResponse(Response.Status.PARTIAL_CONTENT, mime, fis, dataLen)\n                        res.addHeader(\"Content-Length\", \"\" + dataLen)\n                        res.addHeader(\"Content-Range\", \"bytes \" + startFrom + \"-\" +\n                                endAt + \"/\" + fileLen)\n                        res.addHeader(\"ETag\", etag)\n                    }\n                } else {\n                    if (etag == header[\"if-none-match\"])\n                        res = createResponse(Response.Status.NOT_MODIFIED, mime, \"\")\n                    else {\n                        res = createResponse(Response.Status.OK, mime, fileWrapper.inputStream(), fileLen)\n                        res.addHeader(\"Content-Length\", \"\" + fileLen)\n                        res.addHeader(\"ETag\", etag)\n                    }\n                }\n            } catch (ioe: IOException) {\n                res = getResponse(\"Forbidden: Reading file failed\")\n            }\n\n            return res ?: getResponse(\"Error 404: File not found\")\n        }\n\n        private fun serveFile(header: Map<String, String>, file: File): Response {\n            var res: Response?\n            val mime = \"video/mp4\"\n            try {\n                // Calculate etag\n                val etag = Integer.toHexString((file.absolutePath +\n                        file.lastModified() + \"\" + file.length()).hashCode())\n\n                // Support (simple) skipping:\n                var startFrom: Long = 0\n                var endAt: Long = -1\n                var range = header[\"range\"]\n                if (range != null) {\n                    if (range.startsWith(\"bytes=\")) {\n                        range = range.substring(\"bytes=\".length)\n                        val minus = range.indexOf('-')\n                        try {\n                            if (minus > 0) {\n                                startFrom = java.lang.Long.parseLong(range.substring(0, minus))\n                                endAt = java.lang.Long.parseLong(range.substring(minus + 1))\n                            }\n                        } catch (ignored: NumberFormatException) {\n                        }\n\n                    }\n                }\n\n                // Change return code and add Content-Range header when skipping is requested\n                val fileLen = file.length()\n                if (range != null && startFrom >= 0) {\n                    if (startFrom >= fileLen) {\n                        res = createResponse(Response.Status.RANGE_NOT_SATISFIABLE, MIME_PLAINTEXT, \"\")\n                        res.addHeader(\"Content-Range\", \"bytes 0-0/$fileLen\")\n                        res.addHeader(\"ETag\", etag)\n                    } else {\n                        if (endAt < 0) {\n                            endAt = fileLen - 1\n                        }\n                        var newLen = endAt - startFrom + 1\n                        if (newLen < 0) {\n                            newLen = 0\n                        }\n\n                        val dataLen = newLen\n                        val fis = FileInputStream(file)\n                        fis.skip(startFrom)\n\n                        res = createResponse(Response.Status.PARTIAL_CONTENT, mime, fis, dataLen)\n                        res.addHeader(\"Content-Length\", \"\" + dataLen)\n                        res.addHeader(\"Content-Range\", \"bytes \" + startFrom + \"-\" +\n                                endAt + \"/\" + fileLen)\n                        res.addHeader(\"ETag\", etag)\n                    }\n                } else {\n                    if (etag == header[\"if-none-match\"])\n                        res = createResponse(Response.Status.NOT_MODIFIED, mime, \"\")\n                    else {\n                        res = createResponse(Response.Status.OK, mime, FileInputStream(file), fileLen)\n                        res.addHeader(\"Content-Length\", \"\" + fileLen)\n                        res.addHeader(\"ETag\", etag)\n                    }\n                }\n            } catch (ioe: IOException) {\n                res = getResponse(\"Forbidden: Reading file failed\")\n            }\n\n            return res ?: getResponse(\"Error 404: File not found\")\n        }\n\n        // Announce that the file server accepts partial content requests\n        private fun createResponse(status: Response.Status, mimeType: String, message: InputStream?, lenght: Long): Response {\n            val res = newFixedLengthResponse(status, mimeType, message, lenght)\n            res.addHeader(\"Accept-Ranges\", \"bytes\")\n            return res\n        }\n\n        // Announce that the file server accepts partial content requests\n        private fun createResponse(status: Response.Status, mimeType: String, message: String): Response {\n            val res = newFixedLengthResponse(status, mimeType, message)\n            res.addHeader(\"Accept-Ranges\", \"bytes\")\n            return res\n        }\n\n        private fun getResponse(message: String): Response {\n            return createResponse(Response.Status.OK, \"text/plain\", message)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/SharedPreferenceLiveData.kt",
    "content": "package knf.kuma.commons\n\nimport android.content.SharedPreferences\nimport androidx.lifecycle.LiveData\n\nabstract class SharedPreferenceLiveData<T>(val sharedPrefs: SharedPreferences,\n                                           val key: String,\n                                           private val defValue: T) : LiveData<T>() {\n\n    private val preferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->\n        if (key == this.key) {\n            value = getValueFromPreferences(key, defValue)\n        }\n    }\n\n    abstract fun getValueFromPreferences(key: String, defValue: T): T\n\n    override fun onActive() {\n        super.onActive()\n        value = getValueFromPreferences(key, defValue)\n        sharedPrefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener)\n    }\n\n    override fun onInactive() {\n        sharedPrefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener)\n        super.onInactive()\n    }\n}\n\nclass SharedPreferenceIntLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Int) :\n        SharedPreferenceLiveData<Int>(sharedPrefs, key, defValue) {\n    override fun getValueFromPreferences(key: String, defValue: Int): Int = sharedPrefs.getInt(key, defValue)\n}\n\nclass SharedPreferenceStringLiveData(sharedPrefs: SharedPreferences, key: String, defValue: String) :\n        SharedPreferenceLiveData<String>(sharedPrefs, key, defValue) {\n    override fun getValueFromPreferences(key: String, defValue: String): String = sharedPrefs.getString(key, defValue)\n            ?: defValue\n}\n\nclass SharedPreferenceBooleanLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Boolean) :\n        SharedPreferenceLiveData<Boolean>(sharedPrefs, key, defValue) {\n    override fun getValueFromPreferences(key: String, defValue: Boolean): Boolean = sharedPrefs.getBoolean(key, defValue)\n}\n\nclass SharedPreferenceFloatLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Float) :\n        SharedPreferenceLiveData<Float>(sharedPrefs, key, defValue) {\n    override fun getValueFromPreferences(key: String, defValue: Float): Float = sharedPrefs.getFloat(key, defValue)\n}\n\nclass SharedPreferenceLongLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Long) :\n        SharedPreferenceLiveData<Long>(sharedPrefs, key, defValue) {\n    override fun getValueFromPreferences(key: String, defValue: Long): Long = sharedPrefs.getLong(key, defValue)\n}\n\nclass SharedPreferenceStringSetLiveData(sharedPrefs: SharedPreferences, key: String, defValue: Set<String>) :\n        SharedPreferenceLiveData<Set<String>>(sharedPrefs, key, defValue) {\n    override fun getValueFromPreferences(key: String, defValue: Set<String>): Set<String> = sharedPrefs.getStringSet(key, defValue)\n            ?: defValue\n}\n\nfun SharedPreferences.intLiveData(key: String, defValue: Int): SharedPreferenceLiveData<Int> {\n    return SharedPreferenceIntLiveData(this, key, defValue)\n}\n\nfun SharedPreferences.stringLiveData(key: String, defValue: String): SharedPreferenceLiveData<String> {\n    return SharedPreferenceStringLiveData(this, key, defValue)\n}\n\nfun SharedPreferences.booleanLiveData(key: String, defValue: Boolean): SharedPreferenceLiveData<Boolean> {\n    return SharedPreferenceBooleanLiveData(this, key, defValue)\n}\n\nfun SharedPreferences.floatLiveData(key: String, defValue: Float): SharedPreferenceLiveData<Float> {\n    return SharedPreferenceFloatLiveData(this, key, defValue)\n}\n\nfun SharedPreferences.longLiveData(key: String, defValue: Long): SharedPreferenceLiveData<Long> {\n    return SharedPreferenceLongLiveData(this, key, defValue)\n}\n\nfun SharedPreferences.stringSetLiveData(key: String, defValue: Set<String>): SharedPreferenceLiveData<Set<String>> {\n    return SharedPreferenceStringSetLiveData(this, key, defValue)\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/commons/ThumbsDownloader.kt",
    "content": "package knf.kuma.commons\r\n\r\nimport android.content.Context\r\nimport android.graphics.Bitmap\r\nimport android.util.Log\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.launch\r\nimport java.io.File\r\nimport java.io.FileOutputStream\r\n\r\nobject ThumbsDownloader {\r\n    fun start(context: Context) {\r\n        GlobalScope.launch(Dispatchers.IO) {\r\n            val thumbs = context.getExternalFilesDir(\"thumbs\")\r\n            for (id in 1..3500) {\r\n                val result = try {\r\n                    val thumb = File(thumbs, \"$id.jpg\")\r\n                    if (!thumb.exists()) {\r\n                        val bitmap = PicassoSingle.get()\r\n                            .load(\"https://www3.animeflv.net/uploads/animes/thumbs/$id.jpg\").get()\r\n                        thumb.createNewFile()\r\n                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, FileOutputStream(thumb))\r\n                        delay(100)\r\n                    }\r\n                    true\r\n                } catch (e: Exception) {\r\n                    false\r\n                }\r\n                Log.e(\"Thumb\", \"Download id $id, success: $result\")\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/AchievementUnlocked.java",
    "content": "package knf.kuma.custom;\r\n\r\nimport static android.text.TextUtils.isEmpty;\r\nimport static android.view.Gravity.CENTER_HORIZONTAL;\r\nimport static android.view.View.GONE;\r\nimport static android.widget.LinearLayout.VERTICAL;\r\nimport static java.lang.Boolean.FALSE;\r\n\r\nimport android.animation.Animator;\r\nimport android.animation.AnimatorListenerAdapter;\r\nimport android.animation.AnimatorSet;\r\nimport android.animation.ArgbEvaluator;\r\nimport android.animation.ObjectAnimator;\r\nimport android.animation.TimeInterpolator;\r\nimport android.animation.ValueAnimator;\r\nimport android.annotation.SuppressLint;\r\nimport android.content.Context;\r\nimport android.content.res.Resources;\r\nimport android.graphics.Color;\r\nimport android.graphics.PixelFormat;\r\nimport android.graphics.PorterDuff;\r\nimport android.graphics.drawable.Drawable;\r\nimport android.graphics.drawable.GradientDrawable;\r\nimport android.os.Build;\r\nimport android.os.Build.VERSION;\r\nimport android.os.PowerManager;\r\nimport android.provider.Settings;\r\nimport android.text.Editable;\r\nimport android.text.TextWatcher;\r\nimport android.util.AttributeSet;\r\nimport android.util.DisplayMetrics;\r\nimport android.util.Log;\r\nimport android.view.Gravity;\r\nimport android.view.MotionEvent;\r\nimport android.view.View;\r\nimport android.view.View.MeasureSpec;\r\nimport android.view.ViewConfiguration;\r\nimport android.view.ViewGroup;\r\nimport android.view.WindowManager;\r\nimport android.view.animation.AccelerateInterpolator;\r\nimport android.view.animation.AnticipateInterpolator;\r\nimport android.view.animation.LinearInterpolator;\r\nimport android.view.animation.OvershootInterpolator;\r\nimport android.widget.ImageView;\r\nimport android.widget.LinearLayout;\r\nimport android.widget.RelativeLayout;\r\nimport android.widget.RelativeLayout.LayoutParams;\r\nimport android.widget.TextView;\r\nimport android.widget.Toast;\r\n\r\nimport androidx.annotation.Nullable;\r\n\r\nimport java.util.Collection;\r\n\r\nimport knf.kuma.App;\r\nimport knf.kuma.BuildConfig;\r\n\r\n/**\r\n * Basically an animated toast notification with queue support.\r\n * <p>\r\n * It uses a set of invisible views (called 'fake') to measure\r\n * the data before showing it to user. This similar to using measureText\r\n * method but more accurate.\r\n * <p>\r\n * Doesn't work with power-saving mode on unless you implement your\r\n * own valueAnimator class.\r\n * <p>\r\n * This is 'all-in-one' library. You have to copy the class file\r\n * to your package folder, otherwise you won't have access to inner\r\n * classes such as AchievementData and listener.\r\n * <p>\r\n * Don't forget to grant 'draw over apps' permission (SYSTEM_ALERT_WINDOW)\r\n * <p>\r\n * GPL\r\n * By Darkion Avey @ http://darkion.net/\r\n */\r\n@SuppressWarnings({\"unused\", \"SetTextI18n\"})\r\npublic class AchievementUnlocked {\r\n    //animation interpolators\r\n    private final static TimeInterpolator TIME_INTERPOLATOR = new DeceleratingInterpolator(50);\r\n    private static final String TAG = \"AU\";\r\n    private final OvershootInterpolator overshootInterpolator = new OvershootInterpolator();\r\n    private final AnticipateInterpolator anticipateInterpolator = new AnticipateInterpolator();\r\n    private final TimeInterpolator accelerateInterpolator = new AccelerateInterpolator(50);\r\n    private final int focusable = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;\r\n    private final int nonFocusable = WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;\r\n    private final boolean DEBUG = BuildConfig.DEBUG;\r\n    private int currentContainerWidth;\r\n    //dimens\r\n    private int smallSize, largeSize, elevation, paddingLarge, paddingSmall, translationY, margin;\r\n    private int initialSize = -1;\r\n    //indices of data iterator\r\n    private int index = 0;\r\n    private final Context context;\r\n    private boolean dismissible = false;\r\n    private boolean added = false;\r\n    //achievements data\r\n    private AchievementData[] achievements;\r\n    private int readingDelay = 1300;\r\n    private int matchParent;\r\n    private boolean dismissed = false;\r\n    private AchievementListenerAdapter listener;\r\n    private boolean isPowerSavingModeOn = false;\r\n    private boolean isLarge = true, alignTop = true, isRounded = true;\r\n    private boolean notchMode = VERSION.SDK_INT >= 26;\r\n    private Integer statusBarHeight;\r\n    private ViewGroup container;\r\n    private AchievementIconView icon;\r\n    private TextView titleTextView;\r\n    private ScrollTextView subtitleTextView;\r\n    private ViewGroup achievementLayout;\r\n    private WindowManager.LayoutParams mainViewLP;\r\n    private float mPxPerSeconds = 40;\r\n    //private AchievementQueue queue = new AchievementQueue();\r\n    private boolean initiatedGlobalFields = false;\r\n    private boolean hasBeenDismissed = false;\r\n\r\n    public AchievementUnlocked(Context context) {\r\n        this.context = context;\r\n        initGlobalFields();\r\n    }\r\n\r\n    /**\r\n     * For debugging purposes\r\n     */\r\n    static long getScaledDuration(int duration) {\r\n        return (long) (1f * duration);\r\n    }\r\n\r\n    private static int countMatches(final String str, final String sub) {\r\n        if (isEmpty(str) || isEmpty(sub)) {\r\n            return 0;\r\n        }\r\n        int count = 0;\r\n        int idx = 0;\r\n        while ((idx = str.indexOf(sub, idx)) != -1) {\r\n            count++;\r\n            idx += sub.length();\r\n        }\r\n        return count;\r\n    }\r\n\r\n    /**\r\n     * Set how many pixels should be scrolled per second when\r\n     * the subtitle is scrollable (longer than screen width)\r\n     * <p>\r\n     * Default value is 40;\r\n     *\r\n     * @param PxPerSeconds higher values will result in faster\r\n     *                     scrolling\r\n     */\r\n    public void setScrollingPxPerSeconds(float PxPerSeconds) {\r\n        this.mPxPerSeconds = PxPerSeconds;\r\n    }\r\n\r\n    /**\r\n     * Indicate that the system is running on a notched device.\r\n     * This is set to true on Oreo+ devices since TYPE_SYSTEM_ERROR is\r\n     * deprecated anyway and the popup will have to move below the status bar\r\n     *\r\n     * @param statusBarHeight custom status bar height (y shift) since this library\r\n     *                        does not have direct access to decor view. You can supply\r\n     *                        a null value and use the hardcoded status bar height\r\n     */\r\n    public void setNotchMode(@Nullable Integer statusBarHeight) {\r\n        this.notchMode = true;\r\n        if (statusBarHeight != null) this.statusBarHeight = statusBarHeight;\r\n    }\r\n\r\n    /**\r\n     * Indicate whether the popup should appear on top of the screen\r\n     * or not\r\n     *\r\n     * @param alignTop true for top alignment\r\n     * @return same AchievementUnlocked object\r\n     */\r\n    public AchievementUnlocked setTopAligned(boolean alignTop) {\r\n        this.alignTop = alignTop;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Set how many milliseconds the popup should wait before the next\r\n     * animation is played. This value is ignored when the popup width\r\n     * exceeds display width (aka scrolling popup).\r\n     * The default value is 1500 which is 1.5 seconds\r\n     *\r\n     * @param readingDelay reading duration in milliseconds\r\n     * @return same AchievementUnlocked object\r\n     */\r\n    public AchievementUnlocked setReadingDelay(int readingDelay) {\r\n        this.readingDelay = readingDelay;\r\n        return this;\r\n\r\n    }\r\n\r\n    /**\r\n     * Set true if you want the popup to be rounded. Default\r\n     * value is true\r\n     *\r\n     * @param rounded true for complete rounded appearance, false for rounded box\r\n     * @return same AchievementUnlocked object\r\n     */\r\n    public AchievementUnlocked setRounded(boolean rounded) {\r\n        isRounded = rounded;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * Callbacks for different events occurring throughout the popup's\r\n     * life span\r\n     *\r\n     * @param listener the listener to be used\r\n     */\r\n    public void setAchievementListener(@Nullable AchievementListenerAdapter listener) {\r\n        this.listener = listener;\r\n    }\r\n\r\n    /**\r\n     * Set to true if you want the popup to be large. Default value\r\n     * is true. Large popup height is 65dp whereas the small one is\r\n     * 50dp\r\n     *\r\n     * @param large true for large popups, false for small ones\r\n     * @return same AchievementUnlocked object\r\n     */\r\n    public AchievementUnlocked setLarge(boolean large) {\r\n        this.isLarge = large;\r\n        return this;\r\n    }\r\n\r\n    /**\r\n     * @return the popup view without the scrim. You should not modify\r\n     * any of its properties since that might cause the animations\r\n     * to go haywire\r\n     */\r\n    public View getAchievementView() {\r\n        return container;\r\n    }\r\n\r\n    /**\r\n     * @return the title text view\r\n     */\r\n    public TextView getTitleTextView() {\r\n        return titleTextView;\r\n    }\r\n\r\n    /**\r\n     * @return the subtitle text view\r\n     */\r\n    public TextView getSubtitleTextView() {\r\n        return subtitleTextView;\r\n    }\r\n\r\n    /**\r\n     * @return the icon view\r\n     */\r\n    public View getIconView() {\r\n        return icon;\r\n    }\r\n\r\n    /**\r\n     * @return get the view containing the scrim (background fade) and\r\n     * the popup. You should not modify any of its properties since that might\r\n     * cause the animations to go haywire\r\n     */\r\n    public ViewGroup getAchievementParent() {\r\n        return achievementLayout;\r\n    }\r\n\r\n    private int convertDpToPixel(float dp) {\r\n        DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();\r\n        float px = dp * (metrics.densityDpi / 160f);\r\n        return Math.round(px);\r\n    }\r\n\r\n    @SuppressLint({\"ObsoleteSdkInt\", \"SetTextI18n\"})\r\n    private void initGlobalFields() {\r\n        try {\r\n            if (!initiatedGlobalFields) {\r\n                margin = convertDpToPixel(16);\r\n                elevation = convertDpToPixel(10);\r\n                paddingLarge = convertDpToPixel(10);\r\n                paddingSmall = convertDpToPixel(5);\r\n                smallSize = convertDpToPixel(50);\r\n                largeSize = convertDpToPixel(65);\r\n                translationY = convertDpToPixel(20);\r\n\r\n                achievementLayout = new RelativeLayout(context);\r\n                achievementLayout.setClipToPadding(FALSE);\r\n                LayoutParams motherLayoutLP = new LayoutParams(-2, -2);\r\n                achievementLayout.setLayoutParams(motherLayoutLP);\r\n                achievementLayout.setTag(\"motherLayout\");\r\n                LinearLayout textContainerFake = new LinearLayout(context);\r\n                textContainerFake.setOrientation(VERTICAL);\r\n                textContainerFake.setPadding(convertDpToPixel(10), 0, convertDpToPixel(20), 0);\r\n                textContainerFake.setVisibility(View.INVISIBLE);\r\n                LayoutParams textContainerFakeLP = new LayoutParams(-2, -2);\r\n                textContainerFakeLP.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);\r\n                textContainerFake.setLayoutParams(textContainerFakeLP);\r\n                textContainerFake.setTag(\"textContainerFake\");\r\n                TextView titleFake = new TextView(context);\r\n                titleFake.setText(\"Title\");\r\n                LayoutParams titleFakeLP = new LayoutParams(-2, -2);\r\n                titleFake.setLayoutParams(titleFakeLP);\r\n                titleFake.setTag(\"titleFake\");\r\n                titleFake.setMaxLines(1);\r\n                ScrollTextView subtitleFake = new ScrollTextView(context);\r\n                subtitleFake.setText(\"Subtitle\");\r\n                subtitleFake.setVisibility(GONE);\r\n                subtitleFake.setMaxLines(1);\r\n                LayoutParams subtitleFakeLP = new LayoutParams(-2, -2);\r\n                subtitleFake.setLayoutParams(subtitleFakeLP);\r\n                subtitleFake.setTag(\"subtitleFake\");\r\n                textContainerFake.addView(titleFake);\r\n                textContainerFake.addView(subtitleFake);\r\n                achievementLayout.addView(textContainerFake);\r\n                container = new RelativeLayout(context);\r\n                container.setClipToPadding(false);\r\n                container.setClipChildren(false);\r\n\r\n                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {\r\n                    achievementLayout.setClipToOutline(true);\r\n                }\r\n\r\n                LayoutParams achievementBodyLP = new LayoutParams(-2, largeSize);\r\n                achievementBodyLP.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);\r\n                achievementBodyLP.addRule(CENTER_HORIZONTAL, RelativeLayout.TRUE);\r\n                achievementBodyLP.bottomMargin = achievementBodyLP.topMargin = convertDpToPixel(10);\r\n\r\n                if ((VERSION.SDK_INT >= 26 || notchMode) && alignTop) {\r\n                    achievementBodyLP.topMargin += statusBarHeight == null ? Math.round(getStatusBarHeight() * 1.7f) : statusBarHeight;\r\n                }\r\n\r\n                container.setLayoutParams(achievementBodyLP);\r\n                container.setTag(\"achievementBody\");\r\n                LinearLayout achievementIconBg = new LinearLayout(context);\r\n                LayoutParams achievementIconBgLP = new LayoutParams(largeSize, largeSize);\r\n                achievementIconBg.setLayoutParams(achievementIconBgLP);\r\n                achievementIconBg.setTag(\"achievementIconBg\");\r\n                container.addView(achievementIconBg);\r\n                icon = new AchievementIconView(context);\r\n                icon.setPadding(convertDpToPixel(7), convertDpToPixel(7), convertDpToPixel(7), convertDpToPixel(7));\r\n                LayoutParams achievementIconLP = new LayoutParams(largeSize, largeSize);\r\n                icon.setMaxWidth(largeSize);\r\n                icon.setLayoutParams(achievementIconLP);\r\n                icon.setTag(\"achievementIcon\");\r\n                achievementIconBg.addView(icon);\r\n                LinearLayout textContainer = new LinearLayout(context);\r\n                textContainer.setClipToPadding(false);\r\n                textContainer.setClipChildren(false);\r\n                textContainer.setOrientation(VERTICAL);\r\n                textContainer.setTag(\"textContainer\");\r\n                LayoutParams textContainerLP = new LayoutParams(-2, -2);\r\n                textContainer.setLayoutParams(textContainerLP);\r\n                textContainerLP.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);\r\n                container.addView(textContainer);\r\n\r\n                container.setTag(\"achievementBody\");\r\n                titleTextView = new TextView(context);\r\n                titleTextView.setText(\"Title\");\r\n                titleTextView.setMaxLines(1);\r\n                LayoutParams titleLP = new LayoutParams(-2, -2);\r\n                titleTextView.setLayoutParams(titleLP);\r\n                titleTextView.setTag(\"title\");\r\n                subtitleTextView = new ScrollTextView(context);\r\n                subtitleTextView.setText(\"Subtitle\");\r\n                subtitleTextView.setVisibility(GONE);\r\n                subtitleTextView.setLayoutParams(titleLP);\r\n                subtitleTextView.setMaxLines(1);\r\n                subtitleTextView.setTag(\"subtitle\");\r\n                textContainer.addView(titleTextView);\r\n                textContainer.addView(subtitleTextView);\r\n                achievementLayout.addView(container);\r\n\r\n\r\n                if (mainViewLP == null) {\r\n                    mainViewLP = new WindowManager.LayoutParams(\r\n                            WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT,\r\n                            WindowOverlayCompat.TYPE_SYSTEM_ERROR, focusable,\r\n                            PixelFormat.TRANSLUCENT);\r\n                }\r\n\r\n                if (titleTextView != null) {\r\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && isLarge) {\r\n                        titleTextView.setGravity(View.TEXT_ALIGNMENT_CENTER);\r\n                    }\r\n                    titleTextView.setSingleLine(true);\r\n                    titleTextView.addTextChangedListener(new TextWatcher() {\r\n                        @Override\r\n                        public void beforeTextChanged(CharSequence s, int start, int count, int after) {\r\n                        }\r\n\r\n                        @Override\r\n                        public void onTextChanged(CharSequence s, int start, int before, int count) {\r\n                        }\r\n\r\n                        @Override\r\n                        public void afterTextChanged(Editable s) {\r\n                            ((TextView) achievementLayout.findViewWithTag(\"titleFake\")).setText(titleTextView.getText());\r\n                        }\r\n                    });\r\n                }\r\n                if (subtitleTextView != null) {\r\n                    subtitleTextView.setSingleLine(true);\r\n                    subtitleTextView.addTextChangedListener(new TextWatcher() {\r\n                        @Override\r\n                        public void beforeTextChanged(CharSequence s, int start, int count, int after) {\r\n                        }\r\n\r\n                        @Override\r\n                        public void onTextChanged(CharSequence s, int start, int before, int count) {\r\n                        }\r\n\r\n                        @Override\r\n                        public void afterTextChanged(Editable s) {\r\n                            ((TextView) achievementLayout.findViewWithTag(\"subtitleFake\")).setText(subtitleTextView.getText());\r\n                        }\r\n                    });\r\n                }\r\n                initiatedGlobalFields = true;\r\n            }\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Set to true if you want the popup to be swipeable\r\n     *\r\n     * @param dismissible true for swipe to dismiss behaviour\r\n     */\r\n    public void setDismissible(boolean dismissible) {\r\n        this.dismissible = dismissible;\r\n        if (dismissible) {\r\n            achievementLayout.setOnTouchListener(new SwipeDismissTouchListener());\r\n            container.setOnTouchListener(new SwipeDismissTouchListener());\r\n        } else {\r\n            achievementLayout.setOnTouchListener(null);\r\n            container.setOnTouchListener(null);\r\n        }\r\n    }\r\n\r\n    private int getTargetWidth(AchievementData data) {\r\n        View textContainerFake = achievementLayout.findViewWithTag(\"textContainerFake\");\r\n        ((TextView) textContainerFake.findViewWithTag(\"titleFake\")).setText(data.getTitle());\r\n        ((TextView) textContainerFake.findViewWithTag(\"subtitleFake\")).setText(data.getSubtitle());\r\n        textContainerFake.measure(MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);\r\n        return textContainerFake.getMeasuredWidth();\r\n    }\r\n\r\n    private void buildAchievement() {\r\n        initGlobalFields();\r\n        int padding;\r\n        if (isLarge) {\r\n            initialSize = largeSize;\r\n            padding = paddingLarge;\r\n        } else {\r\n            initialSize = smallSize;\r\n            padding = paddingSmall;\r\n        }\r\n        ((View) icon.getParent()).invalidate();\r\n        icon.setPadding(padding, padding, padding, padding);\r\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\r\n            container.setElevation(elevation);\r\n        }\r\n        titleTextView.addTextChangedListener(new TextWatcher() {\r\n            @Override\r\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\r\n            }\r\n\r\n            @Override\r\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\r\n            }\r\n\r\n            @Override\r\n            public void afterTextChanged(Editable s) {\r\n                if (s == null || s.length() == 0) {\r\n                    titleTextView.setVisibility(GONE);\r\n                } else {\r\n                    titleTextView.setVisibility(View.VISIBLE);\r\n                }\r\n            }\r\n        });\r\n        final TextView fakeTitle = (achievementLayout.findViewWithTag(\"titleFake\"));\r\n        fakeTitle.addTextChangedListener(new TextWatcher() {\r\n            @Override\r\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\r\n            }\r\n\r\n            @Override\r\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\r\n            }\r\n\r\n            @Override\r\n            public void afterTextChanged(Editable s) {\r\n                if (s == null || s.length() == 0) {\r\n                    fakeTitle.setVisibility(GONE);\r\n                } else {\r\n                    fakeTitle.setVisibility(View.VISIBLE);\r\n                }\r\n            }\r\n        });\r\n        final TextView fakeSubTitle = (achievementLayout.findViewWithTag(\"subtitleFake\"));\r\n        fakeSubTitle.addTextChangedListener(new TextWatcher() {\r\n            @Override\r\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\r\n            }\r\n\r\n            @Override\r\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\r\n            }\r\n\r\n            @Override\r\n            public void afterTextChanged(Editable s) {\r\n                if (s == null || s.length() == 0) {\r\n                    fakeSubTitle.setVisibility(GONE);\r\n                } else {\r\n                    fakeSubTitle.setVisibility(View.VISIBLE);\r\n                }\r\n            }\r\n        });\r\n        subtitleTextView.addTextChangedListener(new TextWatcher() {\r\n            @Override\r\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\r\n            }\r\n\r\n            @Override\r\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\r\n            }\r\n\r\n            @Override\r\n            public void afterTextChanged(Editable s) {\r\n                if (s == null || s.length() == 0) {\r\n                    subtitleTextView.setVisibility(GONE);\r\n                } else subtitleTextView.setVisibility(View.VISIBLE);\r\n            }\r\n        });\r\n        titleTextView.setAlpha(0f);\r\n        titleTextView.setTranslationY(translationY);\r\n        subtitleTextView.setTranslationY(translationY);\r\n        subtitleTextView.setAlpha(0f);\r\n        container.setScaleY(0f);\r\n        container.setScaleX(0f);\r\n        container.setVisibility(GONE);\r\n\r\n        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();\r\n\r\n        matchParent = Math.min(displayMetrics.widthPixels, displayMetrics.heightPixels) - margin;\r\n        //stretched = 900;\r\n        //  textContainer.setVisibility(View.GONE);\r\n\r\n        View textContainer = achievementLayout.findViewWithTag(\"textContainer\");\r\n        if (textContainer != null) {\r\n            textContainer.setPadding(convertDpToPixel(10) + (initialSize), 0, convertDpToPixel(20), 0);\r\n            achievementLayout.findViewWithTag(\"textContainerFake\").setPadding(textContainer.getPaddingLeft(), textContainer.getPaddingTop(), textContainer.getPaddingRight(), textContainer.getPaddingBottom());\r\n        }\r\n        icon.setMaxWidth(initialSize);\r\n        container.getLayoutParams().width = container.getLayoutParams().height = icon.getLayoutParams().height = icon.getLayoutParams().width = ((View) icon.getParent()).getLayoutParams().height = ((View) icon.getParent()).getLayoutParams().width = initialSize;\r\n        container.requestLayout();\r\n\r\n\r\n        if (alignTop) {\r\n            mainViewLP.gravity = Gravity.TOP;\r\n        } else {\r\n            mainViewLP.gravity = Gravity.BOTTOM;\r\n        }\r\n        // No scrim for Android P\r\n        if (alignTop && VERSION.SDK_INT < 28 && (achievementLayout.getBackground() == null || !(achievementLayout.getBackground() instanceof GradientDrawable))) {\r\n            GradientDrawable scrim = new GradientDrawable();\r\n            scrim.setShape(GradientDrawable.RECTANGLE);\r\n            scrim.setColors(new int[]{0x40000000, 0});\r\n            scrim.setAlpha(0);\r\n            achievementLayout.setBackground(scrim);\r\n            achievementLayout.setClipToPadding(false);\r\n        } else if (!alignTop) {\r\n            achievementLayout.setBackground(null);\r\n        }\r\n\r\n        final WindowManager manager = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE));\r\n        if (manager == null) throw new RuntimeException(\"No window manager found\");\r\n        manager.addView(achievementLayout, mainViewLP);\r\n        added = true;\r\n    }\r\n\r\n    private void setTextColor(int textColor) {\r\n        subtitleTextView.setTextColor(Color.parseColor(\"#B2FFFFFF\"));\r\n        titleTextView.setTextColor(Color.rgb(Color.red(textColor), Color.green(textColor), Color.blue(textColor)));\r\n    }\r\n\r\n    /**\r\n     * use listeners instead\r\n     */\r\n    @Deprecated\r\n    public AchievementUnlocked createViews() {\r\n        buildAchievement();\r\n        return this;\r\n    }\r\n\r\n    public void show(Collection<AchievementData> data) {\r\n        show(data.toArray(new AchievementData[0]));\r\n    }\r\n\r\n    /**\r\n     * Pop the popup with the supplied data\r\n     *\r\n     * @param data data to be shown\r\n     */\r\n    public void show(AchievementData... data) {\r\n        if (data == null || data.length == 0) {\r\n            return;\r\n        }\r\n        //Check permission first\r\n        if (VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(context)) {\r\n            if (DEBUG)\r\n                Toast.makeText(context, \"'canDrawOverlays' permission is not granted\", Toast.LENGTH_LONG).show();\r\n            Log.e(TAG, \"'canDrawOverlays' permission is not granted\");\r\n            return;\r\n        }\r\n        //Don't bother if powersaving is on\r\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {\r\n            final PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);\r\n            isPowerSavingModeOn = powerManager != null && powerManager.isPowerSaveMode();\r\n            if (isPowerSavingModeOn) {\r\n                Log.w(TAG, \"Power saving is on, AU was canceled\");\r\n                return;\r\n            }\r\n        }\r\n\r\n        if (added) {\r\n            if (achievements != null) {\r\n                achievements = concat(achievements, data);\r\n            } else\r\n                achievements = data;\r\n            return;\r\n        }\r\n        dismissWithoutAnimation();\r\n        this.achievements = data;\r\n        buildAchievement();\r\n        setContainerBg(achievements[0].getBackgroundColor());\r\n        if (listener != null)\r\n            listener.onViewCreated(this, data);\r\n        prepareMorphism();\r\n    }\r\n\r\n    /**\r\n     * Instantly remove the popup view from window manager\r\n     */\r\n    public void dismissWithoutAnimation() {\r\n        removeView();\r\n        if (listener != null)\r\n            listener.onAchievementDismissed(this);\r\n    }\r\n\r\n    private void removeListeners(Animator animatorSet) {\r\n        if (animatorSet == null) return;\r\n        if (animatorSet instanceof AnimatorSet && !((AnimatorSet) animatorSet).getChildAnimations().isEmpty())\r\n            for (Animator animator : ((AnimatorSet) animatorSet).getChildAnimations()) {\r\n                removeListeners(animator);\r\n            }\r\n        else {\r\n            if (animatorSet instanceof ValueAnimator) {\r\n                ((ValueAnimator) animatorSet).removeAllUpdateListeners();\r\n            }\r\n            animatorSet.removeAllListeners();\r\n            animatorSet.end();\r\n            animatorSet.cancel();\r\n        }\r\n    }\r\n\r\n    private AchievementData[] concat(AchievementData[] a, AchievementData[] b) {\r\n        int aLen = a.length;\r\n        int bLen = b.length;\r\n        AchievementData[] c = new AchievementData[aLen + bLen];\r\n        System.arraycopy(a, 0, c, 0, aLen);\r\n        System.arraycopy(b, 0, c, aLen, bLen);\r\n        return c;\r\n    }\r\n\r\n    @SuppressLint(\"ObsoleteSdkInt\")\r\n    private void setBackground(View v, Drawable d) {\r\n        v.setBackground(d);\r\n    }\r\n\r\n    private void removeView() {\r\n        if (!added) return;\r\n        index = 0;\r\n        setSwipeEffect(0);\r\n\r\n        hasBeenDismissed = false;\r\n        isPowerSavingModeOn = false;\r\n        icon.setVisibility(View.VISIBLE);\r\n        setBackground(((View) icon.getParent()), null);\r\n        setBackground(container, null);\r\n        setBackground(icon, null);\r\n        isLarge = true;\r\n        alignTop = true;\r\n        isRounded = true;\r\n        icon.setOnClickListener(null);\r\n        container.setOnClickListener(null);\r\n        achievementLayout.setOnClickListener(null);\r\n        achievementLayout.setVisibility(View.VISIBLE);\r\n        //    container.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;\r\n        container.setOnTouchListener(null);\r\n        container.setVisibility(View.VISIBLE);\r\n        container.setTranslationX(0f);\r\n        container.setAlpha(1f);\r\n        achievementLayout.setAlpha(1f);\r\n        setDismissible(false);\r\n        listener = null;\r\n        ((View) icon.getParent()).setBackground(null);\r\n        dismissed = false;\r\n        final WindowManager manager = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE));\r\n\r\n        try {\r\n            if (manager != null) manager.removeView(achievementLayout);\r\n            added = false;\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n            // *shrug emoji*\r\n            //there's no way to check if view is already added to windowManager or not, probably the exception is nullPointerException where achievementLayout is null\r\n            //best thing we could do is to check added boolean\r\n        }\r\n    }\r\n\r\n    private int clamp(int val, int min, int max) {\r\n        return Math.max(min, Math.min(max, val));\r\n    }\r\n\r\n    private int getStartValue(int start) {\r\n        return clamp(start, initialSize, matchParent);\r\n    }\r\n\r\n    private int getEndValue(int end) {\r\n        return Math.min(end, matchParent);\r\n    }\r\n\r\n    private ValueAnimator getContainerStretchAnimation(int start, int end) {\r\n        final ValueAnimator containerStretch = ValueAnimator.ofInt(getStartValue(start), getEndValue(end));\r\n        containerStretch.addUpdateListener(valueAnimator -> {\r\n            if (!dismissed) {\r\n                int val = (Integer) valueAnimator.getAnimatedValue();\r\n                ViewGroup.LayoutParams layoutParams = container.getLayoutParams();\r\n                layoutParams.width = val;\r\n                currentContainerWidth = val;\r\n                container.setLayoutParams(layoutParams);\r\n            }\r\n        });\r\n        containerStretch.setInterpolator(TIME_INTERPOLATOR);\r\n        containerStretch.setDuration(getScaledDuration(300));\r\n        return containerStretch;\r\n    }\r\n\r\n    private GradientDrawableWithColors getContainerBg() {\r\n        if ((container.getBackground()) instanceof GradientDrawableWithColors)\r\n            return (GradientDrawableWithColors) (container.getBackground());\r\n        GradientDrawableWithColors iconBackground = new GradientDrawableWithColors();\r\n        if (isRounded)\r\n            iconBackground.setCornerRadius(initialSize / 2f);\r\n        else iconBackground.setCornerRadius(convertDpToPixel(2));\r\n        return iconBackground;\r\n    }\r\n\r\n    private void setContainerBg(int color) {\r\n        Drawable bgDrawable = container.getBackground();\r\n        if (bgDrawable instanceof GradientDrawable)\r\n            ((GradientDrawableWithColors) bgDrawable).setColor(color);\r\n        else {\r\n            GradientDrawableWithColors iconBackground = getContainerBg();\r\n            iconBackground.setColor(color);\r\n            setBackground(container, iconBackground);\r\n        }\r\n    }\r\n\r\n    private int getIconBgColor(int defaultColor) {\r\n        Drawable bgDrawable = ((View) icon.getParent()).getBackground();\r\n        if (bgDrawable instanceof GradientDrawable)\r\n            return ((GradientDrawableWithColors) bgDrawable).getGradientColor();\r\n        return defaultColor;\r\n    }\r\n\r\n    private int getContainerBgColor(int defaultColor) {\r\n        Drawable bgDrawable = container.getBackground();\r\n        if (bgDrawable instanceof GradientDrawable)\r\n            return ((GradientDrawableWithColors) bgDrawable).getGradientColor();\r\n        return defaultColor;\r\n    }\r\n\r\n    private GradientDrawableWithColors getIconBg() {\r\n        if ((((View) icon.getParent()).getBackground()) instanceof GradientDrawable)\r\n            return (GradientDrawableWithColors) (((View) icon.getParent()).getBackground());\r\n        GradientDrawableWithColors iconBackground = new GradientDrawableWithColors();\r\n        if (isRounded)\r\n            iconBackground.setShape(GradientDrawable.OVAL);\r\n        else iconBackground.setCornerRadius(convertDpToPixel(2));\r\n        return iconBackground;\r\n    }\r\n\r\n    private void setIconBg(int color) {\r\n        Drawable bgDrawable = (((View) icon.getParent()).getBackground());\r\n        if (bgDrawable instanceof GradientDrawable)\r\n            bgDrawable.setColorFilter(Color.argb(bgDrawable.getAlpha(), Color.red(color), Color.green(color), Color.blue(color)), PorterDuff.Mode.SRC_IN);\r\n        else {\r\n            GradientDrawableWithColors iconBackground = getIconBg();\r\n            iconBackground.setColor(color);\r\n            setBackground(((View) icon.getParent()), iconBackground);\r\n        }\r\n    }\r\n\r\n    private AnimatorSet getExitAnimation() {\r\n        final ObjectAnimator containerScale = ObjectAnimator.ofFloat(container, View.SCALE_X, 1f, 0f);\r\n        containerScale.addUpdateListener(animation -> {\r\n            if (!dismissed)\r\n                container.setScaleY((float) animation.getAnimatedValue());\r\n        });\r\n        containerScale.setDuration(getScaledDuration(250));\r\n        containerScale.setStartDelay(100);\r\n        containerScale.setInterpolator(anticipateInterpolator);\r\n        boolean scrimIsAvailable = alignTop && achievementLayout.getBackground() != null;\r\n        ObjectAnimator scrim = null;\r\n        if (scrimIsAvailable) {\r\n            scrim = ObjectAnimator.ofInt(achievementLayout.getBackground(), \"alpha\", 255, 0);\r\n        }\r\n        AnimatorSet out = new AnimatorSet();\r\n        if (scrim != null)\r\n            out.playTogether(containerScale, scrim);\r\n        else out.play(containerScale);\r\n        AnimatorSet set = new AnimatorSet();\r\n        set.playSequentially(getContainerStretchAnimation(Math.min(container.getMeasuredWidth(), matchParent), initialSize), out);\r\n        set.addListener(new AnimatorListenerAdapter() {\r\n            @Override\r\n            public void onAnimationEnd(Animator animation) {\r\n                try {\r\n                    super.onAnimationEnd(animation);\r\n                    dismissWithoutAnimation();\r\n                } catch (Exception e) {\r\n                    //\r\n                }\r\n            }\r\n        });\r\n        return set;\r\n    }\r\n\r\n    private int getContainerBackgroundColor() {\r\n        if ((container).getBackground() != null)\r\n            if ((container).getBackground() instanceof GradientDrawableWithColors)\r\n                return ((GradientDrawableWithColors) (container).getBackground()).getGradientColor();\r\n        return 0xffffffff;\r\n    }\r\n\r\n    private int getSubtitleLines(String subtitleRaw) {\r\n        if (subtitleRaw.contains(\"\\n\"))\r\n            return countMatches(subtitleRaw, \"\\n\") + 1;\r\n        return 1;\r\n    }\r\n\r\n    private boolean isBlank(final String cs) {\r\n        int strLen;\r\n        if (cs == null || (strLen = cs.length()) == 0) {\r\n            return true;\r\n        }\r\n        for (int i = 0; i < strLen; i++) {\r\n            if (!Character.isWhitespace(cs.charAt(i))) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    }\r\n\r\n    private boolean allClear(AnimatorSet[] sets) {\r\n        for (AnimatorSet set : sets) {\r\n            if (set == null) return false;\r\n        }\r\n        return true;\r\n    }\r\n\r\n    private AnimatorSet morphData() {\r\n        AnimatorSet sets = new AnimatorSet();\r\n        AchievementData data = achievements[index];\r\n        sets.play(animateData(achievements[index]));\r\n        sets.addListener(new AnimatorListenerAdapter() {\r\n            @Override\r\n            public void onAnimationEnd(Animator animation) {\r\n                try {\r\n                    super.onAnimationEnd(animation);\r\n                    if (AchievementUnlocked.this.achievements != null && !hasBeenDismissed && AchievementUnlocked.this.achievements.length > 0 && index + 1 < AchievementUnlocked.this.achievements.length) {\r\n                        index++;\r\n                        morphData().start();\r\n                    } else\r\n                        getExitAnimation().start();\r\n                } catch (Exception e) {\r\n                    //\r\n                }\r\n            }\r\n        });\r\n        return sets;\r\n    }\r\n\r\n    private AnimatorSet animateData(final AchievementData data) {\r\n        final AnimatorSet backgroundAnimators = new AnimatorSet();\r\n        final AnimatorSet inAnimation = new AnimatorSet();\r\n        final AnimatorSet outAnimation = new AnimatorSet();\r\n        final AnimatorSet result = new AnimatorSet();\r\n\r\n        ObjectAnimator titleIn, subtitleIn = null, titleOut, subtitleOut = null;\r\n        if ((container.getTag() != null && container.getTag() != data)) {\r\n            int previousBgColor = 0xffffffff;\r\n            int previousIconBgColor = 0x30ffffff;\r\n            if (index == 0) {\r\n                previousBgColor = data.getBackgroundColor();\r\n                previousIconBgColor = data.getIconBackgroundColor();\r\n            } else if (index > 0 && index < achievements.length) {\r\n                previousBgColor = achievements[index - 1].getBackgroundColor();\r\n                previousIconBgColor = achievements[index - 1].getIconBackgroundColor();\r\n            }\r\n            ValueAnimator iconBgColor = ValueAnimator.ofInt(getIconBgColor(previousIconBgColor), data.getIconBackgroundColor());\r\n            iconBgColor.setEvaluator(new ArgbEvaluator());\r\n            iconBgColor.addUpdateListener(animation -> {\r\n                if (!dismissed)\r\n                    setIconBg((int) animation.getAnimatedValue());\r\n            });\r\n            ValueAnimator bgColor = ValueAnimator.ofInt(getContainerBgColor(previousBgColor), data.getBackgroundColor());\r\n            bgColor.setEvaluator(new ArgbEvaluator());\r\n            bgColor.addUpdateListener(animation -> {\r\n                if (!dismissed)\r\n                    setContainerBg((int) animation.getAnimatedValue());\r\n            });\r\n            bgColor.addListener(new AnimatorListenerAdapter() {\r\n                @Override\r\n                public void onAnimationStart(Animator animation) {\r\n                    super.onAnimationStart(animation);\r\n                    if (index > 0) setIcon(data);\r\n                }\r\n            });\r\n\r\n            backgroundAnimators.play(iconBgColor).with(bgColor);\r\n            backgroundAnimators.setInterpolator(TIME_INTERPOLATOR);\r\n            backgroundAnimators.setDuration(getScaledDuration(300));\r\n\r\n\r\n        }\r\n        titleIn = ObjectAnimator.ofFloat(titleTextView, View.TRANSLATION_Y, translationY, 0);\r\n        titleIn.addUpdateListener(animation -> {\r\n            if (dismissed) return;\r\n            titleTextView.setAlpha(animation.getAnimatedFraction());\r\n        });\r\n        titleIn.setDuration(getScaledDuration(300));\r\n        titleIn.setInterpolator(TIME_INTERPOLATOR);\r\n\r\n        titleOut = ObjectAnimator.ofFloat(titleTextView, View.TRANSLATION_Y, 0, translationY);\r\n        titleOut.addUpdateListener(animation -> {\r\n            if (dismissed) return;\r\n            titleTextView.setAlpha(1f - animation.getAnimatedFraction());\r\n        });\r\n        titleOut.setInterpolator(accelerateInterpolator);\r\n\r\n        final boolean dataHasSubtitle = dataHasSubtitle(data);\r\n        //indicates that scrolling is needed\r\n        final boolean overFlow = (matchParent) < getTargetWidth(data);\r\n        final int startScrollingDelay = dataHasSubtitle ? 800 : 0;\r\n        final int scrollDistance = overFlow ? Math.abs(getTargetWidth(data) - matchParent) : 0;\r\n        //if the text is scrolling, pause for a while at the end before collapsing\r\n        final int endReadingDelay = overFlow ? 400 : 0;\r\n\r\n        final int duration;\r\n        if (overFlow) {\r\n            final float density = context.getResources().getDisplayMetrics().density;\r\n            float dpPerSec = mPxPerSeconds * density;\r\n            //if the scroll distance is short, then use standard readingDelay value since the animation\r\n            //will run too quickly and user won't be abel to read the contents\r\n            duration = scrollDistance <= matchParent / 4 ? readingDelay : Math.round(scrollDistance * 1000 / dpPerSec);\r\n        } else {\r\n            duration = readingDelay;\r\n        }\r\n\r\n        ValueAnimator stretch = getContainerStretchAnimation(container.getMeasuredWidth(), getTargetWidth(data));\r\n\r\n        if (dataHasSubtitle) {\r\n            subtitleIn = ObjectAnimator.ofFloat(subtitleTextView, View.TRANSLATION_Y, translationY, 0);\r\n            subtitleIn.addUpdateListener(animation -> {\r\n                if (dismissed) return;\r\n                subtitleTextView.setAlpha(animation.getAnimatedFraction());\r\n            });\r\n            subtitleIn.setInterpolator(TIME_INTERPOLATOR);\r\n            subtitleIn.setStartDelay(getScaledDuration(150));\r\n            subtitleIn.setInterpolator(TIME_INTERPOLATOR);\r\n            subtitleIn.setDuration(getScaledDuration(300));\r\n        }\r\n        //use previousWidth better than real-time measuring to increase performance\r\n\r\n        if (dataHasSubtitle) {\r\n            AnimatorSet textViews = new AnimatorSet();\r\n            //this null check is useful when seperating subtitle different lines\r\n            //into different poups\r\n            if (titleIn != null)\r\n                textViews.playTogether(titleIn, subtitleIn);\r\n            else textViews.playTogether(subtitleIn);\r\n\r\n            inAnimation.play(stretch).with(backgroundAnimators).before(textViews);\r\n        } else {\r\n            if (titleIn != null)\r\n                inAnimation.play(stretch).with(backgroundAnimators).before(titleIn);\r\n            else inAnimation.playTogether(backgroundAnimators, stretch);\r\n\r\n        }\r\n        // inAnimation.setInterpolator(interpolator);\r\n        if (dataHasSubtitle) {\r\n            subtitleOut = ObjectAnimator.ofFloat(subtitleTextView, View.TRANSLATION_Y, 0, translationY);\r\n            subtitleOut.addUpdateListener(animation -> {\r\n                if (dismissed) return;\r\n                subtitleTextView.setAlpha(1f - animation.getAnimatedFraction());\r\n            });\r\n            subtitleOut.addListener(new AnimatorListenerAdapter() {\r\n                @Override\r\n                public void onAnimationEnd(Animator animation) {\r\n                    super.onAnimationEnd(animation);\r\n                    subtitleTextView.stopScrolling();\r\n\r\n                }\r\n            });\r\n            subtitleOut.setInterpolator(accelerateInterpolator);\r\n\r\n        }\r\n\r\n        if (dataHasSubtitle) {\r\n            if (titleOut != null) {\r\n                titleOut.setStartDelay(getScaledDuration(150));\r\n                outAnimation.playTogether(subtitleOut, titleOut);\r\n            } else outAnimation.play(subtitleOut);\r\n        } else {\r\n            if (titleOut != null)\r\n                outAnimation.play(titleOut);\r\n        }\r\n        final String title = data.getTitle(), subtitle = data.getSubtitle();\r\n        result.addListener(new AnimatorListenerAdapter() {\r\n            @Override\r\n            public void onAnimationStart(Animator animation) {\r\n                super.onAnimationStart(animation);\r\n                if (listener != null)\r\n                    listener.onAchievementMorphed(AchievementUnlocked.this, data);\r\n                if (data.getPopUpOnClickListener() != null || dismissible) {\r\n                    mainViewLP.flags = focusable;\r\n                } else {\r\n                    mainViewLP.flags = nonFocusable;\r\n                }\r\n                container.setOnClickListener(data.getPopUpOnClickListener());\r\n                final WindowManager manager = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE));\r\n                if (manager != null && added)\r\n                    manager.updateViewLayout(achievementLayout, mainViewLP);\r\n                subtitleTextView.setText(subtitle);\r\n                subtitleTextView.updateScroller(scrollDistance);\r\n                titleTextView.setText(title);\r\n                setTextColor(data.getTextColor());\r\n            }\r\n\r\n\r\n        });\r\n\r\n        ScrollTextView fake = (achievementLayout.findViewWithTag(\"subtitleFake\"));\r\n        fake.setText(data.getSubtitle());\r\n\r\n        subtitleTextView.setDurations(getScaledDuration(duration + endReadingDelay), getScaledDuration(startScrollingDelay));\r\n        outAnimation.setStartDelay(getScaledDuration(duration + endReadingDelay + startScrollingDelay));\r\n        outAnimation.setDuration(getScaledDuration(300));\r\n        result.playSequentially(inAnimation, outAnimation);\r\n        result.setInterpolator(TIME_INTERPOLATOR);\r\n        container.setTag(data);\r\n        return result;\r\n    }\r\n\r\n    private void prepareMorphism() {\r\n        if (achievements == null || achievements.length == 0)\r\n            return;\r\n        index = 0;\r\n        AnimatorSet scene = new AnimatorSet();\r\n        scene.playSequentially(getEntranceAnimation(achievements[0]), morphData());\r\n\r\n        scene.start();\r\n    }\r\n\r\n    private boolean dataHasSubtitle(AchievementData data) {\r\n        return data.getSubtitle() != null && data.getSubtitle().length() > 0 && !data.getSubtitle().isEmpty();\r\n    }\r\n\r\n    private AnimatorSet getEntranceAnimation(final AchievementData data) {\r\n        final int iconBG = data.getIconBackgroundColor();\r\n        // final Drawable iconDrawable = data.getIcon();\r\n        // final int bg = data.getBackgroundColor();\r\n        //ValueAnimator stretch = getContainerStretchAnimation(initialSize, getTargetWidth(data));\r\n        ObjectAnimator containerScale = ObjectAnimator.ofFloat(container, View.SCALE_X, 0f, 1f);\r\n        containerScale.addUpdateListener(animation -> {\r\n            if (dismissed) return;\r\n            container.setScaleY((float) animation.getAnimatedValue());\r\n        });\r\n        containerScale.setDuration(getScaledDuration(250));\r\n        containerScale.setInterpolator(overshootInterpolator);\r\n        boolean scrimIsAvailable = alignTop && achievementLayout.getBackground() != null;\r\n        ObjectAnimator scrim = null;\r\n        if (scrimIsAvailable) {\r\n            scrim = ObjectAnimator.ofInt(achievementLayout.getBackground(), \"alpha\", 0, 255);\r\n        }\r\n        AnimatorSet set = new AnimatorSet();\r\n        if (scrim != null)\r\n            set.playTogether(containerScale, scrim);\r\n        else set.play(containerScale);\r\n        set.addListener(new AnimatorListenerAdapter() {\r\n            @Override\r\n            public void onAnimationStart(Animator animation) {\r\n                super.onAnimationStart(animation);\r\n                if (Color.alpha(iconBG) > 0) {\r\n                    setIconBg(iconBG);\r\n                } else {\r\n                    View textContainer = (View) titleTextView.getParent();\r\n                    textContainer.setPadding((isLarge ? largeSize : smallSize), textContainer.getPaddingTop(), textContainer.getPaddingRight(), textContainer.getPaddingBottom());\r\n                    achievementLayout.findViewWithTag(\"textContainerFake\").setPadding(textContainer.getPaddingLeft(), textContainer.getPaddingTop(), textContainer.getPaddingRight(), textContainer.getPaddingBottom());\r\n                }\r\n                container.setVisibility(View.VISIBLE);\r\n                setIcon(data);\r\n            }\r\n        });\r\n        return set;\r\n    }\r\n\r\n    private void setIcon(AchievementData data) {\r\n        if (data == null) {\r\n            //  icon.setDrawable(null);\r\n            return;\r\n        }\r\n        if (data.getState() == AchievementIconView.AchievementIconViewStates.SAME_DRAWABLE)\r\n            return;\r\n        Drawable d = data.getIcon();\r\n        if (d != null) {\r\n            if (data.getState() == AchievementIconView.AchievementIconViewStates.FADE_DRAWABLE)\r\n                icon.fadeDrawable(d);\r\n            else icon.setDrawable(d);\r\n\r\n        } else icon.setDrawable(null);\r\n    }\r\n\r\n    private void setSwipeEffect(float amount) {\r\n        container.setTranslationX(amount);\r\n    }\r\n\r\n    private int getStatusBarHeight() {\r\n        int result = 0;\r\n        int resourceId = Resources.getSystem().getIdentifier(\"status_bar_height\", \"dimen\", \"android\");\r\n        if (resourceId > 0) {\r\n            result = Resources.getSystem().getDimensionPixelSize(resourceId);\r\n        }\r\n        return result;\r\n    }\r\n\r\n    /* used by the abstract class adapter */\r\n    @SuppressWarnings(\"unused\")\r\n    interface AchievementListener {\r\n        void onViewCreated(AchievementUnlocked achievement, AchievementData[] data);\r\n\r\n        void onAchievementMorphed(AchievementUnlocked achievement, AchievementData data);\r\n\r\n        void onAchievementDismissed(AchievementUnlocked achievement);\r\n    }\r\n\r\n    /**\r\n     * Class that holds the data to be displayed by\r\n     * AchievementUnlocked object using the\r\n     * {@link AchievementUnlocked#show(AchievementData...)} method\r\n     */\r\n    public static class AchievementData {\r\n        private String title = \"\", subtitle;\r\n        private Drawable icon;\r\n        private int textColor = 0xff000000, backgroundColor = 0xffffffff, iconBackgroundColor = 0x0;\r\n        private View.OnClickListener onClickListener;\r\n        private AchievementIconView.AchievementIconViewStates state = null;\r\n\r\n        public static AchievementData copyFrom(AchievementData data) {\r\n            AchievementData result = new AchievementData();\r\n            result.setTitle(data.getTitle());\r\n            result.setSubtitle(data.getSubtitle());\r\n            result.setIcon(data.getIcon());\r\n            result.setState(data.getState());\r\n            result.setBackgroundColor(data.getBackgroundColor());\r\n            result.setIconBackgroundColor(data.getIconBackgroundColor());\r\n            result.setTextColor(data.getTextColor());\r\n            result.setPopUpOnClickListener(data.getPopUpOnClickListener());\r\n            return result;\r\n        }\r\n\r\n        public View.OnClickListener getPopUpOnClickListener() {\r\n            return onClickListener;\r\n        }\r\n\r\n        /**\r\n         * Assign a per-data onclick listener to the popup\r\n         *\r\n         * @return same AchievementData object\r\n         */\r\n        public AchievementData setPopUpOnClickListener(View.OnClickListener onClickListener) {\r\n            this.onClickListener = onClickListener;\r\n            return this;\r\n        }\r\n\r\n        public int getTextColor() {\r\n            return textColor;\r\n        }\r\n\r\n        public AchievementData setTextColor(int textColor) {\r\n            this.textColor = textColor;\r\n            return this;\r\n        }\r\n\r\n        public String getTitle() {\r\n            return title;\r\n        }\r\n\r\n        public AchievementData setTitle(String title) {\r\n            this.title = title;\r\n            return this;\r\n        }\r\n\r\n        public String getSubtitle() {\r\n            return subtitle;\r\n        }\r\n\r\n        public AchievementData setSubtitle(String subtitle) {\r\n            this.subtitle = subtitle;\r\n            return this;\r\n        }\r\n\r\n        public AchievementIconView.AchievementIconViewStates getState() {\r\n            return state;\r\n        }\r\n\r\n        /**\r\n         * Indicate whether the popup icon should stay the same or\r\n         * fade when showing different Achievement data. Default is\r\n         * null which is the same as SAME_DRAWABLE.\r\n         * When FADE_DRAWABLE is set, the icon will animate change to the\r\n         * next data icon.\r\n         *\r\n         * @param state either of these two: FADE_DRAWABLE, SAME_DRAWABLE\r\n         */\r\n        public void setState(AchievementIconView.AchievementIconViewStates state) {\r\n            this.state = state;\r\n        }\r\n\r\n        public Drawable getIcon() {\r\n            return icon;\r\n        }\r\n\r\n        /**\r\n         * Set popuup icon. Transparent one will be used if non is assigned\r\n         *\r\n         * @param icon icon drawable\r\n         * @return same AchievementData object\r\n         */\r\n        public AchievementData setIcon(Drawable icon) {\r\n            this.icon = icon;\r\n            return this;\r\n        }\r\n\r\n        int getBackgroundColor() {\r\n            return backgroundColor;\r\n        }\r\n\r\n        /**\r\n         * Set popup background color\r\n         *\r\n         * @param backgroundColor integer color of background\r\n         * @return same AchievementData object\r\n         */\r\n        public AchievementData setBackgroundColor(int backgroundColor) {\r\n            this.backgroundColor = backgroundColor;\r\n            return this;\r\n        }\r\n\r\n        int getIconBackgroundColor() {\r\n            return iconBackgroundColor;\r\n        }\r\n\r\n        /**\r\n         * Set the background of the popup's icon\r\n         *\r\n         * @param iconBackgroundColor integer color\r\n         * @return same AchievementData object\r\n         */\r\n        public AchievementData setIconBackgroundColor(int iconBackgroundColor) {\r\n            this.iconBackgroundColor = iconBackgroundColor;\r\n            return this;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Ticker text view used for subtitle view\r\n     */\r\n    @SuppressLint(\"AppCompatCustomView\")\r\n    @SuppressWarnings(\"unused\")\r\n    final static class ScrollTextView extends TextView {\r\n        private static final LinearInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();\r\n        private final ValueAnimator mScrollingAnimator = ValueAnimator.ofInt(0, 1);\r\n        private long mDuration, mStartOffset;\r\n\r\n        public ScrollTextView(Context context) {\r\n            super(context);\r\n            init();\r\n        }\r\n\r\n        public ScrollTextView(Context context, AttributeSet attrs) {\r\n            super(context, attrs);\r\n            init();\r\n        }\r\n\r\n        public ScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {\r\n            super(context, attrs, defStyleAttr);\r\n            init();\r\n        }\r\n\r\n        private void init() {\r\n            setSingleLine();\r\n        }\r\n\r\n\r\n        @Override\r\n        public void setVisibility(int visibility) {\r\n            super.setVisibility(visibility);\r\n            setSelected(visibility == VISIBLE);\r\n        }\r\n\r\n        @Override\r\n        public void setAlpha(float alpha) {\r\n            super.setAlpha(alpha);\r\n            if (alpha <= 0.1f) {\r\n                stopScrolling();\r\n            }\r\n        }\r\n\r\n        public void stopScrolling() {\r\n            if (mScrollingAnimator.isRunning())\r\n                mScrollingAnimator.cancel();\r\n        }\r\n\r\n        public void startScrolling() {\r\n            requestFocus();\r\n            setSelected(true);\r\n\r\n        }\r\n\r\n        @Override\r\n        protected void onDetachedFromWindow() {\r\n            super.onDetachedFromWindow();\r\n            stopScrolling();\r\n        }\r\n\r\n\r\n        /**\r\n         * Directly apply previously-calculated values instead of recalculating them\r\n         *\r\n         * @param scrollingDuration how many milliseconds shall the animator take to finish\r\n         *                          scrolling the overflown text\r\n         * @param startOffset       how many milliseconds before the animator starts\r\n         */\r\n        public void setDurations(long scrollingDuration, long startOffset) {\r\n            this.mDuration = scrollingDuration;\r\n            this.mStartOffset = startOffset;\r\n        }\r\n\r\n        /**\r\n         * Use previously-calculated values for efficiency\r\n         *\r\n         * @param scrollAmount previously-calculated horizontal scroll amount\r\n         */\r\n        void updateScroller(int scrollAmount) {\r\n            if (mScrollingAnimator.isRunning()) {\r\n                mScrollingAnimator.cancel();\r\n            }\r\n            if (scrollAmount == 0) return;\r\n            mScrollingAnimator.setIntValues(0, -scrollAmount);\r\n            mScrollingAnimator.removeAllListeners();\r\n            mScrollingAnimator.removeAllUpdateListeners();\r\n            mScrollingAnimator.addUpdateListener(animation -> scrollTo(-(Integer) animation.getAnimatedValue(), 0));\r\n            mScrollingAnimator.setDuration(mDuration);\r\n            //LINEAR_INTERPOLATOR must be used\r\n            mScrollingAnimator.setInterpolator(LINEAR_INTERPOLATOR);\r\n            mScrollingAnimator.setStartDelay(mStartOffset);\r\n            mScrollingAnimator.start();\r\n\r\n        }\r\n    }\r\n\r\n    /**\r\n     * GradientDrawable that saves the drawable colors; used for AU background\r\n     */\r\n    final static class GradientDrawableWithColors extends GradientDrawable {\r\n        private int mColor;\r\n\r\n        int getGradientColor() {\r\n            return mColor;\r\n        }\r\n\r\n        @Override\r\n        public void setColor(int argb) {\r\n            super.setColors(new int[]{argb, argb});\r\n            mColor = argb;\r\n        }\r\n\r\n        @Override\r\n        public void setColors(int[] colors) {\r\n            super.setColors(colors);\r\n            mColor = colors[0];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * ImageView that animates drawable change. It also scales\r\n     * according to the drawable size to make sure it doesn't clip\r\n     */\r\n    @SuppressLint(\"AppCompatCustomView\")\r\n    static class AchievementIconView extends ImageView {\r\n        public AchievementIconView(Context context) {\r\n            super(context);\r\n        }\r\n\r\n        public void setDrawable(final Drawable drawable) {\r\n            if (drawable == null) {\r\n                setImageDrawable(null);\r\n                return;\r\n            }\r\n            if (getScaleType() != ScaleType.CENTER_CROP) setScaleType(ScaleType.CENTER_CROP);\r\n\r\n            final float scaleX = 3.5f / (getMaxWidth() / drawable.getIntrinsicWidth());\r\n            final float scaleY = 3.5f / (getMaxWidth() / drawable.getIntrinsicHeight());\r\n\r\n            if (getDrawable() == null) {\r\n                setImageDrawable(drawable);\r\n                setScaleX(1 / Math.max(scaleX, scaleY));\r\n                setScaleY(1 / Math.max(scaleX, scaleY));\r\n            } else {\r\n                if (drawable.getAlpha() < 255)\r\n                    drawable.setAlpha(255);\r\n\r\n                animate()\r\n                        .scaleX(0f)\r\n                        .setDuration(AchievementUnlocked.getScaledDuration(200))\r\n                        .scaleY(0f)\r\n                        .alpha(0f)\r\n                        .withEndAction(() -> animate()\r\n                                .setDuration(AchievementUnlocked.getScaledDuration(200))\r\n                                .scaleX(1 / Math.max(scaleX, scaleY))\r\n                                .scaleY(1 / Math.max(scaleX, scaleY))\r\n                                .alpha(1f)\r\n                                .withStartAction(() -> setImageDrawable(drawable))\r\n                                .start())\r\n                        .start();\r\n            }\r\n        }\r\n\r\n        public void fadeDrawable(final Drawable drawable) {\r\n            if (drawable == null) {\r\n                setImageDrawable(null);\r\n                return;\r\n            }\r\n            if (getScaleType() != ScaleType.CENTER_CROP) setScaleType(ScaleType.CENTER_CROP);\r\n\r\n            final float scaleX = 3.5f / (getMaxWidth() / drawable.getIntrinsicWidth());\r\n            final float scaleY = 3.5f / (getMaxWidth() / drawable.getIntrinsicHeight());\r\n\r\n            if (getDrawable() == null) {\r\n                setImageDrawable(drawable);\r\n                setScaleX(1 / Math.max(scaleX, scaleY));\r\n                setScaleY(1 / Math.max(scaleX, scaleY));\r\n            } else {\r\n                if (drawable.getAlpha() < 255)\r\n                    drawable.setAlpha(255);\r\n\r\n                animate()\r\n                        .setDuration(AchievementUnlocked.getScaledDuration(50))\r\n                        .alpha(0f)\r\n                        .withEndAction(() -> animate()\r\n                                .setDuration(AchievementUnlocked.getScaledDuration(50))\r\n                                .alpha(1f)\r\n                                .withStartAction(() -> setImageDrawable(drawable))\r\n                                .start())\r\n                        .start();\r\n            }\r\n        }\r\n\r\n        public enum AchievementIconViewStates {\r\n            FADE_DRAWABLE, SAME_DRAWABLE\r\n        }\r\n\r\n    }\r\n\r\n    /**\r\n     * Same as LogDecelerateInterpolator.java from Launcher3\r\n     */\r\n    final static class DeceleratingInterpolator implements TimeInterpolator {\r\n\r\n        private final float mLogScale;\r\n        private final int mBase;\r\n\r\n        DeceleratingInterpolator(int base) {\r\n            mBase = base;\r\n            mLogScale = 1f / computeLog(1, mBase);\r\n        }\r\n\r\n        private static float computeLog(float t, int base) {\r\n            return (float) -Math.pow(base, -t) + 1;\r\n        }\r\n\r\n        @Override\r\n        public float getInterpolation(float t) {\r\n            return computeLog(t, mBase) * mLogScale;\r\n        }\r\n    }\r\n\r\n    final static class WindowOverlayCompat {\r\n        private static final int ANDROID_OREO = 26;\r\n        private static final int TYPE_APPLICATION_OVERLAY = 2038;\r\n        static final int TYPE_SYSTEM_ERROR = Build.VERSION.SDK_INT < ANDROID_OREO ? WindowManager.LayoutParams.TYPE_SYSTEM_ERROR : TYPE_APPLICATION_OVERLAY;\r\n    }\r\n\r\n    private class SwipeDismissTouchListener implements View.OnTouchListener {\r\n        private final int mSlop;\r\n        private final int mMinFlingVelocity;\r\n        private final int mMaxFlingVelocity;\r\n        private final long mAnimationTime;\r\n        private float mDownX;\r\n        private boolean mSwiping;\r\n        private float mTranslationX;\r\n        private final Runnable end;\r\n\r\n        SwipeDismissTouchListener() {\r\n            ViewConfiguration vc = ViewConfiguration.get(App.Companion.getContext());\r\n            mSlop = vc.getScaledTouchSlop();\r\n            mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();\r\n            mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();\r\n            mAnimationTime = App.Companion.getContext().getResources().getInteger(android.R.integer.config_shortAnimTime);\r\n            end = new Runnable() {\r\n                @Override\r\n                public void run() {\r\n                    hasBeenDismissed = true;\r\n\r\n                    //Fade out the popup view instead of direct visibility\r\n                    // change, for aesthetics.\r\n                    // Since there is no scrim in bottom-aligned and Android P+,\r\n                    // we can use setVisibility directly\r\n\r\n                    if (alignTop && VERSION.SDK_INT < 28)\r\n                        achievementLayout.animate().alpha(0f).setListener(new AnimatorListenerAdapter() {\r\n                            @Override\r\n                            public void onAnimationEnd(Animator animation) {\r\n                                super.onAnimationEnd(animation);\r\n                                achievementLayout.setVisibility(GONE);\r\n                            }\r\n                        }).start();\r\n                    else achievementLayout.setVisibility(GONE);\r\n                }\r\n            };\r\n        }\r\n\r\n\r\n        @SuppressLint(\"ClickableViewAccessibility\")\r\n        @Override\r\n        public boolean onTouch(View view, MotionEvent motionEvent) {\r\n            motionEvent.offsetLocation(mTranslationX, 0);\r\n            float deltaX = (motionEvent.getRawX() - mDownX);\r\n\r\n            switch (motionEvent.getActionMasked()) {\r\n                case MotionEvent.ACTION_DOWN: {\r\n                    mDownX = motionEvent.getRawX();\r\n                    view.onTouchEvent(motionEvent);\r\n                    return false;\r\n                }\r\n                case MotionEvent.ACTION_UP: {\r\n\r\n                    if (container.getAlpha() == 0) {\r\n                        dismissWithoutAnimation();\r\n                        return true;\r\n                    }\r\n\r\n                    boolean dismiss = false;\r\n                    boolean dismissRight = false;\r\n\r\n                    int spaceToEdge = ((achievementLayout.getWidth() - container.getWidth()) / 2);\r\n                    float swipePercentage = Math.abs(mTranslationX / spaceToEdge);\r\n\r\n\r\n                    if (swipePercentage >= 0.5f) {\r\n                        dismiss = true;\r\n                        dismissRight = deltaX > 0;\r\n                    }\r\n                    if (dismiss) {\r\n                        ObjectAnimator translation = ObjectAnimator.ofFloat(container, View.TRANSLATION_X, container.getTranslationX(), dismissRight ? container.getMeasuredWidth() : -container.getMeasuredWidth());\r\n                        translation.addUpdateListener(animation -> setSwipeEffect((float) animation.getAnimatedValue()));\r\n                        translation.addListener(new AnimatorListenerAdapter() {\r\n                            @Override\r\n                            public void onAnimationEnd(Animator animation) {\r\n                                super.onAnimationEnd(animation);\r\n                                if (end != null) end.run();\r\n                            }\r\n                        });\r\n                        translation.setInterpolator(TIME_INTERPOLATOR);\r\n                        translation.setDuration(mAnimationTime);\r\n                        translation.start();\r\n                        dismissed = true;\r\n                    } else {\r\n                        ObjectAnimator translation = ObjectAnimator.ofFloat(container, View.TRANSLATION_X, container.getTranslationX(), 0);\r\n                        translation.addUpdateListener(animation -> setSwipeEffect((float) animation.getAnimatedValue()));\r\n                        translation.setDuration(mAnimationTime);\r\n                        translation.setInterpolator(TIME_INTERPOLATOR);\r\n                        translation.start();\r\n\r\n                        dismissed = false;\r\n                    }\r\n                    mTranslationX = 0;\r\n                    mDownX = 0;\r\n                    mSwiping = false;\r\n                    break;\r\n                }\r\n                case MotionEvent.ACTION_MOVE: {\r\n\r\n                    if (Math.abs(deltaX) > mSlop) {\r\n                        mSwiping = true;\r\n                        container.getParent().requestDisallowInterceptTouchEvent(true);\r\n                        MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);\r\n                        cancelEvent.setAction(MotionEvent.ACTION_CANCEL |\r\n                                (motionEvent.getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));\r\n                        container.onTouchEvent(cancelEvent);\r\n                    }\r\n                    if (mSwiping) {\r\n                        mTranslationX = deltaX;\r\n                        setSwipeEffect(mTranslationX);\r\n                        return true;\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n            return false;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Adapter for listener\r\n     */\r\n    abstract class AchievementListenerAdapter implements AchievementListener {\r\n        @Override\r\n        public void onAchievementDismissed(AchievementUnlocked achievement) {\r\n        }\r\n\r\n        @Override\r\n        public void onViewCreated(AchievementUnlocked achievement, AchievementData[] data) {\r\n        }\r\n\r\n        @Override\r\n        public void onAchievementMorphed(AchievementUnlocked achievement, AchievementData data) {\r\n        }\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/AppWebView.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.webkit.WebView\n\nclass AppWebView : WebView {\n    constructor(context: Context) : super(context.applicationContext)\n\n    constructor(context: Context, attrs: AttributeSet) : super(context.applicationContext, attrs)\n\n    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context.applicationContext, attrs, defStyleAttr)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/BackgroundExecutor.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.os.AsyncTask\r\nimport java.util.concurrent.Executor\r\n\r\nclass BackgroundExecutor : Executor {\r\n    override fun execute(command: Runnable?) {\r\n        AsyncTask.execute(command)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/BannerContainerView.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.content.Context\r\nimport android.util.AttributeSet\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.LinearLayout\r\nimport androidx.core.view.ViewCompat\r\nimport androidx.core.view.WindowInsetsCompat\r\nimport knf.kuma.R\r\nimport org.jetbrains.anko.find\r\n\r\nclass BannerContainerView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : LinearLayout(context, attrs, defStyle) {\r\n    private var showBottom = false\r\n\r\n    init {\r\n        attrs?.let {\r\n            val array = context.obtainStyledAttributes(it, R.styleable.BannerContainerView)\r\n            showBottom = array.getBoolean(R.styleable.BannerContainerView_showBottomSpace, false)\r\n            array.recycle()\r\n        }\r\n        inflate(context, R.layout.lay_banner_container, this)\r\n    }\r\n\r\n    fun show(view: View) {\r\n        if (showBottom) {\r\n            ViewCompat.setOnApplyWindowInsetsListener(this) { _, insets ->\r\n                find<View>(R.id.spaceBottom).layoutParams.height = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom\r\n                WindowInsetsCompat.CONSUMED\r\n            }\r\n            find<View>(R.id.spaceBottom).visibility = VISIBLE\r\n        }\r\n        find<View>(R.id.spaceTop).visibility = VISIBLE\r\n        with(find<ViewGroup>(R.id.container)) {\r\n            removeAllViews()\r\n            addView(view)\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/CenterLayoutManager.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.content.Context\r\nimport android.util.AttributeSet\r\nimport androidx.recyclerview.widget.LinearLayoutManager\r\nimport androidx.recyclerview.widget.LinearSmoothScroller\r\nimport androidx.recyclerview.widget.RecyclerView\r\n\r\nclass CenterLayoutManager : LinearLayoutManager {\r\n    constructor(context: Context) : super(context)\r\n    constructor(context: Context, orientation: Int, reverseLayout: Boolean) : super(context, orientation, reverseLayout)\r\n    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)\r\n\r\n    override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State?, position: Int) {\r\n        val centerSmoothScroller = CenterSmoothScroller(recyclerView.context)\r\n        centerSmoothScroller.targetPosition = position\r\n        startSmoothScroll(centerSmoothScroller)\r\n    }\r\n\r\n    private class CenterSmoothScroller(context: Context) : LinearSmoothScroller(context) {\r\n        override fun calculateDtToFit(viewStart: Int, viewEnd: Int, boxStart: Int, boxEnd: Int, snapPreference: Int): Int = (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/ConnectionState.kt",
    "content": "package knf.kuma.custom\n\nimport android.animation.Animator\nimport android.animation.ValueAnimator\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.Intent\nimport android.graphics.Color\nimport android.util.AttributeSet\nimport android.view.LayoutInflater\nimport android.widget.LinearLayout\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.core.content.ContextCompat\nimport androidx.core.content.res.use\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleObserver\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.OnLifecycleEvent\nimport androidx.lifecycle.lifecycleScope\nimport it.sephiroth.android.library.xtooltip.ClosePolicy\nimport it.sephiroth.android.library.xtooltip.Tooltip\nimport knf.kuma.App\nimport knf.kuma.Diagnostic\nimport knf.kuma.R\nimport knf.kuma.commons.BypassUtil\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.asPx\nimport knf.kuma.commons.distinct\nimport knf.kuma.commons.findActivity\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.noCrashLet\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.LayStatusBarBinding\nimport knf.kuma.directory.DirectoryService\nimport knf.tools.bypass.startBypass\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.sdk27.coroutines.onClick\nimport org.jetbrains.anko.sdk27.coroutines.onLongClick\nimport org.jetbrains.anko.textColor\nimport org.json.JSONObject\nimport org.jsoup.Connection\nimport org.jsoup.HttpStatusException\nimport org.jsoup.Jsoup\nimport java.net.NoRouteToHostException\nimport java.net.SocketTimeoutException\nimport java.net.URL\nimport java.net.UnknownHostException\nimport javax.net.ssl.SSLException\n\n@SuppressLint(\"SetTextI18n\")\nclass ConnectionState : LinearLayout {\n    constructor(context: Context) : super(context) {\n        inflate(context)\n    }\n\n    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {\n        inflate(context, attrs)\n    }\n\n    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {\n        inflate(context, attrs)\n    }\n\n    private var bgColor = Color.TRANSPARENT\n    private lateinit var binding: LayStatusBarBinding\n\n    private fun inflate(context: Context, attrs: AttributeSet? = null) {\n        context.obtainStyledAttributes(attrs, R.styleable.ConnectionState).use {\n            bgColor = it.getColor(R.styleable.ConnectionState_cs_bg_color, ContextCompat.getColor(context, R.color.colorPrimary))\n        }\n        val inflater = context\n                .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater\n        inflater.inflate(R.layout.lay_status_bar, this)\n        binding = LayStatusBarBinding.bind(this)\n    }\n\n    override fun onFinishInflate() {\n        super.onFinishInflate()\n        binding.container.setBackgroundColor(bgColor)\n    }\n\n    private var isInitialized = false\n\n    fun setUp(owner: LifecycleOwner, onShowDialog: (message: String) -> Unit) {\n        if (!isInitialized || visibility == VISIBLE)\n            GlobalScope.launch(Dispatchers.Main + untilDestroyJob(owner)) {\n                normalState()\n                show()\n                delay(1000)\n                if (!Network.isConnected) {\n                    noNetworkState()\n                    while (!Network.isConnected) {\n                        delay(3000)\n                    }\n                    normalState()\n                }\n                doNetworkTests(owner, onShowDialog)\n                isInitialized = true\n            }\n    }\n\n    private suspend fun doNetworkTests(owner: LifecycleOwner, onShowDialog: (message: String) -> Unit) {\n        when (val code = withContext(Dispatchers.IO + untilDestroyJob(owner)) {\n            doCookiesTest()\n        }) {\n            -2 -> networkTimeoutState(owner, onShowDialog)\n            200 -> {\n                if (!PrefsUtil.isDirectoryFinished && !withContext(Dispatchers.IO) { BypassUtil.isCloudflareActive() })\n                    directoryListenState()\n                else {\n                    okState()\n                    dismiss()\n                }\n            }\n            403 -> {\n                errorBlockedState(403, onShowDialog)\n                var defResult = true\n                val observer = Observer<Pair<Boolean, Boolean>> {\n                    if (defResult) {\n                        defResult = false\n                        return@Observer\n                    }\n                    GlobalScope.launch(Dispatchers.Main + untilDestroyJob(owner)) {\n                        if (BypassUtil.isLoading) {\n                            warningCreatingState()\n                        } else if (it.first && !it.second) {\n                            okState()\n                            delay(1000)\n                            dismiss()\n                            GenericActivity.removeBypassObserver(\"connectionState\")\n                        } else if (!it.first && !it.second) {\n                            //dismiss()\n                            GenericActivity.removeBypassObserver(\"connectionState\")\n                            normalState()\n                            doNetworkTests(owner, onShowDialog)\n                        }\n                    }\n                }\n                GenericActivity.addBypassObserver(\"connectionState\", owner, observer)\n            }\n            502 -> errorDownState(owner, onShowDialog)\n            503 -> {\n                errorBlockedState(503, onShowDialog)\n                var defResult = true\n                val observer = Observer<Pair<Boolean, Boolean>> {\n                    if (defResult) {\n                        defResult = false\n                        return@Observer\n                    }\n                    GlobalScope.launch(Dispatchers.Main + untilDestroyJob(owner)) {\n                        if (BypassUtil.isLoading) {\n                            warningCreatingState()\n                        } else if (it.first && !it.second) {\n                            okState()\n                            delay(1000)\n                            dismiss()\n                            GenericActivity.removeBypassObserver(\"connectionState\")\n                        } else if (!it.first && !it.second) {\n                            //dismiss()\n                            GenericActivity.removeBypassObserver(\"connectionState\")\n                            normalState()\n                            doNetworkTests(owner, onShowDialog)\n                        }\n                    }\n                }\n                GenericActivity.addBypassObserver(\"connectionState\", owner, observer)\n            }\n            else -> {\n                try {\n                    val json = JSONObject(withContext(Dispatchers.IO) { URL(\"https://ipinfo.io/json\").readText() })\n                    if (json.getString(\"country\") == \"PE\") {\n                        errorCountryState(owner, onShowDialog)\n                    } else {\n                        networkErrorState(owner = owner, onShowDialog = onShowDialog)\n                    }\n                } catch (e: Exception) {\n                    when (e) {\n                        is UnknownHostException, is NoRouteToHostException, is SSLException -> {\n                            okState()\n                            dismiss()\n                        }\n\n                        else -> {\n                            networkErrorState(owner = owner, message = \"HTTP $code Error\", onShowDialog = onShowDialog)\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private fun untilDestroyJob(owner: LifecycleOwner): Job {\n        val job = Job()\n        owner.lifecycle.addObserver(object : LifecycleObserver {\n            @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)\n            fun onDestroy() {\n                job.cancel()\n            }\n        })\n        return job\n    }\n\n    private fun doCookiesTest(): Int {\n        return try {\n            val timeout = PrefsUtil.timeoutTime.toInt() * 1000\n            val response = Jsoup.connect(BypassUtil.testLink)\n                    .cookies(BypassUtil.getMapCookie(App.context))\n                    .userAgent(BypassUtil.userAgent)\n                    .timeout(if (timeout == 0) 30000 else timeout)\n                    .method(Connection.Method.GET)\n                    .execute()\n            response.statusCode()\n        } catch (e: HttpStatusException) {\n            e.statusCode\n        } catch (e: SocketTimeoutException) {\n            -2\n        } catch (e: Exception) {\n            -1\n        }\n    }\n\n    private fun tryTimeoutFix(): Boolean {\n        val timeout = when (PrefsUtil.timeoutTime) {\n            10L -> {\n                PrefsUtil.timeoutTime = 20L\n                20L\n            }\n            20L -> {\n                PrefsUtil.timeoutTime = 30L\n                30L\n            }\n            else -> return false\n        } * 1000\n        return try {\n            Jsoup.connect(\"https://www3.animeflv.net\")\n                    .cookies(BypassUtil.getMapCookie(App.context))\n                    .userAgent(BypassUtil.userAgent)\n                    .timeout(timeout.toInt())\n                    .method(Connection.Method.GET)\n                    .execute()\n            true\n        } catch (e: SocketTimeoutException) {\n            false\n        } catch (e: Exception) {\n            true\n        }\n    }\n\n    private fun normalState() {\n        binding.container.setBackgroundColor(bgColor)\n        binding.progress.visibility = VISIBLE\n        binding.icon.visibility = GONE\n        binding.message.text = \"Comprobando...\"\n        binding.message.textColor = ContextCompat.getColor(context, R.color.textSecondary)\n        binding.container.setOnClickListener(null)\n        binding.container.setOnLongClickListener(null)\n    }\n\n    private fun noNetworkState() {\n        binding.container.setBackgroundColor(bgColor)\n        binding.progress.visibility = GONE\n        binding.icon.setImageResource(R.drawable.ic_no_network)\n        binding.icon.visibility = VISIBLE\n        binding.message.text = \"Sin internet!\"\n        binding.message.textColor = ContextCompat.getColor(context, R.color.textSecondary)\n        binding.container.setOnClickListener(null)\n        binding.container.setOnLongClickListener(null)\n    }\n\n    private fun errorDownState(owner: LifecycleOwner, onShowDialog: (message: String) -> Unit) {\n        binding.container.setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccent))\n        binding.progress.visibility = GONE\n        binding.icon.setImageResource(R.drawable.ic_error)\n        binding.icon.visibility = VISIBLE\n        binding.message.text = \"Animeflv caido\"\n        binding.message.textColor = Color.WHITE\n        binding.container.onClick { onShowDialog(\"Animeflv parece estar caido por el momento, intenta de nuevo mas tarde\") }\n        binding.container.onLongClick { setUp(owner, onShowDialog) }\n    }\n\n    private fun errorBlockedState(errorCode: Int, onShowDialog: (message: String) -> Unit) {\n        binding.container.setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccent))\n        binding.progress.visibility = GONE\n        binding.icon.setImageResource(R.drawable.ic_error)\n        binding.icon.visibility = VISIBLE\n        binding.message.text = \"Error HTTP $errorCode!\"\n        binding.message.textColor = Color.WHITE\n        binding.container.onClick {\n            PrefsUtil.isForbiddenTipShown = true\n            //context.startActivity(Intent(context, Diagnostic.FullBypass::class.java))\n            (context.findActivity() as? AppCompatActivity)?.startBypass(\n                4157,\n                BypassUtil.createRequest()\n            )\n        }\n        binding.container.setOnLongClickListener(null)\n        if (isFullMode && !PrefsUtil.isForbiddenTipShown) {\n            noCrash {\n                Tooltip.Builder(context).apply {\n                    arrow(true)\n                    text(\"Haz click en la barra roja para resolver el captcha!\")\n                    overlay(true)\n                    styleId(R.style.ToolTipAltStyle)\n                    anchor(this@ConnectionState)\n                    closePolicy(ClosePolicy.TOUCH_ANYWHERE_CONSUME)\n                }.create().show(this, Tooltip.Gravity.TOP)\n            }\n        }\n    }\n\n    private fun errorCountryState(owner: LifecycleOwner, onShowDialog: (message: String) -> Unit) {\n        binding.container.setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccent))\n        binding.progress.visibility = GONE\n        binding.icon.setImageResource(R.drawable.ic_error)\n        binding.icon.visibility = VISIBLE\n        binding.message.text = \"VPN necesario\"\n        binding.message.textColor = Color.WHITE\n        binding.container.onClick { onShowDialog(\"Tu pais ha bloqueado la conexion con Animeflv por lo que es necesario usar una VPN para seguir usando la app\") }\n        binding.container.onLongClick { setUp(owner, onShowDialog) }\n    }\n\n    private fun networkErrorState(owner: LifecycleOwner, message: String = \"Error desconocido!\", onShowDialog: (message: String) -> Unit) {\n        binding.container.setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccent))\n        binding.progress.visibility = GONE\n        binding.icon.setImageResource(R.drawable.ic_error)\n        binding.icon.visibility = VISIBLE\n        binding.message.text = message\n        binding.message.textColor = Color.WHITE\n        binding.container.onClick { onShowDialog(\"Hubo un error haciendo las pruebas de conexion!\") }\n        binding.container.onLongClick { setUp(owner, onShowDialog) }\n    }\n\n    private fun networkTimeoutState(owner: LifecycleOwner, onShowDialog: (message: String) -> Unit) {\n        binding.container.setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccent))\n        binding.progress.visibility = GONE\n        binding.icon.setImageResource(R.drawable.ic_error)\n        binding.icon.visibility = VISIBLE\n        binding.message.text = \"Animeflv lento!\"\n        binding.message.textColor = Color.WHITE\n        binding.container.onClick { onShowDialog(\"Se detectó un problema con la página de Animeflv, es posible que esté en mantenimiento, este problema se solucionará solo, no es necesario reportarlo!\") }\n        binding.container.onLongClick { setUp(owner, onShowDialog) }\n        owner.doAsync {\n            var isFixed = false\n            repeat(3) {\n                if (!isFixed && tryTimeoutFix()) {\n                    isFixed = true\n                    setUp(owner, onShowDialog)\n                }\n            }\n        }\n    }\n\n    private fun warningState(onShowDialog: (message: String) -> Unit) {\n        binding.container.setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccentAmber))\n        binding.progress.visibility = GONE\n        binding.icon.setImageResource(R.drawable.ic_warning)\n        binding.icon.visibility = VISIBLE\n        binding.message.text = \"Cloudflare activado!\"\n        binding.message.textColor = Color.WHITE\n        binding.container.onClick { onShowDialog(\"Cloudflare activado, espera al bypass\") }\n        binding.container.onLongClick { context.startActivity(Intent(context, Diagnostic.FullBypass::class.java)) }\n    }\n\n    private fun warningCreatingState() {\n        binding.container.setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccentAmber))\n        binding.progress.visibility = GONE\n        binding.icon.setImageResource(R.drawable.ic_warning)\n        binding.icon.visibility = VISIBLE\n        binding.message.text = \"Actualizando bypass!\"\n        binding.message.textColor = Color.WHITE\n        binding.container.setOnClickListener(null)\n        binding.container.setOnLongClickListener(null)\n    }\n\n    private suspend fun directoryListenState() {\n        (context.findActivity() as? AppCompatActivity)?.let { owner ->\n            binding.container.setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccentAmber))\n            binding.progress.visibility = GONE\n            binding.icon.setImageResource(R.drawable.ic_warning)\n            binding.icon.visibility = VISIBLE\n            binding.message.textColor = Color.WHITE\n            binding.container.setOnClickListener(null)\n            binding.container.setOnLongClickListener(null)\n            val maxPages = withContext(Dispatchers.IO) {\n                noCrashLet(\"3200~\") {\n                    val main = jsoupCookies(\"https://www3.animeflv.net/browse\").get()\n                    val lastPage = main.select(\"ul.pagination li:matches(\\\\d+)\").last().text().trim().toInt()\n                    val last = try {\n                        jsoupCookies(\"https://www3.animeflv.net/browse?page=$lastPage\").get().select(\"article\").size\n                    } catch (e: Exception) {\n                        0\n                    }\n                    ((24 * (lastPage - 1)) + last).toString()\n                }\n            }\n            var msg = \"Calculando\"\n            CacheDB.INSTANCE.animeDAO().countLive.distinct.observe(owner, Observer {\n                binding.message.text = \"$msg: $it/$maxPages\"\n            })\n            DirectoryService.getLiveStatus().observe(owner, Observer {\n                when (it) {\n                    DirectoryService.STATE_CACHED -> {\n                        msg = \"Descargando directorio\"\n                    }\n                    in DirectoryService.STATE_PARTIAL..DirectoryService.STATE_FULL -> {\n                        msg = \"Actualizando directorio\"\n                    }\n                    DirectoryService.STATE_FINISHED -> {\n                        owner.lifecycleScope.launch(Dispatchers.Main) {\n                            okState()\n                            dismiss()\n                        }\n                    }\n                }\n            })\n        } ?: run {\n            okState()\n            GlobalScope.launch(Dispatchers.Main) {\n                this@ConnectionState.dismiss()\n            }\n        }\n    }\n\n    private fun okState() {\n        binding.container.setBackgroundColor(ContextCompat.getColor(context, R.color.colorAccentGreen))\n        binding.progress.visibility = GONE\n        binding.icon.setImageResource(R.drawable.ic_check)\n        binding.icon.visibility = VISIBLE\n        binding.message.text = \"Todo en orden!\"\n        binding.message.textColor = Color.WHITE\n        binding.container.setOnClickListener(null)\n        binding.container.setOnLongClickListener(null)\n    }\n\n    private fun show() {\n        val height = 24.asPx\n        layoutParams = layoutParams.apply {\n            this.height = 0\n        }\n        visibility = VISIBLE\n        ValueAnimator.ofInt(0, height).apply {\n            addUpdateListener {\n                layoutParams = layoutParams.apply {\n                    this.height = it.animatedValue as Int\n                }\n            }\n            duration = 350\n        }.start()\n    }\n\n    private suspend fun dismiss() {\n        delay(1000)\n        val height = 24.asPx\n        ValueAnimator.ofInt(height, 0).apply {\n            addUpdateListener {\n                layoutParams = layoutParams.apply {\n                    this.height = it.animatedValue as Int\n                }\n            }\n            addListener(object : Animator.AnimatorListener {\n                override fun onAnimationRepeat(animation: Animator) {\n\n                }\n\n                override fun onAnimationEnd(animation: Animator) {\n                    visibility = GONE\n                    layoutParams = layoutParams.apply {\n                        this.height = height\n                    }\n                }\n\n                override fun onAnimationCancel(animation: Animator) {\n\n                }\n\n                override fun onAnimationStart(animation: Animator) {\n\n                }\n            })\n            duration = 350\n        }.start()\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/ExpandableTV.kt",
    "content": "package knf.kuma.custom\n\nimport android.animation.Animator\nimport android.animation.AnimatorListenerAdapter\nimport android.animation.TimeInterpolator\nimport android.animation.ValueAnimator\nimport android.content.Context\nimport android.graphics.Paint\nimport android.graphics.Rect\nimport android.util.AttributeSet\nimport android.view.ViewGroup\nimport android.view.animation.AccelerateDecelerateInterpolator\nimport android.widget.ImageButton\nimport android.widget.TextView\nimport androidx.appcompat.widget.AppCompatTextView\n\nclass ExpandableTV @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : AppCompatTextView(context, attrs, defStyle) {\n\n    private val onExpandListeners: MutableList<OnExpandListener>\n    private var mMaxLines = 4\n    private var indicator: ImageButton? = null\n    private var needIndicator = true\n\n    private var expandInterpolator: TimeInterpolator? = null\n    private var collapseInterpolator: TimeInterpolator? = null\n    private var animationDuration: Long = 0\n    private var animating: Boolean = false\n    /**\n     * Is this [ExpandableTV] expanded or not?\n     *\n     * @return true if expanded, false if collapsed.\n     */\n    var isExpanded: Boolean = false\n        private set\n    private var collapsedHeight: Int = 0\n\n    init {\n\n        // keep the original value of mMaxLines\n        this.mMaxLines = this.maxLines\n\n        // create bucket of OnExpandListener instances\n        this.onExpandListeners = ArrayList()\n\n        // create default interpolators\n        this.expandInterpolator = AccelerateDecelerateInterpolator()\n        this.collapseInterpolator = AccelerateDecelerateInterpolator()\n    }\n\n    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {\n        var measureSpec = heightMeasureSpec\n        // if this TextView is collapsed and mMaxLines = 0,\n        // than make its height equals to zero\n        if (this.mMaxLines == 0 && !this.isExpanded && !this.animating) {\n            measureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY)\n        }\n\n        super.onMeasure(widthMeasureSpec, measureSpec)\n    }\n\n    //region public helper methods\n\n    /**\n     * Toggle the expanded state of this [ExpandableTV].\n     *\n     * @return true if toggled, false otherwise.\n     */\n    fun toggle(): Boolean {\n        return if (this.isExpanded)\n            this.collapse()\n        else\n            this.expand()\n    }\n\n    /**\n     * Expand this [ExpandableTV].\n     *\n     * @return true if expanded, false otherwise.\n     */\n    private fun expand(): Boolean {\n        if (!this.isExpanded && !this.animating && this.mMaxLines >= 0) {\n            // notify listener\n            this.notifyOnExpand()\n\n            // measure collapsed height\n            this.measure(\n                    MeasureSpec.makeMeasureSpec(this.measuredWidth, MeasureSpec.EXACTLY),\n                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)\n            )\n\n            this.collapsedHeight = this.measuredHeight\n\n            // indicate that we are now animating\n            this.animating = true\n\n            // set mMaxLines to MAX Integer, so we can calculate the expanded height\n            this.maxLines = Integer.MAX_VALUE\n\n            // measure expanded height\n            this.measure(\n                    MeasureSpec.makeMeasureSpec(this.measuredWidth, MeasureSpec.EXACTLY),\n                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)\n            )\n\n            val expandedHeight = this.measuredHeight\n\n            // animate from collapsed height to expanded height\n            val valueAnimator = ValueAnimator.ofInt(this.collapsedHeight, expandedHeight)\n            valueAnimator.addUpdateListener { animation -> this@ExpandableTV.height = animation.animatedValue as Int }\n\n            // wait for the animation to end\n            valueAnimator.addListener(object : AnimatorListenerAdapter() {\n                override fun onAnimationEnd(animation: Animator) {\n                    // reset min & max height (previously set with setHeight() method)\n                    this@ExpandableTV.maxHeight = Integer.MAX_VALUE\n                    this@ExpandableTV.minHeight = 0\n\n                    // if fully expanded, set height to WRAP_CONTENT, because when rotating the device\n                    // the height calculated with this ValueAnimator isn't correct anymore\n                    val layoutParams = this@ExpandableTV.layoutParams\n                    layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT\n                    this@ExpandableTV.layoutParams = layoutParams\n\n                    // keep track of current status\n                    this@ExpandableTV.isExpanded = true\n                    this@ExpandableTV.animating = false\n                }\n            })\n\n            // set interpolator\n            valueAnimator.interpolator = this.expandInterpolator\n\n            // start the animation\n            valueAnimator\n                    .setDuration(this.animationDuration)\n                    .start()\n\n            return true\n        }\n\n        return false\n    }\n\n    /**\n     * Collapse this [TextView].\n     *\n     * @return true if collapsed, false otherwise.\n     */\n    private fun collapse(): Boolean {\n        if (this.isExpanded && !this.animating && this.mMaxLines >= 0) {\n            // notify listener\n            this.notifyOnCollapse()\n\n            // measure expanded height\n            val expandedHeight = this.measuredHeight\n\n            // indicate that we are now animating\n            this.animating = true\n\n            // animate from expanded height to collapsed height\n            val valueAnimator = ValueAnimator.ofInt(expandedHeight, this.collapsedHeight)\n            valueAnimator.addUpdateListener { animation -> this@ExpandableTV.height = animation.animatedValue as Int }\n\n            // wait for the animation to end\n            valueAnimator.addListener(object : AnimatorListenerAdapter() {\n                override fun onAnimationEnd(animation: Animator) {\n                    // keep track of current status\n                    this@ExpandableTV.isExpanded = false\n                    this@ExpandableTV.animating = false\n\n                    // set mMaxLines back to original value\n                    this@ExpandableTV.maxLines = this@ExpandableTV.mMaxLines\n\n                    // if fully collapsed, set height back to WRAP_CONTENT, because when rotating the device\n                    // the height previously calculated with this ValueAnimator isn't correct anymore\n                    val layoutParams = this@ExpandableTV.layoutParams\n                    layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT\n                    this@ExpandableTV.layoutParams = layoutParams\n                }\n            })\n\n            // set interpolator\n            valueAnimator.interpolator = this.collapseInterpolator\n\n            // start the animation\n            valueAnimator\n                    .setDuration(this.animationDuration)\n                    .start()\n\n            return true\n        }\n\n        return false\n    }\n\n    //endregion\n\n    //region public getters and setters\n\n    /**\n     * Sets the duration of the expand / collapse animation.\n     *\n     * @param animationDuration duration in milliseconds.\n     */\n    fun setAnimationDuration(animationDuration: Long) {\n        this.animationDuration = animationDuration\n    }\n\n    /**\n     * Adds a listener which receives updates about this [ExpandableTV].\n     *\n     * @param onExpandListener the listener.\n     */\n    fun addOnExpandListener(onExpandListener: OnExpandListener) {\n        this.onExpandListeners.add(onExpandListener)\n    }\n\n    /**\n     * Removes a listener which receives updates about this [ExpandableTV].\n     *\n     * @param onExpandListener the listener.\n     */\n    fun removeOnExpandListener(onExpandListener: OnExpandListener) {\n        this.onExpandListeners.remove(onExpandListener)\n    }\n\n    /**\n     * Sets a [TimeInterpolator] for expanding and collapsing.\n     *\n     * @param interpolator the interpolator\n     */\n    fun setInterpolator(interpolator: TimeInterpolator) {\n        this.expandInterpolator = interpolator\n        this.collapseInterpolator = interpolator\n    }\n\n    //endregion\n\n    /**\n     * This method will notify the listener about this view being expanded.\n     */\n    private fun notifyOnCollapse() {\n        for (onExpandListener in this.onExpandListeners) {\n            onExpandListener.onCollapse(this)\n        }\n    }\n\n    /**\n     * This method will notify the listener about this view being collapsed.\n     */\n    private fun notifyOnExpand() {\n        for (onExpandListener in this.onExpandListeners) {\n            onExpandListener.onExpand(this)\n        }\n    }\n\n    //region public interfaces\n\n    fun setIndicator(indicator: ImageButton) {\n        this.indicator = indicator\n    }\n\n    fun setTextAndIndicator(charSequence: CharSequence, indicator: ImageButton) {\n        this.indicator = indicator\n        text = charSequence\n        /*getViewTreeObserver().addOnGlobalLayoutListener(() -> {\n            needIndicator=getLineCount()>4;\n            *//*this.measure\n                    (\n                            MeasureSpec.makeMeasureSpec(this.getMeasuredWidth(), MeasureSpec.EXACTLY),\n                            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)\n                    );\n            int nH = getMeasuredHeight();*//*\n            setMaxLines(4);\n            mMaxLines=4;\n            *//*this.measure\n                    (\n                            MeasureSpec.makeMeasureSpec(this.getMeasuredWidth(), MeasureSpec.EXACTLY),\n                            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)\n                    );\n            int cH = getMeasuredHeight();\n            needIndicator = nH>cH;*//*\n            if (!needIndicator)\n                indicator.post(() -> indicator.setVisibility(GONE));\n        });*/\n    }\n\n    fun checkIndicator() {\n        val bounds = Rect()\n        val paint = Paint()\n        paint.textSize = textSize\n        paint.getTextBounds(text.toString(), 0, text.length, bounds)\n        val numLines = Math.ceil((bounds.width().toFloat() / textSize).toDouble()).toInt()\n        needIndicator = numLines > 4\n        maxLines = 4\n        mMaxLines = 4\n        if (!needIndicator)\n            indicator?.post { indicator?.visibility = GONE }\n    }\n\n    /**\n     * Interface definition for a callback to be invoked when\n     * a [ExpandableTV] is expanded or collapsed.\n     */\n    interface OnExpandListener {\n        /**\n         * The [ExpandableTV] is being expanded.\n         *\n         * @param view the textview\n         */\n        fun onExpand(view: ExpandableTV)\n\n        /**\n         * The [ExpandableTV] is being collapsed.\n         *\n         * @param view the textview\n         */\n        fun onCollapse(view: ExpandableTV)\n    }\n\n    /**\n     * Simple implementation of the [ExpandableTV.OnExpandListener] interface with stub\n     * implementations of each method. Extend this if you do not intend to override\n     * every method of [ExpandableTV.OnExpandListener].\n     */\n    class SimpleOnExpandListener : OnExpandListener {\n        override fun onExpand(view: ExpandableTV) {\n            // empty implementation\n        }\n\n        override fun onCollapse(view: ExpandableTV) {\n            // empty implementation\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/ExpandableTextView.kt",
    "content": "package knf.kuma.custom\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.graphics.drawable.Drawable\nimport android.os.Handler\nimport android.os.Message\nimport android.util.AttributeSet\nimport android.util.Log\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.widget.ImageButton\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport androidx.annotation.ColorInt\nimport androidx.core.content.ContextCompat\nimport knf.kuma.R\n\nclass ExpandableTextView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs), View.OnClickListener {\n\n    private val WHAT = 2\n    private val WHAT_ANIMATION_END = 3\n    private val WHAT_EXPAND_ONLY = 4\n    private var textView: TextView? = null\n    private var ivExpandOrShrink: ImageButton? = null\n    private var drawableShrink: Drawable? = null\n    private var drawableExpand: Drawable? = null\n    private var textViewStateColor: Int = 0\n    private var isShrink = false\n    private var isExpandNeeded = false\n    private var isInitTextView = true\n    private var expandLines: Int = 0\n    private var textLines: Int = 0\n    private var textContent: CharSequence? = null\n    private val textContentColor: Int = 0\n    private var textContentSize: Float = 0.toFloat()\n    private var thread: Thread? = null\n    private var sleepTime = 22\n    @SuppressLint(\"HandlerLeak\")\n    private val handler = object : Handler() {\n\n        override fun handleMessage(msg: Message) {\n            when {\n                WHAT == msg.what -> {\n                    textView?.maxLines = msg.arg1\n                    textView?.invalidate()\n                }\n                WHAT_ANIMATION_END == msg.what -> setExpandState(msg.arg1)\n                WHAT_EXPAND_ONLY == msg.what -> changeExpandState(msg.arg1)\n            }\n            super.handleMessage(msg)\n        }\n\n    }\n\n    init {\n        initValue(context, attrs)\n        initView(context)\n        initClick()\n    }\n\n    private fun initValue(context: Context, attrs: AttributeSet) {\n        val ta = context.obtainStyledAttributes(attrs,\n                R.styleable.ExpandableTextView)\n\n        expandLines = ta.getInteger(\n                R.styleable.ExpandableTextView_tvea_expandLines, 5)\n\n        drawableShrink = ta\n                .getDrawable(R.styleable.ExpandableTextView_tvea_shrinkBitmap)\n        drawableExpand = ta\n                .getDrawable(R.styleable.ExpandableTextView_tvea_expandBitmap)\n\n        textViewStateColor = ta.getColor(R.styleable.ExpandableTextView_tvea_textStateColor, ContextCompat.getColor(context, R.color.colorPrimary))\n\n        textContentSize = ta.getDimension(R.styleable.ExpandableTextView_tvea_textContentSize, 18f)\n\n        ta.recycle()\n    }\n\n    private fun initView(context: Context) {\n\n        val inflater = context\n                .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as? LayoutInflater\n        inflater?.inflate(R.layout.layout_expandable_textview, this)\n\n        textView = findViewById(R.id.tv_expand_text_view_animation)\n        //textView.setTextColor(textContentColor);\n        //textView.getPaint().setTextSize(textContentSize);\n\n        textView?.maxLines = expandLines\n\n    }\n\n    fun setExpandIndicatorButton(button: ImageButton) {\n        ivExpandOrShrink = button\n        ivExpandOrShrink?.setOnClickListener(this)\n    }\n\n    private fun initClick() {\n        textView?.setOnClickListener(this)\n    }\n\n    fun setTextColor(@ColorInt color: Int) {\n        textView?.setTextColor(color)\n    }\n\n    fun setStateColorFilter(@ColorInt color: Int) {\n        if (ivExpandOrShrink != null)\n            ivExpandOrShrink?.setColorFilter(color)\n    }\n\n    fun setText(charSequence: CharSequence) {\n        textContent = charSequence\n        textView?.text = charSequence.toString()\n        val viewTreeObserver = textView?.viewTreeObserver\n        viewTreeObserver?.addOnPreDrawListener {\n            if (!isInitTextView) {\n                return@addOnPreDrawListener true\n            }\n            textLines = textView?.lineCount ?: 0\n            Log.e(\"Expandable\", \"Lines: $textLines\")\n            isExpandNeeded = textLines > expandLines\n            isInitTextView = false\n            if (isExpandNeeded) {\n                isShrink = true\n                doAnimation(textLines, expandLines, WHAT_ANIMATION_END)\n            } else {\n                isShrink = false\n                doNotExpand()\n            }\n            true\n        }\n    }\n\n    private fun doAnimation(startIndex: Int, endIndex: Int,\n                            what: Int) {\n\n        thread = Thread {\n\n            if (startIndex < endIndex) {\n                // 如果起止行数小于结束行数，那么往下展开至结束行数\n                // if open index smaller than end index ,do expand action\n                var count = startIndex\n                while (count++ < endIndex) {\n                    val msg = handler.obtainMessage(WHAT, count, 0)\n\n                    try {\n                        Thread.sleep(sleepTime.toLong())\n                    } catch (e: InterruptedException) {\n                        e.printStackTrace()\n                    }\n\n                    handler.sendMessage(msg)\n                }\n            } else if (startIndex > endIndex) {\n                // 如果起止行数大于结束行数，那么往上折叠至结束行数\n                // if open index bigger than end index ,do shrink action\n                var count = startIndex\n                while (count-- > endIndex) {\n                    val msg = handler.obtainMessage(WHAT, count, 0)\n                    try {\n                        Thread.sleep(sleepTime.toLong())\n                    } catch (e: InterruptedException) {\n                        e.printStackTrace()\n                    }\n\n                    handler.sendMessage(msg)\n                }\n            }\n\n            // 动画结束后发送结束的信号\n            // animation end,send signal\n            val msg = handler.obtainMessage(what, endIndex, 0)\n            handler.sendMessage(msg)\n\n        }\n\n        thread?.start()\n\n    }\n\n    private fun changeExpandState(endIndex: Int) {\n        if (endIndex < textLines) {\n            if (ivExpandOrShrink != null)\n                ivExpandOrShrink?.setImageDrawable(drawableExpand)\n        } else {\n            if (ivExpandOrShrink != null)\n                ivExpandOrShrink?.setImageDrawable(drawableShrink)\n        }\n\n    }\n\n    private fun setExpandState(endIndex: Int) {\n\n        if (endIndex < textLines) {\n            isShrink = true\n            if (ivExpandOrShrink != null)\n                ivExpandOrShrink?.setImageDrawable(drawableExpand)\n            textView?.setOnClickListener(this)\n        } else {\n            isShrink = false\n            if (ivExpandOrShrink != null)\n                ivExpandOrShrink?.setImageDrawable(drawableShrink)\n            textView?.setOnClickListener(null)\n        }\n\n    }\n\n    private fun doNotExpand() {\n        textView?.maxLines = expandLines\n        textView?.setOnClickListener(null)\n        if (ivExpandOrShrink != null) {\n            ivExpandOrShrink?.setOnClickListener(null)\n            ivExpandOrShrink?.visibility = GONE\n        }\n    }\n\n    override fun onClick(v: View) {\n        clickImageToggle()\n    }\n\n    private fun clickImageToggle() {\n        if (isShrink) {\n            // 如果是已经折叠，那么进行非折叠处理\n            // do shrink action\n            doAnimation(expandLines, textLines, WHAT_EXPAND_ONLY)\n        } else {\n            // 如果是非折叠，那么进行折叠处理\n            // do expand action\n            doAnimation(textLines, expandLines, WHAT_EXPAND_ONLY)\n        }\n\n        // 切换状态\n        // set flag\n        isShrink = !isShrink\n    }\n\n    fun getExpandLines(): Int {\n        return expandLines\n    }\n\n    fun setExpandLines(newExpandLines: Int) {\n        val start = if (isShrink) this.expandLines else textLines\n        val end = if (textLines < newExpandLines) textLines else newExpandLines\n        doAnimation(start, end, WHAT_ANIMATION_END)\n        this.expandLines = newExpandLines\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/FSGridRecyclerView.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.animation.GridLayoutAnimationController\nimport androidx.recyclerview.widget.GridLayoutManager\n\nclass FSGridRecyclerView : FSRecyclerView {\n\n    constructor(context: Context) : super(context)\n\n    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)\n\n    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)\n\n    override fun attachLayoutAnimationParameters(child: View, params: ViewGroup.LayoutParams,\n                                                 index: Int, count: Int) {\n        val layoutManager = layoutManager\n        if (adapter != null && layoutManager is GridLayoutManager) {\n\n            var animationParams: GridLayoutAnimationController.AnimationParameters? = null\n\n            if (params.layoutAnimationParameters != null)\n                animationParams = params.layoutAnimationParameters as? GridLayoutAnimationController.AnimationParameters\n\n            if (animationParams == null) {\n                // If there are no animation parameters, create new once and attach them to\n                // the LayoutParams.\n                animationParams = GridLayoutAnimationController.AnimationParameters()\n                params.layoutAnimationParameters = animationParams\n            }\n\n            // Next we are updating the parameters\n\n            // Set the number of items in the RecyclerView and the index of this item\n            animationParams.count = count\n            animationParams.index = index\n\n            // Calculate the number of columns and rows in the grid\n            val columns = layoutManager.spanCount\n            animationParams.columnsCount = columns\n            animationParams.rowsCount = count / columns\n\n            // Calculate the column/row position in the grid\n            val invertedIndex = count - 1 - index\n            animationParams.column = columns - 1 - invertedIndex % columns\n            animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns\n\n        } else {\n            // Proceed as normal if using another type of LayoutManager\n            super.attachLayoutAnimationParameters(child, params, index, count)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/FSRecyclerView.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\n\nopen class FSRecyclerView : FastScrollRecyclerView {\n\n    constructor(context: Context) : super(context)\n\n    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)\n\n    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)\n\n    override fun scrollToPositionAtProgress(touchFraction: Float): String {\n        return try {\n            super.scrollToPositionAtProgress(touchFraction)\n        } catch (e: Exception) {\n            \"\"\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/FixedGridLayoutManager.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.content.Context\r\nimport android.util.AttributeSet\r\nimport androidx.recyclerview.widget.GridLayoutManager\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.commons.noCrash\r\n\r\nclass FixedGridLayoutManager : GridLayoutManager {\r\n\r\n    constructor(context: Context, spanCount: Int) : super(context, spanCount)\r\n\r\n    constructor(context: Context, spanCount: Int, orientation: Int, reverseLayout: Boolean) : super(context, spanCount, orientation, reverseLayout)\r\n\r\n    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)\r\n\r\n    override fun onLayoutChildren(recycler: RecyclerView.Recycler?, state: RecyclerView.State?) {\r\n        noCrash { super.onLayoutChildren(recycler, state) }\r\n    }\r\n\r\n    override fun supportsPredictiveItemAnimations(): Boolean {\r\n        return false\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/GenericActivity.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.app.ActivityManager\r\nimport android.content.Intent\r\nimport android.graphics.BitmapFactory\r\nimport android.os.Build\r\nimport android.util.Log\r\nimport android.view.View\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.core.content.ContextCompat\r\nimport androidx.lifecycle.LifecycleOwner\r\nimport androidx.lifecycle.MutableLiveData\r\nimport androidx.lifecycle.Observer\r\nimport androidx.lifecycle.lifecycleScope\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\r\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.BypassUtil\r\nimport knf.kuma.commons.PicassoSingle\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.isFullMode\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.toastLong\r\nimport knf.kuma.directory.DirManager\r\nimport knf.kuma.directory.DirectoryService\r\nimport knf.kuma.retrofit.Repository\r\nimport knf.kuma.uagen.randomUA\r\nimport knf.kuma.videoservers.FileActions\r\nimport knf.kuma.videoservers.ServersFactory\r\nimport knf.tools.bypass.startBypass\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport org.jetbrains.anko.doAsync\r\n\r\n\r\nopen class GenericActivity : AppCompatActivity() {\r\n\r\n    override fun onResume() {\r\n        noCrash {\r\n            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {\r\n                val appIcon = BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher)\r\n                setTaskDescription(ActivityManager.TaskDescription(getString(R.string.app_name), appIcon, ContextCompat.getColor(this, R.color.colorPrimary)))\r\n            }\r\n        }\r\n        logText(\"On Resume check\")\r\n        noCrash { super.onResume() }\r\n    }\r\n\r\n    open fun getSnackbarAnchor(): View? = null\r\n\r\n    open fun onBypassUpdated() {\r\n\r\n    }\r\n\r\n    open fun forceCreation(): Boolean = false\r\n\r\n    open fun logText(text: String) {\r\n        Log.e(\"Bypass\", text)\r\n    }\r\n\r\n    fun checkBypass() {\r\n        if (BypassUtil.isChecking) {\r\n            logText(\"Already checking\")\r\n            return\r\n        }\r\n        BypassUtil.isChecking = true\r\n        doAsync(exceptionHandler = {\r\n            it.also {\r\n                FirebaseCrashlytics.getInstance().recordException(it)\r\n                logText(\"Error: ${it.message}\")\r\n            }.message?.toastLong()\r\n        }) {\r\n            var flag: Int\r\n            if ((BypassUtil.isNeededFlag().also { flag = it } >= 1 || forceCreation()).also { logText(\"Is needed or forced: $it\") }\r\n                    && !BypassUtil.isLoading.also { logText(\"Is already loading: $it\") }) {\r\n                BypassUtil.isChecking = false\r\n                logText(\"Flag: $flag\")\r\n                val runBypass = {\r\n                    lifecycleScope.launch(Dispatchers.Main) {\r\n                        bypassLive.value = Pair(true, true)\r\n                        BypassUtil.isLoading = true\r\n                        startBypass(\r\n                            4157,\r\n                            BypassUtil.createRequest()\r\n                        )\r\n                    }\r\n                }\r\n                if (isFullMode && !PrefsUtil.isBypassWarningShown){\r\n                    lifecycleScope.launch(Dispatchers.Main){\r\n                        MaterialDialog(this@GenericActivity).show {\r\n                            lifecycleOwner(this@GenericActivity)\r\n                            title(text = \"Bypass necesario\")\r\n                            message(text = \"La app necesita saltarse la proteccion de animeflv asi que necesita crear un bypass, esto puede tardar varios minutos, la pantalla cambiara automaticamente una vez terminado el proceso\")\r\n                            cancelable(false)\r\n                            positiveButton(text = \"OK\"){\r\n                                PrefsUtil.isBypassWarningShown = true\r\n                                runBypass()\r\n                            }\r\n                        }\r\n                    }\r\n                }else{\r\n                    runBypass()\r\n                }\r\n            } else {\r\n                BypassUtil.isChecking = false\r\n                logText(\"Creation not needed, aborting\")\r\n                bypassLive.postValue(Pair(false, false))\r\n                Log.e(\"CloudflareBypass\", \"Not needed\")\r\n            }\r\n        }\r\n    }\r\n\r\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\r\n        super.onActivityResult(requestCode, resultCode, data)\r\n        if (requestCode == 4157) {\r\n            val cookiesUpdated = data?.let {\r\n                PrefsUtil.useDefaultUserAgent = false\r\n                PrefsUtil.userAgent = it.getStringExtra(\"user_agent\") ?: randomUA()\r\n                BypassUtil.saveCookies(this, it.getStringExtra(\"cookies\") ?: \"null\")\r\n            } ?: false\r\n            BypassUtil.isLoading = false\r\n            bypassLive.value = Pair(first = cookiesUpdated, second = false)\r\n            Repository().reloadAllRecents()\r\n            onBypassUpdated()\r\n            PicassoSingle.clear()\r\n            //ThumbsDownloader.start(this)\r\n            if (!PrefsUtil.isDirectoryFinished) {\r\n                lifecycleScope.launch(Dispatchers.IO) {\r\n                    DirManager.checkPreDir()\r\n                    DirectoryService.run(this@GenericActivity)\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    override fun onPause() {\r\n        super.onPause()\r\n        BypassUtil.isLoading = false\r\n    }\r\n\r\n    override fun onDestroy() {\r\n        super.onDestroy()\r\n        ServersFactory.clear()\r\n        FileActions.reset()\r\n        if (forceCreation())\r\n            bypassLive.value = Pair(false, false)\r\n    }\r\n\r\n    companion object {\r\n        private val observersList = mutableMapOf<String, Observer<Pair<Boolean, Boolean>>>()\r\n        val bypassLive: MutableLiveData<Pair<Boolean, Boolean>> = MutableLiveData()\r\n\r\n        fun addBypassObserver(id: String, owner: LifecycleOwner, observer: Observer<Pair<Boolean, Boolean>>) {\r\n            removeBypassObserver(id)\r\n            observersList[id] = observer\r\n            bypassLive.observe(owner, observer)\r\n        }\r\n\r\n        fun removeBypassObserver(id: String) {\r\n            if (observersList.containsKey(id)) {\r\n                bypassLive.removeObserver(observersList[id]!!)\r\n                observersList.remove(id)\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/GridRecyclerView.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.animation.GridLayoutAnimationController\n\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\n\nclass GridRecyclerView : RecyclerView {\n\n    constructor(context: Context) : super(context)\n\n    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)\n\n    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)\n\n    override fun attachLayoutAnimationParameters(child: View, params: ViewGroup.LayoutParams,\n                                                 index: Int, count: Int) {\n        val layoutManager = layoutManager\n        if (adapter != null && layoutManager is GridLayoutManager) {\n\n            var animationParams: GridLayoutAnimationController.AnimationParameters? = null\n\n            if (params.layoutAnimationParameters != null)\n                animationParams = params.layoutAnimationParameters as GridLayoutAnimationController.AnimationParameters\n\n            if (animationParams == null) {\n                // If there are no animation parameters, create new once and attach them to\n                // the LayoutParams.\n                animationParams = GridLayoutAnimationController.AnimationParameters()\n                params.layoutAnimationParameters = animationParams\n            }\n\n            // Next we are updating the parameters\n\n            // Set the number of items in the RecyclerView and the index of this item\n            animationParams.count = count\n            animationParams.index = index\n\n            // Calculate the number of columns and rows in the grid\n            val columns = layoutManager.spanCount\n            animationParams.columnsCount = columns\n            animationParams.rowsCount = count / columns\n\n            // Calculate the column/row position in the grid\n            val invertedIndex = count - 1 - index\n            animationParams.column = columns - 1 - invertedIndex % columns\n            animationParams.row = animationParams.rowsCount - 1 - invertedIndex / columns\n\n        } else {\n            // Proceed as normal if using another type of LayoutManager\n            super.attachLayoutAnimationParameters(child, params, index, count)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/HiddenOverlay.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.view.LayoutInflater\nimport android.view.animation.Animation\nimport android.view.animation.AnimationUtils\nimport android.widget.LinearLayout\nimport knf.kuma.R\n\nclass HiddenOverlay : LinearLayout {\n    constructor(context: Context) : super(context) {\n        inflate(context)\n    }\n\n    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {\n        inflate(context)\n    }\n\n    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {\n        inflate(context)\n    }\n\n    private fun inflate(context: Context) {\n        val inflater = context\n                .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater\n        inflater.inflate(R.layout.view_hidden_overlay, this)\n    }\n\n    fun setHidden(hidden: Boolean, animate: Boolean) {\n        setState(hidden)\n        if (animate)\n            post {\n                val animation = AnimationUtils.loadAnimation(context, if (hidden) R.anim.fadein else R.anim.fadeout)\n                animation.duration = 200\n                animation.setAnimationListener(object : Animation.AnimationListener {\n                    override fun onAnimationStart(animation: Animation) {\n\n                    }\n\n                    override fun onAnimationEnd(animation: Animation) {\n\n                    }\n\n                    override fun onAnimationRepeat(animation: Animation) {\n\n                    }\n                })\n                startAnimation(animation)\n            }\n    }\n\n    private fun setState(hidden: Boolean) {\n        post { visibility = if (hidden) VISIBLE else GONE }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/HomeList.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.content.Intent\nimport android.util.AttributeSet\nimport android.widget.LinearLayout\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.button.MaterialButton\nimport knf.kuma.R\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.inflate\nimport knf.kuma.home.UpdateableAdapter\nimport org.jetbrains.anko.sdk27.coroutines.onClick\nimport androidx.core.content.withStyledAttributes\n\nclass HomeList : LinearLayout {\n\n    private var showAll = false\n    private var showAllText = \"Ver Todos\"\n    private var isLarge = false\n    private var startHidden = false\n    private var showError = false\n    private var subheaderText = \"Subheader\"\n    private var errorText: String? = null\n\n    private var isHidden = false\n\n    private val subheader: TextView by bind(R.id.subheader)\n    private val viewAll: MaterialButton by bind(R.id.viewAll)\n    private val progress: ProgressBar by bind(R.id.progress)\n    private val errorTV: TextView by bind(R.id.errorTV)\n    private val recyclerView: RecyclerView by bind(R.id.recycler)\n\n    private var adapter: UpdateableAdapter<*>? = null\n\n    constructor(context: Context) : super(context) {\n        inflate()\n    }\n\n    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {\n        inflate(attrs)\n    }\n\n    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {\n        inflate(attrs)\n    }\n\n    private fun loadVars(attrs: AttributeSet?) {\n        attrs?.let {\n            context.withStyledAttributes(it, R.styleable.HomeList) {\n                showAll = getBoolean(R.styleable.HomeList_hm_showViewAll, false)\n                showAllText = getString(R.styleable.HomeList_hm_viewAllText) ?: \"Ver Todos\"\n                isLarge = getBoolean(R.styleable.HomeList_hm_isLarge, false)\n                startHidden = getBoolean(R.styleable.HomeList_hm_startHidden, false)\n                subheaderText = getString(R.styleable.HomeList_hm_subheader) ?: \"Subheader\"\n                errorText = getString(R.styleable.HomeList_hm_errorText)\n                showError = !errorText.isNullOrEmpty()\n            }\n        }\n    }\n\n    private fun inflate(attrs: AttributeSet? = null) {\n        loadVars(attrs)\n        this.inflate(if (isLarge) R.layout.view_home_list_large else R.layout.view_home_list, true)\n    }\n\n    override fun onFinishInflate() {\n        super.onFinishInflate()\n        if (startHidden) visibility = GONE\n        viewAll.text = showAllText\n        subheader.text = subheaderText\n        errorTV.text = errorText\n        if (showAll) viewAll.visibility = VISIBLE\n    }\n\n    fun hide() {\n        doOnUIGlobal {\n            isHidden = true\n            visibility = GONE\n        }\n    }\n\n    fun show() {\n        doOnUIGlobal {\n            isHidden = false\n            visibility = VISIBLE\n        }\n    }\n\n    fun setSubheader(text: String) {\n        doOnUIGlobal { subheader.text = text.also { subheaderText = it } }\n    }\n\n    fun setError(text: String) {\n        doOnUIGlobal { errorTV.text = text.also { errorText = it } }\n    }\n\n    fun <T> setViewAllClass(clazz: Class<T>) {\n        viewAll.onClick { context.startActivity(Intent(context, clazz)) }\n    }\n\n    fun setViewAllOnClick(func: () -> Unit) {\n        viewAll.onClick { func() }\n    }\n\n    fun setAdapter(adapter: UpdateableAdapter<*>) {\n        doOnUIGlobal {\n            recyclerView.adapter = adapter.also { this.adapter = it }\n        }\n    }\n\n    fun updateList(list: List<Any>) {\n        doOnUIGlobal {\n            if (showError)\n                errorTV.visibility = if (list.isEmpty())\n                    VISIBLE\n                else\n                    GONE\n            else\n                visibility = if (list.isNotEmpty() && !isHidden)\n                    VISIBLE\n                else\n                    GONE\n            progress.visibility = GONE\n            adapter?.updateList(list)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/ListPreferenceDialogFragmentCompat.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.app.Dialog\r\nimport android.content.DialogInterface\r\nimport android.os.Bundle\r\nimport androidx.appcompat.app.AlertDialog\r\nimport androidx.preference.ListPreference\r\nimport androidx.preference.PreferenceDialogFragmentCompat\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\r\nimport com.afollestad.materialdialogs.list.listItemsSingleChoice\r\n\r\nclass ListPreferenceDialogFragmentCompat : PreferenceDialogFragmentCompat() {\r\n\r\n    internal /* synthetic access */ var mClickedDialogEntryIndex: Int = 0\r\n    private var mEntries: Array<CharSequence>? = null\r\n    private var mEntryValues: Array<CharSequence>? = null\r\n\r\n    private val listPreference: ListPreference\r\n        get() = preference as ListPreference\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        if (savedInstanceState == null) {\r\n            val preference = listPreference\r\n\r\n            if (preference.entries == null || preference.entryValues == null) {\r\n                throw IllegalStateException(\r\n                        \"ListPreference requires an entries array and an entryValues array.\")\r\n            }\r\n\r\n            mClickedDialogEntryIndex = preference.findIndexOfValue(preference.value)\r\n            mEntries = preference.entries\r\n            mEntryValues = preference.entryValues\r\n        } else {\r\n            mClickedDialogEntryIndex = savedInstanceState.getInt(SAVE_STATE_INDEX, 0)\r\n            mEntries = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRIES)\r\n            mEntryValues = savedInstanceState.getCharSequenceArray(SAVE_STATE_ENTRY_VALUES)\r\n        }\r\n    }\r\n\r\n    override fun onSaveInstanceState(outState: Bundle) {\r\n        super.onSaveInstanceState(outState)\r\n        outState.putInt(SAVE_STATE_INDEX, mClickedDialogEntryIndex)\r\n        outState.putCharSequenceArray(SAVE_STATE_ENTRIES, mEntries)\r\n        outState.putCharSequenceArray(SAVE_STATE_ENTRY_VALUES, mEntryValues)\r\n    }\r\n\r\n    override fun onPrepareDialogBuilder(builder: AlertDialog.Builder) {\r\n        super.onPrepareDialogBuilder(builder)\r\n        builder.setSingleChoiceItems(\r\n            mEntries, mClickedDialogEntryIndex\r\n        ) { dialog, which ->\r\n            mClickedDialogEntryIndex = which\r\n\r\n            // Clicking on an item simulates the positive button click, and dismisses\r\n            // the dialog.\r\n            this@ListPreferenceDialogFragmentCompat.onClick(\r\n                dialog,\r\n                DialogInterface.BUTTON_POSITIVE\r\n            )\r\n            dialog.dismiss()\r\n        }\r\n\r\n        // The typical interaction for list-based dialogs is to have click-on-an-item dismiss the\r\n        // dialog instead of the user having to press 'Ok'.\r\n        builder.setPositiveButton(null, null)\r\n    }\r\n\r\n    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {\r\n        return activity?.let {\r\n            try {\r\n                val entryList = mutableListOf<String>()\r\n                mEntries?.forEach { entry ->\r\n                    entryList.add(entry.toString())\r\n                }\r\n                MaterialDialog(it).apply {\r\n                    lifecycleOwner()\r\n                    title(text = preference.dialogTitle.toString())\r\n                    listItemsSingleChoice(items = entryList, initialSelection = mClickedDialogEntryIndex, waitForPositiveButton = false) { dialog, index, _ ->\r\n                        mClickedDialogEntryIndex = index\r\n                        this@ListPreferenceDialogFragmentCompat.onClick(dialog,\r\n                                DialogInterface.BUTTON_POSITIVE)\r\n                        dialog.dismiss()\r\n                    }\r\n                    positiveButton(android.R.string.ok)\r\n                }\r\n            } catch (e: Exception) {\r\n                super.onCreateDialog(savedInstanceState)\r\n            }\r\n        } ?: super.onCreateDialog(savedInstanceState)\r\n    }\r\n\r\n    override fun onDialogClosed(positiveResult: Boolean) {\r\n        if (positiveResult && mClickedDialogEntryIndex >= 0) {\r\n            val value = mEntryValues!![mClickedDialogEntryIndex].toString()\r\n            val preference = listPreference\r\n            if (preference.callChangeListener(value)) {\r\n                preference.value = value\r\n            }\r\n        }\r\n    }\r\n\r\n    companion object {\r\n\r\n        private const val SAVE_STATE_INDEX = \"ListPreferenceDialogFragment.index\"\r\n        private const val SAVE_STATE_ENTRIES = \"ListPreferenceDialogFragment.entries\"\r\n        private const val SAVE_STATE_ENTRY_VALUES = \"ListPreferenceDialogFragment.entryValues\"\r\n\r\n        fun newInstance(key: String): ListPreferenceDialogFragmentCompat {\r\n            val fragment = ListPreferenceDialogFragmentCompat()\r\n            val b = Bundle(1)\r\n            b.putString(ARG_KEY, key)\r\n            fragment.arguments = b\r\n            return fragment\r\n        }\r\n    }\r\n\r\n}\r\n\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/MainExecutor.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.os.Handler\r\nimport android.os.Looper\r\nimport java.util.concurrent.Executor\r\n\r\nclass MainExecutor : Executor {\r\n    override fun execute(command: Runnable?) {\r\n        command ?: return\r\n        Handler(Looper.getMainLooper()).post(command)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/PreferenceFragmentCompat.java",
    "content": "package knf.kuma.custom;\r\n\r\nimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;\r\n\r\nimport android.annotation.SuppressLint;\r\nimport android.content.Context;\r\nimport android.content.pm.PackageManager;\r\nimport android.content.res.TypedArray;\r\nimport android.graphics.Canvas;\r\nimport android.graphics.Rect;\r\nimport android.graphics.drawable.Drawable;\r\nimport android.os.Bundle;\r\nimport android.os.Handler;\r\nimport android.os.Message;\r\nimport android.util.TypedValue;\r\nimport android.view.ContextThemeWrapper;\r\nimport android.view.LayoutInflater;\r\nimport android.view.View;\r\nimport android.view.ViewGroup;\r\n\r\nimport androidx.annotation.NonNull;\r\nimport androidx.annotation.Nullable;\r\nimport androidx.annotation.RestrictTo;\r\nimport androidx.annotation.XmlRes;\r\nimport androidx.fragment.app.DialogFragment;\r\nimport androidx.fragment.app.Fragment;\r\nimport androidx.preference.DialogPreference;\r\nimport androidx.preference.EditTextPreference;\r\nimport androidx.preference.EditTextPreferenceDialogFragmentCompat;\r\nimport androidx.preference.ListPreference;\r\nimport androidx.preference.Preference;\r\nimport androidx.preference.PreferenceGroup;\r\nimport androidx.preference.PreferenceGroupAdapter;\r\nimport androidx.preference.PreferenceManager;\r\nimport androidx.preference.PreferenceRecyclerViewAccessibilityDelegate;\r\nimport androidx.preference.PreferenceScreen;\r\nimport androidx.preference.PreferenceViewHolder;\r\nimport androidx.recyclerview.widget.RecyclerView;\r\n\r\nimport knf.kuma.R;\r\n\r\n/**\r\n * Shows a hierarchy of {@link Preference} objects as\r\n * lists. These preferences will\r\n * automatically save to {@link android.content.SharedPreferences} as the user interacts with\r\n * them. To retrieve an instance of {@link android.content.SharedPreferences} that the\r\n * preference hierarchy in this fragment will use, call\r\n * {@link PreferenceManager#getDefaultSharedPreferences(android.content.Context)}\r\n * with a context in the same package as this fragment.\r\n * <p>\r\n * Furthermore, the preferences shown will follow the visual style of system\r\n * preferences. It is easy to create a hierarchy of preferences (that can be\r\n * shown on multiple screens) via XML. For these reasons, it is recommended to\r\n * use this fragment (as a superclass) to deal with preferences in applications.\r\n * <p>\r\n * A {@link PreferenceScreen} object should be at the top of the preference\r\n * hierarchy. Furthermore, subsequent {@link PreferenceScreen} in the hierarchy\r\n * denote a screen break--that is the preferences contained within subsequent\r\n * {@link PreferenceScreen} should be shown on another screen. The preference\r\n * framework handles this by calling {@link #onNavigateToScreen(PreferenceScreen)}.\r\n * <p>\r\n * The preference hierarchy can be formed in multiple ways:\r\n * <li> From an XML file specifying the hierarchy\r\n * <li> From different {@link android.app.Activity Activities} that each specify its own\r\n * preferences in an XML file via {@link android.app.Activity} meta-data\r\n * <li> From an object hierarchy rooted with {@link PreferenceScreen}\r\n * <p>\r\n * To inflate from XML, use the {@link #addPreferencesFromResource(int)}. The\r\n * root element should be a {@link PreferenceScreen}. Subsequent elements can point\r\n * to actual {@link Preference} subclasses. As mentioned above, subsequent\r\n * {@link PreferenceScreen} in the hierarchy will result in the screen break.\r\n * <p>\r\n * To specify an object hierarchy rooted with {@link PreferenceScreen}, use\r\n * {@link #setPreferenceScreen(PreferenceScreen)}.\r\n * <p>\r\n * As a convenience, this fragment implements a click listener for any\r\n * preference in the current hierarchy, see\r\n * {@link #onPreferenceTreeClick(Preference)}.\r\n *\r\n * <div class=\"special reference\">\r\n * <h3>Developer Guides</h3>\r\n * <p>For information about using {@code PreferenceFragment},\r\n * read the <a href=\"{@docRoot}guide/topics/ui/settings.html\">Settings</a>\r\n * guide.</p>\r\n * </div>\r\n *\r\n * <a name=\"SampleCode\"></a>\r\n * <h3>Sample Code</h3>\r\n *\r\n * <p>The following sample code shows a simple preference fragment that is\r\n * populated from a resource.  The resource it loads is:</p>\r\n * <p>\r\n * {@sample frameworks/support/samples/SupportPreferenceDemos/src/main/res/xml/preferences.xml preferences}\r\n *\r\n * <p>The fragment implementation itself simply populates the preferences\r\n * when created.  Note that the preferences framework takes care of loading\r\n * the current values out of the app preferences and writing them when changed:</p>\r\n * <p>\r\n * {@sample frameworks/support/samples/SupportPreferenceDemos/src/main/java/com/example/android/supportpreference/FragmentSupportPreferencesCompat.java\r\n * support_fragment_compat}\r\n *\r\n * @see Preference\r\n * @see PreferenceScreen\r\n */\r\n\r\n@SuppressLint(\"RestrictedApi\")\r\npublic abstract class PreferenceFragmentCompat extends Fragment implements\r\n        PreferenceManager.OnPreferenceTreeClickListener,\r\n        PreferenceManager.OnDisplayPreferenceDialogListener,\r\n        PreferenceManager.OnNavigateToScreenListener,\r\n        DialogPreference.TargetFragment {\r\n    /**\r\n     * Fragment argument used to specify the tag of the desired root\r\n     * {@link androidx.preference.PreferenceScreen} object.\r\n     */\r\n    public static final String ARG_PREFERENCE_ROOT =\r\n            \"androidx.preference.PreferenceFragmentCompat.PREFERENCE_ROOT\";\r\n    private static final String PREFERENCES_TAG = \"android:preferences\";\r\n    private static final String DIALOG_FRAGMENT_TAG =\r\n            \"androidx.preference.PreferenceFragment.DIALOG\";\r\n    private static final int MSG_BIND_PREFERENCES = 1;\r\n    private final DividerDecoration mDividerDecoration = new DividerDecoration();\r\n    @SuppressWarnings(\"WeakerAccess\") /* synthetic access */\r\n            RecyclerView mList;\r\n    final private Runnable mRequestFocus = new Runnable() {\r\n        @Override\r\n        public void run() {\r\n            mList.focusableViewAvailable(mList);\r\n        }\r\n    };\r\n    private PreferenceManager mPreferenceManager;\r\n    private boolean mHavePrefs;\r\n    private boolean mInitDone;\r\n    private Context mStyledContext;\r\n    private int mLayoutResId = R.layout.preference_list_fragment;\r\n    private final Handler mHandler = new Handler() {\r\n        @Override\r\n        public void handleMessage(Message msg) {\r\n            switch (msg.what) {\r\n                case MSG_BIND_PREFERENCES:\r\n                    bindPreferences();\r\n                    break;\r\n            }\r\n        }\r\n    };\r\n    private Runnable mSelectPreferenceRunnable;\r\n\r\n    @Override\r\n    public void onCreate(Bundle savedInstanceState) {\r\n        super.onCreate(savedInstanceState);\r\n        final TypedValue tv = new TypedValue();\r\n        getActivity().getTheme().resolveAttribute(R.attr.preferenceTheme, tv, true);\r\n        int theme = tv.resourceId;\r\n        if (theme == 0) {\r\n            // Fallback to default theme.\r\n            theme = R.style.PreferenceThemeOverlay;\r\n        }\r\n        mStyledContext = new ContextThemeWrapper(getActivity(), theme);\r\n        mPreferenceManager = new PreferenceManager(mStyledContext);\r\n        mPreferenceManager.setOnNavigateToScreenListener(this);\r\n        final Bundle args = getArguments();\r\n        final String rootKey;\r\n        if (args != null) {\r\n            rootKey = getArguments().getString(ARG_PREFERENCE_ROOT);\r\n        } else {\r\n            rootKey = null;\r\n        }\r\n        onCreatePreferences(savedInstanceState, rootKey);\r\n    }\r\n\r\n    /**\r\n     * Called during {@link #onCreate(Bundle)} to supply the preferences for this fragment.\r\n     * Subclasses are expected to call {@link #setPreferenceScreen(PreferenceScreen)} either\r\n     * directly or via helper methods such as {@link #addPreferencesFromResource(int)}.\r\n     *\r\n     * @param savedInstanceState If the fragment is being re-created from\r\n     *                           a previous saved state, this is the state.\r\n     * @param rootKey            If non-null, this preference fragment should be rooted at the\r\n     *                           {@link androidx.preference.PreferenceScreen} with this key.\r\n     */\r\n    public abstract void onCreatePreferences(Bundle savedInstanceState, String rootKey);\r\n\r\n    @Override\r\n    public View onCreateView(LayoutInflater inflater, ViewGroup container,\r\n                             Bundle savedInstanceState) {\r\n        TypedArray a = mStyledContext.obtainStyledAttributes(null,\r\n                R.styleable.PreferenceFragmentCompat,\r\n                R.attr.preferenceFragmentCompatStyle,\r\n                0);\r\n        mLayoutResId = a.getResourceId(R.styleable.PreferenceFragmentCompat_android_layout,\r\n                mLayoutResId);\r\n        final Drawable divider = a.getDrawable(\r\n                R.styleable.PreferenceFragmentCompat_android_divider);\r\n        final int dividerHeight = a.getDimensionPixelSize(\r\n                R.styleable.PreferenceFragmentCompat_android_dividerHeight, -1);\r\n        final boolean allowDividerAfterLastItem = a.getBoolean(\r\n                R.styleable.PreferenceFragmentCompat_allowDividerAfterLastItem, true);\r\n        a.recycle();\r\n        final LayoutInflater themedInflater = inflater.cloneInContext(mStyledContext);\r\n        final View view = themedInflater.inflate(mLayoutResId, container, false);\r\n        final View rawListContainer = view.findViewById(android.R.id.list_container);\r\n        if (!(rawListContainer instanceof ViewGroup listContainer)) {\r\n            throw new RuntimeException(\"Content has view with id attribute \"\r\n                    + \"'android.R.id.list_container' that is not a ViewGroup class\");\r\n        }\r\n        final RecyclerView listView = onCreateRecyclerView(themedInflater, listContainer,\r\n                savedInstanceState);\r\n        if (listView == null) {\r\n            throw new RuntimeException(\"Could not create RecyclerView\");\r\n        }\r\n        mList = listView;\r\n        listView.addItemDecoration(mDividerDecoration);\r\n        setDivider(divider);\r\n        if (dividerHeight != -1) {\r\n            setDividerHeight(dividerHeight);\r\n        }\r\n        mDividerDecoration.setAllowDividerAfterLastItem(allowDividerAfterLastItem);\r\n        // If mList isn't present in the view hierarchy, add it. mList is automatically inflated\r\n        // on an Auto device so don't need to add it.\r\n        if (mList.getParent() == null) {\r\n            listContainer.addView(mList);\r\n        }\r\n        mHandler.post(mRequestFocus);\r\n        return view;\r\n    }\r\n\r\n    /**\r\n     * Sets the drawable that will be drawn between each item in the list.\r\n     * <p>\r\n     * <strong>Note:</strong> If the drawable does not have an intrinsic\r\n     * height, you should also call {@link #setDividerHeight(int)}.\r\n     *\r\n     * @param divider the drawable to use\r\n     * @attr ref R.styleable#PreferenceFragmentCompat_android_divider\r\n     */\r\n    public void setDivider(Drawable divider) {\r\n        mDividerDecoration.setDivider(divider);\r\n    }\r\n\r\n    /**\r\n     * Sets the height of the divider that will be drawn between each item in the list. Calling\r\n     * this will override the intrinsic height as set by {@link #setDivider(Drawable)}\r\n     *\r\n     * @param height The new height of the divider in pixels.\r\n     * @attr ref R.styleable#PreferenceFragmentCompat_android_dividerHeight\r\n     */\r\n    public void setDividerHeight(int height) {\r\n        mDividerDecoration.setDividerHeight(height);\r\n    }\r\n\r\n    @Override\r\n    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {\r\n        super.onViewCreated(view, savedInstanceState);\r\n        if (savedInstanceState != null) {\r\n            Bundle container = savedInstanceState.getBundle(PREFERENCES_TAG);\r\n            if (container != null) {\r\n                final PreferenceScreen preferenceScreen = getPreferenceScreen();\r\n                if (preferenceScreen != null) {\r\n                    preferenceScreen.restoreHierarchyState(container);\r\n                }\r\n            }\r\n        }\r\n        if (mHavePrefs) {\r\n            bindPreferences();\r\n            if (mSelectPreferenceRunnable != null) {\r\n                mSelectPreferenceRunnable.run();\r\n                mSelectPreferenceRunnable = null;\r\n            }\r\n        }\r\n        mInitDone = true;\r\n    }\r\n\r\n    @Override\r\n    public void onStart() {\r\n        super.onStart();\r\n        mPreferenceManager.setOnPreferenceTreeClickListener(this);\r\n        mPreferenceManager.setOnDisplayPreferenceDialogListener(this);\r\n    }\r\n\r\n    @Override\r\n    public void onStop() {\r\n        super.onStop();\r\n        mPreferenceManager.setOnPreferenceTreeClickListener(null);\r\n        mPreferenceManager.setOnDisplayPreferenceDialogListener(null);\r\n    }\r\n\r\n    @Override\r\n    public void onDestroyView() {\r\n        mHandler.removeCallbacks(mRequestFocus);\r\n        mHandler.removeMessages(MSG_BIND_PREFERENCES);\r\n        if (mHavePrefs) {\r\n            unbindPreferences();\r\n        }\r\n        mList = null;\r\n        super.onDestroyView();\r\n    }\r\n\r\n    @Override\r\n    public void onSaveInstanceState(Bundle outState) {\r\n        super.onSaveInstanceState(outState);\r\n        final PreferenceScreen preferenceScreen = getPreferenceScreen();\r\n        if (preferenceScreen != null) {\r\n            Bundle container = new Bundle();\r\n            preferenceScreen.saveHierarchyState(container);\r\n            outState.putBundle(PREFERENCES_TAG, container);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns the {@link PreferenceManager} used by this fragment.\r\n     *\r\n     * @return The {@link PreferenceManager}.\r\n     */\r\n    public PreferenceManager getPreferenceManager() {\r\n        return mPreferenceManager;\r\n    }\r\n\r\n    /**\r\n     * Gets the root of the preference hierarchy that this fragment is showing.\r\n     *\r\n     * @return The {@link PreferenceScreen} that is the root of the preference\r\n     * hierarchy.\r\n     */\r\n    public PreferenceScreen getPreferenceScreen() {\r\n        return mPreferenceManager.getPreferenceScreen();\r\n    }\r\n\r\n    /**\r\n     * Sets the root of the preference hierarchy that this fragment is showing.\r\n     *\r\n     * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy.\r\n     */\r\n    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {\r\n        if (mPreferenceManager.setPreferences(preferenceScreen) && preferenceScreen != null) {\r\n            onUnbindPreferences();\r\n            mHavePrefs = true;\r\n            if (mInitDone) {\r\n                postBindPreferences();\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Inflates the given XML resource and adds the preference hierarchy to the current\r\n     * preference hierarchy.\r\n     *\r\n     * @param preferencesResId The XML resource ID to inflate.\r\n     */\r\n    public void addPreferencesFromResource(@XmlRes int preferencesResId) {\r\n        requirePreferenceManager();\r\n        setPreferenceScreen(mPreferenceManager.inflateFromResource(mStyledContext,\r\n                preferencesResId, getPreferenceScreen()));\r\n    }\r\n\r\n    /**\r\n     * Inflates the given XML resource and replaces the current preference hierarchy (if any) with\r\n     * the preference hierarchy rooted at {@code key}.\r\n     *\r\n     * @param preferencesResId The XML resource ID to inflate.\r\n     * @param key              The preference key of the {@link androidx.preference.PreferenceScreen}\r\n     *                         to use as the root of the preference hierarchy, or null to use the root\r\n     *                         {@link androidx.preference.PreferenceScreen}.\r\n     */\r\n    public void setPreferencesFromResource(@XmlRes int preferencesResId, @Nullable String key) {\r\n        requirePreferenceManager();\r\n        final PreferenceScreen xmlRoot = mPreferenceManager.inflateFromResource(mStyledContext,\r\n                preferencesResId, null);\r\n        final Preference root;\r\n        if (key != null) {\r\n            root = xmlRoot.findPreference(key);\r\n            if (!(root instanceof PreferenceScreen)) {\r\n                throw new IllegalArgumentException(\"Preference object with key \" + key\r\n                        + \" is not a PreferenceScreen\");\r\n            }\r\n        } else {\r\n            root = xmlRoot;\r\n        }\r\n        setPreferenceScreen((PreferenceScreen) root);\r\n    }\r\n\r\n    /**\r\n     * {@inheritDoc}\r\n     */\r\n    @Override\r\n    public boolean onPreferenceTreeClick(Preference preference) {\r\n        if (preference.getFragment() != null) {\r\n            boolean handled = false;\r\n            if (getCallbackFragment() instanceof OnPreferenceStartFragmentCallback) {\r\n                handled = ((OnPreferenceStartFragmentCallback) getCallbackFragment())\r\n                        .onPreferenceStartFragment(this, preference);\r\n            }\r\n            if (!handled && getActivity() instanceof OnPreferenceStartFragmentCallback) {\r\n                handled = ((OnPreferenceStartFragmentCallback) getActivity())\r\n                        .onPreferenceStartFragment(this, preference);\r\n            }\r\n            return handled;\r\n        }\r\n        return false;\r\n    }\r\n\r\n    @Override\r\n    public void onNavigateToScreen(PreferenceScreen preferenceScreen) {\r\n        boolean handled = false;\r\n        if (getCallbackFragment() instanceof OnPreferenceStartScreenCallback) {\r\n            handled = ((OnPreferenceStartScreenCallback) getCallbackFragment())\r\n                    .onPreferenceStartScreen(this, preferenceScreen);\r\n        }\r\n        if (!handled && getActivity() instanceof OnPreferenceStartScreenCallback) {\r\n            ((OnPreferenceStartScreenCallback) getActivity())\r\n                    .onPreferenceStartScreen(this, preferenceScreen);\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public Preference findPreference(CharSequence key) {\r\n        if (mPreferenceManager == null) {\r\n            return null;\r\n        }\r\n        return mPreferenceManager.findPreference(key);\r\n    }\r\n\r\n    private void requirePreferenceManager() {\r\n        if (mPreferenceManager == null) {\r\n            throw new RuntimeException(\"This should be called after super.onCreate.\");\r\n        }\r\n    }\r\n\r\n    private void postBindPreferences() {\r\n        if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) return;\r\n        mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget();\r\n    }\r\n\r\n    @SuppressWarnings(\"WeakerAccess\") /* synthetic access */\r\n    void bindPreferences() {\r\n        try {\r\n            final PreferenceScreen preferenceScreen = getPreferenceScreen();\r\n            if (preferenceScreen != null) {\r\n                getListView().setAdapter(onCreateAdapter(preferenceScreen));\r\n                preferenceScreen.onAttached();\r\n            }\r\n            onBindPreferences();\r\n        } catch (Exception e) {\r\n            e.printStackTrace();\r\n        }\r\n    }\r\n\r\n    private void unbindPreferences() {\r\n        final PreferenceScreen preferenceScreen = getPreferenceScreen();\r\n        if (preferenceScreen != null) {\r\n            preferenceScreen.onDetached();\r\n        }\r\n        onUnbindPreferences();\r\n    }\r\n\r\n    /**\r\n     * @hide\r\n     */\r\n    @RestrictTo(LIBRARY_GROUP)\r\n    protected void onBindPreferences() {\r\n    }\r\n\r\n    /**\r\n     * @hide\r\n     */\r\n    @RestrictTo(LIBRARY_GROUP)\r\n    protected void onUnbindPreferences() {\r\n    }\r\n\r\n    public final RecyclerView getListView() {\r\n        return mList;\r\n    }\r\n\r\n    /**\r\n     * Creates the {@link RecyclerView} used to display the preferences.\r\n     * Subclasses may override this to return a customized\r\n     * {@link RecyclerView}.\r\n     *\r\n     * @param inflater           The LayoutInflater object that can be used to inflate the\r\n     *                           {@link RecyclerView}.\r\n     * @param parent             The parent {@link android.view.View} that the RecyclerView will be attached to.\r\n     *                           This method should not add the view itself, but this can be used to generate\r\n     *                           the LayoutParams of the view.\r\n     * @param savedInstanceState If non-null, this view is being re-constructed from a previous\r\n     *                           saved state as given here\r\n     * @return A new RecyclerView object to be placed into the view hierarchy\r\n     */\r\n    @SuppressLint(\"RestrictedApi\")\r\n    public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,\r\n                                             Bundle savedInstanceState) {\r\n        // If device detected is Auto, use Auto's custom layout that contains a custom ViewGroup\r\n        // wrapping a RecyclerView\r\n        if (mStyledContext.getPackageManager().hasSystemFeature(PackageManager\r\n                .FEATURE_AUTOMOTIVE)) {\r\n            RecyclerView recyclerView = parent.findViewById(R.id.recycler_view);\r\n            if (recyclerView != null) {\r\n                return recyclerView;\r\n            }\r\n        }\r\n        RecyclerView recyclerView = (RecyclerView) inflater\r\n                .inflate(R.layout.preference_recyclerview, parent, false);\r\n        recyclerView.setLayoutManager(onCreateLayoutManager());\r\n        recyclerView.setAccessibilityDelegateCompat(\r\n                new PreferenceRecyclerViewAccessibilityDelegate(recyclerView));\r\n        return recyclerView;\r\n    }\r\n\r\n    /**\r\n     * Called from {@link #onCreateRecyclerView} to create the\r\n     * {@link RecyclerView.LayoutManager} for the created\r\n     * {@link RecyclerView}.\r\n     *\r\n     * @return A new {@link RecyclerView.LayoutManager} instance.\r\n     */\r\n    public RecyclerView.LayoutManager onCreateLayoutManager() {\r\n        return new VariantLinearLayoutManager(getActivity());\r\n    }\r\n\r\n    /**\r\n     * Creates the root adapter.\r\n     *\r\n     * @param preferenceScreen Preference screen object to create the adapter for.\r\n     * @return An adapter that contains the preferences contained in this {@link PreferenceScreen}.\r\n     */\r\n    protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {\r\n        return new PreferenceGroupAdapter(preferenceScreen);\r\n    }\r\n\r\n    /**\r\n     * Called when a preference in the tree requests to display a dialog. Subclasses should\r\n     * override this method to display custom dialogs or to handle dialogs for custom preference\r\n     * classes.\r\n     *\r\n     * @param preference The Preference object requesting the dialog.\r\n     */\r\n    @Override\r\n    public void onDisplayPreferenceDialog(Preference preference) {\r\n        boolean handled = false;\r\n        if (getCallbackFragment() instanceof OnPreferenceDisplayDialogCallback) {\r\n            handled = ((OnPreferenceDisplayDialogCallback) getCallbackFragment())\r\n                    .onPreferenceDisplayDialog(this, preference);\r\n        }\r\n        if (!handled && getActivity() instanceof OnPreferenceDisplayDialogCallback) {\r\n            handled = ((OnPreferenceDisplayDialogCallback) getActivity())\r\n                    .onPreferenceDisplayDialog(this, preference);\r\n        }\r\n        if (handled) {\r\n            return;\r\n        }\r\n        // check if dialog is already showing\r\n        if (getFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) {\r\n            return;\r\n        }\r\n        final DialogFragment f;\r\n        if (preference instanceof EditTextPreference) {\r\n            f = EditTextPreferenceDialogFragmentCompat.newInstance(preference.getKey());\r\n        } else if (preference instanceof ListPreference) {\r\n            f = ListPreferenceDialogFragmentCompat.Companion.newInstance(preference.getKey());\r\n        } else {\r\n            throw new IllegalArgumentException(\"Tried to display dialog for unknown \" +\r\n                    \"preference type. Did you forget to override onDisplayPreferenceDialog()?\");\r\n        }\r\n        f.setTargetFragment(this, 0);\r\n        f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);\r\n    }\r\n\r\n    /**\r\n     * Basically a wrapper for getParentFragment which is v17+. Used by the leanback preference lib.\r\n     *\r\n     * @return Fragment to possibly use as a callback\r\n     * @hide\r\n     */\r\n    @RestrictTo(LIBRARY_GROUP)\r\n    public Fragment getCallbackFragment() {\r\n        return null;\r\n    }\r\n\r\n    public void scrollToPreference(final String key) {\r\n        scrollToPreferenceInternal(null, key);\r\n    }\r\n\r\n    public void scrollToPreference(final Preference preference) {\r\n        scrollToPreferenceInternal(preference, null);\r\n    }\r\n\r\n    private void scrollToPreferenceInternal(final Preference preference, final String key) {\r\n        final Runnable r = new Runnable() {\r\n            @Override\r\n            public void run() {\r\n                final RecyclerView.Adapter adapter = mList.getAdapter();\r\n                if (!(adapter instanceof\r\n                        PreferenceGroup.PreferencePositionCallback)) {\r\n                    if (adapter != null) {\r\n                        throw new IllegalStateException(\"Adapter must implement \"\r\n                                + \"PreferencePositionCallback\");\r\n                    } else {\r\n                        // Adapter was set to null, so don't scroll I guess?\r\n                        return;\r\n                    }\r\n                }\r\n                final int position;\r\n                if (preference != null) {\r\n                    position = ((PreferenceGroup.PreferencePositionCallback) adapter)\r\n                            .getPreferenceAdapterPosition(preference);\r\n                } else {\r\n                    position = ((PreferenceGroup.PreferencePositionCallback) adapter)\r\n                            .getPreferenceAdapterPosition(key);\r\n                }\r\n                if (position != RecyclerView.NO_POSITION) {\r\n                    mList.scrollToPosition(position);\r\n                } else {\r\n                    // Item not found, wait for an update and try again\r\n                    adapter.registerAdapterDataObserver(\r\n                            new ScrollToPreferenceObserver(adapter, mList, preference, key));\r\n                }\r\n            }\r\n        };\r\n        if (mList == null) {\r\n            mSelectPreferenceRunnable = r;\r\n        } else {\r\n            r.run();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Interface that PreferenceFragment's containing activity should\r\n     * implement to be able to process preference items that wish to\r\n     * switch to a specified fragment.\r\n     */\r\n    public interface OnPreferenceStartFragmentCallback {\r\n        /**\r\n         * Called when the user has clicked on a Preference that has\r\n         * a fragment class name associated with it.  The implementation\r\n         * should instantiate and switch to an instance of the given\r\n         * fragment.\r\n         *\r\n         * @param caller The fragment requesting navigation.\r\n         * @param pref   The preference requesting the fragment.\r\n         * @return true if the fragment creation has been handled\r\n         */\r\n        boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref);\r\n    }\r\n\r\n    /**\r\n     * Interface that PreferenceFragment's containing activity should\r\n     * implement to be able to process preference items that wish to\r\n     * switch to a new screen of preferences.\r\n     */\r\n    public interface OnPreferenceStartScreenCallback {\r\n        /**\r\n         * Called when the user has clicked on a PreferenceScreen item in order to navigate to a new\r\n         * screen of preferences.\r\n         *\r\n         * @param caller The fragment requesting navigation.\r\n         * @param pref   The preference screen to navigate to.\r\n         * @return true if the screen navigation has been handled\r\n         */\r\n        boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen pref);\r\n    }\r\n\r\n    public interface OnPreferenceDisplayDialogCallback {\r\n        /**\r\n         * @param caller The fragment containing the preference requesting the dialog.\r\n         * @param pref   The preference requesting the dialog.\r\n         * @return true if the dialog creation has been handled.\r\n         */\r\n        boolean onPreferenceDisplayDialog(@NonNull PreferenceFragmentCompat caller,\r\n                                          Preference pref);\r\n    }\r\n\r\n    private static class ScrollToPreferenceObserver extends RecyclerView.AdapterDataObserver {\r\n        private final RecyclerView.Adapter mAdapter;\r\n        private final RecyclerView mList;\r\n        private final Preference mPreference;\r\n        private final String mKey;\r\n\r\n        public ScrollToPreferenceObserver(RecyclerView.Adapter adapter, RecyclerView list,\r\n                                          Preference preference, String key) {\r\n            mAdapter = adapter;\r\n            mList = list;\r\n            mPreference = preference;\r\n            mKey = key;\r\n        }\r\n\r\n        private void scrollToPreference() {\r\n            mAdapter.unregisterAdapterDataObserver(this);\r\n            final int position;\r\n            if (mPreference != null) {\r\n                position = ((PreferenceGroup.PreferencePositionCallback) mAdapter)\r\n                        .getPreferenceAdapterPosition(mPreference);\r\n            } else {\r\n                position = ((PreferenceGroup.PreferencePositionCallback) mAdapter)\r\n                        .getPreferenceAdapterPosition(mKey);\r\n            }\r\n            if (position != RecyclerView.NO_POSITION) {\r\n                mList.scrollToPosition(position);\r\n            }\r\n        }\r\n\r\n        @Override\r\n        public void onChanged() {\r\n            scrollToPreference();\r\n        }\r\n\r\n        @Override\r\n        public void onItemRangeChanged(int positionStart, int itemCount) {\r\n            scrollToPreference();\r\n        }\r\n\r\n        @Override\r\n        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {\r\n            scrollToPreference();\r\n        }\r\n\r\n        @Override\r\n        public void onItemRangeInserted(int positionStart, int itemCount) {\r\n            scrollToPreference();\r\n        }\r\n\r\n        @Override\r\n        public void onItemRangeRemoved(int positionStart, int itemCount) {\r\n            scrollToPreference();\r\n        }\r\n\r\n        @Override\r\n        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {\r\n            scrollToPreference();\r\n        }\r\n    }\r\n\r\n    private class DividerDecoration extends RecyclerView.ItemDecoration {\r\n        private Drawable mDivider;\r\n        private int mDividerHeight;\r\n        private boolean mAllowDividerAfterLastItem = true;\r\n\r\n        DividerDecoration() {\r\n        }\r\n\r\n        @Override\r\n        public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {\r\n            if (mDivider == null) {\r\n                return;\r\n            }\r\n            final int childCount = parent.getChildCount();\r\n            final int width = parent.getWidth();\r\n            for (int childViewIndex = 0; childViewIndex < childCount; childViewIndex++) {\r\n                final View view = parent.getChildAt(childViewIndex);\r\n                if (shouldDrawDividerBelow(view, parent)) {\r\n                    int top = (int) view.getY() + view.getHeight();\r\n                    mDivider.setBounds(0, top, width, top + mDividerHeight);\r\n                    mDivider.draw(c);\r\n                }\r\n            }\r\n        }\r\n\r\n        @Override\r\n        public void getItemOffsets(Rect outRect, View view, RecyclerView parent,\r\n                                   RecyclerView.State state) {\r\n            if (shouldDrawDividerBelow(view, parent)) {\r\n                outRect.bottom = mDividerHeight;\r\n            }\r\n        }\r\n\r\n        private boolean shouldDrawDividerBelow(View view, RecyclerView parent) {\r\n            final RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);\r\n            final boolean dividerAllowedBelow = holder instanceof PreferenceViewHolder\r\n                    && ((PreferenceViewHolder) holder).isDividerAllowedBelow();\r\n            if (!dividerAllowedBelow) {\r\n                return false;\r\n            }\r\n            boolean nextAllowed = mAllowDividerAfterLastItem;\r\n            int index = parent.indexOfChild(view);\r\n            if (index < parent.getChildCount() - 1) {\r\n                final View nextView = parent.getChildAt(index + 1);\r\n                final RecyclerView.ViewHolder nextHolder = parent.getChildViewHolder(nextView);\r\n                nextAllowed = nextHolder instanceof PreferenceViewHolder\r\n                        && ((PreferenceViewHolder) nextHolder).isDividerAllowedAbove();\r\n            }\r\n            return nextAllowed;\r\n        }\r\n\r\n        public void setDivider(Drawable divider) {\r\n            if (divider != null) {\r\n                mDividerHeight = divider.getIntrinsicHeight();\r\n            } else {\r\n                mDividerHeight = 0;\r\n            }\r\n            mDivider = divider;\r\n            mList.invalidateItemDecorations();\r\n        }\r\n\r\n        public void setDividerHeight(int dividerHeight) {\r\n            mDividerHeight = dividerHeight;\r\n            mList.invalidateItemDecorations();\r\n        }\r\n\r\n        public void setAllowDividerAfterLastItem(boolean allowDividerAfterLastItem) {\r\n            mAllowDividerAfterLastItem = allowDividerAfterLastItem;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/SSLManager.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport knf.kuma.commons.isMIUI\r\nimport knf.kuma.commons.noCrash\r\nimport java.security.SecureRandom\r\nimport java.security.cert.CertificateException\r\nimport java.security.cert.X509Certificate\r\nimport javax.net.ssl.HttpsURLConnection\r\nimport javax.net.ssl.SSLContext\r\nimport javax.net.ssl.TrustManager\r\nimport javax.net.ssl.X509TrustManager\r\n\r\nobject SSLManager {\r\n    fun disable() {\r\n        val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {\r\n            @Throws(CertificateException::class)\r\n            override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {\r\n                noCrash(false) {\r\n                    chain.forEach {\r\n                        it.checkValidity()\r\n                    }\r\n                }\r\n            }\r\n\r\n            @Throws(CertificateException::class)\r\n            override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {\r\n                noCrash(false) {\r\n                    chain.forEach {\r\n                        it.checkValidity()\r\n                    }\r\n                }\r\n            }\r\n\r\n            override fun getAcceptedIssuers(): Array<X509Certificate> {\r\n                return arrayOf()\r\n            }\r\n        })\r\n\r\n        try {\r\n            val sslContext = SSLContext.getInstance(\"SSL\").apply {\r\n                init(null, trustAllCerts, SecureRandom())\r\n            }\r\n            val factory = if (isMIUI) {\r\n                TlsOnlySocketFactory(sslContext.socketFactory)\r\n            } else {\r\n                sslContext.socketFactory\r\n            }\r\n            HttpsURLConnection.setDefaultSSLSocketFactory(factory)\r\n        } catch (e: Exception) {\r\n            e.printStackTrace()\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/SeenAnimeOverlay.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.view.LayoutInflater\nimport android.view.animation.Animation\nimport android.view.animation.AnimationUtils\nimport android.widget.LinearLayout\nimport knf.kuma.R\n\nclass SeenAnimeOverlay : LinearLayout {\n    constructor(context: Context) : super(context) {\n        inflate(context)\n    }\n\n    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {\n        inflate(context)\n    }\n\n    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {\n        inflate(context)\n    }\n\n    private fun inflate(context: Context) {\n        val inflater = context\n                .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater\n        inflater.inflate(R.layout.view_seen_overlay, this)\n    }\n\n    fun setSeen(seen: Boolean, animate: Boolean) {\n        setState(seen)\n        if (animate) {\n            post {\n                val animation = AnimationUtils.loadAnimation(context, if (seen) R.anim.fadein else R.anim.fadeout)\n                animation.duration = 200\n                animation.setAnimationListener(object : Animation.AnimationListener {\n                    override fun onAnimationStart(animation: Animation) {\n\n                    }\n\n                    override fun onAnimationEnd(animation: Animation) {\n\n                    }\n\n                    override fun onAnimationRepeat(animation: Animation) {\n\n                    }\n                })\n                startAnimation(animation)\n            }\n        }\n    }\n\n    private fun setState(seen: Boolean) {\n        post { visibility = if (seen) VISIBLE else GONE }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/SingleFragmentActivity.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.os.Bundle\r\nimport androidx.annotation.LayoutRes\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.appcompat.widget.Toolbar\r\nimport androidx.fragment.app.Fragment\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.EAHelper\r\nimport org.jetbrains.anko.find\r\n\r\nabstract class SingleFragmentActivity : AppCompatActivity() {\r\n\r\n    private val layoutResId: Int\r\n        @LayoutRes\r\n        get() = R.layout.activity_fragment\r\n\r\n    protected abstract fun createFragment(): Fragment\r\n\r\n    abstract fun getActivityTitle(): String\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n\r\n        setContentView(layoutResId)\r\n        with(find<Toolbar>(R.id.toolbar)) {\r\n            setSupportActionBar(this)\r\n            setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\r\n        }\r\n        supportActionBar?.setDisplayShowHomeEnabled(true)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.title = getActivityTitle()\r\n\r\n        val fm = supportFragmentManager\r\n        var fragment = fm.findFragmentById(R.id.fragment_container)\r\n\r\n        if (fragment == null) {\r\n            fragment = createFragment()\r\n            fm.beginTransaction()\r\n                    .add(R.id.fragment_container, fragment)\r\n                    .commit()\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/SingleFragmentMaterialActivity.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.os.Bundle\r\nimport androidx.annotation.LayoutRes\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.appcompat.widget.Toolbar\r\nimport androidx.fragment.app.Fragment\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.setSurfaceBars\r\nimport org.jetbrains.anko.find\r\n\r\nabstract class SingleFragmentMaterialActivity : AppCompatActivity() {\r\n\r\n    private val layoutResId: Int\r\n        @LayoutRes\r\n        get() = R.layout.activity_fragment_material\r\n\r\n    protected abstract fun createFragment(): Fragment\r\n\r\n    abstract fun getActivityTitle(): String\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setSurfaceBars()\r\n        setContentView(layoutResId)\r\n\r\n        with(find<Toolbar>(R.id.toolbar)) {\r\n            setSupportActionBar(this)\r\n            setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\r\n        }\r\n        supportActionBar?.setDisplayShowHomeEnabled(true)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.title = getActivityTitle()\r\n\r\n        val fm = supportFragmentManager\r\n        var fragment = fm.findFragmentById(R.id.fragment_container)\r\n\r\n        if (fragment == null) {\r\n            fragment = createFragment()\r\n            fm.beginTransaction()\r\n                    .add(R.id.fragment_container, fragment)\r\n                    .commit()\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/StateView.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.animation.Animator\r\nimport android.animation.AnimatorListenerAdapter\r\nimport android.content.Context\r\nimport android.util.AttributeSet\r\nimport android.view.View\r\nimport android.widget.LinearLayout\r\nimport android.widget.TextView\r\nimport androidx.core.content.ContextCompat\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport org.jetbrains.anko.find\r\nimport org.jetbrains.anko.textColor\r\n\r\nclass StateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : LinearLayout(context, attrs, defStyle) {\r\n    private var titleText = \"PlaceHolder\"\r\n    private var isSetted = false\r\n\r\n    init {\r\n        attrs?.let {\r\n            val array = context.obtainStyledAttributes(it, R.styleable.StateView)\r\n            titleText = array.getString(R.styleable.StateView_sv_title) ?: titleText\r\n            array.recycle()\r\n        }\r\n        inflate(context, R.layout.layout_loading_text, this)\r\n    }\r\n\r\n    override fun onFinishInflate() {\r\n        super.onFinishInflate()\r\n        find<TextView>(R.id.title).text = titleText\r\n    }\r\n\r\n    fun load(contentText: String, state: Int = STATE_NORMAL) {\r\n        val shortAnimationDuration = resources.getInteger(android.R.integer.config_shortAnimTime).toLong()\r\n        doOnUIGlobal {\r\n            visibility = VISIBLE\r\n            val textView = find<TextView>(R.id.text)\r\n            val loading = find<View>(R.id.loading)\r\n            when (state) {\r\n                STATE_OK -> textView.textColor = ContextCompat.getColor(context, R.color.stateOk)\r\n                STATE_WARNING -> textView.textColor = ContextCompat.getColor(context, R.color.stateWarning)\r\n                STATE_ERROR -> textView.textColor = ContextCompat.getColor(context, R.color.stateError)\r\n            }\r\n            textView.apply {\r\n                text = contentText\r\n                if (!isSetted) {\r\n                    alpha = 0f\r\n                    visibility = VISIBLE\r\n                    animate()\r\n                            .alpha(1f)\r\n                            .setDuration(shortAnimationDuration)\r\n                            .setListener(null)\r\n                }\r\n            }\r\n            if (!isSetted)\r\n                loading.animate()\r\n                        .alpha(0f)\r\n                        .setDuration(shortAnimationDuration)\r\n                        .setListener(object : AnimatorListenerAdapter() {\r\n                            override fun onAnimationEnd(animation: Animator) {\r\n                                loading.visibility = GONE\r\n                            }\r\n                        })\r\n            isSetted = true\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        const val STATE_NORMAL = 0\r\n        const val STATE_OK = 1\r\n        const val STATE_WARNING = 2\r\n        const val STATE_ERROR = 3\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/StateViewMaterial.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.animation.Animator\r\nimport android.animation.AnimatorListenerAdapter\r\nimport android.content.Context\r\nimport android.util.AttributeSet\r\nimport android.view.View\r\nimport android.widget.LinearLayout\r\nimport android.widget.TextView\r\nimport androidx.core.content.ContextCompat\r\nimport androidx.core.content.withStyledAttributes\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport org.jetbrains.anko.find\r\nimport org.jetbrains.anko.textColor\r\n\r\nclass StateViewMaterial @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : LinearLayout(context, attrs, defStyle) {\r\n    private var titleText = \"PlaceHolder\"\r\n    private var isSetted = false\r\n\r\n    init {\r\n        attrs?.let {\r\n            context.withStyledAttributes(it, R.styleable.StateViewMaterial) {\r\n                titleText = getString(R.styleable.StateViewMaterial_svm_title) ?: titleText\r\n            }\r\n        }\r\n        inflate(context, R.layout.layout_loading_text_material, this)\r\n    }\r\n\r\n    override fun onFinishInflate() {\r\n        super.onFinishInflate()\r\n        find<TextView>(R.id.title).text = titleText\r\n    }\r\n\r\n    fun load(contentText: String, state: Int = STATE_NORMAL) {\r\n        val shortAnimationDuration = resources.getInteger(android.R.integer.config_shortAnimTime).toLong()\r\n        doOnUIGlobal {\r\n            visibility = VISIBLE\r\n            val textView = find<TextView>(R.id.text)\r\n            val loading = find<View>(R.id.loading)\r\n            when (state) {\r\n                STATE_OK -> textView.textColor = ContextCompat.getColor(context, R.color.stateOk)\r\n                STATE_WARNING -> textView.textColor = ContextCompat.getColor(context, R.color.stateWarning)\r\n                STATE_ERROR -> textView.textColor = ContextCompat.getColor(context, R.color.stateError)\r\n            }\r\n            textView.apply {\r\n                text = contentText\r\n                if (!isSetted) {\r\n                    alpha = 0f\r\n                    visibility = VISIBLE\r\n                    animate()\r\n                            .alpha(1f)\r\n                            .setDuration(shortAnimationDuration)\r\n                            .setListener(null)\r\n                }\r\n            }\r\n            if (!isSetted)\r\n                loading.animate()\r\n                        .alpha(0f)\r\n                        .setDuration(shortAnimationDuration)\r\n                        .setListener(object : AnimatorListenerAdapter() {\r\n                            override fun onAnimationEnd(animation: Animator) {\r\n                                loading.visibility = GONE\r\n                            }\r\n                        })\r\n            isSetted = true\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        const val STATE_NORMAL = 0\r\n        const val STATE_OK = 1\r\n        const val STATE_WARNING = 2\r\n        const val STATE_ERROR = 3\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/SyncItemView.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.view.LayoutInflater\nimport android.widget.RelativeLayout\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.backup.Backups\nimport knf.kuma.backup.framework.BackupService\nimport knf.kuma.backup.objects.BackupObject\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.noCrash\nimport knf.kuma.databinding.SyncItemLayoutBinding\nimport org.jetbrains.anko.sdk27.coroutines.onLongClick\nimport xdroid.toaster.Toaster\n\nclass SyncItemView : RelativeLayout {\n\n    private var cardTitle: String? = \"Error\"\n    private var showDivider = true\n    private var hideBackup = false\n    private var actionId: String = \"neutral\"\n\n    var backupObj: BackupObject<*>? = null\n        private set\n\n    constructor(context: Context) : super(context) {\n        inflate(context)\n    }\n\n    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {\n        inflate(context)\n        setDefaults(context, attrs)\n    }\n\n    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {\n        inflate(context)\n        setDefaults(context, attrs)\n    }\n\n    private lateinit var binding: SyncItemLayoutBinding\n    private fun inflate(context: Context) {\n        val inflater = context\n                .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater\n        inflater.inflate(R.layout.sync_item_layout, this)\n        binding = SyncItemLayoutBinding.bind(this)\n    }\n\n    private fun setDefaults(context: Context, attrs: AttributeSet) {\n        val array = context.obtainStyledAttributes(attrs, R.styleable.SyncItemView)\n        cardTitle = array.getString(R.styleable.SyncItemView_si_title)\n        showDivider = array.getBoolean(R.styleable.SyncItemView_si_showDivider, true)\n        hideBackup = array.getBoolean(R.styleable.SyncItemView_si_hideBackup, false)\n        actionId = array.getString(R.styleable.SyncItemView_si_actionId) ?: \"neutral\"\n        array.recycle()\n    }\n\n    override fun onFinishInflate() {\n        super.onFinishInflate()\n        binding.title.text = cardTitle\n        if (!showDivider)\n            binding.separator.visibility = GONE\n        if (hideBackup)\n            binding.backup.isEnabled = false\n    }\n\n    fun enableBackup(backupObject: BackupObject<*>?, onClick: OnClick) {\n        post {\n            noCrash {\n                if (Network.isConnected) {\n                    if (!hideBackup)\n                        binding.backup.isEnabled = true\n                    if (backupObject == null)\n                        binding.date.text = \"Sin respaldo\"\n                    else {\n                        binding.date.text = backupObject.date\n                        binding.restore.isEnabled = true\n                    }\n                    binding.backup.onLongClick(returnValue = true) { Toaster.toast(\"Respaldar a la nube\") }\n                    binding.backup.setOnClickListener {\n                        noCrash {\n                            onClick.onAction(this@SyncItemView, actionId, true)\n                            AchievementManager.onBackup()\n                        }\n                    }\n                    binding.restore.onLongClick(returnValue = true) { Toaster.toast(\"Restaurar desde la nube\") }\n                    binding.restore.setOnClickListener { noCrash { onClick.onAction(this@SyncItemView, actionId, false) } }\n                } else {\n                    binding.date.text = \"Sin internet\"\n                }\n            }\n        }\n    }\n\n    fun clear() {\n        backupObj = null\n        post {\n            binding.backup.isEnabled = false\n            binding.restore.isEnabled = false\n            binding.date.text = \"Cargando...\"\n        }\n    }\n\n    fun init(service: BackupService?, onClick: OnClick) {\n        Backups.search(service, actionId) {\n            backupObj = it\n            enableBackup(backupObj, onClick)\n        }\n    }\n\n    interface OnClick {\n        fun onAction(syncItemView: SyncItemView, id: String, isBackup: Boolean)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/SyncStaticItemView.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.graphics.drawable.AnimatedVectorDrawable\nimport android.util.AttributeSet\nimport android.view.LayoutInflater\nimport android.view.animation.Animation\nimport android.view.animation.LinearInterpolator\nimport android.view.animation.RotateAnimation\nimport android.widget.RelativeLayout\nimport androidx.core.content.ContextCompat\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.Observer\nimport com.github.marlonlom.utilities.timeago.TimeAgo\nimport knf.kuma.R\nimport knf.kuma.backup.firestore.FirestoreManager\nimport knf.kuma.databinding.ViewSyncFirestoreBinding\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.defaultSharedPreferences\n\n\nclass SyncStaticItemView : RelativeLayout {\n\n    private var cardTitle: String? = \"Error\"\n    private var showDivider = true\n    private var prefId: String = \"neutral\"\n    private lateinit var lastState: FirestoreManager.State\n    private var rotateAnimation: RotateAnimation? = null\n    private var isRotating = false\n    private var stopRotating = false\n\n    constructor(context: Context) : super(context) {\n        inflate(context)\n    }\n\n    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {\n        inflate(context)\n        setDefaults(context, attrs)\n    }\n\n    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {\n        inflate(context)\n        setDefaults(context, attrs)\n    }\n\n    private lateinit var binding: ViewSyncFirestoreBinding\n    private fun inflate(context: Context) {\n        val inflater = context\n                .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater\n        binding = ViewSyncFirestoreBinding.inflate(inflater, this, true)\n    }\n\n    private fun setDefaults(context: Context, attrs: AttributeSet) {\n        val array = context.obtainStyledAttributes(attrs, R.styleable.SyncStaticItemView)\n        cardTitle = array.getString(R.styleable.SyncStaticItemView_ssi_title)\n        showDivider = array.getBoolean(R.styleable.SyncStaticItemView_ssi_showDivider, true)\n        prefId = array.getString(R.styleable.SyncStaticItemView_ssi_prefId) ?: \"neutral\"\n        array.recycle()\n    }\n\n    fun suscribe(owner: LifecycleOwner, liveData: LiveData<FirestoreManager.State>) {\n        liveData.observe(owner, Observer {\n            when (it) {\n                FirestoreManager.State.IDLE -> stateOk(it)\n                FirestoreManager.State.UPLOAD, FirestoreManager.State.SYNC -> stateSync(it)\n                else -> stateOk(FirestoreManager.State.IDLE)\n            }\n        })\n    }\n\n    private fun stateOk(state: FirestoreManager.State) {\n        GlobalScope.launch(Dispatchers.Main) {\n            if (!::lastState.isInitialized) {\n                lastState = state\n                binding.indicator.setImageResource(R.drawable.ic_check_bold)\n                binding.stateText.text = \"Última sincronización: ${timeAgo()}\"\n                return@launch\n            } else if (lastState != FirestoreManager.State.IDLE) {\n                lastState = state\n                stopRotating = true\n                while (isRotating) {\n                    delay(100)\n                }\n                val transform = ContextCompat.getDrawable(context, R.drawable.anim_sync_check) as? AnimatedVectorDrawable\n                binding.indicator.setImageDrawable(transform)\n                transform?.start()\n                delay(600)\n                binding.stateText.text = \"Última sincronización: ${timeAgo()}\"\n                binding.indicator.setImageResource(R.drawable.ic_check_bold)\n            }\n        }\n    }\n\n    private fun timeAgo() = context.defaultSharedPreferences.getLong(prefId, -1L).let {\n        if (it == -1L)\n            \"Sin registros\"\n        else\n            TimeAgo.using(it)\n    }\n\n    private fun stateSync(state: FirestoreManager.State) {\n        GlobalScope.launch(Dispatchers.Main) {\n            if (!::lastState.isInitialized) {\n                lastState = state\n                binding.stateText.text = \"Sincronizando...\"\n                binding.indicator.setImageResource(R.drawable.ic_sync_rotate)\n            } else if (lastState == FirestoreManager.State.IDLE) {\n                lastState = state\n                val transform = ContextCompat.getDrawable(context, R.drawable.anim_check_sync) as? AnimatedVectorDrawable\n                binding.indicator.setImageDrawable(transform)\n                transform?.start()\n                delay(600)\n                binding.stateText.text = \"Sincronizando...\"\n                binding.indicator.setImageResource(R.drawable.ic_sync_rotate)\n            }\n            rotateAnimation = RotateAnimation(180f, 0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f).apply {\n                duration = 500\n                interpolator = LinearInterpolator()\n                repeatCount = Animation.INFINITE\n                setAnimationListener(object : Animation.AnimationListener {\n                    override fun onAnimationRepeat(p0: Animation?) {\n                        if (stopRotating) {\n                            p0?.repeatCount = 1\n                            stopRotating = false\n                        }\n                    }\n\n                    override fun onAnimationEnd(p0: Animation?) {\n                        isRotating = false\n                    }\n\n                    override fun onAnimationStart(p0: Animation?) {\n                    }\n                })\n            }.also {\n                isRotating = true\n                binding.indicator.startAnimation(it)\n            }\n        }\n    }\n\n    override fun onFinishInflate() {\n        super.onFinishInflate()\n        binding.title.text = cardTitle\n        if (!showDivider)\n            binding.separator.visibility = GONE\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/ThemedControlsActivity.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.os.Bundle\r\nimport android.widget.RelativeLayout\r\nimport com.bumptech.glide.load.model.GlideUrl\r\nimport com.bumptech.glide.load.model.LazyHeaders\r\nimport es.munix.multidisplaycast.CastControlsActivity\r\nimport knf.kuma.App\r\nimport knf.kuma.ads.implBannerCast\r\nimport knf.kuma.commons.BypassUtil\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.PrefsUtil\r\n\r\nclass ThemedControlsActivity : CastControlsActivity() {\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n    }\r\n\r\n    override fun createImgUrl(url: String): GlideUrl {\r\n        return GlideUrl(url, LazyHeaders.Builder().apply {\r\n            addHeader(\"Cookie\", BypassUtil.getStringCookie(App.context))\r\n            addHeader(\"User-Agent\", BypassUtil.userAgent)\r\n        }.build())\r\n    }\r\n\r\n    override fun setUpAd(placeholder: RelativeLayout) {\r\n        if (PrefsUtil.isAdsEnabled)\r\n            placeholder.implBannerCast()\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/TlsOnlySocketFactory.java",
    "content": "/*\n * Copyright 2015 Bhavit Singh Sengar\n * Copyright 2015-2016 Hans-Christoph Steiner\n * Copyright 2015-2016 Nathan Freitas\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 * http://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 * From https://stackoverflow.com/a/29946540\n */\n\npackage knf.kuma.custom;\n\nimport android.net.SSLCertificateSocketFactory;\nimport android.os.Build;\nimport android.util.Log;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.net.InetAddress;\nimport java.net.Socket;\nimport java.net.SocketAddress;\nimport java.net.SocketException;\nimport java.nio.channels.SocketChannel;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.regex.Pattern;\n\nimport javax.net.ssl.HandshakeCompletedListener;\nimport javax.net.ssl.HttpsURLConnection;\nimport javax.net.ssl.SSLSession;\nimport javax.net.ssl.SSLSocket;\nimport javax.net.ssl.SSLSocketFactory;\n\n/**\n * While making a secure connection, Android's {@link HttpsURLConnection} falls\n * back to SSLv3 from TLSv1. This is a bug in android versions &lt; 4.4. It can be\n * fixed by removing the SSLv3 protocol from Enabled Protocols list. Use this as\n * the {@link SSLSocketFactory} for\n * {@link HttpsURLConnection#setDefaultSSLSocketFactory(SSLSocketFactory)}\n *\n * @author Bhavit S. Sengar\n * @author Hans-Christoph Steiner\n * @see SSLSocket table of protocols and ciphers Android supports\n * @see <a href=\"https://android.googlesource.com/platform/external/boringssl/+/refs/tags/android-7.1.2_r36/src/include/openssl/ssl.h#3267\">source of protocol name constants</a>\n */\npublic class TlsOnlySocketFactory extends SSLSocketFactory {\n\n    public static final String TLSV1_2 = \"TLSv1.2\";\n    public static final String TLSV1_1 = \"TLSv1.1\";\n    public static final String TLSV1 = \"TLSv1\";\n    public static final String SSLV3 = \"SSLv3\";\n    public static final String SSLV2 = \"SSLv2\";\n\n    private static final int HANDSHAKE_TIMEOUT = 0;\n    private static final String TAG = \"TlsOnlySocketFactory\";\n    private final SSLSocketFactory delegate;\n    private final boolean compatible;\n\n    public TlsOnlySocketFactory() {\n        this.delegate = SSLCertificateSocketFactory.getDefault(HANDSHAKE_TIMEOUT, null);\n        this.compatible = false;\n    }\n\n    public TlsOnlySocketFactory(SSLSocketFactory delegate) {\n        this.delegate = delegate;\n        this.compatible = false;\n    }\n\n    /**\n     * Make {@link SSLSocket}s that are compatible with outdated servers.\n     *\n     * @param delegate\n     * @param compatible\n     */\n    public TlsOnlySocketFactory(SSLSocketFactory delegate, boolean compatible) {\n        this.delegate = delegate;\n        this.compatible = compatible;\n    }\n\n    @Override\n    public String[] getDefaultCipherSuites() {\n        return delegate.getDefaultCipherSuites();\n    }\n\n    @Override\n    public String[] getSupportedCipherSuites() {\n        return delegate.getSupportedCipherSuites();\n    }\n\n    /**\n     * @see <a href=\"https://timtaubert.de/blog/2014/11/the-sad-state-of-server-side-tls-session-resumption-implementations/\">The sad state of server-side TLS Session Resumption implementations</a>\n     */\n    private Socket makeSocketSafe(Socket socket, String host) {\n        if (socket instanceof SSLSocket) {\n            TlsOnlySSLSocket tempSocket =\n                    new TlsOnlySSLSocket((SSLSocket) socket, compatible);\n\n            if (delegate instanceof SSLCertificateSocketFactory factory &&\n                    Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {\n                factory.setHostname(socket, host);\n                factory.setUseSessionTickets(socket, false);\n            } else {\n                tempSocket.setHostname(host);\n            }\n\n            socket = tempSocket;\n        }\n        return socket;\n    }\n\n    @Override\n    public Socket createSocket(Socket s, String host, int port, boolean autoClose)\n            throws IOException {\n        return makeSocketSafe(delegate.createSocket(s, host, port, autoClose), host);\n    }\n\n    @Override\n    public Socket createSocket(String host, int port) throws IOException {\n        return makeSocketSafe(delegate.createSocket(host, port), host);\n    }\n\n    @Override\n    public Socket createSocket(String host, int port, InetAddress localHost, int localPort)\n            throws IOException {\n        return makeSocketSafe(delegate.createSocket(host, port, localHost, localPort), host);\n    }\n\n    @Override\n    public Socket createSocket(InetAddress host, int port) throws IOException {\n        return makeSocketSafe(delegate.createSocket(host, port), host.getHostName());\n    }\n\n    @Override\n    public Socket createSocket(InetAddress address, int port, InetAddress localAddress,\n                               int localPort) throws IOException {\n        return makeSocketSafe(delegate.createSocket(address, port, localAddress, localPort),\n                address.getHostName());\n    }\n\n    private class TlsOnlySSLSocket extends DelegateSSLSocket {\n\n        final boolean compatible;\n\n        private TlsOnlySSLSocket(SSLSocket delegate, boolean compatible) {\n            super(delegate);\n            this.compatible = compatible;\n\n            // badly configured servers can't handle a good config\n            if (compatible) {\n                ArrayList<String> protocols = new ArrayList<String>(Arrays.asList(delegate\n                        .getEnabledProtocols()));\n                protocols.remove(SSLV2);\n                protocols.remove(SSLV3);\n                super.setEnabledProtocols(protocols.toArray(new String[protocols.size()]));\n\n                /*\n                 * Exclude extremely weak EXPORT ciphers. NULL ciphers should\n                 * never even have been an option in TLS.\n                 */\n                ArrayList<String> enabled = new ArrayList<String>(10);\n                Pattern exclude = Pattern.compile(\".*(EXPORT|NULL).*\");\n                for (String cipher : delegate.getEnabledCipherSuites()) {\n                    if (!exclude.matcher(cipher).matches()) {\n                        enabled.add(cipher);\n                    }\n                }\n                super.setEnabledCipherSuites(enabled.toArray(new String[enabled.size()]));\n                return;\n            } // else\n\n            // 16-19 support v1.1 and v1.2 but only by default starting in 20+\n            // https://developer.android.com/reference/javax/net/ssl/SSLSocket.html\n            ArrayList<String> protocols = new ArrayList<String>(Arrays.asList(delegate\n                    .getSupportedProtocols()));\n            protocols.remove(SSLV2);\n            protocols.remove(SSLV3);\n            if (Build.VERSION.SDK_INT >= 24) {\n                protocols.remove(TLSV1);\n                protocols.remove(TLSV1_1);\n            }\n            super.setEnabledProtocols(protocols.toArray(new String[protocols.size()]));\n\n            /*\n             * Exclude weak ciphers, like EXPORT, MD5, DES, and DH. NULL ciphers\n             * should never even have been an option in TLS.\n             */\n            ArrayList<String> enabledCiphers = new ArrayList<String>(10);\n            Pattern exclude = Pattern.compile(\".*(_DES|DH_|DSS|EXPORT|MD5|NULL|RC4|TLS_FALLBACK_SCSV).*\");\n            for (String cipher : delegate.getSupportedCipherSuites()) {\n                if (!exclude.matcher(cipher).matches()) {\n                    enabledCiphers.add(cipher);\n                }\n            }\n            super.setEnabledCipherSuites(enabledCiphers.toArray(new String[enabledCiphers.size()]));\n        }\n\n        /**\n         * This works around a bug in Android < 19 where SSLv3 is forced\n         */\n        @Override\n        public void setEnabledProtocols(String[] protocols) {\n            if (protocols != null && protocols.length == 1 && SSLV3.equals(protocols[0])) {\n                List<String> systemProtocols;\n                if (this.compatible) {\n                    systemProtocols = Arrays.asList(delegate.getEnabledProtocols());\n                } else {\n                    systemProtocols = Arrays.asList(delegate.getSupportedProtocols());\n                }\n                List<String> enabledProtocols = new ArrayList<String>(systemProtocols);\n                if (enabledProtocols.size() > 1) {\n                    enabledProtocols.remove(SSLV2);\n                    enabledProtocols.remove(SSLV3);\n                } else {\n                    Log.w(TAG, \"SSL stuck with protocol available for \"\n                            + enabledProtocols);\n                }\n                protocols = enabledProtocols.toArray(new String[enabledProtocols.size()]);\n            }\n            super.setEnabledProtocols(protocols);\n        }\n    }\n\n    public class DelegateSSLSocket extends SSLSocket {\n\n        protected final SSLSocket delegate;\n\n        DelegateSSLSocket(SSLSocket delegate) {\n            this.delegate = delegate;\n        }\n\n        @Override\n        public String[] getSupportedCipherSuites() {\n            return delegate.getSupportedCipherSuites();\n        }\n\n        @Override\n        public String[] getEnabledCipherSuites() {\n            return delegate.getEnabledCipherSuites();\n        }\n\n        @Override\n        public void setEnabledCipherSuites(String[] suites) {\n            delegate.setEnabledCipherSuites(suites);\n        }\n\n        @Override\n        public String[] getSupportedProtocols() {\n            return delegate.getSupportedProtocols();\n        }\n\n        @Override\n        public String[] getEnabledProtocols() {\n            return delegate.getEnabledProtocols();\n        }\n\n        @Override\n        public void setEnabledProtocols(String[] protocols) {\n            delegate.setEnabledProtocols(protocols);\n        }\n\n        @Override\n        public SSLSession getSession() {\n            return delegate.getSession();\n        }\n\n        @Override\n        public void addHandshakeCompletedListener(HandshakeCompletedListener listener) {\n            delegate.addHandshakeCompletedListener(listener);\n        }\n\n        @Override\n        public void removeHandshakeCompletedListener(HandshakeCompletedListener listener) {\n            delegate.removeHandshakeCompletedListener(listener);\n        }\n\n        @Override\n        public void startHandshake() throws IOException {\n            delegate.startHandshake();\n        }\n\n        @Override\n        public boolean getUseClientMode() {\n            return delegate.getUseClientMode();\n        }\n\n        @Override\n        public void setUseClientMode(boolean mode) {\n            delegate.setUseClientMode(mode);\n        }\n\n        @Override\n        public boolean getNeedClientAuth() {\n            return delegate.getNeedClientAuth();\n        }\n\n        @Override\n        public void setNeedClientAuth(boolean need) {\n            delegate.setNeedClientAuth(need);\n        }\n\n        @Override\n        public boolean getWantClientAuth() {\n            return delegate.getWantClientAuth();\n        }\n\n        @Override\n        public void setWantClientAuth(boolean want) {\n            delegate.setWantClientAuth(want);\n        }\n\n        @Override\n        public boolean getEnableSessionCreation() {\n            return delegate.getEnableSessionCreation();\n        }\n\n        @Override\n        public void setEnableSessionCreation(boolean flag) {\n            delegate.setEnableSessionCreation(flag);\n        }\n\n        @Override\n        public void bind(SocketAddress localAddr) throws IOException {\n            delegate.bind(localAddr);\n        }\n\n        @Override\n        public synchronized void close() throws IOException {\n            delegate.close();\n        }\n\n        @Override\n        public void connect(SocketAddress remoteAddr) throws IOException {\n            delegate.connect(remoteAddr);\n        }\n\n        @Override\n        public void connect(SocketAddress remoteAddr, int timeout) throws IOException {\n            delegate.connect(remoteAddr, timeout);\n        }\n\n        @Override\n        public SocketChannel getChannel() {\n            return delegate.getChannel();\n        }\n\n        @Override\n        public InetAddress getInetAddress() {\n            return delegate.getInetAddress();\n        }\n\n        @Override\n        public InputStream getInputStream() throws IOException {\n            return delegate.getInputStream();\n        }\n\n        @Override\n        public boolean getKeepAlive() throws SocketException {\n            return delegate.getKeepAlive();\n        }\n\n        @Override\n        public void setKeepAlive(boolean keepAlive) throws SocketException {\n            delegate.setKeepAlive(keepAlive);\n        }\n\n        @Override\n        public InetAddress getLocalAddress() {\n            return delegate.getLocalAddress();\n        }\n\n        @Override\n        public int getLocalPort() {\n            return delegate.getLocalPort();\n        }\n\n        @Override\n        public SocketAddress getLocalSocketAddress() {\n            return delegate.getLocalSocketAddress();\n        }\n\n        @Override\n        public boolean getOOBInline() throws SocketException {\n            return delegate.getOOBInline();\n        }\n\n        @Override\n        public void setOOBInline(boolean oobinline) throws SocketException {\n            delegate.setOOBInline(oobinline);\n        }\n\n        @Override\n        public OutputStream getOutputStream() throws IOException {\n            return delegate.getOutputStream();\n        }\n\n        @Override\n        public int getPort() {\n            return delegate.getPort();\n        }\n\n        @Override\n        public synchronized int getReceiveBufferSize() throws SocketException {\n            return delegate.getReceiveBufferSize();\n        }\n\n        @Override\n        public synchronized void setReceiveBufferSize(int size) throws SocketException {\n            delegate.setReceiveBufferSize(size);\n        }\n\n        @Override\n        public SocketAddress getRemoteSocketAddress() {\n            return delegate.getRemoteSocketAddress();\n        }\n\n        @Override\n        public boolean getReuseAddress() throws SocketException {\n            return delegate.getReuseAddress();\n        }\n\n        @Override\n        public void setReuseAddress(boolean reuse) throws SocketException {\n            delegate.setReuseAddress(reuse);\n        }\n\n        @Override\n        public synchronized int getSendBufferSize() throws SocketException {\n            return delegate.getSendBufferSize();\n        }\n\n        @Override\n        public synchronized void setSendBufferSize(int size) throws SocketException {\n            delegate.setSendBufferSize(size);\n        }\n\n        @Override\n        public int getSoLinger() throws SocketException {\n            return delegate.getSoLinger();\n        }\n\n        @Override\n        public synchronized int getSoTimeout() throws SocketException {\n            return delegate.getSoTimeout();\n        }\n\n        @Override\n        public synchronized void setSoTimeout(int timeout) throws SocketException {\n            delegate.setSoTimeout(timeout);\n        }\n\n        @Override\n        public boolean getTcpNoDelay() throws SocketException {\n            return delegate.getTcpNoDelay();\n        }\n\n        @Override\n        public void setTcpNoDelay(boolean on) throws SocketException {\n            delegate.setTcpNoDelay(on);\n        }\n\n        @Override\n        public int getTrafficClass() throws SocketException {\n            return delegate.getTrafficClass();\n        }\n\n        @Override\n        public void setTrafficClass(int value) throws SocketException {\n            delegate.setTrafficClass(value);\n        }\n\n        @Override\n        public boolean isBound() {\n            return delegate.isBound();\n        }\n\n        @Override\n        public boolean isClosed() {\n            return delegate.isClosed();\n        }\n\n        @Override\n        public boolean isConnected() {\n            return delegate.isConnected();\n        }\n\n        @Override\n        public boolean isInputShutdown() {\n            return delegate.isInputShutdown();\n        }\n\n        @Override\n        public boolean isOutputShutdown() {\n            return delegate.isOutputShutdown();\n        }\n\n        @Override\n        public void sendUrgentData(int value) throws IOException {\n            delegate.sendUrgentData(value);\n        }\n\n        @Override\n        public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {\n            delegate.setPerformancePreferences(connectionTime,\n                    latency, bandwidth);\n        }\n\n        @Override\n        public void setSoLinger(boolean on, int timeout) throws SocketException {\n            delegate.setSoLinger(on, timeout);\n        }\n\n        @Override\n        public void shutdownInput() throws IOException {\n            delegate.shutdownInput();\n        }\n\n        @Override\n        public void shutdownOutput() throws IOException {\n            delegate.shutdownOutput();\n        }\n\n        // inspired by https://github.com/k9mail/k-9/commit/54f9fd36a77423a55f63fbf9b1bcea055a239768\n\n        public DelegateSSLSocket setHostname(String host) {\n            try {\n                delegate\n                        .getClass()\n                        .getMethod(\"setHostname\", String.class)\n                        .invoke(delegate, host);\n            } catch (Exception e) {\n                //throw new IllegalStateException(\"Could not enable SNI\", e);\n            }\n\n            return (this);\n        }\n\n        @Override\n        public String toString() {\n            return delegate.toString();\n        }\n\n        @Override\n        public boolean equals(Object o) {\n            return delegate.equals(o);\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/VariantGridLayoutManager.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.content.Context\r\nimport android.util.AttributeSet\r\nimport androidx.annotation.Keep\r\nimport androidx.recyclerview.widget.GridLayoutManager\r\n\r\nclass VariantGridLayoutManager : GridLayoutManager {\r\n    @Keep\r\n    constructor(context: Context, spanCount: Int) : super(context, spanCount)\r\n    @Keep\r\n    constructor(context: Context, spanCount: Int, orientation: Int, reverseLayout: Boolean) : super(context, spanCount, orientation, reverseLayout)\r\n    @Keep\r\n    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)\r\n\r\n    override fun supportsPredictiveItemAnimations(): Boolean = false\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/VariantLinearLayoutManager.kt",
    "content": "package knf.kuma.custom\r\n\r\nimport android.content.Context\r\nimport android.util.AttributeSet\r\nimport androidx.annotation.Keep\r\nimport androidx.recyclerview.widget.LinearLayoutManager\r\n\r\nclass VariantLinearLayoutManager : LinearLayoutManager {\r\n    @Keep\r\n    constructor(context: Context) : super(context)\r\n    @Keep\r\n    constructor(context: Context, orientation: Int, reverseLayout: Boolean) : super(context, orientation, reverseLayout)\r\n    @Keep\r\n    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)\r\n\r\n    override fun supportsPredictiveItemAnimations(): Boolean = false\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/WrapWebView.kt",
    "content": "package knf.kuma.custom\n\nimport android.content.Context\nimport android.content.res.Configuration\nimport android.os.Build\nimport android.util.AttributeSet\nimport android.webkit.WebView\n\nclass WrapWebView : WebView {\n    constructor(context: Context) : super(context.configurated)\n\n    constructor(context: Context, attrs: AttributeSet) : super(context.configurated, attrs)\n\n    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context.configurated, attrs, defStyleAttr)\n}\n\nval Context.configurated: Context\n    get() = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)\n        createConfigurationContext(Configuration())\n    else this\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/exceptions/EJNFException.kt",
    "content": "package knf.kuma.custom.exceptions\r\n\r\nclass EJNFException(message: String? = null) : IllegalStateException(message)"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/snackbar/SnackProgressBar.kt",
    "content": "package knf.kuma.custom.snackbar\r\n\r\nimport android.graphics.Bitmap\r\nimport android.os.Bundle\r\nimport androidx.annotation.DrawableRes\r\nimport androidx.annotation.IntDef\r\nimport androidx.annotation.IntRange\r\nimport androidx.annotation.Keep\r\nimport knf.kuma.custom.snackbar.SnackProgressBar.Companion.TYPE_CIRCULAR\r\nimport knf.kuma.custom.snackbar.SnackProgressBar.Companion.TYPE_HORIZONTAL\r\nimport knf.kuma.custom.snackbar.SnackProgressBar.Companion.TYPE_NORMAL\r\n\r\n/**\r\n * Main class containing the display information of SnackProgressBar to be displayed\r\n * via SnackProgressBarManager.\r\n *\r\n * @property type SnackProgressBar of either\r\n *  [TYPE_NORMAL], [TYPE_HORIZONTAL] or [TYPE_CIRCULAR]\r\n * @property message Message of SnackProgressBar.\r\n */\r\n@Keep\r\nclass SnackProgressBar(@SnackProgressBarType private var type: Int, private var message: String) {\r\n\r\n    @Retention(AnnotationRetention.SOURCE)\r\n    @IntDef(TYPE_NORMAL, TYPE_HORIZONTAL, TYPE_CIRCULAR)\r\n    annotation class SnackProgressBarType\r\n\r\n    companion object {\r\n        /**\r\n         * SnackProgressBar layout with message only.\r\n         */\r\n        const val TYPE_NORMAL = 100\r\n        /**\r\n         * SnackProgressBar layout with message and horizontal progressBar.\r\n         */\r\n        const val TYPE_HORIZONTAL = 200\r\n        /**\r\n         * SnackProgressBar layout with message and circular progressBar.\r\n         */\r\n        const val TYPE_CIRCULAR = 300\r\n\r\n        internal const val DEFAULT_ICON_RES_ID = -1\r\n    }\r\n\r\n    /**\r\n     * Interface definition for a callback to be invoked when an action is clicked.\r\n     */\r\n    interface OnActionClickListener {\r\n        /**\r\n         * Called when an action is clicked.\r\n         */\r\n        fun onActionClick()\r\n    }\r\n\r\n    /* variables */\r\n    private var action: String = \"\"\r\n    private var onActionClickListener: OnActionClickListener? = null\r\n    private var iconBitmap: Bitmap? = null\r\n    private var iconResId: Int = DEFAULT_ICON_RES_ID\r\n    private var progressMax: Int = 100\r\n    private var allowUserInput: Boolean = false\r\n    private var swipeToDismiss: Boolean = false\r\n    private var isIndeterminate: Boolean = false\r\n    private var showProgressPercentage: Boolean = false\r\n    private var bundle: Bundle? = null\r\n\r\n    /**\r\n     * Internal constructor for duplicating SnackProgressBar.\r\n     */\r\n    internal constructor (type: Int,\r\n                          message: String,\r\n                          action: String,\r\n                          onActionClickListener: OnActionClickListener?,\r\n                          iconBitmap: Bitmap?,\r\n                          iconResId: Int,\r\n                          progressMax: Int,\r\n                          allowUserInput: Boolean,\r\n                          swipeToDismiss: Boolean,\r\n                          isIndeterminate: Boolean,\r\n                          showProgressPercentage: Boolean,\r\n                          bundle: Bundle?) : this(type, message) {\r\n        this.action = action\r\n        this.onActionClickListener = onActionClickListener\r\n        this.iconBitmap = iconBitmap\r\n        this.iconResId = iconResId\r\n        this.progressMax = progressMax\r\n        this.allowUserInput = allowUserInput\r\n        this.swipeToDismiss = swipeToDismiss\r\n        this.isIndeterminate = isIndeterminate\r\n        this.showProgressPercentage = showProgressPercentage\r\n        this.bundle = bundle\r\n    }\r\n\r\n    /**\r\n     * Sets the type of SnackProgressBar.\r\n     *\r\n     * @param type SnackProgressBar of either\r\n     * [TYPE_NORMAL], [TYPE_HORIZONTAL] or [TYPE_CIRCULAR]\r\n     */\r\n    fun setType(type: Int) {\r\n        this.type = type\r\n    }\r\n\r\n    internal fun getType(): Int {\r\n        return type\r\n    }\r\n\r\n    /**\r\n     * Sets the message of SnackProgressBar.\r\n     *\r\n     * @param message Message of SnackProgressBar.\r\n     */\r\n    fun setMessage(message: String): SnackProgressBar {\r\n        this.message = message\r\n        return this\r\n    }\r\n\r\n    internal fun getMessage(): String {\r\n        return message\r\n    }\r\n\r\n    /**\r\n     * Sets the action of SnackProgressBar.\r\n     *\r\n     * @param action Action to be displayed.\r\n     */\r\n    fun setAction(action: String, onActionClickListener: OnActionClickListener?): SnackProgressBar {\r\n        this.action = action\r\n        this.onActionClickListener = onActionClickListener\r\n        return this\r\n    }\r\n\r\n    internal fun getAction(): String {\r\n        return action\r\n    }\r\n\r\n    internal fun getOnActionClickListener(): OnActionClickListener? {\r\n        return onActionClickListener\r\n    }\r\n\r\n    /**\r\n     * Sets the icon of SnackProgressBar. Only a bitmap or a resId can be specified at any one time.\r\n     *\r\n     * @param bitmap Bitmap of icon.\r\n     */\r\n    fun setIconBitmap(bitmap: Bitmap): SnackProgressBar {\r\n        iconBitmap = bitmap\r\n        iconResId = DEFAULT_ICON_RES_ID\r\n        return this\r\n    }\r\n\r\n    internal fun getIconBitmap(): Bitmap? {\r\n        return iconBitmap\r\n    }\r\n\r\n    /**\r\n     * Sets the icon of SnackProgressBar. Only a bitmap or a resId can be specified at any one time.\r\n     *\r\n     * @param iconResId The resource identifier of the icon to be displayed.\r\n     */\r\n    fun setIconResource(@DrawableRes iconResId: Int): SnackProgressBar {\r\n        iconBitmap = null\r\n        this.iconResId = iconResId\r\n        return this\r\n    }\r\n\r\n    internal fun getIconResource(): Int {\r\n        return iconResId\r\n    }\r\n\r\n    /**\r\n     * Sets the max progress for determinate ProgressBar.\r\n     *\r\n     * @param progressMax Max progress for determinate ProgressBar. Default = 100.\r\n     */\r\n    fun setProgressMax(@IntRange(from = 1) progressMax: Int): SnackProgressBar {\r\n        this.progressMax = progressMax\r\n        return this\r\n    }\r\n\r\n    internal fun getProgressMax(): Int {\r\n        return progressMax\r\n    }\r\n\r\n    /**\r\n     * Sets whether user input is allowed. Setting to FALSE will display an OverlayLayout which blocks user input.\r\n     *\r\n     * @param allowUserInput Whether to allow user input. Default = FALSE.\r\n     */\r\n    fun setAllowUserInput(allowUserInput: Boolean): SnackProgressBar {\r\n        this.allowUserInput = allowUserInput\r\n        return this\r\n    }\r\n\r\n    internal fun isAllowUserInput(): Boolean {\r\n        return allowUserInput\r\n    }\r\n\r\n    /**\r\n     * Sets whether user can swipe to dismiss.\r\n     *\r\n     * @param swipeToDismiss Whether user can swipe to dismiss. Default = FALSE.\r\n     */\r\n    fun setSwipeToDismiss(swipeToDismiss: Boolean): SnackProgressBar {\r\n        this.swipeToDismiss = swipeToDismiss\r\n        return this\r\n    }\r\n\r\n    internal fun isSwipeToDismiss(): Boolean {\r\n        return swipeToDismiss\r\n    }\r\n\r\n    /**\r\n     * Sets whether the progressBar is indeterminate.\r\n     *\r\n     * @param isIndeterminate Whether the progressBar is indeterminate. Default = FALSE.\r\n     */\r\n    fun setIsIndeterminate(isIndeterminate: Boolean): SnackProgressBar {\r\n        this.isIndeterminate = isIndeterminate\r\n        return this\r\n    }\r\n\r\n    internal fun isIndeterminate(): Boolean {\r\n        return isIndeterminate\r\n    }\r\n\r\n    /**\r\n     * Sets whether to show progress in percentage.\r\n     *\r\n     * @param showProgressPercentage Whether to show progressText. Default = FALSE.\r\n     */\r\n    fun setShowProgressPercentage(showProgressPercentage: Boolean): SnackProgressBar {\r\n        this.showProgressPercentage = showProgressPercentage\r\n        return this\r\n    }\r\n\r\n    internal fun isShowProgressPercentage(): Boolean {\r\n        return showProgressPercentage\r\n    }\r\n\r\n    /**\r\n     * Sets the additional bundle of SnackProgressBar.\r\n     *\r\n     * @param bundle Bundle of SnackProgressBar.\r\n     */\r\n    fun putBundle(bundle: Bundle): SnackProgressBar {\r\n        this.bundle = bundle\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Gets the additional bundle of SnackProgressBar. This value may be null.\r\n     */\r\n    fun getBundle(): Bundle? {\r\n        return bundle\r\n    }\r\n\r\n    // toString\r\n    override fun toString(): String {\r\n        val typeString = when (type) {\r\n            TYPE_CIRCULAR -> \"TYPE_CIRCULAR\"\r\n            TYPE_HORIZONTAL -> \"TYPE_HORIZONTAL\"\r\n            else -> \"TYPE_NORMAL\"\r\n        }\r\n        val hasIcon = iconBitmap != null && iconResId != DEFAULT_ICON_RES_ID\r\n        return \"SnackProgressBar(type='$typeString', \" +\r\n                \"message='$message', \" +\r\n                \"action='$action', \" +\r\n                \"hasIcon=$hasIcon, \" +\r\n                \"progressMax=$progressMax, \" +\r\n                \"allowUserInput=$allowUserInput, \" +\r\n                \"swipeToDismiss=$swipeToDismiss, \" +\r\n                \"isIndeterminate=$isIndeterminate, \" +\r\n                \"showProgressPercentage=$showProgressPercentage)\"\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/snackbar/SnackProgressBarCore.kt",
    "content": "package knf.kuma.custom.snackbar\r\n\r\nimport android.os.Handler\r\nimport android.view.LayoutInflater\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport androidx.annotation.IntRange\r\nimport androidx.annotation.Keep\r\nimport androidx.coordinatorlayout.widget.CoordinatorLayout\r\nimport androidx.core.content.ContextCompat\r\nimport com.google.android.material.snackbar.BaseTransientBottomBar\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.custom.snackbar.SnackProgressBar.Companion.TYPE_CIRCULAR\r\nimport knf.kuma.custom.snackbar.SnackProgressBar.Companion.TYPE_HORIZONTAL\r\nimport knf.kuma.custom.snackbar.SnackProgressBar.Companion.TYPE_NORMAL\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\nimport java.util.Locale\r\n\r\n/**\r\n * Core class constructing the SnackProgressBar.\r\n */\r\n@Keep\r\ninternal class SnackProgressBarCore private constructor(\r\n        private val parentView: ViewGroup,\r\n        private val snackProgressBarLayout: SnackProgressBarLayout,\r\n        private val overlayLayout: View,\r\n        private var showDuration: Int,\r\n        private var snackProgressBar: SnackProgressBar)\r\n    : BaseTransientBottomBar<SnackProgressBarCore>(parentView, snackProgressBarLayout, snackProgressBarLayout) {\r\n\r\n    /* variables */\r\n    private val shortDurationMillis = 1500          // as per SnackbarManager\r\n    private val longDurationMillis = 2750           // as per SnackbarManager\r\n    private val handler = Handler()\r\n    private val runnable = Runnable { dismiss() }\r\n\r\n    companion object {\r\n        /**\r\n         * Prepares SnackProgressBarCore.\r\n         *\r\n         * @param parentView       View to hold the SnackProgressBar, prepared by SnackProgressBarManager\r\n         * @param snackProgressBar SnackProgressBar to be shown.\r\n         * @param showDuration     Duration to show the SnackProgressBar.\r\n         * @param viewsToMove      View to be animated along with the SnackProgressBar.\r\n         */\r\n        internal fun make(parentView: ViewGroup, snackProgressBar: SnackProgressBar,\r\n                          showDuration: Int, viewsToMove: Array<View>?): SnackProgressBarCore {\r\n            // get inflater from parent\r\n            val inflater = LayoutInflater.from(parentView.context)\r\n            // add overlayLayout as background\r\n            val overlayLayout = inflater.inflate(R.layout.overlay, parentView, false)\r\n            overlayLayout.tag = \"Overlay\"\r\n            parentView.addView(overlayLayout)\r\n            // inflate SnackProgressBarLayout and pass viewsToMove\r\n            val snackProgressBarLayout = inflater.inflate(\r\n                    R.layout.snackprogressbar, parentView, false) as SnackProgressBarLayout\r\n            snackProgressBarLayout.setViewsToMove(viewsToMove)\r\n            // create SnackProgressBarCore\r\n            val snackProgressBarCore = SnackProgressBarCore(\r\n                    parentView,\r\n                    snackProgressBarLayout,\r\n                    overlayLayout,\r\n                    showDuration,\r\n                    snackProgressBar)\r\n            snackProgressBarCore.updateTo(snackProgressBar)\r\n            return snackProgressBarCore\r\n        }\r\n    }\r\n\r\n    init {\r\n        overlayLayout.onClick {\r\n            noCrash {\r\n                if (!isShown)\r\n                    parentView.removeView(overlayLayout)\r\n            }\r\n        }\r\n    }\r\n    /**\r\n     * Gets the attached snackProgressBar.\r\n     */\r\n    internal fun getSnackProgressBar(): SnackProgressBar {\r\n        return snackProgressBar\r\n    }\r\n\r\n    /**\r\n     * Updates the SnackProgressBar without dismissing it to the new SnackProgressBar.\r\n     *\r\n     * @param snackProgressBar SnackProgressBar to be updated to.\r\n     */\r\n    internal fun updateTo(snackProgressBar: SnackProgressBar) {\r\n        this.snackProgressBar = snackProgressBar\r\n        setType()\r\n        setIcon()\r\n        setAction()\r\n        showProgressPercentage()\r\n        setProgressMax()\r\n        setSwipeToDismiss()\r\n        setMessage()\r\n        // only toggle overlayLayout visibility if already shown\r\n        if (isShown) {\r\n            showOverlayLayout()\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Updates the color and alpha of overlayLayout.\r\n     *\r\n     * @param overlayColor       R.color id.\r\n     * @param overlayLayoutAlpha Alpha between 0f to 1f. Default = 0.8f.\r\n     */\r\n    internal fun setOverlayLayout(overlayColor: Int, overlayLayoutAlpha: Float): SnackProgressBarCore {\r\n        overlayLayout.setBackgroundColor(ContextCompat.getColor(context, overlayColor))\r\n        overlayLayout.alpha = overlayLayoutAlpha\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Updates the color of the layout.\r\n     *\r\n     * @param backgroundColor  R.color id.\r\n     * @param messageTextColor R.color id.\r\n     * @param actionTextColor  R.color id.\r\n     * @param progressBarColor R.color id.\r\n     * @param progressTextColor R.color id.\r\n     */\r\n    internal fun setColor(backgroundColor: Int, messageTextColor: Int, actionTextColor: Int, progressBarColor: Int, progressTextColor: Int): SnackProgressBarCore {\r\n        snackProgressBarLayout.setColor(backgroundColor, messageTextColor, actionTextColor, progressBarColor, progressTextColor)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the text size of SnackProgressBar.\r\n     *\r\n     * @param px Font size in pixels.\r\n     */\r\n    internal fun setTextSize(px: Float): SnackProgressBarCore {\r\n        snackProgressBarLayout.setTextSize(px)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the max lines for message.\r\n     *\r\n     * @param maxLines Number of lines.\r\n     */\r\n    internal fun setMaxLines(maxLines: Int): SnackProgressBarCore {\r\n        snackProgressBarLayout.setMaxLines(maxLines)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the progress for SnackProgressBar.\r\n     *\r\n     * @param progress Progress of the ProgressBar.\r\n     */\r\n    internal fun setProgress(@IntRange(from = 0) progress: Int): SnackProgressBarCore {\r\n        val progressBar =\r\n                when (snackProgressBar.getType()) {\r\n                    TYPE_HORIZONTAL -> snackProgressBarLayout.horizontalProgressBar\r\n                    TYPE_CIRCULAR -> snackProgressBarLayout.circularDeterminateProgressBar\r\n                    else -> null\r\n                }\r\n        if (progressBar != null) {\r\n            progressBar.progress = progress\r\n            val progress100 = (progress.toFloat() / progressBar.max * 100).toInt()\r\n            var progressString = progress100.toString()\r\n            snackProgressBarLayout.progressTextCircular.text = progressString\r\n            // include % for progressText\r\n            progressString += \"%\"\r\n            snackProgressBarLayout.progressText.text = progressString\r\n        }\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Show the SnackProgressBar\r\n     */\r\n    override fun show() {\r\n        // show overLayLayout\r\n        showOverlayLayout()\r\n        // use default SnackManager if it is CoordinatorLayout\r\n        if (parentView is CoordinatorLayout) {\r\n            duration = showDuration\r\n        }\r\n        // else, set up own handler for dismiss countdown\r\n        else {\r\n            setOnBarTouchListener()\r\n            // disable SnackManager by stopping countdown\r\n            duration = LENGTH_INDEFINITE\r\n            // assign the actual showDuration if dismiss is required\r\n            if (showDuration != LENGTH_INDEFINITE) {\r\n                when (showDuration) {\r\n                    LENGTH_SHORT -> showDuration = shortDurationMillis\r\n                    LENGTH_LONG -> showDuration = longDurationMillis\r\n                }\r\n                handler.postDelayed(runnable, showDuration.toLong())\r\n            }\r\n        }\r\n        super.show()\r\n    }\r\n\r\n    override fun dismiss() {\r\n        removeOverlayLayout()\r\n        super.dismiss()\r\n    }\r\n\r\n    /**\r\n     * Sets the layout based on SnackProgressBar type.\r\n     * Note: Layout positioning for action is handled by [SnackProgressBarLayout]\r\n     */\r\n    private fun setType(): SnackProgressBarCore {\r\n        // update view\r\n        when (snackProgressBar.getType()) {\r\n            TYPE_NORMAL -> {\r\n                snackProgressBarLayout.horizontalProgressBar.visibility = View.GONE\r\n                snackProgressBarLayout.circularDeterminateProgressBar.visibility = View.GONE\r\n                snackProgressBarLayout.circularIndeterminateProgressBar.visibility = View.GONE\r\n            }\r\n            TYPE_HORIZONTAL -> {\r\n                snackProgressBarLayout.horizontalProgressBar.visibility = View.VISIBLE\r\n                snackProgressBarLayout.circularDeterminateProgressBar.visibility = View.GONE\r\n                snackProgressBarLayout.circularIndeterminateProgressBar.visibility = View.GONE\r\n                snackProgressBarLayout.horizontalProgressBar.isIndeterminate = snackProgressBar.isIndeterminate()\r\n            }\r\n            TYPE_CIRCULAR -> {\r\n                snackProgressBarLayout.horizontalProgressBar.visibility = View.GONE\r\n                if (snackProgressBar.isIndeterminate()) {\r\n                    snackProgressBarLayout.circularDeterminateProgressBar.visibility = View.GONE\r\n                    snackProgressBarLayout.circularIndeterminateProgressBar.visibility = View.VISIBLE\r\n                } else {\r\n                    snackProgressBarLayout.circularDeterminateProgressBar.visibility = View.VISIBLE\r\n                    snackProgressBarLayout.circularIndeterminateProgressBar.visibility = View.GONE\r\n                }\r\n            }\r\n        }\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the icon of SnackProgressBar.\r\n     */\r\n    private fun setIcon(): SnackProgressBarCore {\r\n        val iconBitmap = snackProgressBar.getIconBitmap()\r\n        val iconResId = snackProgressBar.getIconResource()\r\n        when {\r\n            iconBitmap != null -> {\r\n                snackProgressBarLayout.iconImage.setImageBitmap(iconBitmap)\r\n                snackProgressBarLayout.iconImage.visibility = View.VISIBLE\r\n            }\r\n            iconResId != SnackProgressBar.DEFAULT_ICON_RES_ID -> {\r\n                snackProgressBarLayout.iconImage.setImageResource(iconResId)\r\n                snackProgressBarLayout.iconImage.visibility = View.VISIBLE\r\n            }\r\n            else -> snackProgressBarLayout.iconImage.visibility = View.GONE\r\n        }\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the action to be displayed.\r\n     */\r\n    private fun setAction(): SnackProgressBarCore {\r\n        val action = snackProgressBar.getAction()\r\n        val onActionClickListener = snackProgressBar.getOnActionClickListener()\r\n        // set the text\r\n        snackProgressBarLayout.actionText.text = action.uppercase(Locale.getDefault())\r\n        snackProgressBarLayout.actionNextLineText.text = action.uppercase(Locale.getDefault())\r\n        // set the onClickListener\r\n        val onClickListener = View.OnClickListener {\r\n            onActionClickListener?.onActionClick()\r\n            dismiss()\r\n        }\r\n        snackProgressBarLayout.actionText.setOnClickListener(onClickListener)\r\n        snackProgressBarLayout.actionNextLineText.setOnClickListener(onClickListener)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets whether to show progressText.\r\n     */\r\n    private fun showProgressPercentage(): SnackProgressBarCore {\r\n        if (snackProgressBar.isShowProgressPercentage()) {\r\n            if (snackProgressBar.getType() == TYPE_CIRCULAR) {\r\n                snackProgressBarLayout.progressText.visibility = View.GONE\r\n                snackProgressBarLayout.progressTextCircular.visibility = View.VISIBLE\r\n            } else {\r\n                snackProgressBarLayout.progressText.visibility = View.VISIBLE\r\n                snackProgressBarLayout.progressTextCircular.visibility = View.GONE\r\n            }\r\n        } else {\r\n            snackProgressBarLayout.progressText.visibility = View.GONE\r\n            snackProgressBarLayout.progressTextCircular.visibility = View.GONE\r\n        }\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the max progress for progressBar.\r\n     */\r\n    private fun setProgressMax(): SnackProgressBarCore {\r\n        snackProgressBarLayout.horizontalProgressBar.max = snackProgressBar.getProgressMax()\r\n        snackProgressBarLayout.circularDeterminateProgressBar.max = snackProgressBar.getProgressMax()\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets whether user can swipe to dismiss.\r\n     */\r\n    private fun setSwipeToDismiss(): SnackProgressBarCore {\r\n        snackProgressBarLayout.setSwipeToDismiss(snackProgressBar.isSwipeToDismiss())\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the message of SnackProgressBar.\r\n     */\r\n    private fun setMessage(): SnackProgressBarCore {\r\n        snackProgressBarLayout.messageText.text = snackProgressBar.getMessage()\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Shows the overlayLayout based on whether user input is allowed.\r\n     */\r\n    private fun showOverlayLayout(): SnackProgressBarCore {\r\n        if (!snackProgressBar.isAllowUserInput()) {\r\n            overlayLayout.visibility = View.VISIBLE\r\n        } else {\r\n            overlayLayout.visibility = View.GONE\r\n        }\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Removes the overlayLayout\r\n     */\r\n    internal fun removeOverlayLayout() {\r\n        doOnUIGlobal {\r\n            parentView.removeView(overlayLayout)\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Registers a callback to be invoked when the SnackProgressBar is touched.\r\n     * This is only applicable when swipe to dismiss behaviour is true and CoordinatorLayout is not used.\r\n     */\r\n    private fun setOnBarTouchListener() {\r\n        snackProgressBarLayout.setOnBarTouchListener(object : SnackProgressBarLayout.OnBarTouchListener {\r\n            override fun onTouch(event: Int) {\r\n                when (event) {\r\n                    SnackProgressBarLayout.ACTION_DOWN ->\r\n                        // when user touched the SnackProgressBar, stop the dismiss countdown\r\n                        handler.removeCallbacks(runnable)\r\n                    SnackProgressBarLayout.SWIPE_OUT ->\r\n                        // once the SnackProgressBar is swiped out, dismiss after animation ends\r\n                        handler.postDelayed(runnable, SnackProgressBarLayout.ANIMATION_DURATION)\r\n                    SnackProgressBarLayout.SWIPE_IN ->\r\n                        // once the SnackProgressBar is swiped in, resume dismiss countdown\r\n                        if (showDuration != SnackProgressBarManager.LENGTH_INDEFINITE) {\r\n                            handler.postDelayed(runnable, showDuration.toLong())\r\n                        }\r\n                }\r\n            }\r\n        })\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/snackbar/SnackProgressBarLayout.kt",
    "content": "package knf.kuma.custom.snackbar\r\n\r\nimport android.annotation.SuppressLint\r\nimport android.content.Context\r\nimport android.util.AttributeSet\r\nimport android.util.TypedValue\r\nimport android.view.MotionEvent\r\nimport android.view.VelocityTracker\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.LinearLayout\r\nimport androidx.annotation.ColorRes\r\nimport androidx.annotation.Keep\r\nimport androidx.coordinatorlayout.widget.CoordinatorLayout\r\nimport androidx.core.content.ContextCompat\r\nimport androidx.core.view.ViewCompat\r\nimport androidx.core.view.isVisible\r\nimport androidx.interpolator.view.animation.FastOutSlowInInterpolator\r\nimport com.google.android.material.snackbar.ContentViewCallback\r\nimport knf.kuma.R\r\nimport knf.kuma.databinding.SnackprogressbarBinding\r\n\r\n/**\r\n * Layout class for SnackProgressBar.\r\n */\r\n@Keep\r\ninternal class SnackProgressBarLayout @JvmOverloads constructor(\r\n        context: Context,\r\n        attrs: AttributeSet? = null,\r\n        defStyleAttr: Int = 0)\r\n    : LinearLayout(context, attrs, defStyleAttr),\r\n        ContentViewCallback {\r\n\r\n    /* variables */\r\n    companion object {\r\n        internal const val ACTION_DOWN = 123\r\n        internal const val SWIPE_OUT = 456\r\n        internal const val SWIPE_IN = 789\r\n        internal const val ANIMATION_DURATION = 250L      // animation duration as per BaseTransientBottomBar\r\n    }\r\n\r\n    private val binding by lazy { SnackprogressbarBinding.bind(this) }\r\n    private val backgroundLayout by lazy { binding.snackProgressBarLayoutBackground }\r\n    private val mainLayout by lazy { binding.snackProgressBarLayoutMain }\r\n    private val actionNextLineLayout by lazy { binding.snackProgressBarLayoutActionNextLine }\r\n    internal val iconImage by lazy { binding.snackProgressBarImgIcon }\r\n    internal val messageText by lazy { binding.snackProgressBarTxtMessage }\r\n    internal val actionText by lazy { binding.snackProgressBarTxtAction }\r\n    internal val actionNextLineText by lazy { binding.snackProgressBarTxtActionNextLine }\r\n    internal val progressText by lazy { binding.snackProgressBarTxtProgress }\r\n    internal val progressTextCircular by lazy { binding.snackProgressBarTxtProgressCircular }\r\n    internal val horizontalProgressBar by lazy { binding.snackProgressBarProgressbarHorizontal }\r\n    internal val circularDeterminateProgressBar by lazy { binding.snackProgressBarProgressbarCircularDeterminate }\r\n    internal val circularIndeterminateProgressBar by lazy { binding.snackProgressBarProgressbarCircularIndeterminate }\r\n\r\n    private val startAlphaSwipeDistance = 0.1f     // as per Behavior in BaseTransientBottomBar\r\n    private val endAlphaSwipeDistance = 0.6f       // as per Behavior in BaseTransientBottomBar\r\n    private val swipeOutVelocity = 800f\r\n    private val heightSingle = resources.getDimension(R.dimen.snackProgressBar_height_single).toInt()        // height as per Material Design\r\n    private val heightMulti = resources.getDimension(R.dimen.snackProgressBar_height_multi).toInt()         // height as per Material Design\r\n    private val heightActionNextLine = resources.getDimension(R.dimen.snackProgressBar_height_actionNextLine).toInt()\r\n    private val defaultTextSizeDp = resources.getDimension(R.dimen.text_body_dp).toInt()      // use fixed dp for comparison purpose\r\n\r\n    private var isCoordinatorLayout: Boolean = false\r\n    private var swipeToDismiss: Boolean = false\r\n    private var viewsToMove: Array<View>? = null\r\n    private var onBarTouchListener: OnBarTouchListener? = null\r\n\r\n    /**\r\n     * Interface definition for a callback to be invoked when the SnackProgressBar is touched.\r\n     */\r\n    interface OnBarTouchListener {\r\n        /**\r\n         * Called when the SnackProgressBar is touched.\r\n         *\r\n         * @param event Type of touch event.\r\n         */\r\n        fun onTouch(event: Int)\r\n    }\r\n\r\n    /**\r\n     * Registers a callback to be invoked when the SnackProgressBar is touched.\r\n     *\r\n     * @param onBarTouchListener The callback that will run. This value may be null.\r\n     */\r\n    internal fun setOnBarTouchListener(onBarTouchListener: OnBarTouchListener?) {\r\n        this.onBarTouchListener = onBarTouchListener\r\n    }\r\n\r\n    /**\r\n     * Passes the view (e.g. FloatingActionButton) to move up or down as SnackProgressBar is shown or dismissed.\r\n     *\r\n     * @param viewsToMove Views to animate when the SnackProgressBar is shown or dismissed.\r\n     */\r\n    internal fun setViewsToMove(viewsToMove: Array<View>?) {\r\n        this.viewsToMove = viewsToMove\r\n    }\r\n\r\n    /**\r\n     * Updates the color of the layout.\r\n     *\r\n     * @param backgroundColor  R.color id.\r\n     * @param messageTextColor R.color id.\r\n     * @param actionTextColor  R.color id.\r\n     * @param progressBarColor R.color id.\r\n     * @param progressTextColor R.color id.\r\n     */\r\n    internal fun setColor(@ColorRes backgroundColor: Int, @ColorRes messageTextColor: Int,\r\n                          @ColorRes actionTextColor: Int, @ColorRes progressBarColor: Int,\r\n                          @ColorRes progressTextColor: Int) {\r\n        backgroundLayout.setBackgroundColor(ContextCompat.getColor(context, backgroundColor))\r\n        messageText.setTextColor(ContextCompat.getColor(context, messageTextColor))\r\n        actionText.setTextColor(ContextCompat.getColor(context, actionTextColor))\r\n        actionNextLineText.setTextColor(ContextCompat.getColor(context, actionTextColor))\r\n        horizontalProgressBar.progressDrawable.setColorFilter(\r\n                ContextCompat.getColor(context, progressBarColor), android.graphics.PorterDuff.Mode.SRC_IN)\r\n        circularDeterminateProgressBar.progressDrawable.setColorFilter(\r\n                ContextCompat.getColor(context, progressBarColor), android.graphics.PorterDuff.Mode.SRC_IN)\r\n        horizontalProgressBar.indeterminateDrawable.setColorFilter(\r\n                ContextCompat.getColor(context, progressBarColor), android.graphics.PorterDuff.Mode.SRC_IN)\r\n        circularIndeterminateProgressBar.indeterminateDrawable.setColorFilter(\r\n                ContextCompat.getColor(context, progressBarColor), android.graphics.PorterDuff.Mode.SRC_IN)\r\n        progressText.setTextColor(ContextCompat.getColor(context, progressTextColor))\r\n        progressTextCircular.setTextColor(ContextCompat.getColor(context, progressTextColor))\r\n    }\r\n\r\n    /**\r\n     * Sets the text size of SnackProgressBar.\r\n     *\r\n     * @param px Font size in pixels.\r\n     */\r\n    internal fun setTextSize(px: Float) {\r\n        messageText.setTextSize(TypedValue.COMPLEX_UNIT_PX, px)\r\n        actionText.setTextSize(TypedValue.COMPLEX_UNIT_PX, px)\r\n        actionNextLineText.setTextSize(TypedValue.COMPLEX_UNIT_PX, px)\r\n        progressText.setTextSize(TypedValue.COMPLEX_UNIT_PX, px)\r\n        // not changed for progressTextCircular as it will be out of the progressBar.\r\n    }\r\n\r\n    /**\r\n     * Sets the max lines for message.\r\n     *\r\n     * @param maxLines Number of lines.\r\n     */\r\n    internal fun setMaxLines(maxLines: Int) {\r\n        messageText.maxLines = maxLines\r\n    }\r\n\r\n    /**\r\n     * Sets whether user can swipe to dismiss.\r\n     *\r\n     * @param swipeToDismiss Whether user can swipe to dismiss.\r\n     * @see .configureSwipeToDismiss\r\n     */\r\n    internal fun setSwipeToDismiss(swipeToDismiss: Boolean) {\r\n        this.swipeToDismiss = swipeToDismiss\r\n    }\r\n\r\n    // onMeasure for determining actionNextLine and message height\r\n    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {\r\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec)\r\n        val lineCount = messageText.lineCount\r\n        val textSize = messageText.textSize.toInt()\r\n        val hasAction = actionText.text.toString().isNotEmpty()\r\n        // put the action into next line if width is more than 25% of total width, or if other element is taking the space\r\n        val isActionNextLine = (actionText.measuredWidth.toFloat() / backgroundLayout.measuredWidth.toFloat() > 0.25f)\r\n                || circularDeterminateProgressBar.isVisible\r\n                || circularIndeterminateProgressBar.isVisible\r\n                || progressText.isVisible\r\n                || progressTextCircular.isVisible\r\n        if (hasAction) {\r\n            if (isActionNextLine) {\r\n                actionText.visibility = GONE\r\n                // set actionNextLineLayout height\r\n                val height = if (textSize <= defaultTextSizeDp) {\r\n                    heightActionNextLine\r\n                } else {\r\n                    heightActionNextLine + (textSize - defaultTextSizeDp)\r\n                }\r\n                val layoutParams = actionNextLineLayout.layoutParams as LayoutParams\r\n                if (layoutParams.height != height) {\r\n                    layoutParams.height = height\r\n                    actionNextLineLayout.layoutParams = layoutParams\r\n                }\r\n                actionNextLineLayout.visibility = VISIBLE\r\n            } else {\r\n                actionText.visibility = VISIBLE\r\n                actionNextLineLayout.visibility = GONE\r\n            }\r\n        } else {\r\n            actionText.visibility = GONE\r\n            actionNextLineLayout.visibility = GONE\r\n        }\r\n        // set layout height according to message length\r\n        val height: Int = when (lineCount) {\r\n            1 -> {\r\n                if (textSize <= defaultTextSizeDp) {\r\n                    heightSingle\r\n                } else {\r\n                    heightSingle + (textSize - defaultTextSizeDp)\r\n                }\r\n            }\r\n            2 -> {\r\n                if (textSize <= defaultTextSizeDp) {\r\n                    heightMulti\r\n                } else {\r\n                    heightMulti + 2 * (textSize - defaultTextSizeDp)\r\n                }\r\n            }\r\n            else -> (heightMulti + (lineCount * textSize - 2 * defaultTextSizeDp))\r\n        }\r\n        val layoutParams = mainLayout.layoutParams as LayoutParams\r\n        if (layoutParams.height != height) {\r\n            layoutParams.height = height\r\n            mainLayout.layoutParams = layoutParams\r\n            // remeasure after height change\r\n            super.onMeasure(widthMeasureSpec, heightMeasureSpec)\r\n        }\r\n    }\r\n\r\n    // onAttachedToWindow\r\n    override fun onAttachedToWindow() {\r\n        super.onAttachedToWindow()\r\n        // clear the padding of the parent that hold this view\r\n        val parentView = parent as View\r\n        parentView.setPadding(0, 0, 0, 0)\r\n        // check if it is CoordinatorLayout and configure swipe to dismiss\r\n        isCoordinatorLayout = parentView.parent is CoordinatorLayout\r\n        configureSwipeToDismiss()\r\n    }\r\n\r\n    // animation for when updateTo() is called by SnackProgressBarManager\r\n    override fun onSizeChanged(w: Int, h: Int, oldW: Int, oldH: Int) {\r\n        viewsToMove?.run {\r\n            if (oldH != 0 && oldH != h) {\r\n                for (viewToMove in this) {\r\n                    ViewCompat.animate(viewToMove).translationYBy((oldH - h).toFloat()).setDuration(ANIMATION_DURATION).start()\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    // animation as per original Snackbar class\r\n    override fun animateContentIn(delay: Int, duration: Int) {\r\n        val viewsToAnimate = arrayOf(\r\n                messageText,\r\n                actionText,\r\n                actionNextLineText,\r\n                progressText,\r\n                horizontalProgressBar,\r\n                circularDeterminateProgressBar,\r\n                circularIndeterminateProgressBar)\r\n        viewsToAnimate.forEach { viewToAnimate ->\r\n            if (viewToAnimate.visibility == VISIBLE) {\r\n                viewToAnimate.alpha = 0f\r\n                ViewCompat.animate(viewToAnimate).alpha(1f).setDuration(duration.toLong())\r\n                        .setStartDelay(delay.toLong()).start()\r\n            }\r\n        }\r\n        viewsToMove?.run {\r\n            for (viewToMove in this) {\r\n                ViewCompat.animate(viewToMove).translationY((-1 * measuredHeight).toFloat())\r\n                        .setDuration(ANIMATION_DURATION).start()\r\n            }\r\n        }\r\n    }\r\n\r\n    // animation as per original Snackbar class\r\n    override fun animateContentOut(delay: Int, duration: Int) {\r\n        val viewsToAnimate = arrayOf(\r\n                messageText,\r\n                actionText,\r\n                actionNextLineText,\r\n                progressText,\r\n                horizontalProgressBar,\r\n                circularDeterminateProgressBar,\r\n                circularIndeterminateProgressBar)\r\n        viewsToAnimate.forEach { viewToAnimate ->\r\n            if (viewToAnimate.visibility == VISIBLE) {\r\n                viewToAnimate.alpha = 1f\r\n                ViewCompat.animate(viewToAnimate).alpha(0f).setDuration(duration.toLong())\r\n                        .setStartDelay(delay.toLong()).start()\r\n            }\r\n        }\r\n        viewsToMove?.run {\r\n            for (viewToMove in this) {\r\n                ViewCompat.animate(viewToMove).translationY(0f)\r\n                        .setDuration(ANIMATION_DURATION).start()\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun configureSwipeToDismiss() {\r\n        if (swipeToDismiss) {\r\n            // attach touch listener if it is not a CoordinatorLayout to allow extra features\r\n            if (!isCoordinatorLayout) {\r\n                setOnTouchListener()\r\n            }\r\n        } else {\r\n            // remove default behaviour specified in BaseTransientBottomBar for CoordinatorLayout\r\n            if (isCoordinatorLayout) {\r\n                val parentView = parent as ViewGroup\r\n                val layoutParams = parentView.layoutParams as CoordinatorLayout.LayoutParams\r\n                layoutParams.behavior = null\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Sets onTouchListener to allow swipe to dismiss behaviour for layouts other than CoordinatorLayout.\r\n     */\r\n    @SuppressLint(\"ClickableViewAccessibility\")\r\n    private fun setOnTouchListener() {\r\n        backgroundLayout.setOnTouchListener(object : OnTouchListener {\r\n            // variables\r\n            private val parentView = parent as View\r\n            private var startX: Float = 0f\r\n            private var endX: Float = 0f\r\n            private lateinit var velocityTracker: VelocityTracker\r\n\r\n            override fun onTouch(v: View, event: MotionEvent): Boolean {\r\n                val index = event.actionIndex\r\n                val pointerId = event.getPointerId(index)\r\n                when (event.actionMasked) {\r\n                    MotionEvent.ACTION_DOWN -> {\r\n                        // callback onBarTouchListener\r\n                        onBarTouchListener?.onTouch(ACTION_DOWN)\r\n                        // track initial coordinate\r\n                        startX = event.rawX\r\n                        // track velocity\r\n                        velocityTracker = VelocityTracker.obtain()\r\n                        velocityTracker.addMovement(event)\r\n                    }\r\n                    MotionEvent.ACTION_MOVE -> {\r\n                        // track velocity\r\n                        velocityTracker.addMovement(event)\r\n                        // track move coordinate\r\n                        val moveX = event.rawX\r\n                        // set translationX\r\n                        val deltaX = moveX - startX\r\n                        parentView.translationX = deltaX\r\n                        // animate alpha as per behaviour specified in BaseTransientBottomBar for CoordinatorLayout\r\n                        val totalWidth = parentView.measuredWidth\r\n                        val fractionTravelled = Math.abs(deltaX / totalWidth)\r\n                        when {\r\n                            fractionTravelled < startAlphaSwipeDistance -> parentView.alpha = 1f\r\n                            fractionTravelled > endAlphaSwipeDistance -> parentView.alpha = 0f\r\n                            else -> parentView.alpha = 1f - (fractionTravelled - startAlphaSwipeDistance) / (endAlphaSwipeDistance - startAlphaSwipeDistance)\r\n                        }\r\n                    }\r\n                    MotionEvent.ACTION_UP -> {\r\n                        // track final coordinate\r\n                        endX = event.rawX\r\n                        // get velocity and return resources\r\n                        velocityTracker.computeCurrentVelocity(1000)\r\n                        val velocity = Math.abs(velocityTracker.getXVelocity(pointerId))\r\n                        velocityTracker.recycle()\r\n                        // animate layout\r\n                        var toSwipeOut = false\r\n                        // swipe out if layout moved more than half of the screen\r\n                        if (Math.abs(endX - startX) / parentView.width > 0.5) {\r\n                            toSwipeOut = true\r\n                        }\r\n                        // swipe out if velocity is high\r\n                        if (Math.abs(velocity) > swipeOutVelocity) {\r\n                            toSwipeOut = true\r\n                        }\r\n                        if (toSwipeOut) {\r\n                            swipeOut(endX - startX)\r\n                        } else {\r\n                            // else, return to original position\r\n                            swipeIn(endX - startX)\r\n                        }\r\n                        // to satisfy android accessibility\r\n                        v.performClick()\r\n                    }\r\n                }\r\n                return true\r\n            }\r\n        })\r\n    }\r\n\r\n    /**\r\n     * Swipe out animation.\r\n     *\r\n     * @param deltaX Difference between position of ACTION_DOWN and ACTION_UP.\r\n     * Positive value means user swiped to right.\r\n     */\r\n    private fun swipeOut(deltaX: Float) {\r\n        // callback onBarTouchListener\r\n        onBarTouchListener?.onTouch(SWIPE_OUT)\r\n        val parentView = parent as View\r\n        val direction = if (deltaX > 0f) 1f else -1f\r\n        ViewCompat.animate(parentView)\r\n                .translationX(direction * parentView.width)\r\n                .setInterpolator(FastOutSlowInInterpolator())\r\n                .setDuration(ANIMATION_DURATION)\r\n                .setListener(null)      // remove listener that is attached in animateViewIn() of BaseTransientBottomBar\r\n                .start()\r\n        ViewCompat.animate(parentView)\r\n                .alpha(0f)\r\n                .setDuration(ANIMATION_DURATION)\r\n                .start()\r\n    }\r\n\r\n    /**\r\n     * Animation for swipe in.\r\n     *\r\n     * @param deltaX Difference between position of ACTION_DOWN and ACTION_UP.\r\n     * Zero means a user click.\r\n     */\r\n    private fun swipeIn(deltaX: Float) {\r\n        val parentView = parent as View\r\n        // animate if the layout has moved\r\n        if (Math.abs(deltaX) >= 0f) {\r\n            ViewCompat.animate(parentView)\r\n                    .translationX(0f)\r\n                    .setInterpolator(FastOutSlowInInterpolator())\r\n                    .setDuration(ANIMATION_DURATION)\r\n                    .setListener(null)      // remove listener that is attached in animateViewIn() of BaseTransientBottomBar\r\n                    .start()\r\n            ViewCompat.animate(parentView)\r\n                    .alpha(1f)\r\n                    .setDuration(ANIMATION_DURATION)\r\n                    .start()\r\n        } else {\r\n            // else just make sure the layout is at correct position\r\n            parentView.translationX = 0f\r\n            parentView.alpha = 1f\r\n        }\r\n        // callback onBarTouchListener\r\n        onBarTouchListener?.onTouch(SWIPE_IN)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/custom/snackbar/SnackProgressBarManager.kt",
    "content": "package knf.kuma.custom.snackbar\r\n\r\nimport android.util.SparseArray\r\nimport android.util.TypedValue\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.FrameLayout\r\nimport androidx.annotation.ColorRes\r\nimport androidx.annotation.FloatRange\r\nimport androidx.annotation.IntDef\r\nimport androidx.annotation.IntRange\r\nimport androidx.annotation.Keep\r\nimport androidx.coordinatorlayout.widget.CoordinatorLayout\r\nimport com.google.android.material.snackbar.BaseTransientBottomBar\r\nimport knf.kuma.R\r\nimport knf.kuma.custom.snackbar.SnackProgressBarManager.Companion.LENGTH_INDEFINITE\r\nimport knf.kuma.custom.snackbar.SnackProgressBarManager.Companion.LENGTH_LONG\r\nimport knf.kuma.custom.snackbar.SnackProgressBarManager.Companion.LENGTH_SHORT\r\n\r\n/**\r\n * Manager class handling all the SnackProgressBars added.\r\n * <p>\r\n * This class queues the SnackProgressBars to be shown.\r\n * It will dismiss the SnackProgressBar according to its desired duration before showing the next in queue.\r\n * </p>\r\n *\r\n * @constructor If possible, the root view of the activity should be provided and can be any type of layout.\r\n * The constructor will loop and crawl up the view hierarchy to find a suitable parent view if non-root view is provided.\r\n *\r\n * <p>If a CoordinatorLayout is provided, the FloatingActionButton will animate with the SnackProgressBar.\r\n * Else, [setViewsToMove] needs to be called to select the views to be animated.\r\n * Note that [setViewsToMove] can still be used for CoordinatorLayout to move other views.</p>\r\n *\r\n * <p>Swipe to dismiss behaviour can be set via [SnackProgressBar.setSwipeToDismiss].\r\n * This is provided via [BaseTransientBottomBar] for CoordinatorLayout, but provided via\r\n * [SnackProgressBarLayout] for other layout types.</p>\r\n *\r\n * @param view View to hold the SnackProgressBar.\r\n */\r\n@Keep\r\nclass SnackProgressBarManager(view: View) {\r\n\r\n    @Retention(AnnotationRetention.SOURCE)\r\n    @IntRange(from = 1)\r\n    annotation class OneUp\r\n\r\n    companion object {\r\n\r\n        @Retention(AnnotationRetention.SOURCE)\r\n        @IntDef(LENGTH_LONG, LENGTH_SHORT, LENGTH_INDEFINITE)\r\n        @IntRange(from = 1)\r\n        annotation class ShowDuration\r\n\r\n        /**\r\n         * Show the SnackProgressBar indefinitely.\r\n         * Note that this will be changed to LENGTH_SHORT and dismissed\r\n         * if there is another SnackProgressBar in queue before and after.\r\n         */\r\n        const val LENGTH_INDEFINITE = BaseTransientBottomBar.LENGTH_INDEFINITE\r\n        /**\r\n         * Show the SnackProgressBar for a short period of time.\r\n         */\r\n        const val LENGTH_SHORT = BaseTransientBottomBar.LENGTH_SHORT\r\n        /**\r\n         * Show the SnackProgressBar for a long period of time.\r\n         */\r\n        const val LENGTH_LONG = BaseTransientBottomBar.LENGTH_LONG\r\n\r\n        /**\r\n         * Default SnackProgressBar background color as per Material Design.\r\n         */\r\n        const val BACKGROUND_COLOR_DEFAULT = R.color.background\r\n        /**\r\n         * Default message text color as per Material Design.\r\n         */\r\n        const val MESSAGE_COLOR_DEFAULT = R.color.textWhitePrimary\r\n        /**\r\n         * Default action text color as per Material Design i.e. R.color.colorAccent.\r\n         */\r\n        const val ACTION_COLOR_DEFAULT = R.color.colorAccent\r\n        /**\r\n         * Default progressBar color as per Material Design i.e. R.color.colorAccent.\r\n         */\r\n        const val PROGRESSBAR_COLOR_DEFAULT = R.color.colorAccent\r\n        /**\r\n         * Default progressText color as per Material Design.\r\n         */\r\n        const val PROGRESSTEXT_COLOR_DEFAULT = R.color.textWhitePrimary\r\n        /**\r\n         * Default overlayLayout color i.e. android.R.color.white.\r\n         */\r\n        const val OVERLAY_COLOR_DEFAULT = android.R.color.white\r\n    }\r\n\r\n    /* variables */\r\n    private val onDisplayIdDefault = -1\r\n    private val storedBars = SparseArray<SnackProgressBar>()\r\n    private val queueBars = ArrayList<SnackProgressBar>()\r\n    private val queueOnDisplayIds = ArrayList<Int>()\r\n    private val queueDurations = ArrayList<Int>()\r\n\r\n    private var currentQueue = 0\r\n    private var currentCore: SnackProgressBarCore? = null\r\n    private var parentView: ViewGroup = findSuitableParent(view)\r\n    private var viewsToMove: Array<View>? = null\r\n    private var backgroundColor = BACKGROUND_COLOR_DEFAULT\r\n    private var messageTextColor = MESSAGE_COLOR_DEFAULT\r\n    private var actionTextColor = ACTION_COLOR_DEFAULT\r\n    private var progressBarColor = PROGRESSBAR_COLOR_DEFAULT\r\n    private var progressTextColor = PROGRESSTEXT_COLOR_DEFAULT\r\n    private var overlayColor = OVERLAY_COLOR_DEFAULT\r\n    private var textSize = parentView.resources.getDimension(R.dimen.text_body)\r\n    private var maxLines = 2\r\n    private var overlayLayoutAlpha = 0.8f\r\n    private var onDisplayListener: OnDisplayListener? = null\r\n\r\n    /**\r\n     * Interface definition for a callback to be invoked when the SnackProgressBar is shown or dismissed.\r\n     */\r\n    interface OnDisplayListener {\r\n        /**\r\n         * Called when the SnackProgressBar is shown.\r\n         *\r\n         * @param onDisplayId OnDisplayId assigned to the SnackProgressBar which is shown.\r\n         */\r\n        fun onShown(snackProgressBar: SnackProgressBar, onDisplayId: Int)\r\n\r\n        /**\r\n         * Called when the SnackProgressBar is dismissed.\r\n         *\r\n         * @param onDisplayId OnDisplayId assigned to the SnackProgressBar which is shown.\r\n         */\r\n        fun onDismissed(snackProgressBar: SnackProgressBar, onDisplayId: Int)\r\n    }\r\n\r\n    /**\r\n     * Registers a callback to be invoked when the SnackProgressBar is shown or dismissed.\r\n     *\r\n     * @param onDisplayListener The callback that will run. This value may be null.\r\n     */\r\n    fun setOnDisplayListener(onDisplayListener: OnDisplayListener?): SnackProgressBarManager {\r\n        this.onDisplayListener = onDisplayListener\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Stores a SnackProgressBar into SnackProgressBarManager to perform further action.\r\n     * The SnackProgressBar is uniquely identified by the storeId and will be overwritten\r\n     * by another SnackProgressBar with the same storeId.\r\n     *\r\n     * @param snackProgressBar SnackProgressBar to be added.\r\n     * @param storeId          OneUp of the SnackProgressBar to be added.\r\n     * @see SnackProgressBar\r\n     *\r\n     * @see .getSnackProgressBar\r\n     */\r\n    fun put(snackProgressBar: SnackProgressBar, @OneUp storeId: Int) {\r\n        storedBars.setValueAt(storeId, snackProgressBar)\r\n    }\r\n\r\n    /**\r\n     * Retrieves the SnackProgressBar that was previously added into SnackProgressBarManager.\r\n     *\r\n     * @param storeId OneUp of the SnackProgressBar stored in SnackProgressBarManager.\r\n     * @return SnackProgressBar of the storeId. Can be null.\r\n     * @see .put\r\n     */\r\n    fun getSnackProgressBar(@OneUp storeId: Int): SnackProgressBar? {\r\n        return storedBars[storeId]\r\n    }\r\n\r\n    /**\r\n     * Retrieves the SnackProgressBar that is currently or was showing.\r\n     *\r\n     * @return SnackProgressBar that is currently or was showing. Return null if nothing was ever shown.\r\n     */\r\n    fun getLastShown(): SnackProgressBar? {\r\n        return currentCore?.getSnackProgressBar()\r\n    }\r\n\r\n    /**\r\n     * Shows the SnackProgressBar based on its storeId with the specified duration.\r\n     * If another SnackProgressBar is already showing, this SnackProgressBar will be queued\r\n     * and shown accordingly after those queued are dismissed.\r\n     *\r\n     * @param storeId  OneUp of the SnackProgressBar stored in SnackProgressBarManager.\r\n     * @param duration Duration to show the SnackProgressBar of either\r\n     * [LENGTH_SHORT], [LENGTH_LONG], [LENGTH_INDEFINITE]\r\n     * or any positive millis.\r\n     * @see .put\r\n     */\r\n    fun show(@OneUp storeId: Int, @ShowDuration duration: Int) {\r\n        val snackProgressBar = storedBars[storeId]\r\n        snackProgressBar?.run { addToQueue(this, duration, onDisplayIdDefault) }\r\n                ?: throw IllegalArgumentException(\"SnackProgressBar with storeId = $storeId is not found!\")\r\n    }\r\n\r\n    /**\r\n     * Shows the SnackProgressBar based on its storeId with the specified duration.\r\n     * If another SnackProgressBar is already showing, this SnackProgressBar will be queued\r\n     * and shown accordingly after those queued are dismissed.\r\n     *\r\n     * @param storeId     OneUp of the SnackProgressBar stored in SnackProgressBarManager.\r\n     * @param duration    Duration to show the SnackProgressBar of either\r\n     * [LENGTH_SHORT], [LENGTH_LONG], [LENGTH_INDEFINITE]\r\n     * or any positive millis.\r\n     * @param onDisplayId OnDisplayId attached to the SnackProgressBar when implementing the OnDisplayListener.\r\n     * @see .put\r\n     */\r\n    fun show(@OneUp storeId: Int, @ShowDuration duration: Int, @OneUp onDisplayId: Int) {\r\n        val snackProgressBar = storedBars[storeId]\r\n        snackProgressBar?.run { show(this, duration, onDisplayId) }\r\n                ?: throw IllegalArgumentException(\"SnackProgressBar with storeId = $storeId is not found!\")\r\n    }\r\n\r\n    /**\r\n     * Shows the SnackProgressBar with the specified duration.\r\n     * If another SnackProgressBar is already showing, this SnackProgressBar will be queued\r\n     * and shown accordingly after those queued are dismissed.\r\n     *\r\n     * @param snackProgressBar SnackProgressBar to be shown.\r\n     * @param duration         Duration to show the SnackProgressBar of either\r\n     * [LENGTH_SHORT], [LENGTH_LONG], [LENGTH_INDEFINITE]\r\n     * or any positive millis.\r\n     */\r\n    fun show(snackProgressBar: SnackProgressBar, @ShowDuration duration: Int) {\r\n        addToQueue(snackProgressBar, duration, onDisplayIdDefault)\r\n    }\r\n\r\n    /**\r\n     * Shows the SnackProgressBar with the specified duration.\r\n     * If another SnackProgressBar is already showing, this SnackProgressBar will be queued\r\n     * and shown accordingly after those queued are dismissed.\r\n     *\r\n     * @param snackProgressBar SnackProgressBar to be shown.\r\n     * @param duration         Duration to show the SnackProgressBar of either\r\n     * [LENGTH_SHORT], [LENGTH_LONG], [LENGTH_INDEFINITE]\r\n     * or any positive millis.\r\n     * @param onDisplayId      OnDisplayId attached to the SnackProgressBar when implementing the OnDisplayListener.\r\n     */\r\n    fun show(snackProgressBar: SnackProgressBar, @ShowDuration duration: Int, @OneUp onDisplayId: Int) {\r\n        addToQueue(snackProgressBar, duration, onDisplayId)\r\n    }\r\n\r\n    /**\r\n     * Updates the currently showing SnackProgressBar without dismissing it to the SnackProgressBar\r\n     * with the corresponding storeId i.e. updating without animation.\r\n     * Note: This does not change the queue.\r\n     *\r\n     * @param storeId OneUp of the SnackProgressBar stored in SnackProgressBarManager.\r\n     */\r\n    fun updateTo(@OneUp storeId: Int) {\r\n        val snackProgressBar = storedBars[storeId]\r\n        snackProgressBar?.run { updateTo(this) }\r\n                ?: throw IllegalArgumentException(\"SnackProgressBar with storeId = $storeId is not found!\")\r\n    }\r\n\r\n    /**\r\n     * Updates the currently showing SnackProgressBar without dismissing it to the new SnackProgressBar\r\n     * i.e. updating without animation.\r\n     * Note: This does not change the queue.\r\n     *\r\n     * @param snackProgressBar SnackProgressBar to be updated to.\r\n     */\r\n    fun updateTo(snackProgressBar: SnackProgressBar) {\r\n        currentCore?.updateTo(snackProgressBar)\r\n    }\r\n\r\n    /**\r\n     * Dismisses the currently showing SnackProgressBar and show the next in queue.\r\n     */\r\n    fun dismiss() {\r\n        currentCore?.dismiss()\r\n        nextQueue()\r\n    }\r\n\r\n    /**\r\n     * Dismisses all the SnackProgressBar that is in queue.\r\n     * The currently shown SnackProgressBar will also be dismissed.\r\n     */\r\n    fun dismissAll() {\r\n        // reset queue before dismissing currentCore to prevent next in queue from showing\r\n        resetQueue()\r\n        currentCore?.dismiss()\r\n    }\r\n\r\n    /**\r\n     * Passes the view (e.g. FloatingActionButton) to move up or down as SnackProgressBar is shown or dismissed.\r\n     *\r\n     *\r\n     * This is not required for FloatingActionButton if a CoordinatorLayout is provided, but will be required for\r\n     * other layout types. This can be used to animate any view besides FloatingActionButton as well.\r\n     *\r\n     *\r\n     * @param viewToMove View to be animated along with the SnackProgressBar.\r\n     */\r\n    fun setViewToMove(viewToMove: View): SnackProgressBarManager {\r\n        val viewsToMove = arrayOf(viewToMove)\r\n        setViewsToMove(viewsToMove)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Passes the views (e.g. FloatingActionButton) to move up or down as SnackProgressBar is shown or dismissed.\r\n     *\r\n     *\r\n     * This is not required for FloatingActionButton if a CoordinatorLayout is provided, but will be required for\r\n     * other layout types. This can be used to animate any views besides FloatingActionButton as well.\r\n     *\r\n     *\r\n     * @param viewsToMove Views to be animated along with the SnackProgressBar.\r\n     */\r\n    private fun setViewsToMove(viewsToMove: Array<View>): SnackProgressBarManager {\r\n        this.viewsToMove = viewsToMove\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the text size of SnackProgressBar.\r\n     *\r\n     * @param sp Font size in scale-independent pixels.\r\n     */\r\n    fun setTextSize(sp: Float): SnackProgressBarManager {\r\n        textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, parentView.resources.displayMetrics)\r\n        currentCore?.setTextSize(textSize)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the max lines for message.\r\n     *\r\n     * @param maxLines Number of lines.\r\n     */\r\n    fun setMessageMaxLines(maxLines: Int): SnackProgressBarManager {\r\n        this.maxLines = maxLines\r\n        currentCore?.setMaxLines(maxLines)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the transparency of the overlayLayout which blocks user input.\r\n     *\r\n     * @param alpha Alpha between 0f to 1f. Default = 0.8f.\r\n     */\r\n    fun setOverlayLayoutAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float): SnackProgressBarManager {\r\n        overlayLayoutAlpha = alpha\r\n        currentCore?.setOverlayLayout(overlayColor, overlayLayoutAlpha)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the overlayLayout color.\r\n     *\r\n     * @param colorId R.color id.\r\n     * @see .OVERLAY_COLOR_DEFAULT\r\n     */\r\n    fun setOverlayLayoutColor(@ColorRes colorId: Int): SnackProgressBarManager {\r\n        overlayColor = colorId\r\n        // update the UI now if applicable\r\n        currentCore?.setOverlayLayout(overlayColor, overlayLayoutAlpha)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the SnackProgressBar background color.\r\n     *\r\n     * @param colorId R.color id.\r\n     * @see .BACKGROUND_COLOR_DEFAULT\r\n     */\r\n    fun setBackgroundColor(@ColorRes colorId: Int): SnackProgressBarManager {\r\n        backgroundColor = colorId\r\n        // update the UI now if applicable\r\n        currentCore?.setColor(backgroundColor, messageTextColor, actionTextColor, progressBarColor, progressTextColor)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the message text color.\r\n     *\r\n     * @param colorId R.color id.\r\n     * @see .MESSAGE_COLOR_DEFAULT\r\n     */\r\n    fun setMessageTextColor(@ColorRes colorId: Int): SnackProgressBarManager {\r\n        messageTextColor = colorId\r\n        // update the UI now if applicable\r\n        currentCore?.setColor(backgroundColor, messageTextColor, actionTextColor, progressBarColor, progressTextColor)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the action text color.\r\n     *\r\n     * @param colorId R.color id.\r\n     * @see .ACTION_COLOR_DEFAULT\r\n     */\r\n    fun setActionTextColor(@ColorRes colorId: Int): SnackProgressBarManager {\r\n        actionTextColor = colorId\r\n        // update the UI now if applicable\r\n        currentCore?.setColor(backgroundColor, messageTextColor, actionTextColor, progressBarColor, progressTextColor)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the ProgressBar color.\r\n     *\r\n     * @param colorId R.color id.\r\n     * @see .PROGRESSBAR_COLOR_DEFAULT\r\n     */\r\n    fun setProgressBarColor(@ColorRes colorId: Int): SnackProgressBarManager {\r\n        progressBarColor = colorId\r\n        // update the UI now if applicable\r\n        currentCore?.setColor(backgroundColor, messageTextColor, actionTextColor, progressBarColor, progressTextColor)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the ProgressText color.\r\n     *\r\n     * @param colorId R.color id.\r\n     * @see .PROGRESSTEXT_COLOR_DEFAULT\r\n     */\r\n    fun setProgressTextColor(@ColorRes colorId: Int): SnackProgressBarManager {\r\n        progressTextColor = colorId\r\n        // update the UI now if applicable\r\n        currentCore?.setColor(backgroundColor, messageTextColor, actionTextColor, progressBarColor, progressTextColor)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Sets the progress for SnackProgressBar that is currently showing.\r\n     * It will also update the progress in % if it is shown.\r\n     *\r\n     * @param progress Progress of the ProgressBar.\r\n     */\r\n    fun setProgress(@IntRange(from = 0) progress: Int): SnackProgressBarManager {\r\n        currentCore?.setProgress(progress)\r\n        return this\r\n    }\r\n\r\n    /**\r\n     * Adds the SnackProgressBar to queue.\r\n     *\r\n     * @param snackProgressBar SnackProgressBar to be added to queue.\r\n     * @param duration         Duration to show the SnackProgressBar of either\r\n     * [LENGTH_SHORT], [LENGTH_LONG], [LENGTH_INDEFINITE]\r\n     * or any positive millis.\r\n     * @param onDisplayId      OnDisplayId attached to the SnackProgressBar when implementing the OnDisplayListener.\r\n     */\r\n    private fun addToQueue(snackProgressBar: SnackProgressBar, duration: Int, onDisplayId: Int) {\r\n        // get the queue number as the last of queue list\r\n        val queue = queueBars.size\r\n        // create a new object\r\n        val queueBar = SnackProgressBar(snackProgressBar.getType(),\r\n                snackProgressBar.getMessage(),\r\n                snackProgressBar.getAction(),\r\n                snackProgressBar.getOnActionClickListener(),\r\n                snackProgressBar.getIconBitmap(),\r\n                snackProgressBar.getIconResource(),\r\n                snackProgressBar.getProgressMax(),\r\n                snackProgressBar.isAllowUserInput(),\r\n                snackProgressBar.isSwipeToDismiss(),\r\n                snackProgressBar.isIndeterminate(),\r\n                snackProgressBar.isShowProgressPercentage(),\r\n                snackProgressBar.getBundle())\r\n        // put in queue\r\n        queueBars.add(queueBar)\r\n        queueOnDisplayIds.add(onDisplayId)\r\n        queueDurations.add(duration)\r\n        // play queue if first item\r\n        if (queue == 0) {\r\n            playQueue(queue)\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Plays the queue.\r\n     *\r\n     * @param queue Queue number of SnackProgressBar.\r\n     */\r\n    private fun playQueue(queue: Int) {\r\n        // check if queue number is bounded\r\n        if (queue < queueBars.size) {\r\n            // get the variables\r\n            currentQueue = queue\r\n            val snackProgressBar = queueBars[queue]\r\n            val onDisplayId = queueOnDisplayIds[queue]\r\n            var duration = queueDurations[queue]\r\n            // change duration to LENGTH_SHORT if is not last item\r\n            if (duration == LENGTH_INDEFINITE) {\r\n                if (queue < queueBars.size - 1) {\r\n                    duration = LENGTH_SHORT\r\n                }\r\n            }\r\n            // create SnackProgressBarCore\r\n            val finalDuration = duration\r\n            val snackProgressBarCore = SnackProgressBarCore.make(parentView, snackProgressBar, duration, viewsToMove)\r\n                    .setOverlayLayout(overlayColor, overlayLayoutAlpha)\r\n                    .setColor(backgroundColor, messageTextColor, actionTextColor, progressBarColor, progressTextColor)\r\n                    .setTextSize(textSize)\r\n                    .setMaxLines(maxLines)\r\n                    .addCallback(object : BaseTransientBottomBar.BaseCallback<SnackProgressBarCore>() {\r\n                        override fun onShown(snackProgressBarCore: SnackProgressBarCore) {\r\n                            // set current\r\n                            currentCore = snackProgressBarCore\r\n                            // callback onDisplayListener\r\n                            onDisplayListener?.run {\r\n                                if (onDisplayId != onDisplayIdDefault) {\r\n                                    this.onShown(snackProgressBarCore.getSnackProgressBar(), onDisplayId)\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        override fun onDismissed(snackProgressBarCore: SnackProgressBarCore, event: Int) {\r\n                            // remove overlayLayout\r\n                            snackProgressBarCore.removeOverlayLayout()\r\n                            // reset current\r\n                            currentCore = null\r\n                            // callback onDisplayListener\r\n                            onDisplayListener?.run {\r\n                                if (onDisplayId != onDisplayIdDefault) {\r\n                                    this.onDismissed(snackProgressBarCore.getSnackProgressBar(), onDisplayId)\r\n                                }\r\n                            }\r\n                            // play next if this item is dismissed automatically later\r\n                            if (finalDuration != LENGTH_INDEFINITE) {\r\n                                nextQueue()\r\n                            }\r\n                        }\r\n                    })\r\n            // reset queue if this is last item in queue with LENGTH_INDEFINITE\r\n            if (duration == LENGTH_INDEFINITE) {\r\n                resetQueue()\r\n            }\r\n            snackProgressBarCore.show()\r\n        } else {\r\n            // else, queue is done\r\n            resetQueue()\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Play the next item in queue.\r\n     */\r\n    private fun nextQueue() {\r\n        playQueue(currentQueue + 1)\r\n    }\r\n\r\n    /**\r\n     * Reset queue.\r\n     */\r\n    private fun resetQueue() {\r\n        currentQueue = 0\r\n        queueBars.clear()\r\n        queueOnDisplayIds.clear()\r\n        queueDurations.clear()\r\n    }\r\n\r\n    /**\r\n     * Loop and crawl up the providedView hierarchy to find a suitable parent providedView.\r\n     *\r\n     * @param providedView View to hold the SnackProgressBar.\r\n     * If possible, it should be the root providedView of the activity and can be any type of layout.\r\n     * @return Suitable parent providedView of the activity.\r\n     */\r\n    private fun findSuitableParent(providedView: View): ViewGroup {\r\n        var view: View? = providedView\r\n        var fallback: ViewGroup? = null\r\n        do {\r\n            if (view is CoordinatorLayout) {\r\n                // use the CoordinatorLayout found\r\n                return view\r\n            } else if (view is FrameLayout) {\r\n                if (view.id == android.R.id.content) {\r\n                    // use the content providedView since CoordinatorLayout not found\r\n                    return view\r\n                } else {\r\n                    // Non-content providedView, but use it as fallback\r\n                    fallback = view\r\n                }\r\n            }\r\n            if (view != null) {\r\n                // loop and crawl up the providedView hierarchy and try to find a parent\r\n                val parent = view.parent\r\n                view = if (parent is View) parent else null\r\n            }\r\n        } while (view != null)\r\n        // use fallback since CoordinatorLayout and other alternative not found\r\n        fallback?.run { return this }\r\n                ?: throw IllegalArgumentException(\"No suitable parent found from the given view. \" + \"Please provide a valid view.\")\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/BaseConverter.kt",
    "content": "package knf.kuma.database\n\nimport android.net.Uri\nimport androidx.room.TypeConverter\nimport com.google.gson.Gson\nimport com.google.gson.reflect.TypeToken\nimport knf.kuma.videoservers.Headers\n\nclass BaseConverter {\n    @TypeConverter\n    fun booleanToInt(b: Boolean): Int {\n        return if (b) 1 else 0\n    }\n\n    @TypeConverter\n    fun intToBoolean(i: Int): Boolean {\n        return i == 1\n    }\n\n    @TypeConverter\n    fun uriToString(uri: Uri): String {\n        return uri.toString()\n    }\n\n    @TypeConverter\n    fun stringToUri(s: String): Uri {\n        return Uri.parse(s)\n    }\n\n    @TypeConverter\n    fun headersToString(headers: Headers?): String {\n        return Gson().toJson(headers, object : TypeToken<Headers>() {\n        }.type)\n    }\n\n    @TypeConverter\n    fun stringToHeader(json: String?): Headers? {\n        return Gson().fromJson<Headers>(json, object : TypeToken<Headers>() {\n        }.type)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/CacheDB.kt",
    "content": "package knf.kuma.database\n\nimport android.content.Context\nimport androidx.room.Database\nimport androidx.room.Room\nimport androidx.room.RoomDatabase\nimport androidx.room.migration.Migration\nimport androidx.sqlite.db.SupportSQLiteDatabase\nimport knf.kuma.App\nimport knf.kuma.database.dao.AchievementsDAO\nimport knf.kuma.database.dao.AnimeDAO\nimport knf.kuma.database.dao.ChaptersDAO\nimport knf.kuma.database.dao.DownloadsDAO\nimport knf.kuma.database.dao.ExplorerDAO\nimport knf.kuma.database.dao.FavsDAO\nimport knf.kuma.database.dao.GenresDAO\nimport knf.kuma.database.dao.NotificationDAO\nimport knf.kuma.database.dao.PlayerStateDAO\nimport knf.kuma.database.dao.QueueDAO\nimport knf.kuma.database.dao.RecentModelsDAO\nimport knf.kuma.database.dao.RecentsDAO\nimport knf.kuma.database.dao.RecordsDAO\nimport knf.kuma.database.dao.SeeingDAO\nimport knf.kuma.database.dao.SeenDAO\nimport knf.kuma.player.PlayerState\nimport knf.kuma.pojos.Achievement\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.pojos.ExplorerObject\nimport knf.kuma.pojos.FavoriteObject\nimport knf.kuma.pojos.GenreStatusObject\nimport knf.kuma.pojos.NotificationObj\nimport knf.kuma.pojos.QueueObject\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeeingObject\nimport knf.kuma.pojos.SeenObject\nimport knf.kuma.recents.RecentModel\n\n@Database(entities = [RecentObject::class, RecentModel::class, PlayerState::class, AnimeObject::class, FavoriteObject::class, AnimeObject.WebInfo.AnimeChapter::class, SeenObject::class, NotificationObj::class, DownloadObject::class, RecordObject::class, SeeingObject::class, ExplorerObject::class, GenreStatusObject::class, QueueObject::class, Achievement::class],\n        version = 20)\nabstract class CacheDB : RoomDatabase() {\n\n    abstract fun recentsDAO(): RecentsDAO\n\n    abstract fun recentModelsDAO(): RecentModelsDAO\n\n    abstract fun animeDAO(): AnimeDAO\n\n    abstract fun favsDAO(): FavsDAO\n\n    abstract fun chaptersDAO(): ChaptersDAO\n\n    abstract fun seenDAO(): SeenDAO\n\n    abstract fun notificationDAO(): NotificationDAO\n\n    abstract fun downloadsDAO(): DownloadsDAO\n\n    abstract fun recordsDAO(): RecordsDAO\n\n    abstract fun seeingDAO(): SeeingDAO\n\n    abstract fun explorerDAO(): ExplorerDAO\n\n    abstract fun queueDAO(): QueueDAO\n\n    abstract fun genresDAO(): GenresDAO\n\n    abstract fun achievementsDAO(): AchievementsDAO\n\n    abstract fun playerStateDAO(): PlayerStateDAO\n\n    companion object {\n        private val MIGRATION_1_2: Migration = object : Migration(1, 2) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"CREATE TABLE `genrestatusobject` (`key` INTEGER NOT NULL, \" + \"`name` TEXT, `count` INTEGER NOT NULL, PRIMARY KEY(`key`))\")\n            }\n        }\n        private val MIGRATION_2_3: Migration = object : Migration(2, 3) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"CREATE TABLE `queueobject` (`key` INTEGER, `id` INTEGER NOT NULL,\" + \"`number` TEXT, `eid` TEXT,`isFile` INTEGER NOT NULL,`link` TEXT,`name` TEXT,`aid` TEXT,`time` INTEGER NOT NULL, PRIMARY KEY (`id`))\")\n            }\n        }\n        private val MIGRATION_3_4: Migration = object : Migration(3, 4) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"ALTER TABLE `queueobject`  ADD COLUMN `uri` TEXT\")\n            }\n        }\n        private val MIGRATION_4_5: Migration = object : Migration(4, 5) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"ALTER TABLE `explorerobject`  ADD COLUMN `aid` TEXT\")\n            }\n        }\n        private val MIGRATION_5_6: Migration = object : Migration(5, 6) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"ALTER TABLE `downloadobject`  ADD COLUMN `headers` TEXT\")\n            }\n        }\n        private val MIGRATION_6_7: Migration = object : Migration(6, 7) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"ALTER TABLE `downloadobject`  ADD COLUMN `did` TEXT\")\n                database.execSQL(\"ALTER TABLE `downloadobject`  ADD COLUMN `eta` TEXT\")\n                database.execSQL(\"ALTER TABLE `downloadobject`  ADD COLUMN `speed` TEXT\")\n            }\n        }\n        private val MIGRATION_8_7: Migration = object : Migration(8, 7) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n\n            }\n        }\n        private val MIGRATION_7_8: Migration = object : Migration(7, 8) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"ALTER TABLE `downloadobject`  ADD COLUMN `time` INTEGER NOT NULL DEFAULT 0\")\n            }\n        }\n        private val MIGRATION_8_9: Migration = object : Migration(8, 9) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n\n            }\n        }\n        private val MIGRATION_9_10: Migration = object : Migration(9, 10) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"CREATE TABLE IF NOT EXISTS `recentobject_tmp` (`key` INTEGER NOT NULL, `aid` TEXT, `eid` TEXT, `name` TEXT, `chapter` TEXT, `url` TEXT, `img` TEXT, PRIMARY KEY(`key`))\")\n                database.execSQL(\"DROP TABLE `recentobject`\")\n                database.execSQL(\"ALTER TABLE `recentobject_tmp` RENAME TO `recentobject`\")\n            }\n        }\n\n        private val MIGRATION_10_11: Migration = object : Migration(10, 11) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"ALTER TABLE `seeingobject`  ADD COLUMN `state` INTEGER NOT NULL DEFAULT 1\")\n            }\n        }\n\n        private val MIGRATION_11_12: Migration = object : Migration(11, 12) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"CREATE TABLE `achivement` (\" +\n                        \"`key` INTEGER NOT NULL, \" +\n                        \"`name` TEXT NOT NULL, \" +\n                        \"`description` TEXT NOT NULL, \" +\n                        \"`icon` INTEGER NOT NULL, \" +\n                        \"`points` INTEGER NOT NULL, \" +\n                        \"`isSecret` INTEGER NOT NULL, \" +\n                        \"`group` TEXT, \" +\n                        \"`time` INTEGER NOT NULL, \" +\n                        \"`count` INTEGER NOT NULL, \" +\n                        \"`goal` INTEGER NOT NULL, \" +\n                        \"`isUnlocked` INTEGER NOT NULL, \" +\n                        \"PRIMARY KEY(`key`))\")\n            }\n        }\n\n        private val MIGRATION_12_13: Migration = object : Migration(12, 13) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"CREATE TABLE `achivement_tmp` (\" +\n                        \"`key` INTEGER NOT NULL, \" +\n                        \"`name` TEXT NOT NULL, \" +\n                        \"`description` TEXT NOT NULL, \" +\n                        \"`points` INTEGER NOT NULL, \" +\n                        \"`isSecret` INTEGER NOT NULL, \" +\n                        \"`group` TEXT, \" +\n                        \"`time` INTEGER NOT NULL, \" +\n                        \"`count` INTEGER NOT NULL, \" +\n                        \"`goal` INTEGER NOT NULL, \" +\n                        \"`isUnlocked` INTEGER NOT NULL, \" +\n                        \"PRIMARY KEY(`key`))\")\n                database.execSQL(\"INSERT INTO `achivement_tmp` (`key`,`name`,`description`,`points`,`isSecret`,`group`,`time`,`count`,`goal`,`isUnlocked`) SELECT `key`,`name`,`description`,`points`,`isSecret`,`group`,`time`,`count`,`goal`,`isUnlocked` FROM `achivement`\")\n                database.execSQL(\"DROP TABLE `achivement`\")\n                database.execSQL(\"ALTER TABLE `achivement_tmp` RENAME TO `achievement`\")\n            }\n        }\n\n        private val MIGRATION_13_14: Migration = object : Migration(13, 14) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"ALTER TABLE `animeobject`  ADD COLUMN `followers` TEXT\")\n            }\n        }\n\n        private val MIGRATION_14_15: Migration = object : Migration(14, 15) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"ALTER TABLE `downloadobject` ADD COLUMN `server` TEXT DEFAULT 'desconocido'\")\n            }\n        }\n\n        private val MIGRATION_15_16: Migration = object : Migration(15, 16) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"CREATE TABLE `seenobject` (\" +\n                        \"`eid` TEXT NOT NULL, \" +\n                        \"`aid` TEXT NOT NULL, \" +\n                        \"`number` TEXT NOT NULL, \" +\n                        \"PRIMARY KEY(`eid`))\")\n            }\n        }\n\n        private val MIGRATION_16_17: Migration = object : Migration(16, 17) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"ALTER TABLE `achievement` ADD COLUMN `isRevealed` INTEGER NOT NULL DEFAULT 0\")\n            }\n        }\n\n        private val MIGRATION_17_18: Migration = object : Migration(17, 18) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"CREATE TABLE `recentmodel` (\" +\n                        \"`key` INTEGER NOT NULL, \" +\n                        \"`aid` TEXT NOT NULL, \" +\n                        \"`name` TEXT NOT NULL, \" +\n                        \"`chapter` TEXT NOT NULL, \" +\n                        \"`chapterUrl` TEXT NOT NULL, \" +\n                        \"`img` TEXT NOT NULL, \" +\n                        \"PRIMARY KEY(`key`))\")\n            }\n        }\n\n        private val MIGRATION_18_19: Migration = object : Migration(18, 19) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n                database.execSQL(\"CREATE TABLE `playerstate` (\" +\n                        \"`title` TEXT NOT NULL, \" +\n                        \"`position` INTEGER NOT NULL, \" +\n                        \"PRIMARY KEY(`title`))\")\n            }\n        }\n\n        private val MIGRATION_19_20: Migration = object : Migration(19, 20) {\n            override fun migrate(database: SupportSQLiteDatabase) {\n            }\n        }\n\n        val INSTANCE: CacheDB by lazy { init(App.context) }\n\n        private fun init(context: Context): CacheDB =\n                Room.databaseBuilder(context, CacheDB::class.java, \"cache-db\")\n                    .addMigrations(\n                        MIGRATION_1_2,\n                        MIGRATION_2_3,\n                        MIGRATION_3_4,\n                        MIGRATION_4_5,\n                        MIGRATION_5_6,\n                        MIGRATION_6_7,\n                        MIGRATION_7_8,\n                        MIGRATION_8_7,\n                        MIGRATION_8_9,\n                        MIGRATION_9_10,\n                        MIGRATION_10_11,\n                        MIGRATION_11_12,\n                        MIGRATION_12_13,\n                        MIGRATION_13_14,\n                        MIGRATION_14_15,\n                        MIGRATION_15_16,\n                        MIGRATION_16_17,\n                        MIGRATION_17_18,\n                        MIGRATION_18_19,\n                        MIGRATION_19_20\n                    ).build()\n\n        fun createAndGet(context: Context): CacheDB {\n            return Room.databaseBuilder(context, CacheDB::class.java, \"cache-db\")\n                .addMigrations(\n                    MIGRATION_1_2,\n                    MIGRATION_2_3,\n                    MIGRATION_3_4,\n                    MIGRATION_4_5,\n                    MIGRATION_5_6,\n                    MIGRATION_6_7,\n                    MIGRATION_7_8,\n                    MIGRATION_8_9,\n                    MIGRATION_9_10,\n                    MIGRATION_10_11,\n                    MIGRATION_11_12,\n                    MIGRATION_12_13,\n                    MIGRATION_13_14,\n                    MIGRATION_14_15,\n                    MIGRATION_15_16,\n                    MIGRATION_16_17,\n                    MIGRATION_17_18,\n                    MIGRATION_18_19,\n                    MIGRATION_19_20\n                ).build()\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/CacheDBWrap.java",
    "content": "package knf.kuma.database;\r\n\r\npublic class CacheDBWrap {\r\n    public static CacheDB INSTANCE = CacheDB.Companion.getINSTANCE();\r\n}\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/EADB.kt",
    "content": "package knf.kuma.database\n\nimport android.content.Context\n\nimport androidx.room.Database\nimport androidx.room.Room\nimport androidx.room.RoomDatabase\nimport knf.kuma.App\nimport knf.kuma.database.dao.EaDAO\nimport knf.kuma.pojos.EAObject\n\n@Database(entities = [EAObject::class], version = 1)\nabstract class EADB : RoomDatabase() {\n\n    abstract fun eaDAO(): EaDAO\n\n    companion object {\n        val INSTANCE: EADB by lazy { init(App.context) }\n\n        private fun init(context: Context): EADB =\n                Room.databaseBuilder(context, EADB::class.java, \"ee-db\")\n                        .allowMainThreadQueries()\n                        .build()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/AchievementsDAO.kt",
    "content": "package knf.kuma.database.dao\r\n\r\nimport androidx.lifecycle.LiveData\r\nimport androidx.room.Dao\r\nimport androidx.room.Insert\r\nimport androidx.room.OnConflictStrategy\r\nimport androidx.room.Query\r\nimport androidx.room.TypeConverters\r\nimport androidx.room.Update\r\nimport knf.kuma.database.BaseConverter\r\nimport knf.kuma.pojos.Achievement\r\n\r\n@Dao\r\n@TypeConverters(BaseConverter::class)\r\ninterface AchievementsDAO {\r\n    @get:Query(\"SELECT * FROM achievement\")\r\n    val all: List<Achievement>\r\n\r\n    @get:Query(\"SELECT * FROM achievement WHERE isUnlocked = 1\")\r\n    val allCompleted: List<Achievement>\r\n\r\n    @get:Query(\"SELECT SUM(points) FROM achievement WHERE isUnlocked = 1\")\r\n    val totalUnlockedPoints: LiveData<Int?>\r\n\r\n    @get:Query(\"SELECT SUM(points) FROM achievement\")\r\n    val totalPoints: Int\r\n\r\n    @get:Query(\"SELECT * FROM achievement\")\r\n    val allListener: LiveData<List<Achievement>>\r\n\r\n    @get:Query(\"SELECT * FROM achievement WHERE isUnlocked = 0 AND count >= goal AND NOT goal = 0\")\r\n    val completionListener: LiveData<List<Achievement>>\r\n\r\n    @get:Query(\"SELECT COUNT(*) FROM achievement\")\r\n    val totalAchievements: Int\r\n\r\n    @get:Query(\"SELECT * FROM achievement WHERE isUnlocked = 1 ORDER BY time ASC\")\r\n    val completedAchievements: List<Achievement>\r\n\r\n    @Query(\"SELECT * FROM achievement WHERE isUnlocked = :isUnlocked ORDER BY points ASC, name\")\r\n    fun achievementList(isUnlocked: Int): LiveData<MutableList<Achievement>>\r\n\r\n    @Query(\"SELECT * FROM achievement WHERE `key`=:key\")\r\n    fun find(key: Int): Achievement?\r\n\r\n    @Query(\"SELECT * FROM achievement WHERE `key` IN (:keys)\")\r\n    fun find(vararg keys: Int): List<Achievement>\r\n\r\n    @Query(\"SELECT * FROM achievement WHERE `key` IN (:keys)\")\r\n    fun find(keys: List<Int>): List<Achievement>\r\n\r\n    @Query(\"SELECT isUnlocked FROM achievement WHERE `key`=:key LIMIT 1\")\r\n    fun isUnlocked(key: Int): Boolean\r\n\r\n    @Insert(onConflict = OnConflictStrategy.IGNORE)\r\n    fun insert(vararg achievements: Achievement)\r\n\r\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\r\n    fun update(achievements: List<Achievement>)\r\n\r\n    @Update\r\n    fun update(achievements: Achievement)\r\n\r\n    @Query(\"DELETE FROM achievement\")\r\n    fun nuke()\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/AnimeDAO.kt",
    "content": "package knf.kuma.database.dao\n\nimport androidx.lifecycle.LiveData\nimport androidx.paging.DataSource\nimport androidx.room.Dao\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport androidx.room.Transaction\nimport androidx.room.TypeConverters\nimport androidx.room.Update\nimport knf.kuma.backup.objects.AnimeChapters\nimport knf.kuma.database.BaseConverter\nimport knf.kuma.directory.DirObject\nimport knf.kuma.emision.AnimeSubObject\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.random.RandomObject\nimport knf.kuma.recommended.AnimeShortObject\nimport knf.kuma.search.SearchAdvObject\nimport knf.kuma.search.SearchObject\nimport knf.kuma.slices.AnimeSliceObject\nimport knf.kuma.tv.search.BasicAnimeObject\n\n@Dao\n@TypeConverters(BaseConverter::class, AnimeObject.Converter::class)\ninterface AnimeDAO {\n\n    @get:Query(\"SELECT * FROM AnimeObject\")\n    val all: List<AnimeObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link FROM AnimeObject ORDER BY name\")\n    val allSearch: DataSource.Factory<Int, SearchObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject ORDER BY name\")\n    val allLive: LiveData<List<DirObject>>\n\n    @get:Query(\"SELECT link FROM AnimeObject WHERE state LIKE 'En emisión'\")\n    val allLinksInEmission: List<String>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Anime' ORDER BY name\")\n    val animeDir: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Anime' ORDER BY rate_stars DESC\")\n    val animeDirVotes: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Anime' AND state LIKE 'En emisión' ORDER BY rate_stars DESC, rate_count+0 DESC LIMIT 10\")\n    val emissionVotesLimited: LiveData<List<DirObject>>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Anime' ORDER BY rate_stars DESC, rate_count+0 DESC LIMIT 20\")\n    val allVotesLimited: LiveData<List<DirObject>>\n\n    @Query(\"SELECT `key`,name,link,aid,img,type FROM AnimeObject WHERE aid IN (:aids) ORDER BY RANDOM() LIMIT 10\")\n    fun animesWithIDRandom(aids: List<String>): List<SearchAdvObject>\n\n    @Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE aid IN (:aids) ORDER BY RANDOM() LIMIT 15\")\n    fun animesDirWithIDRandom(aids: List<String>): List<DirObject>\n\n    @Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE aid IN (:aids) ORDER BY RANDOM()\")\n    fun animesDirWithIDRandomNL(aids: List<String>): List<DirObject>\n\n    @Query(\"SELECT aid FROM animeobject WHERE link = :link\")\n    fun findAid(link: String): String?\n\n    @Query(\"SELECT aid FROM animeobject WHERE name = :name\")\n    fun findAidByName(name: String): String?\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Anime' ORDER BY `key` ASC\")\n    val animeDirID: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Anime' ORDER BY `key` DESC\")\n    val animeDirAdded: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Anime' ORDER BY followers+0 DESC\")\n    val animeDirFollowers: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'OVA' OR type LIKE '%special' ORDER BY name\")\n    val ovaDir: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'OVA' OR type LIKE '%special' ORDER BY rate_stars DESC\")\n    val ovaDirVotes: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'OVA' OR type LIKE '%special' ORDER BY `key` ASC\")\n    val ovaDirID: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'OVA' OR type LIKE '%special' ORDER BY `key` DESC\")\n    val ovaDirAdded: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'OVA' OR type LIKE '%special' ORDER BY followers+0 DESC\")\n    val ovaDirFollowers: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Película' ORDER BY name\")\n    val movieDir: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Película' ORDER BY rate_stars DESC\")\n    val movieDirVotes: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Película' ORDER BY `key` ASC\")\n    val movieDirID: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Película' ORDER BY `key` DESC\")\n    val movieDirAdded: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE type LIKE 'Película' ORDER BY followers+0 DESC\")\n    val movieDirFollowers: DataSource.Factory<Int, DirObject>\n\n    @get:Query(\"SELECT count(*) FROM AnimeObject\")\n    val count: Int\n\n    @get:Query(\"SELECT count(*) FROM AnimeObject\")\n    val countLive: LiveData<Int>\n\n    @Query(\"SELECT count(*) FROM AnimeObject\")\n    fun init(): Int\n\n    @Query(\"SELECT * FROM AnimeObject WHERE aid = :aid\")\n    fun getAnimeByAid(aid: String): AnimeObject?\n\n    @Query(\"SELECT `key`,aid,img,link,name,type FROM AnimeObject WHERE aid IN (:aids) ORDER BY name\")\n    fun getAnimesByAids(aids: List<String>): List<AnimeShortObject>\n\n    @Query(\"SELECT * FROM AnimeObject WHERE link LIKE :link\")\n    fun getAnimeRaw(link: String): AnimeObject?\n\n    @Query(\"SELECT `key`,name,link,aid,type FROM AnimeObject ORDER BY RANDOM() LIMIT :limit\")\n    fun getRandom(limit: Int): List<RandomObject>\n\n    @Query(\"SELECT `key`,name,link,aid FROM AnimeObject WHERE state LIKE 'En emisión' AND day = :day AND aid NOT IN (:list) ORDER BY name\")\n    fun getByDay(day: Int, list: Set<String>): LiveData<MutableList<SearchObject>>\n\n    @Query(\"SELECT `key`,name,link,aid FROM AnimeObject WHERE state LIKE 'En emisión' AND day = :day ORDER BY name\")\n    fun getByDay(day: Int): LiveData<MutableList<SearchObject>>\n\n    @Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE state LIKE 'En emisión' AND day = :day ORDER BY name\")\n    fun getByDayDir(day: Int): LiveData<MutableList<DirObject>>\n\n    @Query(\"SELECT `key`,aid,name,link,rate_stars,type FROM AnimeObject WHERE state LIKE 'En emisión' ORDER BY name\")\n    fun getAllEmission(): List<DirObject>\n\n    @Query(\"SELECT count(*) FROM AnimeObject WHERE state = 'En emisión' AND NOT day = 0 AND aid NOT IN (:list)\")\n    fun getInEmission(list: Set<String>): LiveData<Int>\n\n    @Query(\"SELECT `key`,link,name,aid FROM AnimeObject WHERE state LIKE 'En emisión' AND day = :day AND aid NOT IN (:list) ORDER BY name\")\n    fun getByDayDirect(day: Int, list: Set<String>): MutableList<SearchObject>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE name LIKE :query ORDER BY name\")\n    fun getSearch(query: String): DataSource.Factory<Int, SearchObject>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE name LIKE :query ORDER BY name\")\n    fun getSearchList(query: String): LiveData<MutableList<BasicAnimeObject>>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE aid LIKE :query ORDER BY name\")\n    fun getSearchID(query: String): DataSource.Factory<Int, SearchObject>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE genres LIKE :genres ORDER BY name\")\n    fun getSearchG(genres: String): DataSource.Factory<Int, SearchObject>\n\n    @Query(\"SELECT `key`,name,link,aid FROM AnimeObject WHERE genres LIKE :genre ORDER BY name\")\n    fun getAllGenre(genre: String): DataSource.Factory<Int, SearchObject>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE genres LIKE :genre ORDER BY name\")\n    fun getAllGenreLive(genre: String): LiveData<List<BasicAnimeObject>>\n\n    @Query(\"SELECT aid FROM AnimeObject WHERE genres LIKE :genres\")\n    fun getAidsByGenres(genres: String): MutableList<String>\n\n    @Query(\"SELECT aid FROM AnimeObject WHERE genres LIKE :genres ORDER BY RANDOM() LIMIT 15\")\n    fun getAidsByGenresLimited(genres: String): MutableList<String>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE name LIKE :query AND genres LIKE :genres ORDER BY name\")\n    fun getSearchTG(query: String, genres: String): DataSource.Factory<Int, SearchObject>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE name LIKE :query AND state LIKE :state ORDER BY name\")\n    fun getSearchS(query: String, state: String): DataSource.Factory<Int, SearchObject>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE name LIKE :query AND state LIKE :state AND genres LIKE :genres ORDER BY name\")\n    fun getSearchSG(query: String, state: String, genres: String): DataSource.Factory<Int, SearchObject>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE name LIKE :query AND type LIKE :type ORDER BY name\")\n    fun getSearchTY(query: String, type: String): DataSource.Factory<Int, SearchObject>\n\n    @Query(\"SELECT `key`,aid,name,link FROM AnimeObject WHERE name LIKE :query AND type LIKE :type AND genres LIKE :genres ORDER BY name\")\n    fun getSearchTYG(query: String, type: String, genres: String): DataSource.Factory<Int, SearchObject>\n\n    @Query(\"SELECT `key`,link,name,aid,fileName FROM AnimeObject WHERE fileName IN (:names) OR aid IN (:names)\")\n    fun getAllByFile(names: MutableList<String>): MutableList<AnimeSubObject>\n\n    @Query(\"SELECT `key`,name,link,aid,genres FROM AnimeObject WHERE name LIKE :name ORDER BY name COLLATE NOCASE LIMIT 5\")\n    fun getByName(name: String): MutableList<AnimeSliceObject>\n\n    @Query(\"SELECT count(*) FROM AnimeObject WHERE link LIKE :link\")\n    fun existLink(link: String): Boolean\n\n    @Query(\"SELECT count(*) FROM AnimeObject WHERE aid = :aid\")\n    fun existAid(aid: String): Boolean\n\n    @Query(\"SELECT count(*) FROM animeobject WHERE aid = :aid AND genres LIKE :genre\")\n    fun hasGenre(aid: String, genre: String): Boolean\n\n    @Query(\"SELECT count(*) FROM animeobject WHERE aid = :aid AND state = 'Finalizado'\")\n    fun isCompleted(aid: String): Boolean\n\n    @Query(\"SELECT `key`,name,link,aid FROM AnimeObject WHERE sid = :sid\")\n    fun getBySid(sid: String): SearchObject?\n\n    @Query(\"SELECT `key`,name,link,aid FROM AnimeObject WHERE name = :name\")\n    fun getObjByName(name: String): SearchObject?\n\n    @Query(\"SELECT `key`,name,link,aid FROM AnimeObject WHERE link = :link\")\n    fun getByLink(link: String): SearchObject?\n\n    @Query(\"SELECT `key`,name,link,aid,img,type FROM AnimeObject WHERE aid LIKE :aid\")\n    fun getByAid(aid: String): SearchAdvObject?\n\n    @Query(\"SELECT `key`,name,link,aid FROM AnimeObject WHERE aid LIKE :aid\")\n    fun getByAidSimple(aid: String): SearchObject?\n\n    @Query(\"SELECT * FROM AnimeObject WHERE aid LIKE :aid\")\n    fun getFullByAid(aid: String): AnimeObject?\n\n    @Query(\"SELECT aid,chapters FROM AnimeObject WHERE aid = :aid\")\n    fun getChaptersByAid(aid: String): AnimeChapters\n\n    @Query(\"SELECT `key`,name,link,aid FROM AnimeObject WHERE aid = :aid\")\n    fun getSOByAid(aid: String): SearchObject?\n\n    @Query(\"SELECT count(*) FROM AnimeObject WHERE `key` LIKE :aid\")\n    fun getCount(aid: Int): Int\n\n    @Transaction\n    fun hasRange(aidF: String, aidL: String): Boolean {\n        return existAid(aidF) && existAid(aidL)\n    }\n\n    @Update\n    fun updateAnime(animeObject: AnimeObject)\n\n    @Update\n    fun updateAnimes(animeObjects: List<AnimeObject>)\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun insert(animeObject: AnimeObject)\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun insertAll(objects: List<AnimeObject>)\n\n    @Query(\"DELETE FROM animeobject\")\n    fun nuke()\n\n    @Query(\"DELETE FROM animeobject WHERE UPPER(genres) LIKE '%ECCHI%'\")\n    fun nukeEcchi()\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/ChaptersDAO.kt",
    "content": "package knf.kuma.database.dao\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\nimport androidx.room.TypeConverters\nimport knf.kuma.database.BaseConverter\nimport knf.kuma.pojos.AnimeObject\n\n@Dao\n@TypeConverters(BaseConverter::class)\ninterface ChaptersDAO {\n\n    @get:Query(\"SELECT * FROM animechapter\")\n    val all: MutableList<AnimeObject.WebInfo.AnimeChapter>\n\n    @get:Query(\"SELECT count(*) FROM animechapter\")\n    val countLive: LiveData<Int>\n\n    @get:Query(\"SELECT count(*) FROM animechapter\")\n    val count: Int\n\n    @Query(\"SELECT * FROM animechapter WHERE eid = :eid LIMIT 1\")\n    fun chapterSeen(eid: String): LiveData<AnimeObject.WebInfo.AnimeChapter>\n\n    @Query(\"SELECT count(*) FROM animechapter WHERE eid = :eid\")\n    fun chapterIsSeen(eid: String): Boolean\n\n    @Query(\"SELECT * FROM animechapter WHERE eid IN (:eids) ORDER BY eid+0 DESC LIMIT 1\")\n    fun getLast(eids: MutableList<String>): AnimeObject.WebInfo.AnimeChapter?\n\n    @Query(\"SELECT * FROM animechapter WHERE eid IN (:eids)\")\n    fun getAllFrom(eids: MutableList<String>): List<AnimeObject.WebInfo.AnimeChapter>\n\n    @Query(\"SELECT * FROM animechapter WHERE aid = :aid ORDER BY `key` DESC LIMIT 1\")\n    fun getLastByAid(aid: String): AnimeObject.WebInfo.AnimeChapter?\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun addChapter(chapter: AnimeObject.WebInfo.AnimeChapter)\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun addAll(list: List<AnimeObject.WebInfo.AnimeChapter>)\n\n    @Delete\n    fun deleteChapter(chapter: AnimeObject.WebInfo.AnimeChapter)\n\n    @Query(\"DELETE FROM animechapter\")\n    fun clear()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/DownloadsDAO.kt",
    "content": "package knf.kuma.database.dao\n\nimport androidx.lifecycle.LiveData\nimport androidx.paging.DataSource\nimport androidx.room.Dao\nimport androidx.room.Delete\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport androidx.room.Transaction\nimport androidx.room.Update\nimport knf.kuma.pojos.DownloadObject\n\n@Dao\ninterface DownloadsDAO {\n    @get:Query(\"SELECT * FROM downloadobject\")\n    val all: DataSource.Factory<Int, DownloadObject>\n\n    @get:Query(\"SELECT eid FROM downloadobject\")\n    val allEids: List<String>\n\n    @get:Query(\"SELECT * FROM downloadobject WHERE state < 4\")\n    val allRaw: List<DownloadObject>\n\n    @get:Query(\"SELECT * FROM downloadobject WHERE state<=0\")\n    val active: LiveData<List<DownloadObject>>\n\n    @Query(\"SELECT * FROM downloadobject WHERE eid LIKE :eid\")\n    fun getByEid(eid: String): DownloadObject?\n\n    @Query(\"SELECT COUNT(*) FROM downloadobject WHERE eid = :eid\")\n    fun countByEid(eid: String): Int\n\n    @Transaction\n    fun existByEid(eid: String): Boolean = countByEid(eid) > 0\n\n    @Query(\"SELECT * FROM downloadobject WHERE did = :did\")\n    fun getByDid(did: Int): DownloadObject?\n\n    @Query(\"SELECT * FROM downloadobject WHERE file LIKE :name\")\n    fun getByFile(name: String): DownloadObject?\n\n    @Query(\"SELECT * FROM downloadobject WHERE eid = :eid\")\n    fun getLiveByEid(eid: String): LiveData<DownloadObject>\n\n    @Query(\"SELECT * FROM downloadobject WHERE `key` LIKE :key\")\n    fun getLiveByKey(key: Int): LiveData<DownloadObject>\n\n    @Query(\"SELECT count(*) FROM downloadobject WHERE state=-1\")\n    fun countPending(): Int\n\n    @Query(\"SELECT count(*) FROM downloadobject WHERE state=-1 OR state=0\")\n    fun countActive(): Int\n\n    @Query(\"DELETE FROM downloadobject WHERE eid LIKE :eid\")\n    fun deleteByEid(eid: String)\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun insert(downloadObject: DownloadObject)\n\n    @Update(onConflict = OnConflictStrategy.REPLACE)\n    fun update(downloadObject: DownloadObject)\n\n    @Delete\n    fun delete(downloadObject: DownloadObject)\n\n    @Delete\n    fun delete(downloadObjects: List<DownloadObject>)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/EaDAO.kt",
    "content": "package knf.kuma.database.dao\n\nimport androidx.room.Dao\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport androidx.room.TypeConverters\nimport knf.kuma.database.BaseConverter\nimport knf.kuma.pojos.EAObject\n\n@Dao\n@TypeConverters(BaseConverter::class)\ninterface EaDAO {\n    @get:Query(\"SELECT * FROM eaobject\")\n    val all: List<EAObject>\n\n    @Query(\"SELECT count(*) FROM eaobject WHERE code=:code\")\n    fun isUnlocked(code: Int): Boolean\n\n    @Insert(onConflict = OnConflictStrategy.IGNORE)\n    fun unlock(eaObject: EAObject)\n\n    @Insert(onConflict = OnConflictStrategy.IGNORE)\n    fun unlock(eaObjects: List<EAObject>)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/ExplorerDAO.kt",
    "content": "package knf.kuma.database.dao\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\nimport androidx.room.Update\nimport knf.kuma.pojos.ExplorerObject\n\n@Dao\ninterface ExplorerDAO {\n    @get:Query(\"SELECT * FROM explorerobject ORDER BY name\")\n    val all: LiveData<MutableList<ExplorerObject>>\n\n    @Query(\"SELECT * FROM explorerobject WHERE fileName LIKE :file\")\n    fun getItem(file: String): LiveData<ExplorerObject>\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun insert(list: List<ExplorerObject>)\n\n    @Update\n    fun update(explorerObject: ExplorerObject)\n\n    @Delete\n    fun delete(explorerObject: ExplorerObject)\n\n    @Query(\"DELETE FROM explorerobject\")\n    fun deleteAll()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/FavsDAO.kt",
    "content": "package knf.kuma.database.dao\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\nimport androidx.room.TypeConverters\nimport knf.kuma.database.BaseConverter\nimport knf.kuma.pojos.FavoriteObject\nimport kotlinx.coroutines.flow.Flow\n\n@Dao\n@TypeConverters(BaseConverter::class)\ninterface FavsDAO {\n    @get:Query(\"SELECT * FROM favoriteobject ORDER BY name\")\n    val all: LiveData<MutableList<FavoriteObject>>\n\n    @get:Query(\"SELECT * FROM favoriteobject ORDER BY name\")\n    val allRaw: MutableList<FavoriteObject>\n\n    @get:Query(\"SELECT aid FROM favoriteobject\")\n    val allAids: List<String>\n\n    @get:Query(\"SELECT * FROM favoriteobject GROUP BY category ORDER BY category\")\n    val categories: MutableList<FavoriteObject>\n\n    @get:Query(\"SELECT * FROM favoriteobject ORDER BY aid + 0 ASC\")\n    val allID: LiveData<MutableList<FavoriteObject>>\n\n    @get:Query(\"SELECT * FROM favoriteobject ORDER BY category\")\n    val byCategory: MutableList<FavoriteObject>\n\n    @get:Query(\"SELECT count(*) FROM favoriteobject\")\n    val count: Int\n\n    @get:Query(\"SELECT count(*) FROM favoriteobject\")\n    val countLive: LiveData<Int>\n\n    @get:Query(\"SELECT count(*) FROM favoriteobject\")\n    val countFlow: Flow<Int>\n\n    @Query(\"SELECT * FROM favoriteobject WHERE category NOT LIKE :category ORDER BY name\")\n    fun getNotInCategory(category: String): MutableList<FavoriteObject>\n\n    @Query(\"SELECT * FROM favoriteobject WHERE category LIKE :category ORDER BY name\")\n    fun getAllInCategory(category: String): MutableList<FavoriteObject>\n\n    @Query(\"SELECT count(*) FROM favoriteobject WHERE `key` = :key\")\n    fun isFav(key: Int): Boolean\n\n    @Query(\"SELECT count(*) FROM favoriteobject WHERE aid = :aid\")\n    fun isFavAid(aid: String): Boolean\n\n    @Query(\"SELECT count(*) FROM favoriteobject WHERE name = :name\")\n    fun isFavName(name: String): Boolean\n\n    @Query(\"SELECT count(*) FROM favoriteobject WHERE `key` = :key\")\n    fun isFavLive(key: Int): LiveData<Boolean>\n\n    @Query(\"SELECT * FROM favoriteobject WHERE `key` = :key\")\n    fun favObserver(key: Int): LiveData<FavoriteObject?>\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun addFav(favoriteObject: FavoriteObject)\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun addAll(list: List<FavoriteObject>)\n\n    @Delete\n    fun deleteFav(favoriteObject: FavoriteObject)\n\n    @Query(\"DELETE FROM favoriteobject\")\n    fun clear()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/GenresDAO.kt",
    "content": "package knf.kuma.database.dao\n\nimport androidx.room.Dao\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport androidx.room.Update\nimport knf.kuma.pojos.GenreStatusObject\n\n/**\n * Created by jordy on 26/03/2018.\n */\n@Dao\ninterface GenresDAO {\n    @get:Query(\"SELECT * FROM genrestatusobject WHERE count > 0 ORDER BY count DESC LIMIT 3\")\n    val top: MutableList<GenreStatusObject>\n\n    @get:Query(\"SELECT * FROM genrestatusobject WHERE count < 0 ORDER BY name DESC\")\n    val blacklist: MutableList<GenreStatusObject>\n\n    @get:Query(\"SELECT * FROM genrestatusobject ORDER BY name\")\n    val all: MutableList<GenreStatusObject>\n\n    @get:Query(\"SELECT * FROM genrestatusobject WHERE count > 0 ORDER BY count DESC\")\n    val ranking: MutableList<GenreStatusObject>\n\n    @Query(\"SELECT * FROM genrestatusobject WHERE name LIKE :name\")\n    fun getStatus(name: String): GenreStatusObject?\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun insertStatus(statusObject: GenreStatusObject)\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun insertStatus(statusObjects: List<GenreStatusObject>)\n\n    @Update\n    fun update(list: List<GenreStatusObject>)\n\n    @Query(\"DELETE FROM genrestatusobject WHERE count >= 0\")\n    fun reset()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/NotificationDAO.kt",
    "content": "package knf.kuma.database.dao\n\nimport androidx.room.Dao\nimport androidx.room.Delete\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport androidx.room.TypeConverters\nimport knf.kuma.database.BaseConverter\nimport knf.kuma.pojos.NotificationObj\n\n@Dao\n@TypeConverters(BaseConverter::class)\ninterface NotificationDAO {\n    @get:Query(\"SELECT * FROM notificationobj\")\n    val all: MutableList<NotificationObj>\n\n    @Query(\"SELECT * FROM notificationobj WHERE type=:type\")\n    fun getByType(type: Int): MutableList<NotificationObj>\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun add(obj: NotificationObj)\n\n    @Delete\n    fun delete(obj: NotificationObj)\n\n    @Query(\"DELETE FROM notificationobj\")\n    fun clear()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/PlayerStateDAO.kt",
    "content": "package knf.kuma.database.dao\r\n\r\nimport androidx.room.Dao\r\nimport androidx.room.Insert\r\nimport androidx.room.OnConflictStrategy\r\nimport androidx.room.Query\r\nimport knf.kuma.player.PlayerState\r\n\r\n@Dao\r\ninterface PlayerStateDAO {\r\n    @Query(\"SELECT * FROM playerstate WHERE title = :title\")\r\n    fun find(title: String): PlayerState?\r\n\r\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\r\n    fun set(state: PlayerState)\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/QueueDAO.kt",
    "content": "package knf.kuma.database.dao\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\nimport androidx.room.TypeConverters\nimport androidx.room.Update\nimport knf.kuma.database.BaseConverter\nimport knf.kuma.pojos.QueueObject\n\n@Dao\n@TypeConverters(BaseConverter::class)\ninterface QueueDAO {\n\n    @get:Query(\"SELECT MIN(aid) AS id,`key`,aid,name,number,eid,isFile,uri,time,link FROM queueobject ORDER BY name\")\n    val allAlone: LiveData<MutableList<QueueObject>>\n\n    @get:Query(\"SELECT * FROM queueobject ORDER BY name\")\n    val all: LiveData<MutableList<QueueObject>>\n\n    @get:Query(\"SELECT * FROM queueobject ORDER BY name\")\n    val allRaw: MutableList<QueueObject>\n\n    @get:Query(\"SELECT * FROM queueobject ORDER BY time ASC\")\n    val allAsort: LiveData<MutableList<QueueObject>>\n\n    @get:Query(\"SELECT count(*) FROM queueobject\")\n    val countLive: LiveData<Int>\n\n    @Query(\"SELECT count(*) FROM queueobject WHERE eid = :eid\")\n    fun isInQueue(eid: String): Boolean\n\n    @Query(\"SELECT count(*) FROM queueobject WHERE eid = :eid\")\n    fun isInQueueLive(eid: String): LiveData<Boolean>\n\n    @Query(\"SELECT count(*) FROM queueobject WHERE aid LIKE :aid\")\n    fun countAlone(aid: String): Int\n\n    @Query(\"SELECT * FROM queueobject WHERE aid = :aid ORDER BY eid+0 ASC\")\n    fun getByAid(aid: String): LiveData<MutableList<QueueObject>>\n\n    @Query(\"SELECT * FROM queueobject WHERE aid = :aid ORDER BY eid+0 ASC\")\n    fun getByAidUnique(aid: String): MutableList<QueueObject>\n\n    @Query(\"SELECT * FROM queueobject WHERE aid = :aid ORDER BY eid+0 ASC\")\n    fun getAllByAid(aid: String): List<QueueObject>\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun add(queueObject: QueueObject)\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun add(queueObjects: List<QueueObject>)\n\n    @Update\n    fun update(vararg objects: QueueObject)\n\n    @Delete\n    fun remove(queueObject: QueueObject)\n\n    @Delete\n    fun remove(list: MutableList<QueueObject>)\n\n    @Query(\"DELETE FROM queueobject WHERE aid LIKE :aid\")\n    fun removeByID(aid: String)\n\n    @Query(\"DELETE FROM queueobject WHERE eid LIKE :eid\")\n    fun removeByEID(eid: String)\n\n    @Query(\"DELETE FROM queueobject\")\n    fun nuke()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/RecentModelsDAO.kt",
    "content": "package knf.kuma.database.dao\n\nimport androidx.lifecycle.LiveData\nimport androidx.room.Dao\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport knf.kuma.recents.RecentModel\nimport kotlinx.coroutines.flow.Flow\n\n@Dao\ninterface RecentModelsDAO {\n    @get:Query(\"SELECT * FROM recentmodel ORDER BY `key`\")\n    val allLive: LiveData<List<RecentModel>>\n\n    @get:Query(\"SELECT * FROM recentmodel ORDER BY `key`\")\n    val allFlow: Flow<List<RecentModel>>\n\n    @get:Query(\"SELECT * FROM recentmodel ORDER BY `key`\")\n    val all: List<RecentModel>\n\n    @Query(\"DELETE FROM recentmodel\")\n    fun clear()\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun setCache(objects: List<RecentModel>)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/RecentsDAO.kt",
    "content": "package knf.kuma.database.dao\n\nimport androidx.lifecycle.LiveData\nimport androidx.room.Dao\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.recents.RecentModelCh\nimport kotlinx.coroutines.flow.Flow\n\n@Dao\ninterface RecentsDAO {\n    @get:Query(\"SELECT * FROM recentobject ORDER BY `key`\")\n    val objects: LiveData<MutableList<RecentObject>>\n\n    @get:Query(\"SELECT * FROM recentobject ORDER BY `key`\")\n    val objectsFlow: Flow<MutableList<RecentObject>>\n\n    @get:Query(\"SELECT * FROM recentobject ORDER BY `key`\")\n    val all: MutableList<RecentObject>\n\n    @get:Query(\"SELECT name, chapter, url, aid, eid FROM recentobject ORDER BY `key`\")\n    val allSimple: MutableList<RecentModelCh>\n\n    @Query(\"DELETE FROM recentobject\")\n    fun clear()\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun setCache(objects: MutableList<RecentObject>)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/RecordsDAO.kt",
    "content": "package knf.kuma.database.dao\n\nimport androidx.lifecycle.LiveData\nimport androidx.paging.DataSource\nimport androidx.room.Dao\nimport androidx.room.Delete\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport knf.kuma.pojos.RecordObject\n\n@Dao\ninterface RecordsDAO {\n    @get:Query(\"SELECT * FROM recordobject ORDER BY date DESC\")\n    val all: DataSource.Factory<Int, RecordObject>\n\n    @get:Query(\"SELECT * FROM recordobject ORDER BY date DESC\")\n    val allLive: LiveData<MutableList<RecordObject>>\n\n    @get:Query(\"SELECT * FROM recordobject ORDER BY date DESC\")\n    val allRaw: MutableList<RecordObject>\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun add(recordObject: RecordObject)\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun addAll(list: List<RecordObject>)\n\n    @Delete\n    fun delete(recordObject: RecordObject)\n\n    @Query(\"DELETE FROM recordobject\")\n    fun clear()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/SeeingDAO.kt",
    "content": "package knf.kuma.database.dao\n\nimport androidx.lifecycle.LiveData\nimport androidx.paging.DataSource\nimport androidx.room.Dao\nimport androidx.room.Delete\nimport androidx.room.Insert\nimport androidx.room.OnConflictStrategy\nimport androidx.room.Query\nimport androidx.room.TypeConverters\nimport androidx.room.Update\nimport knf.kuma.database.BaseConverter\nimport knf.kuma.pojos.SeeingObject\n\n@Dao\n@TypeConverters(BaseConverter::class)\ninterface SeeingDAO {\n\n    @get:Query(\"SELECT * FROM seeingobject ORDER BY title\")\n    val all: LiveData<List<SeeingObject>>\n\n    @get:Query(\"SELECT * FROM seeingobject ORDER BY title\")\n    val allPaging: DataSource.Factory<Int, SeeingObject>\n\n    @get:Query(\"SELECT * FROM seeingobject ORDER BY title\")\n    val allRaw: MutableList<SeeingObject>\n\n    @get:Query(\"SELECT aid FROM seeingobject\")\n    val allAids: List<String>\n\n    @Query(\"SELECT * FROM seeingobject WHERE state=:state ORDER BY title\")\n    fun getLiveByState(state: Int): LiveData<List<SeeingObject>>\n\n    @Query(\"SELECT count(*) FROM seeingobject WHERE state=:state\")\n    suspend fun countByState(state: Int): Int\n\n    @Query(\"SELECT * FROM seeingobject WHERE state=:state ORDER BY title\")\n    fun getLiveByStatePaging(state: Int): DataSource.Factory<Int, SeeingObject>\n\n    @get:Query(\"SELECT count(*) FROM seeingobject\")\n    val countLive: LiveData<Int>\n\n    @get:Query(\"SELECT count(*) FROM seeingobject\")\n    val countAll: Int\n\n    @get:Query(\"SELECT count(*) FROM seeingobject WHERE state=1\")\n    val countWatchingLive: LiveData<Int>\n\n    @get:Query(\"SELECT count(*) FROM seeingobject WHERE state=3\")\n    val countCompletedLive: LiveData<Int>\n\n    @get:Query(\"SELECT count(*) FROM seeingobject WHERE state=4\")\n    val countDroppedLive: LiveData<Int>\n\n    @Query(\"SELECT * FROM seeingobject WHERE aid LIKE :aid\")\n    fun getByAid(aid: String): SeeingObject?\n\n    @Query(\"SELECT * FROM seeingobject WHERE state IN (:states) ORDER BY RANDOM() LIMIT 10\")\n    fun getAllWState(vararg states: Int): LiveData<List<SeeingObject>>\n\n    @Query(\"SELECT count(*) FROM seeingobject WHERE aid = :aid AND state>0 AND state <3\")\n    fun isSeeing(aid: String): Boolean\n\n    @Query(\"SELECT count(*) FROM seeingobject WHERE aid = :aid\")\n    fun isSeeingAll(aid: String): Boolean\n\n    @Query(\"SELECT count(*) FROM seeingobject WHERE aid IN (:list) AND state=3\")\n    fun isAnimeCompleted(list: List<String>): LiveData<Int>\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun add(seeingObject: SeeingObject)\n\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\n    fun addAll(list: List<SeeingObject>)\n\n    @Update\n    fun update(seeingObject: SeeingObject)\n\n    @Delete\n    fun remove(seeingObject: SeeingObject)\n\n    @Query(\"DELETE FROM seeingobject\")\n    fun clear()\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/database/dao/SeenDAO.kt",
    "content": "package knf.kuma.database.dao\r\n\r\nimport androidx.lifecycle.LiveData\r\nimport androidx.room.Dao\r\nimport androidx.room.Insert\r\nimport androidx.room.OnConflictStrategy\r\nimport androidx.room.Query\r\nimport androidx.room.TypeConverters\r\nimport knf.kuma.database.BaseConverter\r\nimport knf.kuma.pojos.SeenObject\r\n\r\n@Dao\r\n@TypeConverters(BaseConverter::class)\r\ninterface SeenDAO {\r\n    @get:Query(\"SELECT * FROM seenobject\")\r\n    val all: MutableList<SeenObject>\r\n\r\n    @get:Query(\"SELECT count(*) FROM seenobject\")\r\n    val countLive: LiveData<Int>\r\n\r\n    @get:Query(\"SELECT count(*) FROM seenobject\")\r\n    val count: Int\r\n\r\n    @Query(\"SELECT * FROM seenobject WHERE aid = :aid AND number = :number LIMIT 1\")\r\n    fun chapterSeen(aid: String, number: String): LiveData<SeenObject>\r\n\r\n    @Query(\"SELECT count(*) FROM seenobject WHERE aid = :aid AND number = :number LIMIT 1\")\r\n    fun chapterIsSeenLive(aid: String, number: String): LiveData<Int>\r\n\r\n    @Query(\"SELECT count(*) FROM seenobject WHERE aid = :aid AND number = :number\")\r\n    fun chapterIsSeen(aid: String, number: String): Boolean\r\n\r\n    @Query(\"SELECT * FROM seenobject WHERE eid IN (:eids) ORDER BY eid+0 DESC LIMIT 1\")\r\n    fun getLast(eids: List<String>): SeenObject?\r\n\r\n    @Query(\"SELECT * FROM seenobject WHERE aid = :aid ORDER BY eid+0 DESC LIMIT 1\")\r\n    fun getLastByAid(aid: String): SeenObject?\r\n\r\n    @Query(\"SELECT * FROM seenobject WHERE eid IN (:eids)\")\r\n    fun getAllFrom(eids: MutableList<String>): List<SeenObject>\r\n\r\n    @Query(\"SELECT * FROM seenobject WHERE aid = :aid\")\r\n    fun getAllByAid(aid: String): List<SeenObject>\r\n\r\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\r\n    fun addChapter(chapter: SeenObject)\r\n\r\n    @Insert(onConflict = OnConflictStrategy.REPLACE)\r\n    fun addAll(list: List<SeenObject>)\r\n\r\n    @Query(\"DELETE FROM seenobject WHERE aid = :aid AND number = :number\")\r\n    fun deleteChapter(aid: String, number: String)\r\n\r\n    @Query(\"DELETE FROM seenobject\")\r\n    fun clear()\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirManager.kt",
    "content": "package knf.kuma.directory\r\n\r\nimport com.google.gson.Gson\r\nimport com.google.gson.reflect.TypeToken\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.AnimeObject\r\nimport org.json.JSONObject\r\nimport java.net.URL\r\n\r\nobject DirManager {\r\n\r\n    fun checkPreDir(forced: Boolean = false) {\r\n        if (forced || CacheDB.INSTANCE.animeDAO().count < 3500) {\r\n            doOnUIGlobal {\r\n                DirectoryService.setStatus(DirectoryService.STATE_CACHED)\r\n            }\r\n            noCrash {\r\n                val info = JSONObject(URL(\"https://ukiku.app/dirs/directoryInfo.json\").readText())\r\n                for (index in 0 until info.keys().asSequence().count()) {\r\n                    val json = info.getJSONObject(index.toString())\r\n                    if (!CacheDB.INSTANCE.animeDAO().hasRange(json.getString(\"idF\"), json.getString(\"idL\"))) {\r\n                        val sliceJson = URL(\"https://ukiku.app/dirs/directory$index.json\").readText()\r\n                        val list: List<AnimeObject> = Gson().fromJson(sliceJson, object : TypeToken<List<AnimeObject>>() {}.type)\r\n                        CacheDB.INSTANCE.animeDAO().insertAll(list)\r\n                    }\r\n                }\r\n                PrefsUtil.isDirectoryFinished = true\r\n            }\r\n        }\r\n    }\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirObject.kt",
    "content": "package knf.kuma.directory\r\n\r\ndata class DirObject(\r\n        var key: Int = 0,\r\n        var aid: String = \"\",\r\n        var name: String = \"\",\r\n        var link: String? = null,\r\n        var type: String = \"\",\r\n    var rate_stars: String? = \"\"\r\n)"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirObjectCompact.kt",
    "content": "package knf.kuma.directory\r\n\r\nimport androidx.annotation.Keep\r\nimport androidx.recyclerview.widget.DiffUtil\r\nimport org.jsoup.nodes.Element\r\nimport pl.droidsonroids.jspoon.ElementConverter\r\nimport pl.droidsonroids.jspoon.annotation.Selector\r\n\r\nclass DirObjectCompact {\r\n    @Selector(value = \":root\", converter = ImageExtractor::class)\r\n    var aid: String = \"\"\r\n    @Selector(\"h3.Title\")\r\n    var name: String = \"\"\r\n    @Selector(value = \":root\", converter = LinkExtractor::class)\r\n    var link: String? = null\r\n\r\n    override fun hashCode(): Int {\r\n        return aid.hashCode()\r\n    }\r\n\r\n    override fun equals(other: Any?): Boolean {\r\n        return other is DirObjectCompact && other.aid == aid\r\n    }\r\n\r\n    class LinkExtractor @Keep constructor() : ElementConverter<String> {\r\n        override fun convert(node: Element, selector: Selector): String {\r\n            return \"https://www3.animeflv.net${node.select(\"a\").attr(\"href\")}\"\r\n        }\r\n    }\r\n\r\n    class ImageExtractor @Keep constructor() : ElementConverter<String> {\r\n        override fun convert(node: Element, selector: Selector): String {\r\n            val img = node.select(\"figure img\").first().let {\r\n                when {\r\n                    it.hasAttr(\"data-cfsrc\") -> it.attr(\"data-cfsrc\")\r\n                    it.hasAttr(\"src\") -> it.attr(\"src\")\r\n                    else -> \"/0.jpg\"\r\n                }\r\n            }\r\n            return \"/(\\\\d+)\\\\.\".toRegex().find(img)?.destructured?.component1() ?: \"0\"\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        val DIFF = object : DiffUtil.ItemCallback<DirObjectCompact>() {\r\n            override fun areItemsTheSame(oldItem: DirObjectCompact, newItem: DirObjectCompact): Boolean =\r\n                    oldItem.aid == newItem.aid\r\n\r\n            override fun areContentsTheSame(oldItem: DirObjectCompact, newItem: DirObjectCompact): Boolean =\r\n                    oldItem == newItem\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirPagerAdapter.kt",
    "content": "package knf.kuma.directory\n\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.fragment.app.FragmentPagerAdapter\n\nclass DirPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {\n\n    private val animes = DirectoryPageFragment[DirectoryPageFragment.DirType.ANIMES]\n    private val ovas = DirectoryPageFragment[DirectoryPageFragment.DirType.OVAS]\n    private val movies = DirectoryPageFragment[DirectoryPageFragment.DirType.MOVIES]\n\n    override fun getPageTitle(position: Int): CharSequence? {\n        return when (position) {\n            1 -> \"OVA\"\n            2 -> \"PELICULA\"\n            else -> \"ANIME\"\n        }\n    }\n\n    fun onChangeOrder() {\n        animes.onChangeOrder()\n        ovas.onChangeOrder()\n        movies.onChangeOrder()\n    }\n\n    override fun getItem(position: Int): Fragment {\n        return when (position) {\n            1 -> ovas\n            2 -> movies\n            else -> animes\n        }\n    }\n\n    override fun getCount(): Int {\n        return 3\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirPagerAdapterMaterial.kt",
    "content": "package knf.kuma.directory\n\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.fragment.app.FragmentPagerAdapter\n\nclass DirPagerAdapterMaterial(fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {\n\n    private val animes = DirectoryPageFragmentMaterial[DirectoryPageFragmentMaterial.DirType.ANIMES]\n    private val ovas = DirectoryPageFragmentMaterial[DirectoryPageFragmentMaterial.DirType.OVAS]\n    private val movies = DirectoryPageFragmentMaterial[DirectoryPageFragmentMaterial.DirType.MOVIES]\n\n    override fun getPageTitle(position: Int): CharSequence? {\n        return when (position) {\n            1 -> \"OVA\"\n            2 -> \"PELICULA\"\n            else -> \"ANIME\"\n        }\n    }\n\n    fun onChangeOrder() {\n        animes.onChangeOrder()\n        ovas.onChangeOrder()\n        movies.onChangeOrder()\n    }\n\n    override fun getItem(position: Int): Fragment {\n        return when (position) {\n            1 -> ovas\n            2 -> movies\n            else -> animes\n        }\n    }\n\n    override fun getCount(): Int {\n        return 3\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirPagerAdapterOnline.kt",
    "content": "package knf.kuma.directory\n\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.fragment.app.FragmentPagerAdapter\n\nclass DirPagerAdapterOnline(fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {\n\n    private val animes = DirectoryPageFragmentOnline[DirectoryPageFragmentMaterial.DirType.ANIMES.value]\n    private val ovas = DirectoryPageFragmentOnline[DirectoryPageFragmentMaterial.DirType.OVAS.value]\n    private val movies = DirectoryPageFragmentOnline[DirectoryPageFragmentMaterial.DirType.MOVIES.value]\n\n    override fun getPageTitle(position: Int): CharSequence? {\n        return when (position) {\n            1 -> \"OVA\"\n            2 -> \"PELICULA\"\n            else -> \"ANIME\"\n        }\n    }\n\n    fun onChangeOrder() {\n\n    }\n\n    override fun getItem(position: Int): Fragment {\n        return when (position) {\n            1 -> ovas\n            2 -> movies\n            else -> animes\n        }\n    }\n\n    override fun getCount(): Int {\n        return 3\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryDataSource.kt",
    "content": "package knf.kuma.directory\r\n\r\nimport androidx.paging.Pager\r\nimport androidx.paging.PagingConfig\r\nimport androidx.paging.PagingSource\r\nimport androidx.paging.PagingState\r\nimport knf.kuma.commons.jsoupCookiesAdapter\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.withContext\r\n\r\nclass DirectoryDataSource(val type: String, val retryCallback: () -> Unit) : PagingSource<Int, DirObjectCompact>() {\r\n\r\n    override fun getRefreshKey(state: PagingState<Int, DirObjectCompact>): Int? = state.anchorPosition\r\n\r\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, DirObjectCompact> {\r\n        val page = params.key?: 1\r\n        try {\r\n            val dir = withContext(Dispatchers.IO) {\r\n                jsoupCookiesAdapter(\"https://www3.animeflv.net/browse?order=title&type[]=$type&page=$page\", DirectoryPageCompact::class.java)\r\n            }\r\n            return LoadResult.Page(dir.list, null, if (dir.hasNext) page + 1 else null)\r\n        }catch (e:Exception){\r\n            e.printStackTrace()\r\n            retryCallback()\r\n            return LoadResult.Error(e)\r\n        }\r\n    }\r\n}\r\n\r\nfun createDirectoryPagedList(type: String, retryCallback: () -> Unit) =\r\n        Pager(\r\n            config = PagingConfig(24),\r\n            pagingSourceFactory = { DirectoryDataSource(type, retryCallback) }\r\n        ).flow"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryFragment.kt",
    "content": "package knf.kuma.directory\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport com.google.android.material.snackbar.Snackbar\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.safeDismiss\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.custom.BannerContainerView\nimport knf.kuma.database.CacheDB\nimport knf.kuma.directory.viewholders.DirMainFragmentHolder\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.support.v4.findOptional\n\nclass DirectoryFragment : BottomFragment() {\n    private var fragmentHolder: DirMainFragmentHolder? = null\n    private var snackbar: Snackbar? = null\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        if (!PrefsUtil.isDirectoryFinished) {\n            snackbar = activity?.findViewById<View>(R.id.root)?.showSnackbar(\"Creando directorio...\", Snackbar.LENGTH_INDEFINITE)\n            CacheDB.INSTANCE.animeDAO().countLive.observe(viewLifecycleOwner, Observer {\n                try {\n                    snackbar?.setText(\"Agregados... $it\")\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n            })\n            DirectoryService.getLiveStatus().observe(viewLifecycleOwner, Observer {\n                when (it) {\n                    DirectoryService.STATE_VERIFYING ->\n                        snackbar?.setText(\"Verificando directorio...\")\n                    DirectoryService.STATE_INTERRUPTED,\n                    DirectoryService.STATE_FINISHED ->\n                        snackbar?.safeDismiss()\n                }\n            })\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(R.layout.fragment_directory, container, false)\n        fragmentHolder = DirMainFragmentHolder(view, childFragmentManager)\n        EAHelper.enter1(\"D\")\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        if (PrefsUtil.isDirectoryFinished)\n            lifecycleScope.launch(Dispatchers.IO) {\n                delay(1000)\n                findOptional<BannerContainerView>(R.id.adContainer)?.implBanner(AdsType.DIRECTORY_BANNER, true)\n            }\n    }\n\n    override fun onDestroyView() {\n        super.onDestroyView()\n        snackbar?.safeDismiss()\n    }\n\n    fun onChangeOrder() {\n        fragmentHolder?.onChangeOrder()\n    }\n\n    override fun onReselect() {\n        EAHelper.enter1(\"D\")\n        fragmentHolder?.onReselect()\n    }\n\n    companion object {\n\n        fun get(): DirectoryFragment {\n            return DirectoryFragment()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryFragmentMaterial.kt",
    "content": "package knf.kuma.directory\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.lifecycle.lifecycleScope\nimport com.google.android.material.snackbar.Snackbar\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.safeDismiss\nimport knf.kuma.custom.BannerContainerView\nimport knf.kuma.directory.viewholders.DirMainFragmentMaterialHolder\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.support.v4.find\n\nclass DirectoryFragmentMaterial : BottomFragment() {\n    private var fragmentHolder: DirMainFragmentMaterialHolder? = null\n    private var snackbar: Snackbar? = null\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(R.layout.fragment_directory_material, container, false)\n        fragmentHolder = DirMainFragmentMaterialHolder(view, childFragmentManager)\n        EAHelper.enter1(\"D\")\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        lifecycleScope.launch(Dispatchers.IO) {\n            delay(1000)\n            noCrash {\n                find<BannerContainerView>(R.id.adContainer).implBanner(AdsType.DIRECTORY_BANNER, true)\n            }\n        }\n    }\n\n    override fun onDestroyView() {\n        super.onDestroyView()\n        snackbar?.safeDismiss()\n    }\n\n    fun onChangeOrder() {\n        fragmentHolder?.onChangeOrder()\n    }\n\n    override fun onReselect() {\n        EAHelper.enter1(\"D\")\n        fragmentHolder?.onReselect()\n    }\n\n    companion object {\n\n        fun get(): DirectoryFragmentMaterial {\n            return DirectoryFragmentMaterial()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryPageAdapter.kt",
    "content": "package knf.kuma.directory\n\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.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\n\nclass DirectoryPageAdapter internal constructor(private val fragment: Fragment) :\n    PagingDataAdapter<DirObject, DirectoryPageAdapter.ItemHolder>(DIFF_CALLBACK),\n    FastScrollRecyclerView.SectionedAdapter {\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {\n        return ItemHolder(LayoutInflater.from(parent.context).inflate(getLayType(), parent, false))\n    }\n\n    @LayoutRes\n    private fun getLayType(): Int {\n        return if (PrefsUtil.layType == \"0\") {\n            R.layout.item_dir\n        } else {\n            R.layout.item_dir_grid\n        }\n    }\n\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\n        if (fragment.context == null) return\n        val animeObject = getItem(position)\n        if (animeObject?.aid != null) {\n            holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n            holder.progressView.visibility = View.GONE\n            holder.textView.text = animeObject.name\n            holder.cardView.setOnClickListener { ActivityAnime.open(fragment, animeObject, holder.imageView, persist = false) }\n        } else {\n            holder.progressView.visibility = View.VISIBLE\n            holder.textView.text = null\n        }\n    }\n\n    override fun getSectionName(position: Int): String {\n        return when (PrefsUtil.dirOrder) {\n            1 -> \"\\u2605${getItem(position)?.rate_stars ?: \"?.?\"}\"\n            2 -> getItem(position)?.aid ?: \"\"\n            3 -> getItem(position)?.aid ?: \"\"\n            else -> getItem(position)?.name?.first()?.uppercaseChar()?.toString() ?: \"\"\n        }\n    }\n\n    class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val progressView: ProgressBar by itemView.bind(R.id.progress)\n        val textView: TextView by itemView.bind(R.id.title)\n    }\n\n    companion object {\n\n        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<DirObject>() {\n            override fun areItemsTheSame(oldItem: DirObject, newItem: DirObject): Boolean {\n                return oldItem.key == newItem.key && oldItem.link == newItem.link\n            }\n\n            override fun areContentsTheSame(oldItem: DirObject, newItem: DirObject): Boolean {\n                return oldItem.name == newItem.name && oldItem.link == newItem.link\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryPageAdapterMaterial.kt",
    "content": "package knf.kuma.directory\n\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.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\n\nclass DirectoryPageAdapterMaterial internal constructor(private val fragment: Fragment) :\n    PagingDataAdapter<DirObject, DirectoryPageAdapterMaterial.ItemHolder>(DIFF_CALLBACK),\n    FastScrollRecyclerView.SectionedAdapter {\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {\n        return ItemHolder(LayoutInflater.from(parent.context).inflate(getLayType(), parent, false))\n    }\n\n    @LayoutRes\n    private fun getLayType(): Int {\n        return if (PrefsUtil.layType == \"0\") {\n            R.layout.item_dir_material\n        } else {\n            R.layout.item_dir_grid_material\n        }\n    }\n\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\n        if (fragment.context == null) return\n        val animeObject = getItem(position)\n        if (animeObject?.aid != null) {\n            holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n            holder.progressView.visibility = View.GONE\n            holder.textView.text = animeObject.name\n            holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(fragment, animeObject) }\n        } else {\n            holder.progressView.visibility = View.VISIBLE\n            holder.textView.text = null\n        }\n    }\n\n    override fun getSectionName(position: Int): String {\n        return when (PrefsUtil.dirOrder) {\n            1 -> \"\\u2605${getItem(position)?.rate_stars ?: \"?.?\"}\"\n            2 -> getItem(position)?.aid ?: \"\"\n            3 -> getItem(position)?.aid ?: \"\"\n            else -> getItem(position)?.name?.first()?.uppercaseChar()?.toString() ?: \"\"\n        }\n    }\n\n    class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val progressView: ProgressBar by itemView.bind(R.id.progress)\n        val textView: TextView by itemView.bind(R.id.title)\n    }\n\n    companion object {\n\n        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<DirObject>() {\n            override fun areItemsTheSame(oldItem: DirObject, newItem: DirObject): Boolean {\n                return oldItem.key == newItem.key && oldItem.link == newItem.link\n            }\n\n            override fun areContentsTheSame(oldItem: DirObject, newItem: DirObject): Boolean {\n                return oldItem.name == newItem.name && oldItem.link == newItem.link\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryPageAdapterOnline.kt",
    "content": "package knf.kuma.directory\n\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.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\n\nclass DirectoryPageAdapterOnline(private val fragment: Fragment) : PagingDataAdapter<DirObjectCompact, DirectoryPageAdapterOnline.ItemHolder>(DirObjectCompact.DIFF), FastScrollRecyclerView.SectionedAdapter {\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {\n        return ItemHolder(LayoutInflater.from(parent.context).inflate(getLayType(), parent, false))\n    }\n\n    @LayoutRes\n    private fun getLayType(): Int {\n        return if (PrefsUtil.layType == \"0\") {\n            R.layout.item_dir_material\n        } else {\n            R.layout.item_dir_grid_material\n        }\n    }\n\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\n        if (fragment.context == null) return\n        val animeObject = getItem(position)\n        if (animeObject?.aid != null) {\n            holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n            holder.progressView.visibility = View.GONE\n            holder.textView.text = animeObject.name\n            holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(fragment, animeObject, true) }\n        } else {\n            holder.progressView.visibility = View.VISIBLE\n            holder.textView.text = null\n        }\n    }\n\n    override fun getSectionName(position: Int): String {\n        return getItem(position)?.name?.first()?.uppercaseChar()?.toString() ?: \"\"\n    }\n\n    class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val progressView: ProgressBar by itemView.bind(R.id.progress)\n        val textView: TextView by itemView.bind(R.id.title)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryPageCompact.kt",
    "content": "package knf.kuma.directory\r\n\r\nimport androidx.annotation.Keep\r\nimport org.jsoup.nodes.Element\r\nimport pl.droidsonroids.jspoon.ElementConverter\r\nimport pl.droidsonroids.jspoon.annotation.Selector\r\n\r\nclass DirectoryPageCompact {\r\n    @Selector(\"article.Anime\")\r\n    var list: List<DirObjectCompact> = emptyList()\r\n    @Selector(value = \"ul.pagination\", converter = NextConverter::class)\r\n    var hasNext: Boolean = false\r\n\r\n    class NextConverter @Keep constructor() : ElementConverter<Boolean> {\r\n        override fun convert(node: Element, selector: Selector): Boolean {\r\n            val pages = node.select(\"li\")\r\n            if (pages.size <= 1) return false\r\n            val last = pages.last()\r\n            val child = last.child(0)\r\n            return !last.hasClass(\"disabled\") && child.hasAttr(\"rel\") && child.attr(\"href\") != \"#\"\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryPageFragment.kt",
    "content": "package knf.kuma.directory\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport androidx.annotation.LayoutRes\nimport androidx.annotation.UiThread\nimport androidx.fragment.app.viewModels\nimport androidx.lifecycle.lifecycleScope\nimport androidx.paging.PagingData\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.verifyManager\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.find\n\nclass DirectoryPageFragment : BottomFragment() {\n    lateinit var recyclerView: RecyclerView\n    lateinit var progress: ProgressBar\n    private var manager: RecyclerView.LayoutManager? = null\n    private var adapter: DirectoryPageAdapter? = null\n    private var isFirst = true\n    private var waitingScroll = false\n    private var listUpdated = false\n    private val model: DirectoryViewModel by viewModels()\n    private var dataJob: Job? = null\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_dir\n        } else {\n            R.layout.recycler_dir_grid\n        }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        activity?.let {\n            getData { animeObjects ->\n                hideProgress()\n                adapter?.submitData(animeObjects)\n                makeAnimation()\n            }\n        }\n    }\n\n    private fun getData(callback: suspend (PagingData<DirObject>) -> Unit) {\n        dataJob?.cancel()\n        dataJob = lifecycleScope.launch {\n            when (arguments?.getInt(\"type\", 0) ?: 0) {\n                1 -> model.getOvas()\n                2 -> model.getMovies()\n                else -> model.getAnimes()\n            }.collectLatest {\n                callback(it)\n            }\n        }\n    }\n\n    fun onChangeOrder() {\n        activity?.let {\n            waitingScroll = true\n            lifecycleScope.launch {\n                adapter?.submitData(PagingData.empty())\n                showProgress()\n                getData { animeObjects ->\n                    hideProgress()\n                    listUpdated = true\n                    adapter?.submitData(animeObjects)\n                    makeAnimation()\n                }\n            }\n        }\n    }\n\n    private fun hideProgress() {\n        progress.post { progress.visibility = View.GONE }\n    }\n\n    private fun showProgress() {\n        isFirst = true\n        progress.post { progress.visibility = View.VISIBLE }\n    }\n\n    private fun makeAnimation() {\n        if (isFirst) {\n            recyclerView.scheduleLayoutAnimation()\n            isFirst = false\n        }\n    }\n\n    @UiThread\n    private fun scrollTop() {\n        try {\n            recyclerView.smoothScrollToPosition(0)\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(layout, container, false)\n        recyclerView = view.find(R.id.recycler)\n        progress = view.find(R.id.progress)\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        manager = recyclerView.layoutManager\n        recyclerView.layoutManager = manager\n        adapter = DirectoryPageAdapter(this)\n        adapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {\n            override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {\n                super.onItemRangeInserted(positionStart, itemCount)\n                if (positionStart == 0 && waitingScroll) {\n                    scrollTop()\n                    waitingScroll = false\n                }\n            }\n\n            override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {\n                super.onItemRangeMoved(fromPosition, toPosition, itemCount)\n                if (toPosition == 0 && waitingScroll) {\n                    scrollTop()\n                    waitingScroll = false\n                }\n            }\n        })\n        recyclerView.verifyManager()\n        recyclerView.adapter = adapter\n        isFirst = true\n    }\n\n    override fun onReselect() {\n        manager?.smoothScrollToPosition(recyclerView, null, 0)\n    }\n\n    enum class DirType(var value: Int) {\n        ANIMES(0),\n        OVAS(1),\n        MOVIES(2)\n    }\n\n    companion object {\n\n        operator fun get(type: DirType): DirectoryPageFragment {\n            val bundle = Bundle()\n            bundle.putInt(\"type\", type.value)\n            val fragment = DirectoryPageFragment()\n            fragment.arguments = bundle\n            return fragment\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryPageFragmentMaterial.kt",
    "content": "package knf.kuma.directory\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport androidx.annotation.LayoutRes\nimport androidx.annotation.UiThread\nimport androidx.fragment.app.viewModels\nimport androidx.lifecycle.lifecycleScope\nimport androidx.paging.PagingData\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.verifyManager\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.find\n\nclass DirectoryPageFragmentMaterial : BottomFragment() {\n    lateinit var recyclerView: RecyclerView\n    lateinit var progress: ProgressBar\n    private var manager: RecyclerView.LayoutManager? = null\n    private var adapter: DirectoryPageAdapterMaterial? = null\n    private var isFirst = true\n    private var waitingScroll = false\n    private var listUpdated = false\n    private val model: DirectoryViewModel by viewModels()\n\n    private var dataJob: Job? = null\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_dir\n        } else {\n            R.layout.recycler_dir_grid\n        }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        activity?.let {\n            getData { animeObjects ->\n                hideProgress()\n                adapter?.submitData(animeObjects)\n                makeAnimation()\n            }\n        }\n    }\n\n    private fun getData(callback: suspend (PagingData<DirObject>) -> Unit) {\n        dataJob?.cancel()\n        dataJob = lifecycleScope.launch {\n            when (arguments?.getInt(\"type\", 0) ?: 0) {\n                1 -> model.getOvas()\n                2 -> model.getMovies()\n                else -> model.getAnimes()\n            }.collectLatest {\n                callback(it)\n            }\n        }\n    }\n\n    fun onChangeOrder() {\n        activity?.let {\n            waitingScroll = true\n            lifecycleScope.launch {\n                adapter?.submitData(PagingData.empty())\n                showProgress()\n                getData { animeObjects ->\n                    hideProgress()\n                    listUpdated = true\n                    adapter?.submitData(animeObjects)\n                    makeAnimation()\n                }\n            }\n        }\n    }\n\n    private fun hideProgress() {\n        progress.post { progress.visibility = View.GONE }\n    }\n\n    private fun showProgress() {\n        isFirst = true\n        progress.post { progress.visibility = View.VISIBLE }\n    }\n\n    private fun makeAnimation() {\n        if (isFirst) {\n            recyclerView.scheduleLayoutAnimation()\n            isFirst = false\n        }\n    }\n\n    @UiThread\n    private fun scrollTop() {\n        try {\n            recyclerView.smoothScrollToPosition(0)\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(layout, container, false)\n        recyclerView = view.find(R.id.recycler)\n        progress = view.find(R.id.progress)\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        manager = recyclerView.layoutManager\n        recyclerView.layoutManager = manager\n        adapter = DirectoryPageAdapterMaterial(this)\n        adapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {\n            override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {\n                super.onItemRangeInserted(positionStart, itemCount)\n                if (positionStart == 0 && waitingScroll) {\n                    scrollTop()\n                    waitingScroll = false\n                }\n            }\n\n            override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {\n                super.onItemRangeMoved(fromPosition, toPosition, itemCount)\n                if (toPosition == 0 && waitingScroll) {\n                    scrollTop()\n                    waitingScroll = false\n                }\n            }\n        })\n        recyclerView.verifyManager()\n        recyclerView.adapter = adapter\n        isFirst = true\n    }\n\n    override fun onReselect() {\n        manager?.smoothScrollToPosition(recyclerView, null, 0)\n    }\n\n    enum class DirType(var value: Int) {\n        ANIMES(0),\n        OVAS(1),\n        MOVIES(2)\n    }\n\n    companion object {\n\n        operator fun get(type: DirType): DirectoryPageFragmentMaterial {\n            val bundle = Bundle()\n            bundle.putInt(\"type\", type.value)\n            val fragment = DirectoryPageFragmentMaterial()\n            fragment.arguments = bundle\n            return fragment\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryPageFragmentOnline.kt",
    "content": "package knf.kuma.directory\n\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport androidx.annotation.LayoutRes\nimport androidx.annotation.UiThread\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.snackbar.Snackbar\nimport knf.kuma.BottomFragment\nimport knf.kuma.DiagnosticMaterial\nimport knf.kuma.R\nimport knf.kuma.commons.BypassUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.commons.verifyManager\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.find\n\nclass DirectoryPageFragmentOnline : BottomFragment() {\n    lateinit var recyclerView: RecyclerView\n    lateinit var progress: ProgressBar\n    private var manager: RecyclerView.LayoutManager? = null\n    private val adapter: DirectoryPageAdapterOnline by lazy { DirectoryPageAdapterOnline(this) }\n    private var isFirst = true\n    private var waitingScroll = false\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_dir\n        } else {\n            R.layout.recycler_dir_grid\n        }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        lifecycleScope.launch {\n            createDirectoryPagedList(getType()) {\n                try {\n                    var snack: Snackbar? = null\n                    snack = recyclerView.showSnackbar(\"Error al cargar directorio\", Snackbar.LENGTH_INDEFINITE, \"reintentar\") {\n                        lifecycleScope.launch(Dispatchers.Main) {\n                            if (withContext(Dispatchers.IO) { BypassUtil.isNeeded(BypassUtil.testLink) }) {\n                                startActivity(Intent(requireContext(), DiagnosticMaterial.FullBypass::class.java))\n                            }else {\n                                snack?.dismiss()\n                                delay(2000)\n                                adapter.retry()\n                            }\n                        }\n                    }\n                }catch (e:Exception){\n                    lifecycleScope.launch {\n                        delay(2000)\n                        adapter.retry()\n                    }\n                }\n            }.collect {\n                adapter.submitData(it)\n            }\n        }\n        progress.post { progress.visibility = View.GONE }\n    }\n\n    fun getType() =\n            when (arguments?.getInt(\"type\", 0)) {\n                1 -> \"ova\"\n                2 -> \"movie\"\n                else -> \"tv\"\n            }\n\n    @UiThread\n    private fun scrollTop() {\n        try {\n            recyclerView.smoothScrollToPosition(0)\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(layout, container, false)\n        recyclerView = view.find(R.id.recycler)\n        progress = view.find(R.id.progress)\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        manager = recyclerView.layoutManager\n        recyclerView.layoutManager = manager\n        adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {\n            override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {\n                super.onItemRangeInserted(positionStart, itemCount)\n                if (positionStart == 0 && waitingScroll) {\n                    scrollTop()\n                    waitingScroll = false\n                }\n            }\n\n            override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {\n                super.onItemRangeMoved(fromPosition, toPosition, itemCount)\n                if (toPosition == 0 && waitingScroll) {\n                    scrollTop()\n                    waitingScroll = false\n                }\n            }\n        })\n        recyclerView.verifyManager()\n        recyclerView.adapter = adapter\n        isFirst = true\n    }\n\n    override fun onReselect() {\n        manager?.smoothScrollToPosition(recyclerView, null, 0)\n    }\n\n    enum class DirType(var value: Int) {\n        ANIMES(0),\n        OVAS(1),\n        MOVIES(2)\n    }\n\n    companion object {\n\n        operator fun get(type: Int): DirectoryPageFragmentOnline {\n            val bundle = Bundle()\n            bundle.putInt(\"type\", type)\n            val fragment = DirectoryPageFragmentOnline()\n            fragment.arguments = bundle\n            return fragment\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryService.kt",
    "content": "package knf.kuma.directory\n\nimport android.annotation.SuppressLint\nimport android.app.IntentService\nimport android.app.Notification\nimport android.app.NotificationManager\nimport android.content.Context\nimport android.content.Intent\nimport android.media.AudioManager\nimport android.util.Log\nimport androidx.core.app.NotificationCompat\nimport androidx.core.content.ContextCompat\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport androidx.preference.PreferenceManager\nimport knf.kuma.R\nimport knf.kuma.commons.BypassUtil\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.SSLSkipper\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.commons.jsoupCookiesDir\nimport knf.kuma.commons.noCrash\nimport knf.kuma.database.CacheDB\nimport knf.kuma.database.dao.AnimeDAO\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.download.foreground\nimport knf.kuma.download.service\nimport knf.kuma.jobscheduler.DirUpdateWork\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.DirectoryPage\nimport knf.kuma.widgets.emision.WEmisionProvider\nimport org.jsoup.HttpStatusException\nimport pl.droidsonroids.jspoon.Jspoon\nimport kotlin.properties.Delegates\n\nclass DirectoryService : IntentService(\"Directory update\") {\n    private val CURRENT_TIME = System.currentTimeMillis()\n    private var manager: NotificationManager? = null\n    private var count = 0\n    private var page = 0\n    private var maxAnimes = 3200\n    private val TAG = \"Directory Getter\"\n    private var needCookies by Delegates.notNull<Boolean>()\n\n    private val keyFailedPages = \"failed_pages\"\n\n    private val startNotification: Notification\n        get() {\n            val notification = NotificationCompat.Builder(this, \"directory_update\")\n                    .setOngoing(true)\n                    .setPriority(NotificationCompat.PRIORITY_MIN)\n                    .setSmallIcon(R.drawable.ic_directory_not)\n                    .setSound(null, AudioManager.STREAM_NOTIFICATION)\n                    .setColor(ContextCompat.getColor(this, EAHelper.getThemeColor()))\n                    .setWhen(CURRENT_TIME)\n            if (PrefsUtil.collapseDirectoryNotification)\n                notification.setSubText(\"Verificando directorio\")\n            else\n                notification.setContentTitle(\"Verificando directorio\")\n            return notification.build()\n        }\n\n    override fun onCreate() {\n        foreground(NOT_CODE, startNotification)\n        super.onCreate()\n    }\n\n    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {\n        foreground(NOT_CODE, startNotification)\n        return super.onStartCommand(intent, flags, startId)\n    }\n\n    override fun onHandleIntent(intent: Intent?) {\n        foreground(NOT_CODE, startNotification)\n        if (!Network.isConnected) {\n            cancelForeground()\n            stopSelf()\n            return\n        }\n        needCookies = BypassUtil.isCloudflareActive(BypassUtil.testLink)\n        isRunning = true\n        setStatus(STATE_VERIFYING)\n        manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager\n        val animeDAO = CacheDB.INSTANCE.animeDAO()\n        count = animeDAO.count\n        SSLSkipper.skip()\n        val jspoon = Jspoon.create()\n        calculateMax()\n        setStatus(STATE_PARTIAL)\n        doPartialSearch(jspoon, animeDAO)\n        setStatus(STATE_FULL)\n        doEcchiRemove(animeDAO)\n        checkDownloaded(animeDAO)\n        doFullSearch(jspoon, animeDAO)\n        doEmissionRefresh(jspoon, animeDAO)\n        cancelForeground()\n    }\n\n    private fun calculateMax() {\n        noCrash {\n            val main = jsoupCookiesDir(\"https://www3.animeflv.net/browse\", needCookies).get()\n            val lastPage = main.select(\"ul.pagination li:matches(\\\\d+)\").last().text().trim().toInt()\n            val last = try {\n                jsoupCookiesDir(\"https://www3.animeflv.net/browse?page=$lastPage\", needCookies).get().select(\"article\").size\n            } catch (e: Exception) {\n                0\n            }\n            maxAnimes = ((24 * (lastPage - 1)) + last) - 1\n            Log.e(TAG, \"Max animes = $maxAnimes\")\n        }\n    }\n\n    private fun doEcchiRemove(animeDAO: AnimeDAO) {\n        if (!isFullMode || PrefsUtil.isFamilyFriendly) {\n            animeDAO.nukeEcchi()\n        }\n    }\n\n    private fun checkDownloaded(animeDAO: AnimeDAO) {\n        val jspoon = Jspoon.create()\n        FileAccessHelper.downloadExplorerCreator.createLinksList().forEach {\n            if (!animeDAO.existLink(\"%${it.substringAfterLast(\".net\")}\")){\n                try {\n                    val response = jsoupCookies(it).execute()\n                    val body = response.body()\n                    if (response.statusCode() == 200 && body != null) {\n                        val webInfo = jspoon.adapter(AnimeObject.WebInfo::class.java).fromHtml(body)\n                        animeDAO.insert(AnimeObject(it, webInfo))\n                    }\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n                if (needCookies)\n                    Thread.sleep(5000)\n            }\n        }\n    }\n\n    private fun doEmissionRefresh(jspoon: Jspoon, animeDAO: AnimeDAO) {\n        try {\n            animeDAO.allLinksInEmission.forEach {\n                try {\n                    val animeObject = AnimeObject(it, jspoon.adapter(AnimeObject.WebInfo::class.java).fromHtml(jsoupCookiesDir(it,needCookies).get().outerHtml()))\n                    val current = animeDAO.getAnimeByAid(animeObject.aid)\n                    if (current == null || current != animeObject)\n                        animeDAO.updateAnime(animeObject)\n                    WEmisionProvider.update(this)\n                } catch (e: Exception) {\n                    return@forEach\n                }\n            }\n        }catch (e:Exception){\n            //\n        }\n    }\n\n    @SuppressLint(\"ApplySharedPref\")\n    private fun doPartialSearch(jspoon: Jspoon, animeDAO: AnimeDAO) {\n        val strings = PreferenceManager.getDefaultSharedPreferences(this).getStringSet(keyFailedPages, LinkedHashSet())\n        val newStrings = LinkedHashSet<String>()\n        var partialCount = 0\n        if (strings?.size == 0)\n            Log.e(TAG, \"No pending pages\")\n        for (s in LinkedHashSet(strings)) {\n            partialCount++\n            if (!Network.isConnected) {\n                Log.e(TAG, \"Processed $partialCount pages before disconnection\")\n                stopSelf()\n                return\n            }\n            try {\n                if (needCookies)\n                    Thread.sleep(6000)\n                else\n                    Thread.sleep(1000)\n                val document = jsoupCookiesDir(\"https://www3.animeflv.net/browse?order=added&page=$s\", needCookies).get()\n                if (document.select(\"article\").size != 0) {\n                    val animeObjects = jspoon.adapter(DirectoryPage::class.java).fromHtml(document.outerHtml()).getAnimes(animeDAO, jspoon, object : DirectoryPage.UpdateInterface {\n                        override fun onAdd() {\n                            count++\n                            updateNotification()\n                        }\n\n                        override fun onError() {\n                            Log.e(TAG, \"Error at page: $s\")\n                            if (!newStrings.contains(s))\n                                newStrings.add(s.toString())\n                        }\n                    }, needCookies)\n                    if (animeObjects.isNotEmpty())\n                        animeDAO.insertAll(animeObjects)\n                }\n            } catch (e: HttpStatusException) {\n                if (e.statusCode == 403 || e.statusCode == 503) {\n                    setStatus(STATE_INTERRUPTED)\n                    stopSelf()\n                    cancelForeground()\n                }\n            } catch (e: Exception) {\n                Log.e(TAG, \"Page error: $s | ${e.message}\")\n                if (!newStrings.contains(s.toString()))\n                    newStrings.add(s.toString())\n            }\n\n        }\n        PreferenceManager.getDefaultSharedPreferences(this).edit().putStringSet(keyFailedPages, newStrings).commit()\n    }\n\n    private fun doFullSearch(jspoon: Jspoon, animeDAO: AnimeDAO) {\n        page = 1\n        var skipCount = 0\n        var finished = false\n        val strings = PreferenceManager.getDefaultSharedPreferences(this).getStringSet(keyFailedPages, LinkedHashSet())\n        while (!finished) {\n            if (!Network.isConnected) {\n                Log.e(TAG, \"Processed $page pages before disconnection\")\n                stopSelf()\n                return\n            }\n            try {\n                if (needCookies)\n                    Thread.sleep(6000)\n                val document = jsoupCookiesDir(\"https://www3.animeflv.net/browse?order=added&page=$page\", needCookies).get()\n                Log.e(TAG, \"Read page $page\")\n                if (document.select(\"ul.ListAnimes\").isNotEmpty() && document.select(\"article\").isNotEmpty()) {\n                    page++\n                    val animeObjects = jspoon.adapter(DirectoryPage::class.java).fromHtml(document.outerHtml()).getAnimes(animeDAO, jspoon, object : DirectoryPage.UpdateInterface {\n                        override fun onAdd() {\n                            count++\n                            updateNotification()\n                        }\n\n                        override fun onError() {\n                            Log.e(TAG, \"At page: $page\")\n                            if (strings?.contains(page.toString()) == false)\n                                strings.add(page.toString())\n                        }\n                    }, needCookies)\n                    if (animeObjects.isNotEmpty()) {\n                        animeDAO.insertAll(animeObjects)\n                    } else if (PrefsUtil.isDirectoryFinished || animeDAO.count >= maxAnimes || skipCount >= 3) {\n                        PrefsUtil.isDirectoryFinished = (animeDAO.count in (maxAnimes - 5)..(maxAnimes + 5))\n                        Log.e(TAG, \"Stop searching at page $page\")\n                        setStatus(STATE_FINISHED)\n                        cancelForeground()\n                        break\n                    } else {\n                        skipCount++\n                    }\n                } else {\n                    finished = true\n                    Log.e(TAG, \"Processed $page pages\")\n                    PrefsUtil.isDirectoryFinished = animeDAO.count in (maxAnimes - 5)..(maxAnimes + 5)\n                    PreferenceManager.getDefaultSharedPreferences(this).edit().putStringSet(keyFailedPages, strings).apply()\n                    DirUpdateWork.schedule(this)\n                    setStatus(STATE_FINISHED)\n                }\n            } catch (e: HttpStatusException) {\n                Log.e(TAG, \"Page error: $page | Code: ${e.statusCode}\")\n                if (e.statusCode == 403 || e.statusCode == 503) {\n                    e.printStackTrace()\n                    finished = true\n                    setStatus(STATE_INTERRUPTED)\n                    stopSelf()\n                    cancelForeground()\n                }\n            } catch (e: Exception) {\n                Log.e(TAG, \"Page error: $page | ${e.message}\")\n                if (strings?.contains(page.toString()) == false)\n                    strings.add(page.toString())\n                page++\n                if (page > maxAnimes / 24){\n                    finished = true\n                    setStatus(STATE_INTERRUPTED)\n                }\n            }\n        }\n    }\n\n    private fun cancelForeground() {\n        noCrash {\n            isRunning = false\n            stopForeground(true)\n            notCancel(NOT_CODE)\n        }\n    }\n\n    private fun updateNotification() {\n        val notification = NotificationCompat.Builder(this, CHANNEL).apply {\n            setOngoing(true)\n            priority = NotificationCompat.PRIORITY_MIN\n            setSmallIcon(R.drawable.ic_directory_not)\n            color = ContextCompat.getColor(this@DirectoryService, EAHelper.getThemeColor())\n            setWhen(CURRENT_TIME)\n            setSound(null)\n            if (PrefsUtil.collapseDirectoryNotification)\n                setSubText(\"Creando directorio: $count/$maxAnimes~\")\n            else {\n                setContentTitle(\"Creando directorio\")\n                setContentText(\"Agregados: $count/$maxAnimes~\")\n                if (maxAnimes > 0)\n                    setProgress(maxAnimes, count, false)\n            }\n        }\n        notShow(NOT_CODE, notification.build())\n    }\n\n    private fun notShow(code: Int, notification: Notification) {\n        manager?.notify(code, notification)\n    }\n\n    private fun notCancel(code: Int) {\n        manager?.cancel(code)\n    }\n\n    override fun onTaskRemoved(rootIntent: Intent) {\n        cancelForeground()\n        super.onTaskRemoved(rootIntent)\n    }\n\n    interface OnDirStatus {\n        fun onFinished()\n    }\n\n    companion object {\n        const val STATE_CACHED = 0\n        const val STATE_PARTIAL = 1\n        const val STATE_FULL = 2\n        const val STATE_FINISHED = 3\n        const val STATE_INTERRUPTED = 4\n        const val STATE_VERIFYING = 5\n        var NOT_CODE = 5598\n        var CHANNEL = \"directory_update\"\n        var isRunning = false\n            private set\n        private val liveStatus = MutableLiveData<Int>()\n\n        fun run(context: Context?) {\n            if (context == null) return\n            if (!isRunning)\n                context.service(Intent(context, DirectoryService::class.java))\n        }\n\n        fun setStatus(status: Int) {\n            doOnUIGlobal { liveStatus.value = status }\n        }\n\n        fun getLiveStatus(): LiveData<Int> {\n            return liveStatus\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryUpdateService.kt",
    "content": "package knf.kuma.directory\n\nimport android.app.IntentService\nimport android.app.Notification\nimport android.app.NotificationManager\nimport android.content.Context\nimport android.content.Intent\nimport android.util.Log\nimport androidx.core.app.NotificationCompat\nimport androidx.core.content.ContextCompat\nimport knf.kuma.R\nimport knf.kuma.commons.BypassUtil\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.jsoupCookiesDir\nimport knf.kuma.database.CacheDB\nimport knf.kuma.database.dao.AnimeDAO\nimport knf.kuma.download.foreground\nimport knf.kuma.pojos.DirectoryPage\nimport org.jsoup.HttpStatusException\nimport pl.droidsonroids.jspoon.Jspoon\nimport kotlin.properties.Delegates\n\nclass DirectoryUpdateService : IntentService(\"Directory re-update\") {\n    private val CURRENT_TIME = System.currentTimeMillis()\n    private var manager: NotificationManager? = null\n    private var count = 0\n    private var page = 0\n    private val maxAnimes = 72\n    private var needCookies by Delegates.notNull<Boolean>()\n\n    private val startNotification: Notification\n        get() {\n            val notification = NotificationCompat.Builder(this, CHANNEL)\n                    .setOngoing(true)\n                    .setSubText(\"Actualizando directorio\")\n                    .setPriority(NotificationCompat.PRIORITY_MIN)\n                    .setSmallIcon(R.drawable.ic_dir_update)\n                    .setColor(ContextCompat.getColor(this, EAHelper.getThemeColor()))\n                    .setWhen(CURRENT_TIME)\n            return notification.build()\n        }\n\n    override fun onCreate() {\n        foreground(NOT_CODE, startNotification)\n        super.onCreate()\n    }\n\n    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {\n        foreground(NOT_CODE, startNotification)\n        return super.onStartCommand(intent, flags, startId)\n    }\n\n    override fun onHandleIntent(intent: Intent?) {\n        foreground(NOT_CODE, startNotification)\n        if (!Network.isConnected) {\n            stopSelf()\n            cancelForeground()\n            return\n        }\n        isRunning = true\n        manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager\n        val animeDAO = CacheDB.INSTANCE.animeDAO()\n        needCookies = BypassUtil.isCloudflareActive()\n        DirManager.checkPreDir(true)\n        val jspoon = Jspoon.create()\n        doFullSearch(jspoon, animeDAO)\n        cancelForeground()\n    }\n\n    private fun doFullSearch(jspoon: Jspoon, animeDAO: AnimeDAO) {\n        page = 1\n        var finished = false\n        while (!finished) {\n            if (!Network.isConnected) {\n                Log.e(\"Directory Getter\", \"Processed $page pages before disconnection\")\n                stopSelf()\n                cancelForeground()\n                return\n            }\n            try {\n                if (needCookies)\n                    Thread.sleep(6000)\n                else\n                    Thread.sleep(1000)\n                val document = jsoupCookiesDir(\"https://www3.animeflv.net/browse?order=added&page=$page\", needCookies).get()\n                if (document.select(\"article\").size != 0) {\n                    val animeObjects = jspoon.adapter(DirectoryPage::class.java).fromHtml(document.outerHtml()).getAnimesRecreate(jspoon, object : DirectoryPage.UpdateInterface {\n                        override fun onAdd() {\n                            count++\n                            updateNotification()\n                        }\n\n                        override fun onError() {\n                            Log.e(\"Directory Getter\", \"At page: $page\")\n                        }\n                    }, needCookies)\n                    if (animeObjects.isNotEmpty())\n                        animeDAO.insertAll(animeObjects)\n                    page++\n                    if (page >= 4)\n                        finished = true\n                } else {\n                    finished = true\n                    Log.e(\"Directory Getter\", \"Processed ${page - 1} pages\")\n                }\n            } catch (e: HttpStatusException) {\n                if (e.statusCode == 403 || e.statusCode == 503) {\n                    Log.e(\"Directory Getter\", \"Processed $page pages before interrupted\")\n                    finished = true\n                }\n            } catch (e: Exception) {\n                Log.e(\"Directory Getter\", \"Page error: $page | ${e.message}\")\n                page++\n                if (page >= 4)\n                    finished = true\n            }\n\n        }\n        cancelForeground()\n    }\n\n    private fun cancelForeground() {\n        isRunning = false\n        stopForeground(true)\n        manager?.cancel(NOT_CODE)\n    }\n\n    private fun updateNotification() {\n        val notification = NotificationCompat.Builder(this, CHANNEL).apply {\n            setOngoing(true)\n            priority = NotificationCompat.PRIORITY_MIN\n            setSmallIcon(R.drawable.ic_dir_update)\n            color = ContextCompat.getColor(this@DirectoryUpdateService, EAHelper.getThemeColor())\n            setWhen(CURRENT_TIME)\n            setSound(null)\n            if (PrefsUtil.collapseDirectoryNotification)\n                setSubText(\"Actualizando directorio: $count/$maxAnimes~\")\n            else {\n                setContentTitle(\"Actualizando directorio\")\n                setContentText(\"Actualizados: $count/$maxAnimes~\")\n                if (maxAnimes > 0)\n                    setProgress(maxAnimes, count, false)\n            }\n        }\n        manager?.notify(NOT_CODE, notification.build())\n    }\n\n    override fun onTaskRemoved(rootIntent: Intent) {\n        cancelForeground()\n        super.onTaskRemoved(rootIntent)\n    }\n\n    companion object {\n        var NOT_CODE = 5599\n        var CHANNEL = \"directory_update\"\n        var isRunning = false\n            private set\n\n        fun run(context: Context) {\n            if (!isRunning)\n                ContextCompat.startForegroundService(context, Intent(context, DirectoryUpdateService::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/DirectoryViewModel.kt",
    "content": "package knf.kuma.directory\n\nimport androidx.lifecycle.ViewModel\nimport androidx.paging.PagingData\nimport knf.kuma.retrofit.Repository\nimport kotlinx.coroutines.flow.Flow\n\nclass DirectoryViewModel : ViewModel() {\n    private val repository = Repository()\n\n    fun getAnimes(): Flow<PagingData<DirObject>> {\n        return repository.getAnimeDir()\n    }\n\n    fun getOvas(): Flow<PagingData<DirObject>> {\n        return repository.getOvaDir()\n    }\n\n    fun getMovies(): Flow<PagingData<DirObject>> {\n        return repository.getMovieDir()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/viewholders/DirMainFragmentHolder.kt",
    "content": "package knf.kuma.directory.viewholders\n\nimport android.view.View\nimport androidx.fragment.app.FragmentManager\nimport androidx.viewpager.widget.ViewPager\nimport com.google.android.material.tabs.TabLayout\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.directory.DirPagerAdapter\nimport org.jetbrains.anko.find\n\nclass DirMainFragmentHolder(view: View, manager: FragmentManager) {\n    private val tabLayout: TabLayout = view.find(R.id.tabs)\n    internal val pager: ViewPager = view.find(R.id.pager)\n    private val adapter: DirPagerAdapter\n\n    init {\n        pager.offscreenPageLimit = 3\n        adapter = DirPagerAdapter(manager)\n        pager.adapter = adapter\n        tabLayout.setupWithViewPager(pager)\n    }\n\n    fun onChangeOrder() {\n        adapter.onChangeOrder()\n    }\n\n    fun onReselect() {\n        (adapter.getItem(pager.currentItem) as BottomFragment).onReselect()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/directory/viewholders/DirMainFragmentMaterialHolder.kt",
    "content": "package knf.kuma.directory.viewholders\n\nimport android.view.View\nimport androidx.fragment.app.FragmentManager\nimport androidx.fragment.app.FragmentPagerAdapter\nimport androidx.viewpager.widget.ViewPager\nimport com.google.android.material.tabs.TabLayout\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.directory.DirPagerAdapterMaterial\nimport knf.kuma.directory.DirPagerAdapterOnline\nimport org.jetbrains.anko.find\n\nclass DirMainFragmentMaterialHolder(view: View, manager: FragmentManager) {\n    private val tabLayout: TabLayout = view.find(R.id.tabs)\n    internal val pager: ViewPager = view.find(R.id.pager)\n    private val adapter: FragmentPagerAdapter\n\n    init {\n        pager.offscreenPageLimit = 3\n        adapter = if (PrefsUtil.isDirectoryFinished || !Network.isConnected)\n            DirPagerAdapterMaterial(manager)\n        else\n            DirPagerAdapterOnline(manager)\n        pager.adapter = adapter\n        tabLayout.setupWithViewPager(pager)\n    }\n\n    fun onChangeOrder() {\n        (adapter as? DirPagerAdapterMaterial)?.onChangeOrder()\n    }\n\n    fun onReselect() {\n        (adapter.getItem(pager.currentItem) as BottomFragment).onReselect()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/DownloadDialogActivity.kt",
    "content": "package knf.kuma.download\n\nimport android.graphics.Color\nimport android.graphics.drawable.ColorDrawable\nimport android.os.Bundle\nimport android.view.View\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.list.listItems\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.commons.safeDismiss\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.pojos.NotificationObj\nimport knf.kuma.videoservers.ServersFactory\nimport org.jetbrains.anko.doAsync\nimport java.util.regex.Pattern\n\nclass DownloadDialogActivity : GenericActivity() {\n\n    private lateinit var downloadObject: DownloadObject\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getThemeDialog())\n        super.onCreate(savedInstanceState)\n        title = \" \"\n        window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))\n        setFinishOnTouchOutside(false)\n        val dialog = MaterialDialog(this).safeShow {\n            message(text = \"Obteniendo informacion...\")\n            cancelable(false)\n            cancelOnTouchOutside(false)\n        }\n        doAsync {\n            try {\n                val document = jsoupCookies(intent.dataString).get()\n                val name = PatternUtil.fromHtml(document.select(\"nav.Brdcrmb.fa-home a[href^=/anime/]\").first().text())\n                lateinit var aid: String\n                lateinit var num: String\n                val matcher = Pattern.compile(\"var (.*) = (\\\\d+);\").matcher(document.html())\n                while (matcher.find()) {\n                    when (matcher.group(1)) {\n                        \"anime_id\" -> aid = matcher.group(2)\n                        \"episode_number\" -> num = matcher.group(2)\n                    }\n                }\n                val eid = \"${aid}Episodio $num\".hashCode().toString()\n                val chapter = AnimeObject.WebInfo.AnimeChapter(Integer.parseInt(aid), \"Episodio $num\", eid, intent.dataString\n                        ?: \"\", name, aid)\n                downloadObject = DownloadObject.fromChapter(chapter, false)\n                doOnUI {\n                    dialog.safeDismiss()\n                    try {\n                        showSelectDialog()\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                        finish()\n                    }\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                finish()\n            }\n        }\n\n    }\n\n    private fun showSelectDialog() {\n        MaterialDialog(this).safeShow {\n            listItems(items = listOf(\"Descarga\", \"Streaming\")) { _, index, _ ->\n                ServersFactory.start(this@DownloadDialogActivity, intent.dataString\n                        ?: \"\", downloadObject, index == 1, object : ServersFactory.ServersInterface {\n                    override fun onFinish(started: Boolean, success: Boolean) {\n                        if (success)\n                            removeNotification()\n                        finish()\n                    }\n\n                    override fun onCast(url: String?) {\n\n                    }\n\n                    override fun onProgressIndicator(boolean: Boolean) {\n\n                    }\n\n                    override fun getView(): View? {\n                        return null\n                    }\n                })\n            }\n            setOnCancelListener { finish() }\n        }\n    }\n\n    private fun extract(st: String?, regex: String): String {\n        val matcher = Pattern.compile(regex).matcher(st)\n        matcher.find()\n        return matcher.group(1)\n    }\n\n    private fun removeNotification() {\n        if (intent.getBooleanExtra(\"notification\", false))\n            sendBroadcast(NotificationObj.fromIntent(intent).getBroadcast(this))\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/DownloadManager.kt",
    "content": "package knf.kuma.download\n\nimport android.annotation.SuppressLint\nimport android.app.Notification\nimport android.app.NotificationManager\nimport android.app.PendingIntent\nimport android.app.Service\nimport android.content.Context\nimport android.content.Intent\nimport android.media.MediaScannerConnection\nimport android.net.Uri\nimport android.os.IBinder\nimport android.util.Log\nimport androidx.core.app.NotificationCompat\nimport androidx.core.content.ContextCompat\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport com.tonyodev.fetch2.Download\nimport com.tonyodev.fetch2.EnqueueAction\nimport com.tonyodev.fetch2.Error\nimport com.tonyodev.fetch2.Fetch\nimport com.tonyodev.fetch2.FetchConfiguration\nimport com.tonyodev.fetch2.FetchListener\nimport com.tonyodev.fetch2.Request\nimport com.tonyodev.fetch2.Status\nimport com.tonyodev.fetch2core.DownloadBlock\nimport com.tonyodev.fetch2core.Func\nimport com.tonyodev.fetch2okhttp.OkHttpDownloader\nimport knf.kuma.App\nimport knf.kuma.BuildConfig\nimport knf.kuma.R\nimport knf.kuma.commons.AllSSLOkHttpClient\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.FileUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.noCrash\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.videoservers.ServersFactory\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.notificationManager\nimport xdroid.toaster.Toaster\nimport java.util.Locale\n\nclass DownloadManager : Service() {\n\n    override fun onBind(intent: Intent): IBinder? {\n        return null\n    }\n\n    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {\n        foreground(23498, foregroundGroupNotification())\n        if (intent != null && intent.action != null && intent.action == \"stop.foreground\") {\n            stopForeground(true)\n            stopSelf()\n        }\n        return START_STICKY\n    }\n\n    override fun onCreate() {\n        super.onCreate()\n        foreground(23498, foregroundGroupNotification())\n        //notificationManager?.notify(22498, foregroundGroupNotification())\n    }\n\n    companion object {\n        const val CHANNEL_FOREGROUND = \"service.LifeSaver\"\n        internal const val ACTION_PAUSE = 0\n        internal const val ACTION_RESUME = 1\n        internal const val ACTION_CANCEL = 2\n        private const val CHANNEL = \"service.Downloads\"\n        private const val CHANNEL_ONGOING = \"service.Downloads.Ongoing\"\n\n        @SuppressLint(\"StaticFieldLeak\")\n        private val context: Context = App.context\n        private var fetch: Fetch? = null\n        private val fetchConfiguration: FetchConfiguration.Builder by lazy {\n            FetchConfiguration.Builder(context)\n                    .setDownloadConcurrentLimit(PrefsUtil.maxParallelDownloads)\n                    .enableLogging(BuildConfig.DEBUG)\n                    .enableRetryOnNetworkGain(true)\n                    .setAutoRetryMaxAttempts(3)\n                    .createDownloadFileOnEnqueue(false)\n                .setHttpDownloader(OkHttpDownloader(AllSSLOkHttpClient.get()))\n        }\n        private val downloadDao = CacheDB.INSTANCE.downloadsDAO()\n        private val notificationManager: NotificationManager by lazy { context.notificationManager }\n\n        fun setParallelDownloads(newValue: String?) {\n            if (newValue.isNullOrEmpty()) return\n            fetch?.pauseAll()\n            fetchConfiguration.setDownloadConcurrentLimit(Integer.parseInt(newValue))\n            fetch = Fetch.getInstance(fetchConfiguration.build()).apply {\n                fetch?.getListenerSet()?.forEach {\n                    addListener(it, autoStart = true)\n                }\n            }\n            fetch?.resumeAll()\n        }\n\n        init {\n            fetch = Fetch.getInstance(fetchConfiguration.build()).addListener(object : FetchListener {\n                override fun onAdded(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.PENDING\n                            downloadDao.update(downloadObject)\n                        }\n                    }\n                }\n\n                override fun onQueued(download: Download, waitingOnNetwork: Boolean) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.PENDING\n                            downloadDao.update(downloadObject)\n                        }\n                    }\n                }\n\n                override fun onWaitingNetwork(download: Download) {\n\n                }\n\n                override fun onCompleted(download: Download) {\n                    doAsync { val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            if (FileAccessHelper.isTempFile(download.file)) {\n                                if (FileAccessHelper.getTmpFile(downloadObject.file).length() < 5) {\n                                    Log.e(\"Download\", \"Damaged tmp file, aborting\")\n                                    errorNotification(downloadObject)\n                                    downloadDao.delete(downloadObject)\n                                    fetch?.delete(download.id)\n                                    stopIfNeeded()\n                                    return@doAsync\n                                }\n                                Log.e(\"Download\", \"Moving temp\")\n                                downloadObject.setEta(-2)\n                                downloadObject.progress = 0\n                                downloadDao.update(downloadObject)\n                                FileUtil.moveFile(\n                                    downloadObject.file,\n                                    object : FileUtil.MoveCallback {\n                                        override fun onProgress(pair: android.util.Pair<Int, Boolean>) {\n                                            if (!pair.second) {\n                                                downloadObject.progress = pair.first\n                                                updateNotification(downloadObject, false)\n                                                downloadDao.update(downloadObject)\n                                        } else if (pair.first == -1) {\n                                            downloadDao.delete(downloadObject)\n                                            errorNotification(downloadObject)\n                                        } else {\n                                            downloadObject.progress = 100\n                                            downloadObject.state = DownloadObject.COMPLETED\n                                            downloadDao.update(downloadObject)\n                                            notificationManager.cancel(downloadObject.eid.toInt())\n                                            completedNotification(downloadObject)\n                                        }\n                                        stopIfNeeded()\n                                    }\n                                })\n                            } else {\n                                downloadObject.state = DownloadObject.COMPLETED\n                                downloadDao.update(downloadObject)\n                                completedNotification(downloadObject)\n                            }\n                        }\n                        stopIfNeeded() }\n                }\n\n                override fun onError(download: Download, error: Error, throwable: Throwable?) {\n                    doAsync {\n                        Log.e(\"Download\", \"Error downloader\")\n                        if (throwable != null) {\n                            throwable.printStackTrace()\n                            FirebaseCrashlytics.getInstance().recordException(throwable)\n                        }\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            errorNotification(downloadObject)\n                            downloadDao.delete(downloadObject)\n                            fetch?.delete(download.id)\n                            stopIfNeeded()\n                        }\n                    }\n                }\n\n                override fun onDownloadBlockUpdated(download: Download, downloadBlock: DownloadBlock, totalBlocks: Int) {\n\n                }\n\n                override fun onStarted(download: Download, downloadBlocks: List<DownloadBlock>, totalBlocks: Int) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.DOWNLOADING\n                            downloadDao.update(downloadObject)\n                            updateNotification(downloadObject, false)\n                        }\n                        context.service(Intent(context, DownloadManager::class.java))\n                    }\n                }\n\n                override fun onProgress(download: Download, etaInMilliSeconds: Long, downloadedBytesPerSecond: Long) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.DOWNLOADING\n                            downloadObject.setEta(etaInMilliSeconds)\n                            downloadObject.setSpeed(downloadedBytesPerSecond)\n                            downloadObject.progress = download.progress\n                            downloadObject.t_bytes = download.total\n                            downloadObject.d_bytes = download.downloaded\n                            downloadDao.update(downloadObject)\n                            updateNotification(downloadObject, false)\n                        }\n                    }\n                }\n\n                override fun onPaused(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.PAUSED\n                            downloadObject.setEta(-1)\n                            downloadDao.update(downloadObject)\n                            updateNotification(downloadObject, true)\n                        }\n                        stopIfNeeded()\n                    }\n                }\n\n                override fun onResumed(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.PENDING\n                            downloadObject.time = System.currentTimeMillis()\n                            downloadDao.update(downloadObject)\n                            updateNotification(downloadObject, false)\n                        }\n                    }\n                }\n\n                override fun onCancelled(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null)\n                            notificationManager.cancel(downloadObject.getDid())\n                        stopIfNeeded()\n                    }\n                }\n\n                override fun onRemoved(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null)\n                            notificationManager.cancel(downloadObject.getDid())\n                        stopIfNeeded()\n                    }\n                }\n\n                override fun onDeleted(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null)\n                            notificationManager.cancel(downloadObject.getDid())\n                        stopIfNeeded()\n                    }\n                }\n            }, autoStart = true)\n        }\n\n        fun start(downloadObject: DownloadObject): Boolean {\n            try {\n                val file = FileAccessHelper.getFileCreate(downloadObject.file)\n                file?.let {\n                    val request = Request(downloadObject.link, file.absolutePath)\n                    if (downloadObject.headers != null)\n                        for (header in downloadObject.headers?.createHeaders()\n                                ?: listOf())\n                            request.addHeader(header.first, header.second)\n                    request.enqueueAction = EnqueueAction.REPLACE_EXISTING\n                    downloadObject.setDid(request.id)\n                    downloadObject.canResume = true\n                    downloadDao.insert(downloadObject)\n                    fetch?.enqueue(request, { Log.e(\"Download\", \"Queued \" + it.id) }, {\n                        it.throwable?.printStackTrace()\n                        GlobalScope.launch(Dispatchers.IO) {\n                            downloadDao.delete(downloadObject)\n                        }\n                    })\n                    fetch?.resumeAll()\n                } ?: return false\n                return true\n            } catch (e: Exception) {\n                e.printStackTrace()\n                FirebaseCrashlytics.getInstance().recordException(e)\n                Toaster.toast(\"Error al iniciar descarga: ${e.message}\")\n                return false\n            }\n\n        }\n\n        fun cancel(eid: String) {\n            doAsync {\n                val downloadObject = downloadDao.getByEid(eid)\n            if (downloadObject != null) {\n                downloadDao.delete(downloadObject)\n                notificationManager.cancel(downloadObject.eid?.toInt() ?: 0)\n                if (downloadObject.did != null)\n                    fetch?.delete(downloadObject.getDid())\n            }\n            }\n        }\n\n        fun cancelAll() {\n            doAsync {\n                noCrash {\n                    val downloads = downloadDao.allRaw\n                    val dids = mutableListOf<Int>()\n                    downloads.forEach {\n                        dids.add(it.getDid())\n                        notificationManager.cancel(it.eid?.toInt() ?: 0)\n                    }\n                    fetch?.delete(dids)\n                    downloadDao.delete(downloads)\n                    stopIfNeeded()\n                }\n            }\n        }\n\n        fun pause(downloadObject: DownloadObject) {\n            pause(downloadObject.getDid())\n        }\n\n        fun pauseAll() {\n            fetch?.getDownloadsWithStatus(Status.DOWNLOADING, Func {\n                val list = mutableListOf<Int>()\n                it.forEach { download ->\n                    list.add(download.id)\n                }\n                fetch?.pause(list)\n            })\n        }\n\n        fun pause(did: Int) {\n            doAsync { fetch?.pause(did) }\n        }\n\n        fun resume(downloadObject: DownloadObject) {\n            resume(downloadObject.getDid())\n        }\n\n        internal fun resume(did: Int) {\n            doAsync { fetch?.resume(did) }\n        }\n\n        private fun updateNotification(downloadObject: DownloadObject?, isPaused: Boolean) {\n            if (downloadObject == null) return\n            val notification = NotificationCompat.Builder(context, CHANNEL_ONGOING).apply {\n                setSmallIcon(if (isPaused) R.drawable.ic_pause_not else if (downloadObject.eta.toLong() == -2L) R.drawable.ic_move else android.R.drawable.stat_sys_download)\n                setContentTitle(downloadObject.name)\n                setContentText(downloadObject.chapter)\n                setOnlyAlertOnce(!isPaused || downloadObject.eta.toLong() == -2L)\n                setProgress(100, downloadObject.progress, downloadObject.state == DownloadObject.PENDING)\n                color = ContextCompat.getColor(App.context, EAHelper.getThemeColor())\n                setGroup(\"manager\")\n                setOngoing(!isPaused)\n                setSound(null)\n                setWhen(downloadObject.time)\n                priority = NotificationCompat.PRIORITY_LOW\n                if (downloadObject.eta.toLong() != -2L) {\n                    if (isPaused)\n                        addAction(R.drawable.ic_play_not, \"Reanudar\", getPending(downloadObject, ACTION_RESUME))\n                    else\n                        addAction(R.drawable.ic_pause_not, \"Pausar\", getPending(downloadObject, ACTION_PAUSE))\n                    addAction(R.drawable.ic_delete, \"Cancelar\", getPending(downloadObject, ACTION_CANCEL))\n                }\n                if (!isPaused)\n                    setSubText(downloadObject.subtext)\n            }\n            notificationManager.notify(downloadObject.eid?.toInt() ?: 0, notification.build())\n        }\n\n        private fun completedNotification(downloadObject: DownloadObject) {\n            val notification = NotificationCompat.Builder(context, CHANNEL)\n                    .setColor(ContextCompat.getColor(context, android.R.color.holo_green_dark))\n                    .setSmallIcon(android.R.drawable.stat_sys_download_done)\n                    .setContentTitle(downloadObject.name)\n                    .setContentText(downloadObject.chapter)\n                    .setContentIntent(ServersFactory.getPlayIntent(context, downloadObject.name, downloadObject.file))\n                    .setOngoing(false)\n                    .setAutoCancel(true)\n                    .setWhen(downloadObject.time)\n                    .setPriority(NotificationCompat.PRIORITY_HIGH)\n                    .build()\n            notificationManager.notify(downloadObject.eid?.toInt() ?: 0, notification)\n            updateMedia(downloadObject)\n        }\n\n        private fun errorNotification(downloadObject: DownloadObject) {\n            val notification = NotificationCompat.Builder(context, CHANNEL)\n                .setColor(ContextCompat.getColor(context, android.R.color.holo_red_dark))\n                .setSmallIcon(android.R.drawable.stat_notify_error)\n                .setContentTitle(downloadObject.name)\n                .setContentText(\"Error al descargar \" + downloadObject.chapter.lowercase(Locale.ENGLISH))\n                    .setOngoing(false)\n                    .setWhen(downloadObject.time)\n                    .setPriority(NotificationCompat.PRIORITY_HIGH)\n                    .build()\n            notificationManager.notify(downloadObject.eid?.toInt() ?: 0, notification)\n        }\n\n        private fun foregroundGroupNotification(): Notification {\n            return NotificationCompat.Builder(context, CHANNEL_FOREGROUND).apply {\n                setSmallIcon(R.drawable.ic_service)\n                setOngoing(true)\n                priority = NotificationCompat.PRIORITY_MIN\n                if (PrefsUtil.isGroupingEnabled) {\n                    setGroup(\"manager\")\n                    setGroupSummary(true)\n                }\n                if (PrefsUtil.collapseDirectoryNotification)\n                    setSubText(\"Descargas en progreso\")\n                else\n                    setContentTitle(\"Descargas en progreso\")\n            }.build()\n        }\n\n        private fun updateMedia(downloadObject: DownloadObject) {\n            try {\n                val file = downloadObject.file\n                context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(FileAccessHelper.getFile(file))))\n                MediaScannerConnection.scanFile(context, arrayOf(FileAccessHelper.getFile(file).absolutePath), arrayOf(\"video/mp4\"), null)\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n\n        }\n\n        private fun getPending(downloadObject: DownloadObject, action: Int): PendingIntent {\n            return try {\n                val intent = Intent(context, DownloadReceiver::class.java)\n                    .putExtra(\"did\", downloadObject.getDid())\n                    .putExtra(\"eid\", downloadObject.eid)\n                    .putExtra(\"action\", action)\n                PendingIntent.getBroadcast(\n                    context,\n                    downloadObject.key + action,\n                    intent,\n                    PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE\n                )\n            } catch (e: IllegalStateException) {\n                PendingIntent.getBroadcast(\n                    context,\n                    0,\n                    Intent(),\n                    PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE\n                )\n            }\n        }\n\n        private fun stopIfNeeded() {\n            GlobalScope.launch(Dispatchers.IO){\n                if (downloadDao.countActive() == 0 && context.isServiceRunning(DownloadManager::class.java)) {\n                    launch(Dispatchers.Main){\n                        context.service(Intent(context, DownloadManager::class.java).setAction(\"stop.foreground\"))\n                    }\n                    notificationManager.cancel(22498)\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/DownloadManagerCentral.kt",
    "content": "package knf.kuma.download\r\n\r\nimport android.app.job.JobScheduler\r\nimport android.content.Context\r\nimport android.os.Build\r\nimport knf.kuma.App\r\nimport knf.kuma.pojos.DownloadObject\r\n\r\nobject DownloadManagerCentral {\r\n    private val isSchedulerEnabled = try {\r\n        App.context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler\r\n        Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE\r\n    } catch (_: Exception) {\r\n        false\r\n    }\r\n\r\n    fun start(downloadObject: DownloadObject): Boolean {\r\n        return if (isSchedulerEnabled) {\r\n            DownloadManagerJob.start(downloadObject)\r\n        } else {\r\n            DownloadManager.start(downloadObject)\r\n        }\r\n    }\r\n\r\n    fun cancel(eid: String) {\r\n        if (isSchedulerEnabled) {\r\n            DownloadManagerJob.cancel(eid)\r\n        } else {\r\n            DownloadManager.cancel(eid)\r\n        }\r\n    }\r\n\r\n    fun cancelAll() {\r\n        if (isSchedulerEnabled) {\r\n            DownloadManagerJob.cancelAll()\r\n        } else {\r\n            DownloadManager.cancelAll()\r\n        }\r\n    }\r\n\r\n    fun pause(downloadObject: DownloadObject) {\r\n        if (isSchedulerEnabled) {\r\n            DownloadManagerJob.pause(downloadObject)\r\n        } else {\r\n            DownloadManager.pause(downloadObject)\r\n        }\r\n    }\r\n\r\n    fun pauseAll() {\r\n        if (isSchedulerEnabled) {\r\n            DownloadManagerJob.pauseAll()\r\n        } else {\r\n            DownloadManager.pauseAll()\r\n        }\r\n    }\r\n\r\n    fun pause(did: Int) {\r\n        if (isSchedulerEnabled) {\r\n            DownloadManagerJob.pause(did)\r\n        } else {\r\n            DownloadManager.pause(did)\r\n        }\r\n    }\r\n\r\n    fun resume(downloadObject: DownloadObject) {\r\n        if (isSchedulerEnabled) {\r\n            DownloadManagerJob.resume(downloadObject)\r\n        } else {\r\n            DownloadManager.resume(downloadObject)\r\n        }\r\n    }\r\n\r\n    fun resume(did: Int) {\r\n        if (isSchedulerEnabled) {\r\n            DownloadManagerJob.resume(did)\r\n        } else {\r\n            DownloadManager.resume(did)\r\n        }\r\n    }\r\n\r\n    fun setParallelDownloads(newValue: String?) {\r\n        if (isSchedulerEnabled) {\r\n            DownloadManagerJob.setParallelDownloads(newValue)\r\n        } else {\r\n            DownloadManager.setParallelDownloads(newValue)\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/DownloadManagerJob.kt",
    "content": "package knf.kuma.download\n\nimport android.annotation.SuppressLint\nimport android.app.Notification\nimport android.app.NotificationManager\nimport android.app.PendingIntent\nimport android.app.job.JobParameters\nimport android.app.job.JobService\nimport android.content.BroadcastReceiver\nimport android.content.Context\nimport android.content.Intent\nimport android.content.IntentFilter\nimport android.media.MediaScannerConnection\nimport android.net.Uri\nimport android.os.Build\nimport android.util.Log\nimport android.util.Pair\nimport androidx.annotation.RequiresApi\nimport androidx.core.app.NotificationCompat\nimport androidx.core.content.ContextCompat\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport com.tonyodev.fetch2.Download\nimport com.tonyodev.fetch2.EnqueueAction\nimport com.tonyodev.fetch2.Error\nimport com.tonyodev.fetch2.Fetch\nimport com.tonyodev.fetch2.FetchConfiguration\nimport com.tonyodev.fetch2.FetchListener\nimport com.tonyodev.fetch2.Request\nimport com.tonyodev.fetch2.Status\nimport com.tonyodev.fetch2core.DownloadBlock\nimport com.tonyodev.fetch2core.Func\nimport com.tonyodev.fetch2okhttp.OkHttpDownloader\nimport knf.kuma.App\nimport knf.kuma.BuildConfig\nimport knf.kuma.R\nimport knf.kuma.commons.AllSSLOkHttpClient\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.FileUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.noCrash\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.videoservers.ServersFactory\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.notificationManager\nimport xdroid.toaster.Toaster\nimport java.util.Locale\n\nclass DownloadManagerJob : JobService() {\n\n    private lateinit var currentParams: JobParameters\n\n    private val stopReceiver = object : BroadcastReceiver() {\n        override fun onReceive(context: Context?, intent: Intent?) {\n            if (intent?.action == \"stop.foreground\") {\n                unregisterReceiver(this)\n                jobFinished(currentParams, false)\n            }\n        }\n    }\n\n    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)\n    override fun onStartJob(params: JobParameters): Boolean {\n        currentParams = params\n        setNotification(params, 23498, foregroundGroupNotification(), JOB_END_NOTIFICATION_POLICY_REMOVE)\n        registerReceiver(stopReceiver, IntentFilter(\"stop.foreground\"), RECEIVER_NOT_EXPORTED)\n        return true\n    }\n\n    override fun onStopJob(params: JobParameters?): Boolean {\n        try {\n            unregisterReceiver(stopReceiver)\n        } catch (e: Exception) {\n            //\n        }\n        return true\n    }\n\n    companion object {\n        const val CHANNEL_FOREGROUND = \"service.LifeSaver\"\n        internal const val ACTION_PAUSE = 0\n        internal const val ACTION_RESUME = 1\n        internal const val ACTION_CANCEL = 2\n        private const val CHANNEL = \"service.Downloads\"\n        private const val CHANNEL_ONGOING = \"service.Downloads.Ongoing\"\n\n        @SuppressLint(\"StaticFieldLeak\")\n        private val context: Context = App.context\n        private var fetch: Fetch? = null\n        private val fetchConfiguration: FetchConfiguration.Builder by lazy {\n            FetchConfiguration.Builder(context)\n                .setDownloadConcurrentLimit(PrefsUtil.maxParallelDownloads)\n                .enableLogging(BuildConfig.DEBUG)\n                .enableRetryOnNetworkGain(true)\n                .setAutoRetryMaxAttempts(3)\n                .createDownloadFileOnEnqueue(false)\n                .setHttpDownloader(OkHttpDownloader(AllSSLOkHttpClient.get()))\n        }\n        private val downloadDao = CacheDB.INSTANCE.downloadsDAO()\n        private val notificationManager: NotificationManager by lazy { context.notificationManager }\n\n        fun setParallelDownloads(newValue: String?) {\n            if (newValue.isNullOrEmpty()) return\n            fetch?.pauseAll()\n            fetchConfiguration.setDownloadConcurrentLimit(Integer.parseInt(newValue))\n            fetch = Fetch.getInstance(fetchConfiguration.build()).apply {\n                fetch?.getListenerSet()?.forEach {\n                    addListener(it, autoStart = true)\n                }\n            }\n            fetch?.resumeAll()\n        }\n\n        init {\n            fetch = Fetch.getInstance(fetchConfiguration.build()).addListener(object : FetchListener {\n                override fun onAdded(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.PENDING\n                            downloadDao.update(downloadObject)\n                        }\n                    }\n                }\n\n                override fun onQueued(download: Download, waitingOnNetwork: Boolean) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.PENDING\n                            downloadDao.update(downloadObject)\n                        }\n                    }\n                }\n\n                override fun onWaitingNetwork(download: Download) {\n\n                }\n\n                override fun onCompleted(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            if (FileAccessHelper.isTempFile(download.file)) {\n                                if (FileAccessHelper.getTmpFile(downloadObject.file).length() < 5) {\n                                    Log.e(\"Download\", \"Damaged tmp file, aborting\")\n                                    errorNotification(downloadObject)\n                                    downloadDao.delete(downloadObject)\n                                    fetch?.delete(download.id)\n                                    stopIfNeeded()\n                                    return@doAsync\n                                }\n                                Log.e(\"Download\", \"Moving temp\")\n                                downloadObject.setEta(-2)\n                                downloadObject.progress = 0\n                                downloadDao.update(downloadObject)\n                                FileUtil.moveFile(\n                                    downloadObject.file,\n                                    object : FileUtil.MoveCallback {\n                                        override fun onProgress(pair: Pair<Int, Boolean>) {\n                                            if (!pair.second) {\n                                                downloadObject.progress = pair.first\n                                                updateNotification(downloadObject, false)\n                                                downloadDao.update(downloadObject)\n                                            } else if (pair.first == -1) {\n                                                downloadDao.delete(downloadObject)\n                                                errorNotification(downloadObject)\n                                            } else {\n                                                downloadObject.progress = 100\n                                                downloadObject.state = DownloadObject.COMPLETED\n                                                downloadDao.update(downloadObject)\n                                                notificationManager.cancel(downloadObject.eid.toInt())\n                                                completedNotification(downloadObject)\n                                            }\n                                            stopIfNeeded()\n                                        }\n                                    })\n                            } else {\n                                downloadObject.state = DownloadObject.COMPLETED\n                                downloadDao.update(downloadObject)\n                                completedNotification(downloadObject)\n                            }\n                        }\n                        stopIfNeeded()\n                    }\n                }\n\n                override fun onError(download: Download, error: Error, throwable: Throwable?) {\n                    doAsync {\n                        Log.e(\"Download\", \"Error downloader\")\n                        if (throwable != null) {\n                            throwable.printStackTrace()\n                            FirebaseCrashlytics.getInstance().recordException(throwable)\n                        }\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            errorNotification(downloadObject)\n                            downloadDao.delete(downloadObject)\n                            fetch?.delete(download.id)\n                            stopIfNeeded()\n                        }\n                    }\n                }\n\n                override fun onDownloadBlockUpdated(download: Download, downloadBlock: DownloadBlock, totalBlocks: Int) {\n\n                }\n\n                override fun onStarted(download: Download, downloadBlocks: List<DownloadBlock>, totalBlocks: Int) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.DOWNLOADING\n                            downloadDao.update(downloadObject)\n                            updateNotification(downloadObject, false)\n                        }\n                        context.UIDT(DownloadManagerJob::class.java)\n                    }\n                }\n\n                override fun onProgress(download: Download, etaInMilliSeconds: Long, downloadedBytesPerSecond: Long) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.DOWNLOADING\n                            downloadObject.setEta(etaInMilliSeconds)\n                            downloadObject.setSpeed(downloadedBytesPerSecond)\n                            downloadObject.progress = download.progress\n                            downloadObject.t_bytes = download.total\n                            downloadObject.d_bytes = download.downloaded\n                            downloadDao.update(downloadObject)\n                            updateNotification(downloadObject, false)\n                        }\n                    }\n                }\n\n                override fun onPaused(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.PAUSED\n                            downloadObject.setEta(-1)\n                            downloadDao.update(downloadObject)\n                            updateNotification(downloadObject, true)\n                        }\n                        stopIfNeeded()\n                    }\n                }\n\n                override fun onResumed(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null) {\n                            downloadObject.state = DownloadObject.PENDING\n                            downloadObject.time = System.currentTimeMillis()\n                            downloadDao.update(downloadObject)\n                            updateNotification(downloadObject, false)\n                        }\n                    }\n                }\n\n                override fun onCancelled(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null)\n                            notificationManager.cancel(downloadObject.getDid())\n                        stopIfNeeded()\n                    }\n                }\n\n                override fun onRemoved(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null)\n                            notificationManager.cancel(downloadObject.getDid())\n                        stopIfNeeded()\n                    }\n                }\n\n                override fun onDeleted(download: Download) {\n                    doAsync {\n                        val downloadObject = downloadDao.getByDid(download.id)\n                        if (downloadObject != null)\n                            notificationManager.cancel(downloadObject.getDid())\n                        stopIfNeeded()\n                    }\n                }\n            }, autoStart = true)\n        }\n\n        fun start(downloadObject: DownloadObject): Boolean {\n            try {\n                val file = FileAccessHelper.getFileCreate(downloadObject.file)\n                file?.let {\n                    val request = Request(downloadObject.link, file.absolutePath)\n                    if (downloadObject.headers != null)\n                        for (header in downloadObject.headers?.createHeaders()\n                            ?: listOf())\n                            request.addHeader(header.first, header.second)\n                    request.enqueueAction = EnqueueAction.REPLACE_EXISTING\n                    downloadObject.setDid(request.id)\n                    downloadObject.canResume = true\n                    downloadDao.insert(downloadObject)\n                    fetch?.enqueue(request, { Log.e(\"Download\", \"Queued \" + it.id) }, {\n                        it.throwable?.printStackTrace()\n                        GlobalScope.launch(Dispatchers.IO) {\n                            downloadDao.delete(downloadObject)\n                        }\n                    })\n                    fetch?.resumeAll()\n                } ?: return false\n                return true\n            } catch (e: Exception) {\n                e.printStackTrace()\n                FirebaseCrashlytics.getInstance().recordException(e)\n                Toaster.toast(\"Error al iniciar descarga: ${e.message}\")\n                return false\n            }\n\n        }\n\n        fun cancel(eid: String) {\n            doAsync {\n                val downloadObject = downloadDao.getByEid(eid)\n                if (downloadObject != null) {\n                    downloadDao.delete(downloadObject)\n                    notificationManager.cancel(downloadObject.eid?.toInt() ?: 0)\n                    if (downloadObject.did != null)\n                        fetch?.delete(downloadObject.getDid())\n                }\n            }\n        }\n\n        fun cancelAll() {\n            doAsync {\n                noCrash {\n                    val downloads = downloadDao.allRaw\n                    val dids = mutableListOf<Int>()\n                    downloads.forEach {\n                        dids.add(it.getDid())\n                        notificationManager.cancel(it.eid?.toInt() ?: 0)\n                    }\n                    fetch?.delete(dids)\n                    downloadDao.delete(downloads)\n                    stopIfNeeded()\n                }\n            }\n        }\n\n        fun pause(downloadObject: DownloadObject) {\n            pause(downloadObject.getDid())\n        }\n\n        fun pauseAll() {\n            fetch?.getDownloadsWithStatus(Status.DOWNLOADING, Func {\n                val list = mutableListOf<Int>()\n                it.forEach { download ->\n                    list.add(download.id)\n                }\n                fetch?.pause(list)\n            })\n        }\n\n        fun pause(did: Int) {\n            doAsync { fetch?.pause(did) }\n        }\n\n        fun resume(downloadObject: DownloadObject) {\n            resume(downloadObject.getDid())\n        }\n\n        internal fun resume(did: Int) {\n            doAsync { fetch?.resume(did) }\n        }\n\n        private fun updateNotification(downloadObject: DownloadObject?, isPaused: Boolean) {\n            if (downloadObject == null) return\n            val notification = NotificationCompat.Builder(context, CHANNEL_ONGOING).apply {\n                setSmallIcon(if (isPaused) R.drawable.ic_pause_not else if (downloadObject.eta.toLong() == -2L) R.drawable.ic_move else android.R.drawable.stat_sys_download)\n                setContentTitle(downloadObject.name)\n                setContentText(downloadObject.chapter)\n                setOnlyAlertOnce(!isPaused || downloadObject.eta.toLong() == -2L)\n                setProgress(100, downloadObject.progress, downloadObject.state == DownloadObject.PENDING)\n                color = ContextCompat.getColor(App.context, EAHelper.getThemeColor())\n                setGroup(\"manager\")\n                setOngoing(!isPaused)\n                setSound(null)\n                setWhen(downloadObject.time)\n                priority = NotificationCompat.PRIORITY_LOW\n                if (downloadObject.eta.toLong() != -2L) {\n                    if (isPaused)\n                        addAction(R.drawable.ic_play_not, \"Reanudar\", getPending(downloadObject, ACTION_RESUME))\n                    else\n                        addAction(R.drawable.ic_pause_not, \"Pausar\", getPending(downloadObject, ACTION_PAUSE))\n                    addAction(R.drawable.ic_delete, \"Cancelar\", getPending(downloadObject, ACTION_CANCEL))\n                }\n                if (!isPaused)\n                    setSubText(downloadObject.subtext)\n            }\n            notificationManager.notify(downloadObject.eid?.toInt() ?: 0, notification.build())\n        }\n\n        private fun completedNotification(downloadObject: DownloadObject) {\n            val notification = NotificationCompat.Builder(context, CHANNEL)\n                .setColor(ContextCompat.getColor(context, android.R.color.holo_green_dark))\n                .setSmallIcon(android.R.drawable.stat_sys_download_done)\n                .setContentTitle(downloadObject.name)\n                .setContentText(downloadObject.chapter)\n                .setContentIntent(ServersFactory.getPlayIntent(context, downloadObject.name, downloadObject.file))\n                .setOngoing(false)\n                .setAutoCancel(true)\n                .setWhen(downloadObject.time)\n                .setPriority(NotificationCompat.PRIORITY_HIGH)\n                .build()\n            notificationManager.notify(downloadObject.eid?.toInt() ?: 0, notification)\n            updateMedia(downloadObject)\n        }\n\n        private fun errorNotification(downloadObject: DownloadObject) {\n            val notification = NotificationCompat.Builder(context, CHANNEL)\n                .setColor(ContextCompat.getColor(context, android.R.color.holo_red_dark))\n                .setSmallIcon(android.R.drawable.stat_notify_error)\n                .setContentTitle(downloadObject.name)\n                .setContentText(\"Error al descargar \" + downloadObject.chapter.lowercase(Locale.ENGLISH))\n                .setOngoing(false)\n                .setWhen(downloadObject.time)\n                .setPriority(NotificationCompat.PRIORITY_HIGH)\n                .build()\n            notificationManager.notify(downloadObject.eid?.toInt() ?: 0, notification)\n        }\n\n        private fun foregroundGroupNotification(): Notification {\n            return NotificationCompat.Builder(context, CHANNEL_FOREGROUND).apply {\n                setSmallIcon(R.drawable.ic_service)\n                setOngoing(true)\n                priority = NotificationCompat.PRIORITY_MIN\n                if (PrefsUtil.isGroupingEnabled) {\n                    setGroup(\"manager\")\n                    setGroupSummary(true)\n                }\n                if (PrefsUtil.collapseDirectoryNotification)\n                    setSubText(\"Descargas en progreso\")\n                else\n                    setContentTitle(\"Descargas en progreso\")\n            }.build()\n        }\n\n        private fun updateMedia(downloadObject: DownloadObject) {\n            try {\n                val file = downloadObject.file\n                context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(FileAccessHelper.getFile(file))))\n                MediaScannerConnection.scanFile(context, arrayOf(FileAccessHelper.getFile(file).absolutePath), arrayOf(\"video/mp4\"), null)\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n\n        }\n\n        private fun getPending(downloadObject: DownloadObject, action: Int): PendingIntent {\n            return try {\n                val intent = Intent(context, DownloadReceiver::class.java)\n                    .putExtra(\"did\", downloadObject.getDid())\n                    .putExtra(\"eid\", downloadObject.eid)\n                    .putExtra(\"action\", action)\n                PendingIntent.getBroadcast(\n                    context,\n                    downloadObject.key + action,\n                    intent,\n                    PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE\n                )\n            } catch (e: IllegalStateException) {\n                PendingIntent.getBroadcast(\n                    context,\n                    0,\n                    Intent(),\n                    PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE\n                )\n            }\n        }\n\n        private fun stopIfNeeded() {\n            GlobalScope.launch(Dispatchers.IO) {\n                if (downloadDao.countActive() == 0 && context.isServiceRunning(DownloadManagerJob::class.java)) {\n                    launch(Dispatchers.Main) {\n                        context.sendBroadcast(Intent(\"stop.foreground\").setPackage(context.packageName))\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/DownloadReceiver.kt",
    "content": "package knf.kuma.download\n\nimport android.content.BroadcastReceiver\nimport android.content.Context\nimport android.content.Intent\n\nclass DownloadReceiver : BroadcastReceiver() {\n    override fun onReceive(context: Context, intent: Intent) {\n        val did = intent.getIntExtra(\"did\", 0)\n        when (intent.getIntExtra(\"action\", -1)) {\n            DownloadManager.ACTION_PAUSE -> DownloadManagerCentral.pause(did)\n            DownloadManager.ACTION_RESUME -> DownloadManagerCentral.resume(did)\n            DownloadManager.ACTION_CANCEL -> DownloadManagerCentral.cancel(\n                intent.getStringExtra(\"eid\")\n                    ?: \"\")\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/DownloadService.kt",
    "content": "package knf.kuma.download\n\nimport android.app.IntentService\nimport android.app.Notification\nimport android.app.NotificationManager\nimport android.content.Intent\nimport android.media.MediaScannerConnection\nimport android.net.Uri\nimport android.util.Log\nimport androidx.core.app.NotificationCompat\nimport androidx.core.content.ContextCompat\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.notNull\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.queue.QueueManager\nimport knf.kuma.videoservers.ServersFactory\nimport okhttp3.ConnectionSpec\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport java.io.BufferedInputStream\nimport java.io.BufferedOutputStream\nimport java.util.concurrent.TimeUnit\n\n\nclass DownloadService : IntentService(\"Download service\") {\n    private val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n\n    private var manager: NotificationManager? = null\n\n    private var current: DownloadObject? = null\n\n    private var file: String? = null\n    private val bufferSize = PrefsUtil.bufferSize()\n\n    private val startNotification: Notification\n        get() = NotificationCompat.Builder(this, CHANNEL_ONGOING).apply {\n            setSmallIcon(android.R.drawable.stat_sys_download)\n            setContentTitle(current?.name)\n            setContentText(current?.chapter)\n            setProgress(100, current?.progress ?: 0, true)\n            if (PrefsUtil.isGroupingEnabled) {\n                setGroup(\"manager\")\n                setGroupSummary(true)\n            }\n            setOngoing(true)\n            setSound(null)\n            setWhen(current?.time ?: 0)\n            priority = NotificationCompat.PRIORITY_LOW\n        }.build()\n\n    override fun onCreate() {\n        super.onCreate()\n        foreground(DOWNLOADING_ID, startNotification)\n    }\n\n    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {\n        foreground(DOWNLOADING_ID, startNotification)\n        return super.onStartCommand(intent, flags, startId)\n    }\n\n    override fun onHandleIntent(intent: Intent?) {\n        foreground(DOWNLOADING_ID, startNotification)\n        val currentEid = intent?.getStringExtra(\"eid\") ?: return\n        manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager\n        current = downloadsDAO.getByEid(currentEid)\n        if (current == null)\n            return\n        file = current?.file\n        try {\n            val request = Request.Builder()\n                    .url(intent.dataString ?: \"\")\n            if (current?.headers != null)\n                for (pair in current?.headers?.createHeaders() ?: mutableListOf()) {\n                    request.addHeader(pair.first, pair.second)\n                }\n            val response = OkHttpClient().newBuilder()\n                    .connectTimeout(10, TimeUnit.SECONDS)\n                    .readTimeout(10, TimeUnit.SECONDS)\n                    .followRedirects(true)\n                    .followSslRedirects(true)\n                    .connectionSpecs(listOf(ConnectionSpec.CLEARTEXT, ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)\n                            .allEnabledTlsVersions()\n                            .allEnabledCipherSuites()\n                            .build()))\n                    .build().newCall(request.build()).execute()\n            current?.t_bytes = response.body?.contentLength() ?: 0\n            val inputStream = BufferedInputStream(response.body?.byteStream())\n            val outputStream: BufferedOutputStream\n            if (response.code == 200 || response.code == 206) {\n                outputStream = BufferedOutputStream(FileAccessHelper.getOutputStream(current?.file), bufferSize * 1024)\n            } else {\n                Log.e(\"Download error\", \"Code: \" + response.code)\n                errorNotification()\n                current?.let {\n                    downloadsDAO.delete(it)\n                    QueueManager.remove(it.eid)\n                }\n                response.close()\n                cancelForeground()\n                return\n            }\n            current?.state = DownloadObject.DOWNLOADING\n            current?.let { downloadsDAO.update(it) }\n            val data = ByteArray(bufferSize * 1024)\n            var count: Int = inputStream.read(data, 0, bufferSize * 1024)\n            while (count >= 0) {\n                if (!downloadsDAO.existByEid(currentEid)) {\n                    FileAccessHelper.delete(file)\n                    current?.let { downloadsDAO.delete(it) }\n                    QueueManager.remove(current?.eid)\n                    cancelForeground()\n                    return\n                }\n                outputStream.write(data, 0, count)\n                current?.let {\n                    it.d_bytes += count.toLong()\n                    val prog = (it.d_bytes * 100 / it.t_bytes).toInt()\n                    if (prog > it.progress) {\n                        it.progress = prog\n                        updateNotification()\n                        downloadsDAO.update(it)\n                    }\n                    count = inputStream.read(data, 0, bufferSize * 1024)\n                }\n            }\n            outputStream.flush()\n            outputStream.close()\n            inputStream.close()\n            response.close()\n            completedNotification()\n        } catch (e: Exception) {\n            e.printStackTrace()\n            FileAccessHelper.delete(file)\n            current?.let {\n                downloadsDAO.delete(it)\n                QueueManager.remove(it.eid)\n            }\n            errorNotification()\n        }\n\n    }\n\n    private fun updateNotification() {\n        val notification = NotificationCompat.Builder(this, CHANNEL_ONGOING)\n                .setSmallIcon(android.R.drawable.stat_sys_download)\n                .setContentTitle(current?.name)\n                .setContentText(current?.chapter)\n                .setProgress(100, current?.progress ?: 0, false)\n                .setGroup(\"manager\")\n                .setOngoing(true)\n                .setSound(null)\n                .setWhen(current?.time ?: System.currentTimeMillis())\n                .setPriority(NotificationCompat.PRIORITY_LOW)\n        val pending = downloadsDAO.countPending()\n        if (pending > 0)\n            notification.setSubText(pending.toString() + \" \" + if (pending == 1) \"pendiente\" else \"pendientes\")\n        manager?.notify(DOWNLOADING_ID, notification.build())\n    }\n\n    private fun completedNotification() {\n        current?.let {\n            it.state = DownloadObject.COMPLETED\n            downloadsDAO.update(it)\n            val notification = NotificationCompat.Builder(this, CHANNEL)\n                    .setColor(ContextCompat.getColor(applicationContext, android.R.color.holo_green_dark))\n                    .setSmallIcon(android.R.drawable.stat_sys_download_done)\n                    .setContentTitle(current?.name)\n                    .setContentText(current?.chapter)\n                    .setContentIntent(ServersFactory.getPlayIntent(this, it.name, file ?: \"\"))\n                    .setOngoing(false)\n                .setAutoCancel(true)\n                    .setWhen(it.time)\n                .setPriority(NotificationCompat.PRIORITY_HIGH)\n                .build()\n            manager?.notify(it.eid.toInt(), notification)\n        }\n        updateMedia()\n        cancelForeground()\n    }\n\n    private fun updateMedia() {\n        try {\n            sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(FileAccessHelper.getFile(file))))\n            MediaScannerConnection.scanFile(applicationContext, arrayOf(FileAccessHelper.getFile(file).absolutePath), arrayOf(\"video/mp4\"), null)\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n    }\n\n    private fun errorNotification() {\n        val notification = NotificationCompat.Builder(this, CHANNEL)\n                .setColor(ContextCompat.getColor(applicationContext, android.R.color.holo_red_dark))\n                .setSmallIcon(android.R.drawable.stat_notify_error)\n                .setContentTitle(current?.name)\n            .setContentText(\"Error al descargar \" + current?.chapter?.lowercase())\n                .setOngoing(false)\n                .setWhen(current?.time ?: 0)\n                .setPriority(NotificationCompat.PRIORITY_HIGH)\n                .build()\n        manager?.notify(current?.eid?.toInt() ?: 0, notification)\n        cancelForeground()\n    }\n\n    private fun cancelForeground() {\n        stopForeground(true)\n        manager?.cancel(DOWNLOADING_ID)\n    }\n\n    override fun onTaskRemoved(rootIntent: Intent) {\n        noCrash {\n            cancelForeground()\n            FileAccessHelper.delete(file)\n            current?.let {\n                if (manager.notNull())\n                    errorNotification()\n                downloadsDAO.delete(it)\n                QueueManager.remove(it.eid)\n            }\n        }\n        super.onTaskRemoved(rootIntent)\n    }\n\n    companion object {\n        const val CHANNEL = \"service.Downloads\"\n        const val CHANNEL_ONGOING = \"service.Downloads.Ongoing\"\n        private const val DOWNLOADING_ID = 8879\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/FileAccessHelper.kt",
    "content": "package knf.kuma.download\n\nimport android.Manifest\nimport android.annotation.TargetApi\nimport android.content.Context\nimport android.content.Intent\nimport android.content.pm.PackageManager\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Environment\nimport android.provider.DocumentsContract\nimport android.util.Log\nimport androidx.annotation.RequiresApi\nimport androidx.core.content.ContextCompat\nimport androidx.core.content.FileProvider\nimport androidx.documentfile.provider.DocumentFile\nimport androidx.fragment.app.Fragment\nimport androidx.preference.PreferenceManager\nimport knf.kuma.App\nimport knf.kuma.commons.FileUtil\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.findActivity\nimport knf.kuma.commons.getPackage\nimport knf.kuma.commons.isNull\nimport knf.kuma.explorer.creator.Creator\nimport knf.kuma.explorer.creator.DocumentFileCreator\nimport knf.kuma.explorer.creator.SimpleFileCreator\nimport knf.kuma.explorer.creator.SubFile\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport xdroid.toaster.Toaster\nimport java.io.File\nimport java.io.FileFilter\nimport java.io.FileInputStream\nimport java.io.FileOutputStream\nimport java.io.InputStream\nimport java.io.OutputStream\n\nobject FileAccessHelper {\n\n    const val SD_REQUEST = 51247\n    var NOMEDIA_CREATING = false\n\n    val downloadsDirectory: File\n        get() {\n            return try {\n                if (PrefsUtil.downloadType == \"0\") {\n                    File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads\")\n                } else {\n                    File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"UKIKU/downloads\")\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                Environment.getDataDirectory()\n            }\n\n        }\n\n    val downloadExplorerCreator: Creator\n        get() {\n            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                DocumentFileCreator(treeUri?.let { find(DocumentFile.fromTreeUri(App.context, it), \"UKIKU/downloads\", false) })\n            } else {\n                SimpleFileCreator(\n                        if (PrefsUtil.downloadType == \"0\") {\n                            File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads\")\n                        } else {\n                            File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"UKIKU/downloads\")\n                        }\n                )\n            }\n        }\n\n    val internalRoot: File get() = Environment.getExternalStorageDirectory()\n\n    val externalRoot: File? get() = FileUtil.getFullPathFromTreeUri(treeUri, App.context)?.let { File(it) }\n\n    val treeUri: Uri?\n        get() {\n            return try {\n                Uri.parse(PreferenceManager.getDefaultSharedPreferences(App.context).getString(\"tree_uri\", null))\n            } catch (e: Exception) {\n                null\n            }\n\n        }\n\n    fun isStoragePermissionEnabled(): Boolean {\n        return when {\n            (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q || PrefsUtil.downloadType == \"1\") -> treeUri != null && DocumentFile.fromTreeUri(App.context, treeUri!!)?.let { it.exists() && it.canWrite() } == true\n            ContextCompat.checkSelfPermission(App.context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED -> true\n            else -> false\n        }\n    }\n\n    suspend fun isStoragePermissionEnabledAsync(): Boolean {\n        return withContext(Dispatchers.IO) {\n            when {\n                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q || PrefsUtil.downloadType == \"1\") -> treeUri != null && DocumentFile.fromTreeUri(App.context, treeUri!!)?.let { it.exists() && it.canWrite() } == true\n                ContextCompat.checkSelfPermission(App.context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED -> true\n                else -> false\n            }\n        }\n    }\n\n    fun getFile(file_name: String?): File {\n        return try {\n            if (file_name.isNullOrEmpty()) throw IllegalStateException(\"Name can't be null!\")\n            if (PrefsUtil.downloadType == \"0\") {\n                File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\n            } else {\n                File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            File(Environment.getDataDirectory(), \"test.txt\")\n        }\n\n    }\n\n    fun findFile(file_name: String?): File {\n        return try {\n            if (file_name.isNullOrEmpty()) throw IllegalStateException(\"Name can't be null!\")\n            if (PrefsUtil.downloadType == \"0\") {\n                File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name)).listFiles { file -> file.name.contains(file_name) }!![0]\n            } else\n                File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name)).listFiles { file -> file.name.contains(file_name) }!![0]\n        } catch (e: Exception) {\n            e.printStackTrace()\n            File(Environment.getDataDirectory(), \"test.txt\")\n        }\n\n    }\n\n    fun fileFindExist(file_name: String?): Boolean {\n        return try {\n            if (file_name.isNullOrEmpty()) throw IllegalStateException(\"Name can't be null!\")\n            if (PrefsUtil.downloadType == \"0\") {\n                !File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name)).listFiles { file -> file.name.contains(file_name) }.isNullOrEmpty()\n            } else {\n                !find(DocumentFile.fromTreeUri(App.context, treeUri!!), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name), false)?.listFiles()?.mapNotNull { it.name?.contains(file_name) }.isNullOrEmpty()\n\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            false\n        }\n    }\n\n    fun getFileUri(file_name: String?): Uri? {\n        if (file_name.isNullOrEmpty()) throw IllegalStateException(\"Name can't be null!\")\n        return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q)\n            Uri.fromFile(\n                    try {\n                        if (file_name.startsWith(\"$\")) {\n                            findFile(file_name)\n                        } else {\n                            if (PrefsUtil.downloadType == \"0\") {\n                                File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\n                            } else {\n                                File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\n                            }\n                        }\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                        File(Environment.getDataDirectory(), \"test.txt\")\n                    }\n            )\n        else\n            getDataUri(file_name)\n    }\n\n    val rootFile: File\n        get() {\n            return try {\n                if (PrefsUtil.downloadType == \"0\") {\n                    Environment.getExternalStorageDirectory()\n                } else {\n                    File(FileUtil.getFullPathFromTreeUri(treeUri, App.context))\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                Environment.getExternalStorageDirectory()\n            }\n\n        }\n\n    fun getTmpFile(file_name: String): File {\n        return File(getDownloadsCacheDir(), PatternUtil.getNameFromFile(file_name) + file_name)\n    }\n\n    val toneFile: File\n        get() {\n            return File(App.context.getExternalFilesDir(null), \"custom_tone\")\n        }\n\n    fun setToneFile(enable: Boolean) {\n        if (!enable) toneFile.delete()\n        PreferenceManager.getDefaultSharedPreferences(App.context).edit().putBoolean(\"is_custom_tone\", enable).apply()\n    }\n\n    fun getFileCreate(file_name: String): File? {\n        return try {\n            if (PrefsUtil.downloadType == \"0\") {\n                val file = File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\n                file.parentFile?.mkdirs()\n                if (!file.exists())\n                    file.createNewFile()\n                file\n            } else {\n                createTmpIfNotExist()\n                val file = File(getDownloadsCacheDir(), PatternUtil.getNameFromFile(file_name) + file_name)\n                file.parentFile?.mkdirs()\n                if (!file.exists())\n                    file.createNewFile()\n                file\n            }\n        } catch (e: Exception) {\n            Log.e(\"File create\", \"Error\")\n            e.printStackTrace()\n            null\n        }\n\n    }\n\n    private fun getDownloadsCacheDir(): File {\n        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)\n            App.context.getExternalFilesDirs(\"downloads\").last()\n        else\n            File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"Android/data/${getPackage()}/files/downloads\")\n    }\n\n    internal fun isTempFile(file: String): Boolean {\n        return try {\n            val path = FileUtil.getFullPathFromTreeUri(treeUri, App.context) ?: return false\n            file.contains(path)\n        } catch (e: Exception) {\n            false\n        }\n    }\n\n    fun checkNoMedia(noMediaNeeded: Boolean) {\n        NOMEDIA_CREATING = true\n        doAsync {\n            try {\n                if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {\n                    val file = File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads\")\n                    if (!file.exists())\n                        file.mkdirs()\n                    val root = File(file, \".nomedia\")\n                    if (noMediaNeeded && !root.exists())\n                        root.createNewFile()\n                    else if (!noMediaNeeded && root.exists())\n                        root.delete()\n                    val list = file.listFiles(FileFilter { it.isDirectory })\n                    if (list != null && list.isNotEmpty())\n                        for (current in list) {\n                            val inside = File(current, \".nomedia\")\n                            if (noMediaNeeded && !inside.exists())\n                                inside.createNewFile()\n                            else if (!noMediaNeeded && inside.exists())\n                                inside.delete()\n                        }\n                }\n                treeUri?.let {\n                    val documentRoot = find(DocumentFile.fromTreeUri(App.context, it), \"UKIKU/downloads\")\n                    val nomediaRoot = documentRoot?.findFile(\".nomedia\")\n                    if (noMediaNeeded && (nomediaRoot == null || !nomediaRoot.exists()))\n                        documentRoot?.createFile(\"application/nomedia\", \".nomedia\")\n                    else if (!noMediaNeeded && nomediaRoot != null && nomediaRoot.exists())\n                        nomediaRoot.delete()\n                    val documentList = documentRoot?.listFiles()\n                    if (!documentList.isNullOrEmpty())\n                        for (dFile in documentList) {\n                            if (dFile.isDirectory) {\n                                val inside = dFile.findFile(\".nomedia\")\n                                if (noMediaNeeded && (inside == null || !inside.exists()))\n                                    dFile.createFile(\"application/nomedia\", \".nomedia\")\n                                else if (!noMediaNeeded && inside != null && inside.exists())\n                                    inside.delete()\n                            }\n                        }\n                }\n                Toaster.toast(\"Archivos nomedia \" + if (noMediaNeeded) \"creados\" else \"eliminados\")\n                NOMEDIA_CREATING = false\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n    }\n\n    fun getDownloadsDirectory(file_name: String): File {\n        return try {\n            if (PrefsUtil.downloadType == \"0\") {\n                File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/$file_name\")\n            } else {\n                File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"UKIKU/downloads/$file_name\")\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            Environment.getDataDirectory()\n        }\n\n    }\n\n    fun getDownloadsDirectoryFiles(file_name: String): List<SubFile> {\n        return try {\n            when {\n                Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ->\n                    treeUri?.let { find(DocumentFile.fromTreeUri(App.context, it), \"UKIKU/downloads/$file_name\", false) }?.listFiles()?.map {\n                        SubFile(it.name ?: \"\", it.uri.toString())\n                    }?.filter { it.name.endsWith(\".mp4\") } ?: emptyList()\n                PrefsUtil.downloadType == \"0\" -> {\n                    File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/$file_name\").listFiles()?.map { SubFile(it.name, Uri.fromFile(it).toString()) }?.filter { it.name.endsWith(\".mp4\") }\n                            ?: emptyList()\n                }\n                else -> {\n                    File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"UKIKU/downloads/$file_name\").listFiles()?.map { SubFile(it.name, Uri.fromFile(it).toString()) }?.filter { it.name.endsWith(\".mp4\") }\n                            ?: emptyList()\n                }\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            emptyList()\n        }\n\n    }\n\n    fun getDownloadsDirectoryFromFile(file_name: String): File {\n        return try {\n            if (PrefsUtil.downloadType == \"0\") {\n                File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/${PatternUtil.getNameFromFile(file_name)}\")\n            } else {\n                File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"UKIKU/downloads/${PatternUtil.getNameFromFile(file_name)}\")\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            Environment.getDataDirectory()\n        }\n\n    }\n\n    fun delete(file_name: String?, async: Boolean = true) {\n        if (async)\n            doAsync { delete(file_name) }\n        else\n            delete(file_name)\n    }\n\n    fun deletePath(file_name: String?, async: Boolean = true) {\n        if (async)\n            doAsync { deletePath(file_name) }\n        else\n            deletePath(file_name)\n    }\n\n    private fun delete(file_name: String?) {\n        if (file_name.isNull())\n            return\n        try {\n            if (PrefsUtil.downloadType == \"0\") {\n                val file = File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\n                file.delete()\n                val dir = file.parentFile\n                if (dir?.listFiles() == null || dir.listFiles()?.isEmpty() == true)\n                    dir?.delete()\n            } else {\n                treeUri?.let {\n                    val documentFile = DocumentFile.fromTreeUri(App.context, it)\n                    if (documentFile != null && documentFile.exists()) {\n                        val file = find(documentFile, \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\n                        file?.delete()\n                        val dir = file?.parentFile\n                        if (dir != null && dir.listFiles().isEmpty())\n                            dir.delete()\n                    }\n                }\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }\n\n    private fun deletePath(file_name: String?) {\n        if (file_name == null)\n            return\n        try {\n            if (PrefsUtil.downloadType == \"0\") {\n                val file = File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name)).listFiles { file -> file.name.contains(file_name) }!![0]\n                file.delete()\n                val dir = file.parentFile\n                if (dir?.listFiles() == null || dir.listFiles()?.isEmpty() == true)\n                    dir?.delete()\n            } else {\n                treeUri?.let {\n                    val documentFile = DocumentFile.fromTreeUri(App.context, it)\n                    if (documentFile != null && documentFile.exists()) {\n                        val file = find(documentFile, \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name))?.listFiles()?.let {\n                            var tFile: DocumentFile? = null\n                            it.forEach {\n                                if (it.name?.contains(file_name) == true)\n                                    tFile = it\n                            }\n                            tFile\n                        }\n                        file?.delete()\n                        val dir = file?.parentFile\n                        if (dir != null && dir.listFiles().isEmpty())\n                            dir.delete()\n                    }\n                }\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }\n\n    private fun createTmpIfNotExist() {\n        if (!getDownloadsCacheDir().exists()) {\n            treeUri?.let {\n                getDownloadsCacheDir().mkdirs()\n                /*val documentFile = DocumentFile.fromTreeUri(App.context, it)\n                if (documentFile != null && documentFile.exists()) {\n                    val file = find(documentFile, \"Android/data/${getPackage()}/files/downloads/tmp.file\")\n                    file?.delete()\n                }*/\n            }\n        }\n    }\n\n    fun getOutputStream(file_name: String?): OutputStream? {\n        if (file_name == null) return null\n        try {\n            return if (PrefsUtil.downloadType == \"0\" && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {\n                var file = File(\n                    Environment.getExternalStorageDirectory(),\n                    \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name)\n                )\n                if (!file.exists())\n                    file.mkdirs()\n                file = File(file, file_name)\n                if (!file.exists())\n                    file.createNewFile()\n                FileOutputStream(\n                    File(\n                        Environment.getExternalStorageDirectory(),\n                        \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name\n                    )\n                )\n            } else {\n                treeUri?.let {\n                    App.context.contentResolver.openOutputStream(\n                        find(\n                            DocumentFile.fromTreeUri(App.context, it),\n                            \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name\n                        )?.uri\n                            ?: Uri.EMPTY, \"rw\")\n                }\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            return null\n        }\n\n    }\n\n    fun getFileOutputStream(file_name: String): FileOutputStream? {\n        try {\n            return if (PrefsUtil.downloadType == \"0\") {\n                var file = File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name))\n                if (!file.exists())\n                    file.mkdirs()\n                file = File(file, file_name)\n                if (!file.exists())\n                    file.createNewFile()\n                FileOutputStream(File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name))\n            } else {\n                treeUri?.let {\n                    FileOutputStream(App.context.contentResolver.openFileDescriptor(find(DocumentFile.fromTreeUri(App.context, it), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)?.uri\n                            ?: Uri.EMPTY, \"rw\")?.fileDescriptor)\n                }\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            return null\n        }\n\n    }\n\n    fun getInputStream(file_name: String): InputStream? {\n        try {\n            return if (PrefsUtil.downloadType == \"0\") {\n                var file = File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name))\n                if (!file.exists())\n                    file.mkdirs()\n                file = File(file, file_name)\n                if (!file.exists())\n                    file.createNewFile()\n                FileInputStream(File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name))\n            } else {\n                treeUri?.let {\n                    App.context.contentResolver.openInputStream(find(DocumentFile.fromTreeUri(App.context, it), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)?.uri\n                            ?: Uri.EMPTY)\n                }\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            return null\n        }\n\n    }\n\n    fun getTmpInputStream(file_name: String): InputStream? {\n        return try {\n            val file = File(getDownloadsCacheDir(), PatternUtil.getNameFromFile(file_name) + file_name)\n            if (file.parentFile?.exists() == false)\n                file.parentFile?.mkdirs()\n            FileInputStream(file)\n        } catch (e: Exception) {\n            e.printStackTrace()\n            null\n        }\n\n    }\n\n    fun existFile(file_name: String): Boolean {\n        return try {\n            if (PrefsUtil.downloadType == \"0\") {\n                File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name).exists()\n            } else {\n                treeUri?.let {\n                    val documentFile = DocumentFile.fromTreeUri(App.context, it)\n                    if (documentFile != null && documentFile.exists()) {\n                        find(documentFile, \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\n                    }\n                    File(FileUtil.getFullPathFromTreeUri(treeUri, App.context), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name).exists()\n                } ?: false\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            false\n        }\n\n    }\n\n    fun canDownload(fragment: Fragment): Boolean {\n        return if (PrefsUtil.downloadType == \"0\") {\n            true\n        } else {\n            try {\n                val uri = treeUri\n                if (uri != null) {\n                    val documentFile = DocumentFile.fromTreeUri(App.context, uri)\n                    if (documentFile != null && documentFile.exists()) {\n                        true\n                    } else {\n                        openTreeChooser(fragment)\n                        false\n                    }\n                } else {\n                    openTreeChooser(fragment)\n                    false\n                }\n            } catch (e: IllegalArgumentException) {\n                openTreeChooser(fragment)\n                false\n            }\n\n        }\n    }\n\n    fun canDownload(fragment: Fragment, value: String?): Boolean {\n        return if (value == \"0\") {\n            true\n        } else {\n            try {\n                val uri = treeUri\n                if (uri != null) {\n                    val documentFile = DocumentFile.fromTreeUri(App.context, uri)\n                    if (documentFile != null && documentFile.exists()) {\n                        true\n                    } else {\n                        openTreeChooser(fragment)\n                        false\n                    }\n                } else {\n                    openTreeChooser(fragment)\n                    false\n                }\n            } catch (e: IllegalArgumentException) {\n                openTreeChooser(fragment)\n                false\n            }\n\n        }\n    }\n\n    fun getDataUri(file_name: String): Uri? {\n        try {\n            return if (PrefsUtil.downloadType == \"0\") {\n                FileProvider.getUriForFile(App.context, \"${getPackage()}.fileprovider\", if (file_name.startsWith(\"$\")) findFile(file_name) else File(Environment.getExternalStorageDirectory(), \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name))\n            } else {\n                treeUri?.let {\n                    val documentFile = DocumentFile.fromTreeUri(App.context, it)\n                    if (documentFile != null && documentFile.exists()) {\n                        val root = find(documentFile, \"UKIKU/downloads/\" + PatternUtil.getNameFromFile(file_name) + file_name)\n                        return@let root?.uri\n                    }\n                    null\n                }\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            return null\n        }\n\n    }\n\n    @Throws(Exception::class)\n    fun find(root: DocumentFile?, path: String, create: Boolean = true): DocumentFile? {\n        var fRoot = root\n        for (name in path.split(\"/\".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {\n            val file = fRoot?.findFile(name)\n            fRoot = if (file == null || !file.exists()) {\n                if (create)\n                    when {\n                        name.endsWith(\".mp4\") -> fRoot?.createFile(\"video/mp4\", name)\n                        name.endsWith(\".nomedia\") -> fRoot?.createFile(\"application/nomedia\", name)\n                        else -> fRoot?.createDirectory(name)\n                    }\n                fRoot?.findFile(name)\n            } else\n                file\n        }\n        return fRoot\n    }\n\n    fun isUriValid(uri: Uri?): UriValidation {\n        val uriValidation = UriValidation()\n        uri ?: return uriValidation.also { it.errorMessage = \"Uri es nulo\" }\n        if (isSDCardRoot(uri, uriValidation)) {\n            if (isInternalStorage(uri))\n                PrefsUtil.storageType = \"Memoria Interna\"\n            else\n                PrefsUtil.storageType = \"Memoria SD\"\n            App.context.contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)\n            PreferenceManager.getDefaultSharedPreferences(App.context).edit().putString(\"tree_uri\", uri.toString()).apply()\n            uriValidation.isValid = true\n        }\n        return uriValidation\n    }\n\n    fun openTreeChooser(fragment: Fragment) {\n        try {\n            fragment.startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), SD_REQUEST)\n            Log.e(\"FileAccess\", \"On open drocument tree\")\n        } catch (e: Exception) {\n            Toaster.toast(\"Error al buscar SD\")\n        }\n\n    }\n\n    fun openTreeChooser(context: Context) {\n        try {\n            context.findActivity()?.startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), SD_REQUEST)\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)\n                Toaster.toastLong(\"Por favor selecciona un directorio para las descargas\")\n            else\n                Toaster.toastLong(\"Por favor selecciona la raiz del almacenamiento\")\n        } catch (e: Exception) {\n            Toaster.toast(\"Error al buscar SD\")\n        }\n\n    }\n\n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n    private fun isSDCardRoot(uri: Uri, uriValidation: UriValidation): Boolean {\n        return isRootUri(uri, uriValidation) && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q || isExternalStorageDocument(uri, uriValidation))\n    }\n\n    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)\n    private fun isRootUri(uri: Uri, uriValidation: UriValidation): Boolean {\n        return DocumentsContract.getTreeDocumentId(uri).endsWith(\":\")\n                .also {\n                    if (!it) {\n                        Log.e(\"Storage\", \"$uri is not root\")\n                        uriValidation.errorMessage = \"No es la raiz!\"\n                    }\n                } || Build.VERSION.SDK_INT >= Build.VERSION_CODES.R\n    }\n\n    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)\n    private fun isInternalStorage(uri: Uri, uriValidation: UriValidation): Boolean {\n        return isExternalStorageDocument(uri, uriValidation) && DocumentsContract.getTreeDocumentId(uri).contains(\"primary\")\n                .also {\n                    if (it) {\n                        Log.e(\"Storage\", \"$uri is internal storage\")\n                        uriValidation.errorMessage = \"Memoria interna\"\n                    }\n                }\n    }\n\n    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)\n    private fun isInternalStorage(uri: Uri): Boolean {\n        return isExternalStorageDocument(uri) && DocumentsContract.getTreeDocumentId(uri).contains(\"primary\")\n    }\n\n    private fun isExternalStorageDocument(uri: Uri, uriValidation: UriValidation): Boolean {\n        return (\"com.android.externalstorage.documents\" == uri.authority).also {\n            if (!it) {\n                Log.e(\"Storage\", \"$uri is not external storage document\")\n                uriValidation.errorMessage = \"No es almacenamiento externo\"\n            }\n        }\n    }\n\n    private fun isExternalStorageDocument(uri: Uri): Boolean {\n        return (\"com.android.externalstorage.documents\" == uri.authority)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/MultipleDownloadManager.kt",
    "content": "package knf.kuma.download\r\n\r\nimport android.content.Context\r\nimport android.os.Build\r\nimport android.os.StatFs\r\nimport android.text.format.Formatter\r\nimport android.util.Log\r\nimport android.view.View\r\nimport androidx.fragment.app.Fragment\r\nimport knf.kuma.commons.toast\r\nimport knf.kuma.pojos.AnimeObject\r\nimport knf.kuma.videoservers.FileActions\r\n\r\nobject MultipleDownloadManager {\r\n    private const val CHAPTER_SIZE = 160000000L\r\n    private var index = 0\r\n    private var chaptersList: List<AnimeObject.WebInfo.AnimeChapter> = listOf()\r\n    var isLoading = false\r\n    var langSelected = -1\r\n\r\n    fun startDownload(fragment: Fragment, view: View, list: List<AnimeObject.WebInfo.AnimeChapter>, addQueue: Boolean) {\r\n        if (list.isEmpty()) return\r\n        if (!addQueue && !isSpaceAvailable(list.size)) {\r\n            \"Se requieren mínimo ${minSpaceString(fragment.requireContext(), list.size)} libres!\".toast()\r\n            return\r\n        }\r\n        clear(list)\r\n        isLoading = true\r\n        downloadNext(fragment, view, addQueue)\r\n    }\r\n\r\n    private fun downloadNext(fragment: Fragment, view: View, addQueue: Boolean) {\r\n        if (index >= chaptersList.size || !fragment.isAdded || fragment.context == null) {\r\n            isLoading = false\r\n            langSelected = -1\r\n            return\r\n        }\r\n        val current = chaptersList[index]\r\n        val callback: (FileActions.CallbackState, Any?) -> Unit = { state, _ ->\r\n            when (state) {\r\n                FileActions.CallbackState.USER_CANCELLED,\r\n                FileActions.CallbackState.MISSING_PERMISSION,\r\n                FileActions.CallbackState.LOW_STORAGE,\r\n                FileActions.CallbackState.LIFECYCLE_EXPIRED -> {\r\n                    Log.e(\"MultiDownload\", \"Cancel processing\")\r\n                    clear(emptyList())\r\n                }\r\n                FileActions.CallbackState.OPERATION_RUNNING -> {\r\n                    Log.e(\"MultiDownload\", \"Running\")\r\n                }\r\n                else -> {\r\n                    index++\r\n                    downloadNext(fragment, view, addQueue)\r\n                    Log.e(\"MultiDownload\", \"on Next\")\r\n                }\r\n            }\r\n        }\r\n        if (!addQueue)\r\n            FileActions.download(fragment.requireContext(), fragment.viewLifecycleOwner, current, view, callback)\r\n        else\r\n            FileActions.queuedStream(fragment.requireContext(), fragment.viewLifecycleOwner, current, view, callback)\r\n    }\r\n\r\n    private fun clear(list: List<AnimeObject.WebInfo.AnimeChapter>) {\r\n        index = 0\r\n        chaptersList = list\r\n        isLoading = false\r\n        langSelected = -1\r\n    }\r\n\r\n    private fun minSpaceString(context: Context, size: Int): String {\r\n        return Formatter.formatFileSize(context, size * CHAPTER_SIZE)\r\n    }\r\n\r\n    fun isSpaceAvailable(size: Int): Boolean {\r\n        return try {\r\n            getAvailable() > size * CHAPTER_SIZE\r\n        } catch (e: Exception) {\r\n            true\r\n        } || Build.VERSION.SDK_INT >= Build.VERSION_CODES.R\r\n    }\r\n\r\n    private fun getAvailable(): Long {\r\n        val stat = StatFs(FileAccessHelper.rootFile.path)\r\n        return stat.blockSizeLong * stat.availableBlocksLong\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/UriValidation.kt",
    "content": "package knf.kuma.download\r\n\r\nclass UriValidation {\r\n    var errorMessage: String? = null\r\n    var isValid = false\r\n\r\n    override fun toString(): String {\r\n        return errorMessage ?: \"Error desconocido\"\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/download/downloadKt.kt",
    "content": "package knf.kuma.download\r\n\r\nimport android.app.Notification\r\nimport android.app.Service\r\nimport android.app.job.JobInfo\r\nimport android.app.job.JobScheduler\r\nimport android.content.ComponentName\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.content.pm.ServiceInfo\r\nimport android.net.NetworkCapabilities\r\nimport android.net.NetworkRequest\r\nimport android.os.Build\r\nimport androidx.core.content.ContextCompat\r\nimport knf.kuma.ads.AdsUtils\r\nimport knf.kuma.commons.noCrash\r\nimport org.jetbrains.anko.activityManager\r\nimport java.util.Locale\r\n\r\nval isDeviceSamsung: Boolean get() = Build.MANUFACTURER.lowercase(Locale.getDefault()) == \"samsung\"\r\n\r\nfun Context.service(intent: Intent) {\r\n    noCrash {\r\n        if (isDeviceSamsung && AdsUtils.remoteConfigs.getBoolean(\"samsung_disable_foreground\"))\r\n            startService(intent)\r\n        else\r\n            ContextCompat.startForegroundService(this, intent)\r\n    }\r\n}\r\n\r\nfun Context.UIDT(klass: Class<*>) {\r\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {\r\n        val network = NetworkRequest.Builder()\r\n            .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)\r\n            .build()\r\n        val info = JobInfo.Builder(23498, ComponentName(this, klass))\r\n            .setUserInitiated(true)\r\n            .setRequiredNetwork(network)\r\n            .build()\r\n        (getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler).schedule(info)\r\n    }\r\n}\r\n\r\nfun Service.foreground(id: Int, notification: Notification, isDataSync: Boolean = true) {\r\n    noCrash {\r\n        if (isDeviceSamsung && AdsUtils.remoteConfigs.getBoolean(\"samsung_disable_foreground\")) return@noCrash\r\n        if (Build.VERSION.SDK_INT >= 34) {\r\n            startForeground(id, notification, if (isDataSync) ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC else ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)\r\n        } else {\r\n            startForeground(id, notification)\r\n        }\r\n    }\r\n}\r\n\r\nfun Context.isServiceRunning(serviceClass: Class<*>): Boolean{\r\n    activityManager.getRunningServices(Int.MAX_VALUE).forEach {\r\n        if (it.service.className == serviceClass.name)\r\n            return true\r\n    }\r\n    return false\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/AnimeSubObject.kt",
    "content": "package knf.kuma.emision\r\n\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.search.SearchObject\r\n\r\nclass AnimeSubObject : SearchObject() {\r\n    var fileName = \"\"\r\n\r\n    fun getFinalName(): String {\r\n        return if (PrefsUtil.saveWithName)\r\n            fileName\r\n        else\r\n            aid\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/EmissionActivity.kt",
    "content": "package knf.kuma.emision\n\nimport android.app.Activity\nimport android.content.Intent\nimport android.os.Bundle\nimport android.util.Log\nimport android.view.Menu\nimport android.view.MenuItem\nimport com.google.android.material.tabs.TabLayout\nimport knf.kuma.R\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.databinding.ActivityEmisionBinding\nimport java.util.Calendar\n\nclass EmissionActivity : GenericActivity(), TabLayout.OnTabSelectedListener {\n    private var pagerAdapter: EmissionPagerAdapter? = null\n    private val binding by lazy { ActivityEmisionBinding.inflate(layoutInflater) }\n\n    private val currentDay: Int\n        get() {\n            var day = Calendar.getInstance().get(Calendar.DAY_OF_WEEK)\n            day--\n            return when (day) {\n                0 -> 7\n                else -> day\n            }\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(binding.root)\n        binding.toolbar.title = \"Emisión\"\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        binding.toolbar.setNavigationOnClickListener { finish() }\n        binding.pager.offscreenPageLimit = 7\n        pagerAdapter = EmissionPagerAdapter(supportFragmentManager)\n        binding.pager.adapter = pagerAdapter\n        binding.tabs.setupWithViewPager(binding.pager)\n        binding.tabs.addOnTabSelectedListener(this)\n        binding.pager.setCurrentItem(currentDay - 1, true)\n        EAHelper.clear2()\n        showRandomInterstitial(this,PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onResume() {\n        super.onResume()\n        pagerAdapter?.updateChanges()\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_emision, menu)\n        if (PrefsUtil.emissionShowHidden)\n            menu.findItem(R.id.action_hideshow).setIcon(R.drawable.ic_hide_pref)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_hideshow -> {\n                Log.e(\"Emission\", \"On menu click\")\n                val show = PrefsUtil.emissionShowHidden\n                PrefsUtil.emissionShowHidden = !show\n                pagerAdapter?.reloadPages()\n            }\n        }\n        invalidateOptionsMenu()\n        return super.onOptionsItemSelected(item)\n    }\n\n    override fun onTabSelected(tab: TabLayout.Tab) {\n        EAHelper.enter2(getDayByPos(tab.position).toString())\n    }\n\n    override fun onTabUnselected(tab: TabLayout.Tab) {\n\n    }\n\n    override fun onTabReselected(tab: TabLayout.Tab) {\n        EAHelper.enter2(getDayByPos(tab.position).toString())\n    }\n\n    private fun getDayByPos(position: Int): Int {\n        var pos = position + 2\n        if (pos == 8) pos = 1\n        return pos\n    }\n\n    companion object {\n\n        fun open(context: Activity) {\n            context.startActivityForResult(Intent(context, EmissionActivity::class.java), 4987)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/EmissionActivityMaterial.kt",
    "content": "package knf.kuma.emision\n\nimport android.app.Activity\nimport android.content.Intent\nimport android.os.Bundle\nimport android.util.Log\nimport android.view.Menu\nimport android.view.MenuItem\nimport com.google.android.material.tabs.TabLayout\nimport knf.kuma.R\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.databinding.ActivityEmisionMaterialBinding\nimport java.util.Calendar\n\nclass EmissionActivityMaterial : GenericActivity(), TabLayout.OnTabSelectedListener {\n    private var pagerAdapter: EmissionPagerAdapterMaterial? = null\n    private val binding by lazy { ActivityEmisionMaterialBinding.inflate(layoutInflater) }\n\n    private val currentDay: Int\n        get() {\n            var day = Calendar.getInstance().get(Calendar.DAY_OF_WEEK)\n            day--\n            return when (day) {\n                0 -> 7\n                else -> day\n            }\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(binding.root)\n        binding.toolbar.title = \"Emisión\"\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        binding.toolbar.setNavigationOnClickListener { finish() }\n        binding.pager.offscreenPageLimit = 7\n        pagerAdapter = EmissionPagerAdapterMaterial(supportFragmentManager)\n        binding.pager.adapter = pagerAdapter\n        binding.tabs.setupWithViewPager(binding.pager)\n        binding.tabs.addOnTabSelectedListener(this)\n        binding.pager.setCurrentItem(currentDay - 1, true)\n        EAHelper.clear2()\n        showRandomInterstitial(this,PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onResume() {\n        super.onResume()\n        pagerAdapter?.updateChanges()\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_emision, menu)\n        if (PrefsUtil.emissionShowHidden)\n            menu.findItem(R.id.action_hideshow).setIcon(R.drawable.ic_hide_pref)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_hideshow -> {\n                Log.e(\"Emission\", \"On menu click\")\n                val show = PrefsUtil.emissionShowHidden\n                PrefsUtil.emissionShowHidden = !show\n                pagerAdapter?.reloadPages()\n            }\n        }\n        invalidateOptionsMenu()\n        return super.onOptionsItemSelected(item)\n    }\n\n    override fun onTabSelected(tab: TabLayout.Tab) {\n        EAHelper.enter2(getDayByPos(tab.position).toString())\n    }\n\n    override fun onTabUnselected(tab: TabLayout.Tab) {\n\n    }\n\n    override fun onTabReselected(tab: TabLayout.Tab) {\n        EAHelper.enter2(getDayByPos(tab.position).toString())\n    }\n\n    private fun getDayByPos(position: Int): Int {\n        var pos = position + 2\n        if (pos == 8) pos = 1\n        return pos\n    }\n\n    companion object {\n\n        fun open(context: Activity) {\n            context.startActivityForResult(Intent(context, EmissionActivityMaterial::class.java), 4987)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/EmissionAdapter.kt",
    "content": "package knf.kuma.emision\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.Observer\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.distinct\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.load\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.custom.HiddenOverlay\nimport knf.kuma.database.CacheDB\nimport knf.kuma.search.SearchObjectFav\nimport knf.kuma.widgets.emision.WEmisionProvider\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\n\n\nclass EmissionAdapter internal constructor(private val fragment: Fragment) : RecyclerView.Adapter<EmissionAdapter.EmissionItem>() {\n\n    val removeListener = fragment as RemoveListener\n    var list: MutableList<SearchObjectFav> = ArrayList()\n\n    private var blacklist: MutableSet<String> = PrefsUtil.emissionBlacklist\n    private var showHidden: Boolean = PrefsUtil.emissionShowHidden\n    private val showHeart = PrefsUtil.emissionShowFavs\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EmissionItem {\n        return EmissionItem(LayoutInflater.from(parent.context).inflate(R.layout.item_emision, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: EmissionItem, position: Int) {\n        val animeObject = list[position]\n        holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n        holder.title.text = animeObject.name\n        holder.hiddenOverlay.setHidden(blacklist.contains(animeObject.aid), false)\n        holder.heart.visibility = when {\n            showHeart && animeObject.isFav -> View.VISIBLE\n            else -> View.GONE\n        }\n        //holder.observeFav(fragment, animeObject.aid, showHeart)\n        holder.cardView.setOnClickListener { ActivityAnime.open(fragment, animeObject, holder.imageView, false, animate = true) }\n        holder.cardView.setOnLongClickListener {\n            val removed: Boolean = if (blacklist.contains(animeObject.aid)) {\n                updateList(true, animeObject.aid)\n                true\n            } else {\n                updateList(false, animeObject.aid)\n                false\n            }\n            if (showHidden) {\n                holder.hiddenOverlay.setHidden(!removed, true)\n            } else if (!removed) {\n                remove(holder.adapterPosition)\n            }\n            true\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(newList: MutableList<SearchObjectFav>, animate: Boolean = true, callback: () -> Unit) {\n        if (list notSameContent newList)\n            if (PrefsUtil.useSmoothAnimations && newList.isNotEmpty())\n                doAsync {\n                    blacklist = PrefsUtil.emissionBlacklist\n                    showHidden = PrefsUtil.emissionShowHidden\n                    val result = if (animate) DiffUtil.calculateDiff(EmissionDiff(list, newList), true) else null\n                    list = newList\n                    fragment.doOnUI {\n                        try {\n                            if (animate)\n                                result?.dispatchUpdatesTo(this@EmissionAdapter)\n                            else\n                                notifyDataSetChanged()\n                        } catch (e: Exception) {\n                            e.printStackTrace()\n                            notifyDataSetChanged()\n                        }\n                        callback.invoke()\n                    }\n                }\n            else {\n                blacklist = PrefsUtil.emissionBlacklist\n                showHidden = PrefsUtil.emissionShowHidden\n                list = newList\n                notifyDataSetChanged()\n            }\n    }\n\n    private fun updateList(remove: Boolean, aid: String) {\n        this.blacklist = LinkedHashSet(PrefsUtil.emissionBlacklist)\n        if (remove)\n            blacklist.remove(aid)\n        else\n            blacklist.add(aid)\n        PrefsUtil.emissionBlacklist = blacklist\n        WEmisionProvider.update(fragment.context)\n    }\n\n    fun remove(position: Int) {\n        if (position >= 0 && position <= list.size - 1) {\n            list.removeAt(position)\n            notifyItemRemoved(position)\n            removeListener.onRemove(list.size <= 0)\n        }\n    }\n\n    class EmissionItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView = itemView.find(R.id.card)\n        val imageView: ImageView = itemView.find(R.id.img)\n        val hiddenOverlay: HiddenOverlay = itemView.find(R.id.hidden)\n        val heart: ImageView = itemView.find(R.id.heart)\n        val title: TextView = itemView.find(R.id.title)\n\n        private lateinit var liveData: LiveData<Boolean>\n        private lateinit var observer: Observer<Boolean>\n\n        fun observeFav(fragment: Fragment, aid: String, show: Boolean) {\n            if (::liveData.isInitialized && ::observer.isInitialized)\n                liveData.removeObserver(observer)\n            if (!show) {\n                heart.visibility = View.GONE\n                return\n            }\n            liveData = CacheDB.INSTANCE.favsDAO().isFavLive(aid.toInt()).distinct\n            observer = Observer {\n                if (!PrefsUtil.emissionShowFavs)\n                    heart.visibility = View.GONE\n                else\n                    heart.visibility = if (it) View.VISIBLE else View.GONE\n            }\n            liveData.observe(fragment, observer)\n        }\n    }\n}\n\ninternal class EmissionDiff(\n        private val oldList: MutableList<SearchObjectFav>,\n        private val newList: MutableList<SearchObjectFav>) : DiffUtil.Callback() {\n\n    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {\n        return oldList[oldItemPosition] == newList[newItemPosition]\n    }\n\n    override fun getOldListSize(): Int {\n        return oldList.size\n    }\n\n    override fun getNewListSize(): Int {\n        return newList.size\n    }\n\n    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {\n        return oldList[oldItemPosition].isFav == newList[newItemPosition].isFav\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/EmissionAdapterMaterial.kt",
    "content": "package knf.kuma.emision\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.Observer\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.distinct\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.load\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.custom.HiddenOverlay\nimport knf.kuma.database.CacheDB\nimport knf.kuma.search.SearchObjectFav\nimport knf.kuma.widgets.emision.WEmisionProvider\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\n\n\nclass EmissionAdapterMaterial internal constructor(private val fragment: Fragment) : RecyclerView.Adapter<EmissionAdapterMaterial.EmissionItem>() {\n\n    val removeListener = fragment as RemoveListener\n    var list: MutableList<SearchObjectFav> = ArrayList()\n\n    private var blacklist: MutableSet<String> = PrefsUtil.emissionBlacklist\n    private var showHidden: Boolean = PrefsUtil.emissionShowHidden\n    private val showHeart = PrefsUtil.emissionShowFavs\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EmissionItem {\n        return EmissionItem(LayoutInflater.from(parent.context).inflate(R.layout.item_emision_material, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: EmissionItem, position: Int) {\n        val animeObject = list[position]\n        holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n        holder.title.text = animeObject.name\n        holder.hiddenOverlay.setHidden(blacklist.contains(animeObject.aid), false)\n        holder.heart.visibility = when {\n            showHeart && animeObject.isFav -> View.VISIBLE\n            else -> View.GONE\n        }\n        //holder.observeFav(fragment, animeObject.aid, showHeart)\n        holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(fragment, animeObject, holder.imageView, false, animate = true) }\n        holder.cardView.setOnLongClickListener {\n            val removed: Boolean = if (blacklist.contains(animeObject.aid)) {\n                updateList(true, animeObject.aid)\n                true\n            } else {\n                updateList(false, animeObject.aid)\n                false\n            }\n            if (showHidden) {\n                holder.hiddenOverlay.setHidden(!removed, true)\n            } else if (!removed) {\n                remove(holder.adapterPosition)\n            }\n            true\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(newList: MutableList<SearchObjectFav>, animate: Boolean = true, callback: () -> Unit) {\n        if (list notSameContent newList)\n            if (PrefsUtil.useSmoothAnimations && newList.isNotEmpty())\n                doAsync {\n                    blacklist = PrefsUtil.emissionBlacklist\n                    showHidden = PrefsUtil.emissionShowHidden\n                    val result = if (animate) DiffUtil.calculateDiff(EmissionDiff(list, newList), true) else null\n                    list = newList\n                    fragment.doOnUI {\n                        try {\n                            if (animate)\n                                result?.dispatchUpdatesTo(this@EmissionAdapterMaterial)\n                            else\n                                notifyDataSetChanged()\n                        } catch (e: Exception) {\n                            e.printStackTrace()\n                            notifyDataSetChanged()\n                        }\n                        callback.invoke()\n                    }\n                }\n            else {\n                blacklist = PrefsUtil.emissionBlacklist\n                showHidden = PrefsUtil.emissionShowHidden\n                list = newList\n                notifyDataSetChanged()\n            }\n    }\n\n    private fun updateList(remove: Boolean, aid: String) {\n        this.blacklist = LinkedHashSet(PrefsUtil.emissionBlacklist)\n        if (remove)\n            blacklist.remove(aid)\n        else\n            blacklist.add(aid)\n        PrefsUtil.emissionBlacklist = blacklist\n        WEmisionProvider.update(fragment.context)\n    }\n\n    fun remove(position: Int) {\n        if (position >= 0 && position <= list.size - 1) {\n            list.removeAt(position)\n            notifyItemRemoved(position)\n            removeListener.onRemove(list.size <= 0)\n        }\n    }\n\n    class EmissionItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View = itemView.find(R.id.card)\n        val imageView: ImageView = itemView.find(R.id.img)\n        val hiddenOverlay: HiddenOverlay = itemView.find(R.id.hidden)\n        val heart: View = itemView.find(R.id.heart)\n        val title: TextView = itemView.find(R.id.title)\n\n        private lateinit var liveData: LiveData<Boolean>\n        private lateinit var observer: Observer<Boolean>\n\n        fun observeFav(fragment: Fragment, aid: String, show: Boolean) {\n            if (::liveData.isInitialized && ::observer.isInitialized)\n                liveData.removeObserver(observer)\n            if (!show) {\n                heart.visibility = View.GONE\n                return\n            }\n            liveData = CacheDB.INSTANCE.favsDAO().isFavLive(aid.toInt()).distinct\n            observer = Observer {\n                if (!PrefsUtil.emissionShowFavs)\n                    heart.visibility = View.GONE\n                else\n                    heart.visibility = if (it) View.VISIBLE else View.GONE\n            }\n            liveData.observe(fragment, observer)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/EmissionFragment.kt",
    "content": "package knf.kuma.emision\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.distinct\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.RecyclerEmisionBinding\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.search.SearchObject\nimport knf.kuma.search.forFav\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass EmissionFragment : Fragment(), RemoveListener {\n    private var adapter: EmissionAdapter? = null\n    private var isFirst = true\n\n    private lateinit var binding: RecyclerEmisionBinding\n    private lateinit var liveData: LiveData<MutableList<SearchObject>>\n    private lateinit var observer: Observer<MutableList<SearchObject>>\n\n    private val blacklist: Set<String>\n        get() = if (PrefsUtil.emissionShowHidden)\n            LinkedHashSet()\n        else\n            PrefsUtil.emissionBlacklist\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return LayoutInflater.from(context).inflate(R.layout.recycler_emision, container, false).also {\n            binding = RecyclerEmisionBinding.bind(it)\n        }\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        lifecycleScope.launch(Dispatchers.IO) {\n            delay(1000)\n            binding.adContainer.implBanner(AdsType.EMISSION_BANNER, true)\n        }\n    }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        adapter = EmissionAdapter(this)\n        binding.recycler.verifyManager()\n        binding.recycler.adapter = adapter\n        if (context != null)\n            observeList(Observer { animeObjects ->\n                lifecycleScope.launch(Dispatchers.Main){\n                    binding.progress.visibility = View.GONE\n                    adapter?.update(withContext(Dispatchers.IO) { animeObjects.map { it.forFav() }.toMutableList() }, false) { smoothScroll() }\n                    if (isFirst) {\n                        isFirst = false\n                        binding.recycler.scheduleLayoutAnimation()\n                        //checkStates(animeObjects)\n                    }\n                    binding.error.visibility = if (animeObjects.isEmpty()) View.VISIBLE else View.GONE\n                }\n            })\n    }\n\n    private fun observeList(obs: Observer<MutableList<SearchObject>>) {\n        if (::liveData.isInitialized && ::observer.isInitialized)\n            liveData.removeObserver(observer)\n        liveData = CacheDB.INSTANCE.animeDAO().getByDay(arguments?.getInt(\"day\", 1)\n                ?: 1, blacklist).distinct\n        observer = obs\n        liveData.observe(viewLifecycleOwner, observer)\n    }\n\n    override fun onRemove(showError: Boolean) {\n        if (showError) lifecycleScope.launch(Dispatchers.Main) { binding.error.visibility = View.VISIBLE }\n    }\n\n    private fun smoothScroll() {\n        //recycler.layoutManager?.smoothScrollToPosition(recycler,null,0)\n    }\n\n    fun updateChanges() {\n        lifecycleScope.launch(Dispatchers.Main) { adapter?.notifyDataSetChanged() }\n    }\n\n    internal fun reloadList() {\n        if (context != null)\n            observeList { animeObjects ->\n                lifecycleScope.launch(Dispatchers.Main) {\n                    binding.error.visibility = View.GONE\n                    if (animeObjects != null && animeObjects.isNotEmpty())\n                        adapter?.update(withContext(Dispatchers.IO) { animeObjects.map { it.forFav() }.toMutableList() }) { smoothScroll() }\n                    else\n                        adapter?.update(ArrayList()) { smoothScroll() }\n                    if (animeObjects == null || animeObjects.isEmpty())\n                        binding.error.visibility = View.VISIBLE\n                }\n            }\n    }\n\n    companion object {\n\n        operator fun get(day: AnimeObject.Day): EmissionFragment {\n            val bundle = Bundle()\n            bundle.putInt(\"day\", day.value)\n            val fragment = EmissionFragment()\n            fragment.arguments = bundle\n            return fragment\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/EmissionFragmentMaterial.kt",
    "content": "package knf.kuma.emision\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.distinct\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.RecyclerEmisionBinding\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.search.SearchObject\nimport knf.kuma.search.forFav\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass EmissionFragmentMaterial : Fragment(), RemoveListener {\n    private var adapter: EmissionAdapterMaterial? = null\n    private var isFirst = true\n\n    private lateinit var binding: RecyclerEmisionBinding\n    private lateinit var liveData: LiveData<MutableList<SearchObject>>\n    private lateinit var observer: Observer<MutableList<SearchObject>>\n\n    private val blacklist: Set<String>\n        get() = if (PrefsUtil.emissionShowHidden)\n            LinkedHashSet()\n        else\n            PrefsUtil.emissionBlacklist\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return LayoutInflater.from(context).inflate(R.layout.recycler_emision, container, false).also {\n            binding = RecyclerEmisionBinding.bind(it)\n        }\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        lifecycleScope.launch(Dispatchers.IO) {\n            delay(1000)\n            binding.adContainer.implBanner(AdsType.EMISSION_BANNER, true)\n        }\n    }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        adapter = EmissionAdapterMaterial(this)\n        binding.recycler.verifyManager()\n        binding.recycler.adapter = adapter\n        if (context != null)\n            observeList { animeObjects ->\n                lifecycleScope.launch(Dispatchers.Main) {\n                    binding.progress.visibility = View.GONE\n                    adapter?.update(withContext(Dispatchers.IO) { animeObjects.map { it.forFav() }.toMutableList() }, false) { smoothScroll() }\n                    if (isFirst) {\n                        isFirst = false\n                        binding.recycler.scheduleLayoutAnimation()\n                        //checkStates(animeObjects)\n                    }\n                    binding.error.visibility = if (animeObjects.isEmpty()) View.VISIBLE else View.GONE\n                }\n            }\n    }\n\n    private fun observeList(obs: Observer<MutableList<SearchObject>>) {\n        if (::liveData.isInitialized && ::observer.isInitialized)\n            liveData.removeObserver(observer)\n        liveData = CacheDB.INSTANCE.animeDAO().getByDay(arguments?.getInt(\"day\", 1)\n                ?: 1, blacklist).distinct\n        observer = obs\n        liveData.observe(viewLifecycleOwner, observer)\n    }\n\n    override fun onRemove(showError: Boolean) {\n        if (showError) lifecycleScope.launch(Dispatchers.Main) { binding.error.visibility = View.VISIBLE }\n    }\n\n    private fun smoothScroll() {\n        //recycler.layoutManager?.smoothScrollToPosition(recycler,null,0)\n    }\n\n    fun updateChanges() {\n        lifecycleScope.launch(Dispatchers.Main) { adapter?.notifyDataSetChanged() }\n    }\n\n    internal fun reloadList() {\n        if (context != null)\n            observeList { animeObjects ->\n                lifecycleScope.launch(Dispatchers.Main) {\n                    binding.error.visibility = View.GONE\n                    if (animeObjects != null && animeObjects.isNotEmpty())\n                        adapter?.update(withContext(Dispatchers.IO) { animeObjects.map { it.forFav() }.toMutableList() }) { smoothScroll() }\n                    else\n                        adapter?.update(ArrayList()) { smoothScroll() }\n                    if (animeObjects == null || animeObjects.isEmpty())\n                        binding.error.visibility = View.VISIBLE\n                }\n            }\n    }\n\n    companion object {\n\n        operator fun get(day: AnimeObject.Day): EmissionFragmentMaterial {\n            val bundle = Bundle()\n            bundle.putInt(\"day\", day.value)\n            val fragment = EmissionFragmentMaterial()\n            fragment.arguments = bundle\n            return fragment\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/EmissionPagerAdapter.kt",
    "content": "package knf.kuma.emision\n\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.fragment.app.FragmentPagerAdapter\nimport knf.kuma.pojos.AnimeObject\n\nclass EmissionPagerAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm) {\n\n    private val monday = EmissionFragment[AnimeObject.Day.MONDAY]\n    private val tuesday = EmissionFragment[AnimeObject.Day.TUESDAY]\n    private val wednesday = EmissionFragment[AnimeObject.Day.WEDNESDAY]\n    private val thursday = EmissionFragment[AnimeObject.Day.THURSDAY]\n    private val friday = EmissionFragment[AnimeObject.Day.FRIDAY]\n    private val saturday = EmissionFragment[AnimeObject.Day.SATURDAY]\n    private val sunday = EmissionFragment[AnimeObject.Day.SUNDAY]\n\n    override fun getCount(): Int {\n        return 7\n    }\n\n    override fun getPageTitle(position: Int): CharSequence? {\n        return when (position) {\n            0 -> \"Lunes\"\n            1 -> \"Martes\"\n            2 -> \"Miércoles\"\n            3 -> \"Jueves\"\n            4 -> \"Viernes\"\n            5 -> \"Sábado\"\n            6 -> \"Domingo\"\n            else -> \"Lunes\"\n        }\n    }\n\n    override fun getItem(position: Int): Fragment {\n        return when (position) {\n            0 -> monday\n            1 -> tuesday\n            2 -> wednesday\n            3 -> thursday\n            4 -> friday\n            5 -> saturday\n            6 -> sunday\n            else -> monday\n        }\n    }\n\n    fun updateChanges() {\n        monday.updateChanges()\n        tuesday.updateChanges()\n        wednesday.updateChanges()\n        thursday.updateChanges()\n        friday.updateChanges()\n        saturday.updateChanges()\n        sunday.updateChanges()\n    }\n\n    fun reloadPages() {\n        monday.reloadList()\n        tuesday.reloadList()\n        wednesday.reloadList()\n        thursday.reloadList()\n        friday.reloadList()\n        saturday.reloadList()\n        sunday.reloadList()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/EmissionPagerAdapterMaterial.kt",
    "content": "package knf.kuma.emision\n\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.fragment.app.FragmentPagerAdapter\nimport knf.kuma.pojos.AnimeObject\n\nclass EmissionPagerAdapterMaterial internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {\n\n    private val monday = EmissionFragmentMaterial[AnimeObject.Day.MONDAY]\n    private val tuesday = EmissionFragmentMaterial[AnimeObject.Day.TUESDAY]\n    private val wednesday = EmissionFragmentMaterial[AnimeObject.Day.WEDNESDAY]\n    private val thursday = EmissionFragmentMaterial[AnimeObject.Day.THURSDAY]\n    private val friday = EmissionFragmentMaterial[AnimeObject.Day.FRIDAY]\n    private val saturday = EmissionFragmentMaterial[AnimeObject.Day.SATURDAY]\n    private val sunday = EmissionFragmentMaterial[AnimeObject.Day.SUNDAY]\n\n    override fun getCount(): Int {\n        return 7\n    }\n\n    override fun getPageTitle(position: Int): CharSequence? {\n        return when (position) {\n            0 -> \"Lunes\"\n            1 -> \"Martes\"\n            2 -> \"Miércoles\"\n            3 -> \"Jueves\"\n            4 -> \"Viernes\"\n            5 -> \"Sábado\"\n            6 -> \"Domingo\"\n            else -> \"Lunes\"\n        }\n    }\n\n    override fun getItem(position: Int): Fragment {\n        return when (position) {\n            0 -> monday\n            1 -> tuesday\n            2 -> wednesday\n            3 -> thursday\n            4 -> friday\n            5 -> saturday\n            6 -> sunday\n            else -> monday\n        }\n    }\n\n    fun updateChanges() {\n        monday.updateChanges()\n        tuesday.updateChanges()\n        wednesday.updateChanges()\n        thursday.updateChanges()\n        friday.updateChanges()\n        saturday.updateChanges()\n        sunday.updateChanges()\n    }\n\n    fun reloadPages() {\n        monday.reloadList()\n        tuesday.reloadList()\n        wednesday.reloadList()\n        thursday.reloadList()\n        friday.reloadList()\n        saturday.reloadList()\n        sunday.reloadList()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/emision/RemoveListener.kt",
    "content": "package knf.kuma.emision\r\n\r\ninterface RemoveListener {\r\n    fun onRemove(showError: Boolean)\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/DownloadingAdapter.kt",
    "content": "package knf.kuma.explorer\n\nimport android.annotation.SuppressLint\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.Button\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.Observer\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.R\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeShow\nimport knf.kuma.database.CacheDB\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.pojos.DownloadObject\nimport org.jetbrains.anko.find\nimport java.util.Locale\n\nclass DownloadingAdapter internal constructor(private val fragment: Fragment, private val downloadObjects: MutableList<DownloadObject>) : RecyclerView.Adapter<DownloadingAdapter.DownloadingItem>() {\n    private val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n\n    override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): DownloadingItem {\n        return DownloadingItem(LayoutInflater.from(viewGroup.context).inflate(R.layout.item_downloading_extra, viewGroup, false))\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onBindViewHolder(holder: DownloadingItem, position: Int) {\n        val downloadObject = downloadObjects[position]\n        holder.server.text = downloadObject.downloadServer\n        holder.title.text = downloadObject.name\n        holder.chapter.text = downloadObject.chapter\n        holder.eta.text = downloadObject.subtext\n        holder.progress.max = 100\n        holder.action.visibility = if (downloadObject.canResume) View.VISIBLE else View.INVISIBLE\n        if (downloadObject.state == DownloadObject.PENDING) {\n            holder.eta.visibility = View.GONE\n            holder.progress.isIndeterminate = true\n            holder.progress.progress = 0\n        } else {\n            if (downloadObject.state == DownloadObject.PAUSED)\n                holder.eta.visibility = View.GONE\n            else\n                holder.eta.visibility = View.VISIBLE\n            holder.progress.isIndeterminate = false\n            holder.progress.progress = downloadObject.progress\n        }\n        holder.action.setOnClickListener {\n            if (downloadObject.state == DownloadObject.DOWNLOADING) {\n                downloadObject.state = DownloadObject.PAUSED\n                holder.action.text = \"REANUDAR\"\n                DownloadManagerCentral.pause(downloadObject)\n            } else if (downloadObject.state == DownloadObject.PAUSED) {\n                downloadObject.state = DownloadObject.PENDING\n                holder.action.text = \"PAUSAR\"\n                DownloadManagerCentral.resume(downloadObject)\n            }\n        }\n        holder.cancel.setOnClickListener {\n            fragment.context?.let {\n                MaterialDialog(it).safeShow {\n                    message(text = \"¿Cancelar descarga del ${downloadObject.chapter.lowercase(Locale.getDefault())} de ${downloadObject.name}?\")\n                    positiveButton(text = \"CONFIRMAR\") {\n                        try {\n                            downloadObjects.removeAt(holder.bindingAdapterPosition)\n                            notifyItemRemoved(holder.bindingAdapterPosition)\n                            DownloadManagerCentral.cancel(downloadObject.eid)\n                        } catch (_: Exception) {\n                            //\n                        }\n                    }\n                    negativeButton(text = \"CANCELAR\")\n                }\n            }\n        }\n        downloadsDAO.getLiveByKey(downloadObject.key).observe(fragment, Observer { downloadObject1 ->\n            try {\n                if (downloadObject1 == null || downloadObject1.state == DownloadObject.COMPLETED) {\n                    downloadObjects.removeAt(holder.bindingAdapterPosition)\n                    notifyItemRemoved(holder.bindingAdapterPosition)\n                } else {\n                    downloadObject.state = downloadObject1.state\n                    if (downloadObject1.state == DownloadObject.PENDING) {\n                        holder.eta.visibility = View.GONE\n                        holder.progress.isIndeterminate = true\n                        holder.progress.progress = 0\n                    } else {\n                        when (downloadObject.state) {\n                            DownloadObject.DOWNLOADING -> {\n                                holder.action.text = \"PAUSAR\"\n                                holder.eta.visibility = View.VISIBLE\n                            }\n                            DownloadObject.PAUSED -> {\n                                holder.action.text = \"REANUDAR\"\n                                holder.eta.visibility = View.GONE\n                            }\n                        }\n                        holder.progress.isIndeterminate = false\n                        if (downloadObject1.getEta() == -2L || PrefsUtil.downloaderType == 0)\n                            holder.progress.setProgress(downloadObject1.progress, true)\n                        else {\n                            holder.progress.progress = 0\n                            holder.progress.secondaryProgress = downloadObject1.progress\n                        }\n                        holder.eta.text = downloadObject1.subtext\n                    }\n                }\n            } catch (_: Exception) {\n                //\n            }\n        })\n    }\n\n    override fun getItemCount(): Int {\n        return downloadObjects.size\n    }\n\n    fun remove(eid: String) {\n        ArrayList(downloadObjects).forEachIndexed { index, downloadObject ->\n            if (downloadObject.eid == eid) {\n                downloadObjects.removeAt(index)\n                fragment.doOnUI { notifyItemRemoved(index) }\n                return\n            }\n        }\n    }\n\n    class DownloadingItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val server: TextView = itemView.find(R.id.server)\n        val title: TextView = itemView.find(R.id.title)\n        val chapter: TextView = itemView.find(R.id.chapter)\n        val eta: TextView = itemView.find(R.id.eta)\n        val action: Button = itemView.find(R.id.action)\n        val cancel: Button = itemView.find(R.id.cancel)\n        val progress: ProgressBar = itemView.find(R.id.progress)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/DownloadingAdapterMaterial.kt",
    "content": "package knf.kuma.explorer\n\nimport android.annotation.SuppressLint\nimport android.os.Build\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.Observer\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.R\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.onClickMenu\nimport knf.kuma.commons.safeShow\nimport knf.kuma.database.CacheDB\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.pojos.DownloadObject\nimport org.jetbrains.anko.find\nimport java.util.Locale\n\nclass DownloadingAdapterMaterial internal constructor(private val fragment: Fragment, private val downloadObjects: MutableList<DownloadObject>) : RecyclerView.Adapter<DownloadingAdapterMaterial.DownloadingItem>() {\n    private val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n\n    override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): DownloadingItem {\n        return DownloadingItem(LayoutInflater.from(viewGroup.context).inflate(R.layout.item_downloading_extra_material, viewGroup, false))\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onBindViewHolder(holder: DownloadingItem, position: Int) {\n        val downloadObject = downloadObjects[position]\n        holder.server.text = downloadObject.downloadServer\n        holder.title.text = downloadObject.name\n        holder.chapter.text = downloadObject.chapter\n        holder.eta.text = downloadObject.subtext\n        holder.progress.max = 100\n        if (downloadObject.state == DownloadObject.PENDING) {\n            holder.eta.visibility = View.GONE\n            holder.progress.isIndeterminate = true\n            holder.progress.progress = 0\n        } else {\n            if (downloadObject.state == DownloadObject.PAUSED)\n                holder.eta.visibility = View.GONE\n            else\n                holder.eta.visibility = View.VISIBLE\n            holder.progress.isIndeterminate = false\n            holder.progress.progress = downloadObject.progress\n        }\n        holder.actionMenu.onClickMenu(R.menu.menu_download_options,hideItems = { downloadObject.getDisabledOptions() }){ item ->\n            when(item.itemId){\n                R.id.pause -> {\n                    downloadObject.state = DownloadObject.PAUSED\n                    DownloadManagerCentral.pause(downloadObject)\n                }\n                R.id.resume -> {\n                    downloadObject.state = DownloadObject.PENDING\n                    DownloadManagerCentral.resume(downloadObject)\n                }\n                R.id.cancel -> {\n                    fragment.context?.let {\n                        MaterialDialog(it).safeShow {\n                            message(text = \"¿Cancelar descarga del ${downloadObject.chapter.lowercase(Locale.getDefault())} de ${downloadObject.name}?\")\n                            positiveButton(text = \"CONFIRMAR\") {\n                                try {\n                                    downloadObjects.removeAt(holder.adapterPosition)\n                                    notifyItemRemoved(holder.adapterPosition)\n                                    DownloadManagerCentral.cancel(downloadObject.eid)\n                                } catch (e: Exception) {\n                                    //\n                                }\n                            }\n                            negativeButton(text = \"CANCELAR\")\n                        }\n                    }\n                }\n            }\n        }\n        downloadsDAO.getLiveByKey(downloadObject.key).observe(fragment, Observer { downloadObject1 ->\n            try {\n                if (downloadObject1 == null || downloadObject1.state == DownloadObject.COMPLETED) {\n                    downloadObjects.removeAt(holder.adapterPosition)\n                    notifyItemRemoved(holder.adapterPosition)\n                } else {\n                    downloadObject.state = downloadObject1.state\n                    if (downloadObject1.state == DownloadObject.PENDING) {\n                        holder.eta.visibility = View.GONE\n                        holder.progress.isIndeterminate = true\n                        holder.progress.progress = 0\n                    } else {\n                        holder.progress.isIndeterminate = false\n                        if (downloadObject1.getEta() == -2L || PrefsUtil.downloaderType == 0)\n                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)\n                                holder.progress.setProgress(downloadObject1.progress, true)\n                            else\n                                holder.progress.progress = downloadObject1.progress\n                        else {\n                            holder.progress.progress = 0\n                            holder.progress.secondaryProgress = downloadObject1.progress\n                        }\n                        holder.eta.visibility = View.VISIBLE\n                        holder.eta.text = downloadObject1.subtext\n                    }\n                }\n            } catch (e: Exception) {\n                //\n            }\n        })\n    }\n\n    override fun getItemCount(): Int {\n        return downloadObjects.size\n    }\n\n    fun remove(eid: String) {\n        ArrayList(downloadObjects).forEachIndexed { index, downloadObject ->\n            if (downloadObject.eid == eid) {\n                downloadObjects.removeAt(index)\n                fragment.doOnUI { notifyItemRemoved(index) }\n                return\n            }\n        }\n    }\n\n    private fun DownloadObject.getDisabledOptions(): List<Int> {\n        val list = mutableListOf<Int>()\n        if (canResume && (state == DownloadObject.DOWNLOADING || state == DownloadObject.PAUSED)){\n            if (state == DownloadObject.DOWNLOADING)\n                list.add(R.id.resume)\n            if (state == DownloadObject.PAUSED)\n                list.add(R.id.pause)\n        }else{\n            list.add(R.id.resume)\n            list.add(R.id.pause)\n        }\n        return list\n    }\n\n    class DownloadingItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val server: TextView = itemView.find(R.id.server)\n        val title: TextView = itemView.find(R.id.title)\n        val chapter: TextView = itemView.find(R.id.chapter)\n        val eta: TextView = itemView.find(R.id.eta)\n        val actionMenu: View = itemView.find(R.id.actionMenu)\n        val progress: ProgressBar = itemView.find(R.id.progress)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerActivity.kt",
    "content": "package knf.kuma.explorer\n\nimport androidx.activity.addCallback\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport knf.kuma.R\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.databinding.ActivityExplorerBinding\n\nclass ExplorerActivity : GenericActivity(), OnFileStateChange {\n    private val binding by lazy { ActivityExplorerBinding.inflate(layoutInflater) }\n    private var adapter: ExplorerPagerAdapter? = null\n    private var isExplorerFiles = true\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(binding.root)\n        binding.toolbar.title = \"Explorador\"\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\n        if (savedInstanceState == null)\n            ExplorerCreator.onDestroy()\n        binding.pager.offscreenPageLimit = 2\n        adapter = ExplorerPagerAdapter(this, supportFragmentManager)\n        binding.pager.adapter = adapter\n        binding.tabs.setupWithViewPager(binding.pager)\n        onBackPressedDispatcher.addCallback(this) {\n            val currentFragment = adapter?.getItem(binding.pager.currentItem) as? FragmentBase\n            if (currentFragment?.onBackPressed() != true) {\n                isEnabled = false\n                onBackPressedDispatcher.onBackPressed()\n                isEnabled = true\n            }\n        }\n        showRandomInterstitial(this, PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_explorer_connected, menu)\n        if (isExplorerFiles)\n            menu.findItem(R.id.delete_all).isVisible = false\n        CastUtil.registerActivity(this, menu, R.id.castMenu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.delete_all -> adapter?.onRemoveAllClicked()\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    override fun onChange(isFile: Boolean) {\n        isExplorerFiles = isFile\n        invalidateOptionsMenu()\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n        ThumbServer.stop()\n    }\n\n    companion object {\n        @JvmStatic\n        fun open(context: Context) {\n            context.startActivity(Intent(context, ExplorerActivity::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerActivityMaterial.kt",
    "content": "package knf.kuma.explorer\n\nimport androidx.activity.addCallback\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport knf.kuma.R\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.databinding.ActivityExplorerMaterialBinding\n\nclass ExplorerActivityMaterial : GenericActivity(), OnFileStateChange {\n    private val binding by lazy { ActivityExplorerMaterialBinding.inflate(layoutInflater) }\n    private var adapter: ExplorerPagerAdapterMaterial? = null\n    private var isExplorerFiles = true\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(binding.root)\n        binding.toolbar.title = \"Explorador\"\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\n        if (savedInstanceState == null)\n            ExplorerCreator.onDestroy()\n        binding.pager.offscreenPageLimit = 2\n        adapter = ExplorerPagerAdapterMaterial(this, supportFragmentManager)\n        binding.pager.adapter = adapter\n        binding.tabs.setupWithViewPager(binding.pager)\n        onBackPressedDispatcher.addCallback(this) {\n            val currentFragment = adapter?.getItem(binding.pager.currentItem) as? FragmentBase\n            if (currentFragment?.onBackPressed() != true) {\n                isEnabled = false\n                onBackPressedDispatcher.onBackPressed()\n                isEnabled = true\n            }\n        }\n        showRandomInterstitial(this, PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_explorer_connected, menu)\n        if (isExplorerFiles)\n            menu.findItem(R.id.delete_all).isVisible = false\n        CastUtil.registerActivity(this, menu, R.id.castMenu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.delete_all -> adapter?.onRemoveAllClicked()\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    override fun onChange(isFile: Boolean) {\n        isExplorerFiles = isFile\n        invalidateOptionsMenu()\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n        ThumbServer.stop()\n    }\n\n    companion object {\n        @JvmStatic\n        fun open(context: Context) {\n            context.startActivity(Intent(context, ExplorerActivityMaterial::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerChapsAdapter.kt",
    "content": "package knf.kuma.explorer\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.media.MediaMetadataRetriever\nimport android.media.ThumbnailUtils\nimport android.os.Build\nimport android.provider.MediaStore.Video.Thumbnails.MINI_KIND\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageButton\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.App\nimport knf.kuma.R\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.cast.CastMedia\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.PicassoSingle\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.SeenAnimeOverlay\nimport knf.kuma.database.CacheDB\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.pojos.ExplorerObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeenObject\nimport knf.kuma.queue.QueueManager\nimport knf.kuma.videoservers.ServersFactory\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.util.Locale\n\n\nclass ExplorerChapsAdapter internal constructor(val fragment: Fragment, private val recyclerView: RecyclerView, val explorerObject: ExplorerObjectWrap, private val model: ExplorerFilesModel, private var clearInterface: FragmentChapters.ClearInterface?) : RecyclerView.Adapter<ExplorerChapsAdapter.ChapItem>() {\n    private val context: Context? = fragment.context\n\n    private val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n    private val chaptersDAO = CacheDB.INSTANCE.seenDAO()\n    private val recordsDAO = CacheDB.INSTANCE.recordsDAO()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_chap\n        } else {\n            R.layout.item_chap_grid\n        }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChapItem {\n        return ChapItem(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ChapItem, position: Int) {\n        val chapObject = explorerObject.fileList[position]\n        loadThumb(chapObject.obj, holder.imageView)\n        val chapterNum = String.format(Locale.getDefault(), \"Episodio %s\", chapObject.obj.chapter)\n        holder.seenOverlay.setSeen(chapObject.isSeen, false)\n        holder.chapter.text = chapterNum\n        holder.time.text = chapObject.obj.time\n        holder.cardView.setOnClickListener {\n            fragment.lifecycleScope.launch(Dispatchers.IO) {\n                chaptersDAO.addChapter(SeenObject.fromDownloaded(chapObject.obj))\n                recordsDAO.add(RecordObject.fromDownloaded(chapObject.obj))\n            }\n            chapObject.isSeen = true\n            syncData {\n                history()\n                seen()\n            }\n            holder.seenOverlay.setSeen(true, true)\n            if (CastUtil.get().connected()) {\n                CastUtil.get().play(recyclerView, CastMedia.create(chapObject.obj))\n            } else {\n                ServersFactory.startPlay(context, chapObject.obj.chapTitle, chapObject.obj.fileName)\n            }\n        }\n        holder.cardView.setOnLongClickListener {\n            if (!chapObject.isSeen) {\n                fragment.lifecycleScope.launch(Dispatchers.IO){\n                    chaptersDAO.addChapter(SeenObject.fromDownloaded(chapObject.obj))\n                }\n                chapObject.isSeen = true\n                holder.seenOverlay.setSeen(true, true)\n            } else {\n                fragment.lifecycleScope.launch(Dispatchers.IO) {\n                    chaptersDAO.deleteChapter(chapObject.obj.aid, chapterNum)\n                }\n                chapObject.isSeen = false\n                holder.seenOverlay.setSeen(false, true)\n            }\n            syncData { seen() }\n            true\n        }\n        holder.action.setOnClickListener {\n            context?.let {\n                MaterialDialog(context).safeShow {\n                    message(text = \"¿Eliminar el episodio ${chapObject.obj.chapter} de ${chapObject.obj.title}?\")\n                    positiveButton(text = \"CONFIRMAR\") {\n                        delete(chapObject.obj, holder.adapterPosition)\n                    }\n                    negativeButton(text = \"CANCELAR\")\n                }\n            }\n        }\n    }\n\n    fun setInterface(clearInterface: FragmentChapters.ClearInterface) {\n        this.clearInterface = clearInterface\n    }\n\n    private fun delete(obj: ExplorerObject.FileDownObj, position: Int) {\n        if (position < 0) return\n        doAsync {\n            FileAccessHelper.delete(obj.fileName, true)\n            downloadsDAO.deleteByEid(obj.eid)\n            QueueManager.remove(obj.eid)\n            explorerObject.fileList.removeAt(position)\n            fragment.doOnUI { notifyItemRemoved(position) }\n            if (explorerObject.fileList.size == 0) {\n                model.remove(explorerObject.obj)\n                clearInterface?.onClear()\n            } else {\n                model.removeOne(explorerObject.obj)\n            }\n        }\n    }\n\n    internal fun deleteAll() {\n        doAsync {\n            for ((i, obj) in explorerObject.fileList.withIndex()) {\n                FileAccessHelper.delete(obj.obj.fileName, true)\n                downloadsDAO.deleteByEid(obj.obj.eid)\n                QueueManager.remove(obj.obj.eid)\n                fragment.doOnUI {\n                    notifyItemRemoved(i)\n                }\n            }\n            model.remove(explorerObject.obj)\n            clearInterface?.onClear()\n        }\n    }\n\n    private fun loadThumb(fileDownObj: ExplorerObject.FileDownObj, imageView: ImageView?) {\n        val file = File(context?.cacheDir, explorerObject.obj.fileName + \"_\" + fileDownObj.chapter.lowercase(Locale.getDefault()) + \".png\")\n        if (file.exists()) {\n            fileDownObj.thumb = file\n            PicassoSingle.get().load(file).into(imageView)\n        } else {\n            doAsync {\n                try {\n                    val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)\n                        MediaMetadataRetriever().apply {\n                            setDataSource(App.context, fileDownObj.file.getFileUri())\n                        }.frameAtTime\n                    else\n                        ThumbnailUtils.createVideoThumbnail(File(fileDownObj.file.getFileUri().path).absolutePath, MINI_KIND)\n                    if (bitmap == null) {\n                        throw IllegalStateException(\"Null bitmap\")\n                    } else {\n                        file.createNewFile()\n                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, FileOutputStream(file))\n                        fileDownObj.thumb = file\n                        fragment.doOnUI { PicassoSingle.get().load(file).into(imageView) }\n                    }\n                } catch (e: Exception) {\n                    fragment.doOnUI { PicassoSingle.get().load(R.drawable.ic_no_thumb).fit().into(imageView) }\n                }\n            }\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return try {\n            explorerObject.fileList.size\n        } catch (e: Exception) {\n            0\n        }\n\n    }\n\n    class ChapItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val seenOverlay: SeenAnimeOverlay by itemView.bind(R.id.seen)\n        val chapter: TextView by itemView.bind(R.id.chapter)\n        val time: TextView by itemView.bind(R.id.time)\n        val action: ImageButton by itemView.bind(R.id.action)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerChapsAdapterMaterial.kt",
    "content": "package knf.kuma.explorer\n\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.media.MediaMetadataRetriever\nimport android.media.ThumbnailUtils\nimport android.os.Build\nimport android.provider.MediaStore.Video.Thumbnails.MINI_KIND\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageButton\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.App\nimport knf.kuma.R\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.cast.CastMedia\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.PicassoSingle\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.SeenAnimeOverlay\nimport knf.kuma.database.CacheDB\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.pojos.ExplorerObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeenObject\nimport knf.kuma.queue.QueueManager\nimport knf.kuma.videoservers.ServersFactory\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport java.io.File\nimport java.io.FileOutputStream\nimport java.util.Locale\n\n\nclass ExplorerChapsAdapterMaterial internal constructor(val fragment: Fragment, private val recyclerView: RecyclerView, val explorerObject: ExplorerObjectWrap, private val model: ExplorerFilesModel, private var clearInterface: FragmentChaptersMaterial.ClearInterface?) : RecyclerView.Adapter<ExplorerChapsAdapterMaterial.ChapItem>() {\n    private val context: Context? = fragment.context\n\n    private val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n    private val chaptersDAO = CacheDB.INSTANCE.seenDAO()\n    private val recordsDAO = CacheDB.INSTANCE.recordsDAO()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_chap_material\n        } else {\n            R.layout.item_chap_grid_material\n        }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChapItem {\n        return ChapItem(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ChapItem, position: Int) {\n        val chapObject = explorerObject.fileList[position]\n        loadThumb(chapObject.obj, holder.imageView)\n        val chapterNum = String.format(Locale.getDefault(), \"Episodio %s\", chapObject.obj.chapter)\n        holder.seenOverlay.setSeen(chapObject.isSeen, false)\n        holder.chapter.text = chapterNum\n        holder.time.text = chapObject.obj.time\n        holder.cardView.setOnClickListener {\n            fragment.lifecycleScope.launch(Dispatchers.IO) {\n                chaptersDAO.addChapter(SeenObject.fromDownloaded(chapObject.obj))\n                recordsDAO.add(RecordObject.fromDownloaded(chapObject.obj))\n            }\n            chapObject.isSeen = true\n            syncData {\n                history()\n                seen()\n            }\n            holder.seenOverlay.setSeen(true, true)\n            if (CastUtil.get().connected()) {\n                CastUtil.get().play(recyclerView, CastMedia.create(chapObject.obj))\n            } else {\n                ServersFactory.startPlay(context, chapObject.obj.chapTitle, chapObject.obj.fileName)\n            }\n        }\n        holder.cardView.setOnLongClickListener {\n            if (!chapObject.isSeen) {\n                fragment.lifecycleScope.launch(Dispatchers.IO){\n                    chaptersDAO.addChapter(SeenObject.fromDownloaded(chapObject.obj))\n                }\n                chapObject.isSeen = true\n                holder.seenOverlay.setSeen(true, true)\n            } else {\n                fragment.lifecycleScope.launch(Dispatchers.IO) {\n                    chaptersDAO.deleteChapter(chapObject.obj.aid, chapterNum)\n                }\n                chapObject.isSeen = false\n                holder.seenOverlay.setSeen(false, true)\n            }\n            syncData { seen() }\n            true\n        }\n        holder.action.setOnClickListener {\n            context?.let {\n                MaterialDialog(context).safeShow {\n                    message(text = \"¿Eliminar el episodio ${chapObject.obj.chapter} de ${chapObject.obj.title}?\")\n                    positiveButton(text = \"CONFIRMAR\") {\n                        delete(chapObject.obj, holder.adapterPosition)\n                    }\n                    negativeButton(text = \"CANCELAR\")\n                }\n            }\n        }\n    }\n\n    fun setInterface(clearInterface: FragmentChaptersMaterial.ClearInterface) {\n        this.clearInterface = clearInterface\n    }\n\n    private fun delete(obj: ExplorerObject.FileDownObj, position: Int) {\n        if (position < 0) return\n        doAsync {\n            FileAccessHelper.delete(obj.fileName, true)\n            downloadsDAO.deleteByEid(obj.eid)\n            QueueManager.remove(obj.eid)\n            explorerObject.fileList.removeAt(position)\n            fragment.doOnUI { notifyItemRemoved(position) }\n            if (explorerObject.fileList.size == 0) {\n                model.remove(explorerObject.obj)\n                clearInterface?.onClear()\n            } else {\n                model.removeOne(explorerObject.obj)\n            }\n        }\n    }\n\n    internal fun deleteAll() {\n        doAsync {\n            for ((i, obj) in explorerObject.fileList.withIndex()) {\n                FileAccessHelper.delete(obj.obj.fileName, true)\n                downloadsDAO.deleteByEid(obj.obj.eid)\n                QueueManager.remove(obj.obj.eid)\n                fragment.doOnUI {\n                    notifyItemRemoved(i)\n                }\n            }\n            model.remove(explorerObject.obj)\n            clearInterface?.onClear()\n        }\n    }\n\n    private fun loadThumb(fileDownObj: ExplorerObject.FileDownObj, imageView: ImageView?) {\n        val file = File(context?.cacheDir, explorerObject.obj.fileName + \"_\" + fileDownObj.chapter.lowercase(Locale.getDefault()) + \".png\")\n        if (file.exists()) {\n            fileDownObj.thumb = file\n            PicassoSingle.get().load(file).into(imageView)\n        } else {\n            doAsync {\n                try {\n                    val bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)\n                        MediaMetadataRetriever().apply {\n                            setDataSource(App.context, fileDownObj.file.getFileUri())\n                        }.frameAtTime\n                    else\n                        ThumbnailUtils.createVideoThumbnail(File(fileDownObj.file.getFileUri().path).absolutePath, MINI_KIND)\n                    if (bitmap == null) {\n                        throw IllegalStateException(\"Null bitmap\")\n                    } else {\n                        file.createNewFile()\n                        bitmap.compress(Bitmap.CompressFormat.PNG, 100, FileOutputStream(file))\n                        fileDownObj.thumb = file\n                        fragment.doOnUI { PicassoSingle.get().load(file).into(imageView) }\n                    }\n                } catch (e: Exception) {\n                    fragment.doOnUI { PicassoSingle.get().load(R.drawable.ic_no_thumb).fit().into(imageView) }\n                }\n            }\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return try {\n            explorerObject.fileList.size\n        } catch (e: Exception) {\n            0\n        }\n\n    }\n\n    class ChapItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val seenOverlay: SeenAnimeOverlay by itemView.bind(R.id.seen)\n        val chapter: TextView by itemView.bind(R.id.chapter)\n        val time: TextView by itemView.bind(R.id.time)\n        val action: ImageButton by itemView.bind(R.id.action)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerCreator.kt",
    "content": "package knf.kuma.explorer\n\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.pojos.ExplorerObject\nimport org.jetbrains.anko.doAsync\nimport java.util.Locale\n\nobject ExplorerCreator {\n    var IS_CREATED = false\n    var IS_FILES = true\n    var FILES_NAME: ExplorerObject? = null\n    private val STATE_LISTENER = MutableLiveData<String?>()\n\n    internal val stateListener: LiveData<String?>\n        get() = STATE_LISTENER\n\n    fun start(model: ExplorerFilesModel, listener: EmptyListener) {\n        IS_CREATED = true\n        doAsync {\n            if (!FileAccessHelper.isStoragePermissionEnabled()) {\n                //Toaster.toastLong(\"Permiso de almacenamiento no concedido\")\n                listener.onPermissionFailed()\n                postState(null)\n                IS_CREATED = false\n                return@doAsync\n            }\n            postState(\"Iniciando busqueda\")\n            val creator = FileAccessHelper.downloadExplorerCreator\n            if (creator.exist()) {\n                postState(\"Buscando animes\")\n                val list = creator.createDirectoryList { progress, total ->\n                    postState(String.format(Locale.getDefault(), \"Procesando animes %d/%d\", progress, total))\n                }\n                postState(\"Creando lista\")\n                model.setData(list)\n                if (list.isEmpty()) {\n                    listener.onEmpty()\n                }\n                postState(null)\n            } else {\n                model.setData(emptyList())\n                listener.onEmpty()\n                postState(null)\n            }\n        }\n    }\n\n    fun onDestroy() {\n        IS_CREATED = false\n        IS_FILES = true\n        FILES_NAME = null\n    }\n\n    private fun postState(state: String?) {\n        doOnUIGlobal { STATE_LISTENER.value = state }\n    }\n\n    interface EmptyListener {\n        fun onEmpty()\n        fun onPermissionFailed()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerFilesAdapter.kt",
    "content": "package knf.kuma.explorer\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.pojos.ExplorerObject\nimport java.util.Locale\n\nclass ExplorerFilesAdapter internal constructor(private val fragment: Fragment, private var listener: FragmentFiles.SelectedListener?) : RecyclerView.Adapter<ExplorerFilesAdapter.FileItem>() {\n\n    private var list: MutableList<ExplorerObject> = ArrayList()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_explorer\n        } else {\n            R.layout.item_explorer_grid\n        }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileItem {\n        return FileItem(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n    }\n\n    fun setListener(listener: FragmentFiles.SelectedListener) {\n        this.listener = listener\n    }\n\n    override fun onBindViewHolder(holder: FileItem, position: Int) {\n        val explorerObject = list[position]\n        holder.imageView.load(explorerObject.img)\n        holder.title.text = explorerObject.name\n        holder.chapter.text = String.format(Locale.getDefault(), if (explorerObject.count == 1) \"%d archivo\" else \"%d archivos\", explorerObject.count)\n        holder.cardView.setOnClickListener { listener?.onSelected(explorerObject) }\n        holder.cardView.setOnLongClickListener {\n            ActivityAnime.open(fragment, explorerObject, holder.imageView)\n            true\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(list: MutableList<ExplorerObject>) {\n        if (this.list notSameContent list) {\n            this.list = list\n            notifyDataSetChanged()\n        }\n    }\n\n    class FileItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val chapter: TextView by itemView.bind(R.id.chapter)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerFilesAdapterMaterial.kt",
    "content": "package knf.kuma.explorer\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.recyclerview.widget.ListAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.pojos.ExplorerObject\nimport java.util.Locale\n\nclass ExplorerFilesAdapterMaterial internal constructor(private val fragment: Fragment, private var listener: FragmentFilesMaterial.SelectedListener?) : ListAdapter<ExplorerObject,ExplorerFilesAdapterMaterial.FileItem>(ExplorerObjectDiff()) {\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_explorer_material\n        } else {\n            R.layout.item_explorer_grid_material\n        }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileItem {\n        return FileItem(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n    }\n\n    fun setListener(listener: FragmentFilesMaterial.SelectedListener) {\n        this.listener = listener\n    }\n\n    override fun onBindViewHolder(holder: FileItem, position: Int) {\n        val explorerObject = getItem(position)\n        holder.imageView.load(explorerObject.img)\n        holder.title.text = explorerObject.name\n        holder.chapter.text = String.format(Locale.getDefault(), if (explorerObject.count == 1) \"%d archivo\" else \"%d archivos\", explorerObject.count)\n        holder.cardView.setOnClickListener { listener?.onSelected(explorerObject) }\n        holder.cardView.setOnLongClickListener {\n            ActivityAnimeMaterial.open(fragment, explorerObject, holder.imageView)\n            true\n        }\n    }\n\n    fun update(list: List<ExplorerObject>) {\n        submitList(list)\n    }\n\n    class FileItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val chapter: TextView by itemView.bind(R.id.chapter)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerFilesModel.kt",
    "content": "package knf.kuma.explorer\r\n\r\nimport androidx.lifecycle.MutableLiveData\r\nimport androidx.lifecycle.ViewModel\r\nimport androidx.lifecycle.viewModelScope\r\nimport knf.kuma.pojos.ExplorerObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\n\r\nclass ExplorerFilesModel : ViewModel() {\r\n    val localFilesData = MutableLiveData<List<ExplorerObject>>()\r\n    private var localList = mutableListOf<ExplorerObject>()\r\n\r\n    fun setData(list: List<ExplorerObject>) {\r\n        viewModelScope.launch {\r\n            localFilesData.value = list\r\n            localList = list.toMutableList()\r\n        }\r\n    }\r\n\r\n    fun remove(item: ExplorerObject) {\r\n        viewModelScope.launch(Dispatchers.IO) {\r\n            localList.filter { it.key != item.key }.let {\r\n                withContext(Dispatchers.Main) {\r\n                    localFilesData.value = it\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    fun removeOne(item: ExplorerObject) {\r\n        viewModelScope.launch(Dispatchers.IO) {\r\n            val found = localList.find { it.key == item.key }\r\n            val index = localList.indexOf(found)\r\n            if (index >= 0 && found != null) {\r\n                val new = ExplorerObject(found).apply {\r\n                    count -= 1\r\n                }\r\n                localList.removeAt(index)\r\n                localList.add(index, new)\r\n                withContext(Dispatchers.Main) {\r\n                    localFilesData.value = localList\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerObjectDiff.kt",
    "content": "package knf.kuma.explorer\r\n\r\nimport androidx.recyclerview.widget.DiffUtil\r\nimport knf.kuma.pojos.ExplorerObject\r\n\r\nclass ExplorerObjectDiff: DiffUtil.ItemCallback<ExplorerObject>() {\r\n    override fun areItemsTheSame(oldItem: ExplorerObject, newItem: ExplorerObject): Boolean = oldItem.key == newItem.key\r\n\r\n    override fun areContentsTheSame(oldItem: ExplorerObject, newItem: ExplorerObject): Boolean = oldItem.chapters.size == newItem.chapters.size && oldItem.count == newItem.count\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerObjectWrap.kt",
    "content": "package knf.kuma.explorer\r\n\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.ExplorerObject\r\nimport java.util.Locale\r\n\r\nclass ExplorerObjectWrap(val obj: ExplorerObject){\r\n    val fileList = obj.chapters.map { FileDownWrap(it) }.toMutableList()\r\n}\r\n\r\nclass FileDownWrap(val obj: ExplorerObject.FileDownObj) {\r\n    var isSeen = CacheDB.INSTANCE.seenDAO().chapterIsSeen(obj.aid, String.format(Locale.getDefault(), \"Episodio %s\", obj.chapter))\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerPagerAdapter.kt",
    "content": "package knf.kuma.explorer\n\nimport android.content.Context\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.viewpager.widget.PagerAdapter\n\nclass ExplorerPagerAdapter(context: Context, private val fragmentManager: FragmentManager) : PagerAdapter() {\n    private val fragments: Array<Fragment?> = arrayOfNulls(2)\n    private val stateChange: OnFileStateChange? = context as? OnFileStateChange\n\n    override fun instantiateItem(container: ViewGroup, position: Int): Any {\n        val fragment = getItem(position)\n        try {\n            fragment?.let {\n                val trans = fragmentManager.beginTransaction()\n                trans.add(container.id, fragment, \"fragment:$position\")\n                trans.commit()\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n        return fragment ?: Any()\n    }\n\n    override fun destroyItem(container: ViewGroup, position: Int, any: Any) {\n        val fragment = fragments[position]\n        fragment?.let {\n            val trans = fragmentManager.beginTransaction()\n            trans.remove(fragment)\n            trans.commit()\n        }\n        fragments[position] = null\n    }\n\n    override fun getCount(): Int {\n        return fragments.size\n    }\n\n    override fun isViewFromObject(view: View, any: Any): Boolean {\n        return (any as? Fragment)?.view === view\n    }\n\n    override fun getPageTitle(position: Int): CharSequence? {\n        return when (position) {\n            0 -> \"Archivos\"\n            1 -> \"Descargas\"\n            else -> \"Archivos\"\n        }\n    }\n\n    fun getItem(position: Int): Fragment? {\n        if (fragments[position] == null) {\n            fragments[position] = createFragment(position)\n            if (position == 0)\n                (fragments[position] as? FragmentFilesRoot)?.setStateChange(stateChange)\n        }\n        return fragments[position]\n    }\n\n    private fun createFragment(position: Int): Fragment {\n        return when (position) {\n            0 -> FragmentFilesRoot.get()\n            1 -> FragmentDownloads.get()\n            else -> FragmentFilesRoot.get()\n        }\n    }\n\n    internal fun onRemoveAllClicked() {\n        try {\n            (fragments[0] as? FragmentFilesRoot)?.onRemoveAll()\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ExplorerPagerAdapterMaterial.kt",
    "content": "package knf.kuma.explorer\n\nimport android.content.Context\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.viewpager.widget.PagerAdapter\n\nclass ExplorerPagerAdapterMaterial(context: Context, private val fragmentManager: FragmentManager) : PagerAdapter() {\n    private val fragments: Array<Fragment?> = arrayOfNulls(2)\n    private val stateChange: OnFileStateChange? = context as? OnFileStateChange\n\n    override fun instantiateItem(container: ViewGroup, position: Int): Any {\n        val fragment = getItem(position)\n        try {\n            fragment?.let {\n                val trans = fragmentManager.beginTransaction()\n                trans.add(container.id, fragment, \"fragment:$position\")\n                trans.commit()\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n        return fragment ?: Any()\n    }\n\n    override fun destroyItem(container: ViewGroup, position: Int, any: Any) {\n        val fragment = fragments[position]\n        fragment?.let {\n            val trans = fragmentManager.beginTransaction()\n            trans.remove(fragment)\n            trans.commit()\n        }\n        fragments[position] = null\n    }\n\n    override fun getCount(): Int {\n        return fragments.size\n    }\n\n    override fun isViewFromObject(view: View, any: Any): Boolean {\n        return (any as? Fragment)?.view === view\n    }\n\n    override fun getPageTitle(position: Int): CharSequence? {\n        return when (position) {\n            0 -> \"Archivos\"\n            1 -> \"Descargas\"\n            else -> \"Archivos\"\n        }\n    }\n\n    fun getItem(position: Int): Fragment? {\n        if (fragments[position] == null) {\n            fragments[position] = createFragment(position)\n            if (position == 0)\n                (fragments[position] as? FragmentFilesRootMaterial)?.setStateChange(stateChange)\n        }\n        return fragments[position]\n    }\n\n    private fun createFragment(position: Int): Fragment {\n        return when (position) {\n            1 -> FragmentDownloadsMaterial.get()\n            else -> FragmentFilesRootMaterial.get()\n        }\n    }\n\n    internal fun onRemoveAllClicked() {\n        try {\n            (fragments[0] as? FragmentFilesRootMaterial)?.onRemoveAll()\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentBase.kt",
    "content": "package knf.kuma.explorer\n\nimport androidx.fragment.app.Fragment\n\nabstract class FragmentBase : Fragment() {\n\n    abstract fun onBackPressed(): Boolean\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentChapters.kt",
    "content": "package knf.kuma.explorer\n\nimport android.annotation.SuppressLint\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport android.widget.ProgressBar\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.noCrashSuspend\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.ExplorerObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.queue.QueueManager\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.find\nimport org.jetbrains.anko.sdk27.coroutines.onClick\nimport xdroid.toaster.Toaster\n\n\nclass FragmentChapters : Fragment() {\n    private val model: ExplorerFilesModel by activityViewModels()\n    lateinit var recyclerView: RecyclerView\n    lateinit var progressBar: ProgressBar\n    lateinit var fab: FloatingActionButton\n    internal var adapter: ExplorerChapsAdapter? = null\n    private var clearInterface: ClearInterface? = null\n    private var isFirst = true\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_explorer_chaps\n        } else {\n            R.layout.recycler_explorer_chaps_grid\n        }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(layout, container, false)\n        recyclerView = view.find(R.id.recycler)\n        recyclerView.verifyManager(170)\n        progressBar = view.find(R.id.progress)\n        fab = view.find(R.id.fab)\n        view.find<FrameLayout>(R.id.adContainer).implBanner(AdsType.EXPLORER_BANNER, true)\n        return view\n    }\n\n    private fun playAll(list: List<ExplorerObject.FileDownObj>) {\n        lifecycleScope.launch(Dispatchers.Main){\n            noCrashSuspend {\n                withContext(Dispatchers.IO) {\n                    CacheDB.INSTANCE.recordsDAO().add(RecordObject.fromDownloaded(list.last()))\n                    syncData { history() }\n                    QueueManager.startQueueDownloaded(context, list)\n                }\n                adapter?.apply {\n                    explorerObject.fileList.forEach {\n                        it.isSeen = true\n                    }\n                    notifyDataSetChanged()\n                }\n            }\n        }\n    }\n\n    @SuppressLint(\"RestrictedApi\")\n    fun setObject(explorerObject: ExplorerObject?) {\n        noCrash {\n            fab.internalSetVisibility(View.INVISIBLE, true)\n            fab.hide()\n        }\n        clear()\n        explorerObject?.let {\n            it.getLiveData(context)\n                    .observe(this@FragmentChapters, Observer { fileDownObjs ->\n                        if (fileDownObjs.isEmpty()) {\n                            Toaster.toast(\"Directorio vacio\")\n                            lifecycleScope.launch(Dispatchers.IO) {\n                                model.remove(explorerObject)\n                                launch(Dispatchers.Main) {\n                                    clearInterface?.onClear()\n                                }\n                            }\n                        } else {\n                            explorerObject.chapters = fileDownObjs as MutableList<ExplorerObject.FileDownObj>\n                            lifecycleScope.launch(Dispatchers.Main) {\n                                progressBar.visibility = View.GONE\n                                adapter = ExplorerChapsAdapter(this@FragmentChapters, recyclerView, withContext(Dispatchers.IO) { ExplorerObjectWrap(explorerObject) }, model, clearInterface)\n                                recyclerView.adapter = adapter\n                                if (isFirst) {\n                                    isFirst = false\n                                    recyclerView.scheduleLayoutAnimation()\n                                }\n                                if (!CastUtil.get().connected()) {\n                                    fab.show()\n                                    fab.onClick { playAll(fileDownObjs) }\n                                }\n                            }\n                        }\n                    })\n        }\n    }\n\n    internal fun deleteAll() {\n        adapter?.deleteAll()\n    }\n\n    private fun clear() {\n        isFirst = true\n        adapter = null\n        doOnUI {\n            progressBar.visibility = View.VISIBLE\n            recyclerView.adapter = null\n        }\n    }\n\n    fun setInterface(clearInterface: ClearInterface) {\n        this.clearInterface = clearInterface\n        adapter?.setInterface(clearInterface)\n    }\n\n    interface ClearInterface {\n        fun onClear()\n    }\n\n    companion object {\n        const val TAG = \"Chapters\"\n\n        operator fun get(clearInterface: ClearInterface): FragmentChapters {\n            val fragmentChapters = FragmentChapters()\n            fragmentChapters.setInterface(clearInterface)\n            return fragmentChapters\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentChaptersMaterial.kt",
    "content": "package knf.kuma.explorer\n\nimport android.annotation.SuppressLint\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport android.widget.ProgressBar\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.floatingactionbutton.FloatingActionButton\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.noCrashSuspend\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.ExplorerObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.queue.QueueManager\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.find\nimport org.jetbrains.anko.sdk27.coroutines.onClick\nimport xdroid.toaster.Toaster\n\n\nclass FragmentChaptersMaterial : Fragment() {\n    private val model: ExplorerFilesModel by activityViewModels()\n    lateinit var recyclerView: RecyclerView\n    lateinit var progressBar: ProgressBar\n    lateinit var fab: FloatingActionButton\n    internal var adapter: ExplorerChapsAdapterMaterial? = null\n    private var clearInterface: ClearInterface? = null\n    private var isFirst = true\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_explorer_chaps\n        } else {\n            R.layout.recycler_explorer_chaps_grid\n        }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(layout, container, false)\n        recyclerView = view.find(R.id.recycler)\n        recyclerView.verifyManager(170)\n        progressBar = view.find(R.id.progress)\n        fab = view.find(R.id.fab)\n        view.find<FrameLayout>(R.id.adContainer).implBanner(AdsType.EXPLORER_BANNER, true)\n        return view\n    }\n\n    private fun playAll(list: List<ExplorerObject.FileDownObj>) {\n        lifecycleScope.launch(Dispatchers.Main){\n            noCrashSuspend {\n                withContext(Dispatchers.IO) {\n                    CacheDB.INSTANCE.recordsDAO().add(RecordObject.fromDownloaded(list.last()))\n                    syncData { history() }\n                    QueueManager.startQueueDownloaded(context, list)\n                }\n                adapter?.apply {\n                    explorerObject.fileList.forEach {\n                        it.isSeen = true\n                    }\n                    notifyDataSetChanged()\n                }\n            }\n        }\n    }\n\n    @SuppressLint(\"RestrictedApi\")\n    fun setObject(explorerObject: ExplorerObject?) {\n        noCrash {\n            fab.internalSetVisibility(View.INVISIBLE, true)\n            fab.hide()\n        }\n        clear()\n        explorerObject?.let {\n            it.getLiveData(context)\n                    .observe(this@FragmentChaptersMaterial, Observer { fileDownObjs ->\n                        if (fileDownObjs.isEmpty()) {\n                            Toaster.toast(\"Directorio vacio\")\n                            lifecycleScope.launch(Dispatchers.IO) {\n                                model.remove(explorerObject)\n                                launch(Dispatchers.Main) {\n                                    clearInterface?.onClear()\n                                }\n                            }\n                        } else {\n                            explorerObject.chapters = fileDownObjs as MutableList<ExplorerObject.FileDownObj>\n                            lifecycleScope.launch(Dispatchers.Main) {\n                                progressBar.visibility = View.GONE\n                                adapter = ExplorerChapsAdapterMaterial(this@FragmentChaptersMaterial, recyclerView, withContext(Dispatchers.IO) { ExplorerObjectWrap(explorerObject) }, model, clearInterface)\n                                recyclerView.adapter = adapter\n                                if (isFirst) {\n                                    isFirst = false\n                                    recyclerView.scheduleLayoutAnimation()\n                                }\n                                if (!CastUtil.get().connected()) {\n                                    fab.show()\n                                    fab.onClick { playAll(fileDownObjs) }\n                                }\n                            }\n                        }\n                    })\n        }\n    }\n\n    internal fun deleteAll() {\n        adapter?.deleteAll()\n    }\n\n    private fun clear() {\n        isFirst = true\n        adapter = null\n        doOnUI {\n            progressBar.visibility = View.VISIBLE\n            recyclerView.adapter = null\n        }\n    }\n\n    fun setInterface(clearInterface: ClearInterface) {\n        this.clearInterface = clearInterface\n        adapter?.setInterface(clearInterface)\n    }\n\n    interface ClearInterface {\n        fun onClear()\n    }\n\n    companion object {\n        const val TAG = \"Chapters\"\n\n        operator fun get(clearInterface: ClearInterface): FragmentChaptersMaterial {\n            val fragmentChapters = FragmentChaptersMaterial()\n            fragmentChapters.setInterface(clearInterface)\n            return fragmentChapters\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentDownloads.kt",
    "content": "package knf.kuma.explorer\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\nimport com.google.android.material.snackbar.Snackbar\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeDismiss\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.RecyclerDownloadingBinding\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.pojos.DownloadObject\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.sdk27.coroutines.onClick\n\nclass FragmentDownloads : FragmentBase() {\n    private var isFirst = true\n    private var adapter: DownloadingAdapter? = null\n    private lateinit var binding: RecyclerDownloadingBinding\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        binding = RecyclerDownloadingBinding.bind(view)\n        binding.adContainer.implBanner(AdsType.EXPLORER_BANNER, true)\n        CacheDB.INSTANCE.downloadsDAO().active.observe(viewLifecycleOwner) { downloadObjects ->\n            binding.progress.visibility = View.GONE\n            binding.error.visibility = if (downloadObjects.isEmpty()) View.VISIBLE else View.GONE\n            binding.clear.visibility = if (downloadObjects.isEmpty()) View.GONE else View.VISIBLE\n            if (isFirst || downloadObjects.isEmpty() || binding.recycler.adapter != null && downloadObjects.size > binding.recycler.adapter?.itemCount ?: 0) {\n                isFirst = false\n                binding.recycler.adapter = DownloadingAdapter(this@FragmentDownloads, downloadObjects as MutableList<DownloadObject>).also { adapter = it }\n            }\n        }\n        binding.clear.onClick {\n            activity?.let {\n                MaterialDialog(it).safeShow {\n                    lifecycleOwner()\n                    message(text = \"¿Desea limpiar todas las descargas en la lista?\")\n                    positiveButton(text = \"limpiar\") {\n                        onRemoveAll()\n                    }\n                    negativeButton(text = \"Cancelar\")\n                }\n            }\n        }\n    }\n\n    private fun onRemoveAll() {\n        binding.clear.visibility = View.GONE\n        val snackbar = binding.recycler.showSnackbar(\"Limpiando lista...\", Snackbar.LENGTH_INDEFINITE)\n        doAsync {\n            DownloadManagerCentral.cancelAll()\n            doOnUI { snackbar.safeDismiss() }\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return inflater.inflate(R.layout.recycler_downloading, container, false)\n    }\n\n    override fun onBackPressed(): Boolean {\n        return false\n    }\n\n    companion object {\n\n        fun get(): FragmentDownloads {\n            return FragmentDownloads()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentDownloadsMaterial.kt",
    "content": "package knf.kuma.explorer\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.lifecycle.Observer\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\nimport com.google.android.material.snackbar.Snackbar\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeDismiss\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.RecyclerDownloadingBinding\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.pojos.DownloadObject\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.sdk27.coroutines.onClick\n\nclass FragmentDownloadsMaterial : FragmentBase() {\n    private var isFirst = true\n    private var adapter: DownloadingAdapterMaterial? = null\n    private lateinit var binding: RecyclerDownloadingBinding\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        binding = RecyclerDownloadingBinding.bind(view)\n        binding.adContainer.implBanner(AdsType.EXPLORER_BANNER, true)\n        CacheDB.INSTANCE.downloadsDAO().active.observe(viewLifecycleOwner, Observer { downloadObjects ->\n            binding.progress.visibility = View.GONE\n            binding.error.visibility = if (downloadObjects.isEmpty()) View.VISIBLE else View.GONE\n            binding.clear.visibility = if (downloadObjects.isEmpty()) View.GONE else View.VISIBLE\n            if (isFirst || downloadObjects.isEmpty() || binding.recycler.adapter != null && downloadObjects.size > binding.recycler.adapter?.itemCount ?: 0) {\n                isFirst = false\n                binding.recycler.adapter = DownloadingAdapterMaterial(this@FragmentDownloadsMaterial, downloadObjects as MutableList<DownloadObject>).also { adapter = it }\n            }\n        })\n        binding.clear.onClick {\n            activity?.let {\n                MaterialDialog(it).safeShow {\n                    lifecycleOwner()\n                    message(text = \"¿Desea limpiar todas las descargas en la lista?\")\n                    positiveButton(text = \"limpiar\") {\n                        onRemoveAll()\n                    }\n                    negativeButton(text = \"Cancelar\")\n                }\n            }\n        }\n    }\n\n    private fun onRemoveAll() {\n        binding.clear.visibility = View.GONE\n        val snackbar = binding.recycler.showSnackbar(\"Limpiando lista...\", Snackbar.LENGTH_INDEFINITE)\n        doAsync {\n            DownloadManagerCentral.cancelAll()\n            doOnUI { snackbar.safeDismiss() }\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return inflater.inflate(R.layout.recycler_downloading, container, false)\n    }\n\n    override fun onBackPressed(): Boolean {\n        return false\n    }\n\n    companion object {\n\n        fun get(): FragmentDownloadsMaterial {\n            return FragmentDownloadsMaterial()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentFiles.kt",
    "content": "package knf.kuma.explorer\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.Observer\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.pojos.ExplorerObject\nimport org.jetbrains.anko.find\n\nclass FragmentFiles : Fragment() {\n    private val model: ExplorerFilesModel by activityViewModels()\n    lateinit var recyclerView: RecyclerView\n    lateinit var error: View\n    lateinit var progressBar: ProgressBar\n    lateinit var state: TextView\n    private var listener: SelectedListener? = null\n    private var adapter: ExplorerFilesAdapter? = null\n    private var isFist = true\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_explorer\n        } else {\n            R.layout.recycler_explorer_grid\n        }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        model.localFilesData.observe(viewLifecycleOwner, { explorerObjects ->\n            adapter?.update(explorerObjects.toMutableList())\n            if (explorerObjects.isNotEmpty()) {\n                progressBar.visibility = View.GONE\n                state.visibility = View.GONE\n                if (isFist) {\n                    isFist = false\n                    recyclerView.scheduleLayoutAnimation()\n                }\n            }\n        })\n        ExplorerCreator.stateListener.observe(viewLifecycleOwner, Observer { s ->\n            state.text = s\n            state.visibility = if (s == null) View.GONE else View.VISIBLE\n        })\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(layout, container, false)\n        recyclerView = view.find(R.id.recycler)\n        recyclerView.verifyManager()\n        error = view.find(R.id.error)\n        progressBar = view.find(R.id.progress)\n        state = view.find(R.id.state)\n        view.find<FrameLayout>(R.id.adContainer).implBanner(AdsType.EXPLORER_BANNER, true)\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        adapter = ExplorerFilesAdapter(this, listener)\n        recyclerView.adapter = adapter\n    }\n\n    fun onEmpty() {\n        doOnUI {\n            progressBar.visibility = View.GONE\n            error.visibility = View.VISIBLE\n            state.visibility = View.GONE\n        }\n    }\n\n    fun setListener(listener: SelectedListener) {\n        this.listener = listener\n        adapter?.setListener(listener)\n    }\n\n    interface SelectedListener {\n        fun onSelected(explorerObject: ExplorerObject)\n    }\n\n    companion object {\n\n        const val TAG = \"Files\"\n\n        operator fun get(listener: SelectedListener): FragmentFiles {\n            val fragmentFiles = FragmentFiles()\n            fragmentFiles.setListener(listener)\n            return fragmentFiles\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentFilesMaterial.kt",
    "content": "package knf.kuma.explorer\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.activityViewModels\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.pojos.ExplorerObject\nimport org.jetbrains.anko.find\n\nclass FragmentFilesMaterial : Fragment() {\n    private val model: ExplorerFilesModel by activityViewModels()\n    lateinit var recyclerView: RecyclerView\n    lateinit var error: View\n    lateinit var progressBar: ProgressBar\n    lateinit var state: TextView\n    private var listener: SelectedListener? = null\n    private var adapter: ExplorerFilesAdapterMaterial? = null\n    private var isFist = true\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_explorer\n        } else {\n            R.layout.recycler_explorer_grid\n        }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        model.localFilesData.observe(viewLifecycleOwner, { explorerObjects ->\n            adapter?.update(explorerObjects)\n            if (explorerObjects.isNotEmpty()) {\n                progressBar.visibility = View.GONE\n                state.visibility = View.GONE\n                if (isFist) {\n                    isFist = false\n                    recyclerView.scheduleLayoutAnimation()\n                }\n            }\n        })\n        ExplorerCreator.stateListener.observe(viewLifecycleOwner, { s ->\n            state.text = s\n            state.visibility = if (s == null) View.GONE else View.VISIBLE\n        })\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(layout, container, false)\n        recyclerView = view.find(R.id.recycler)\n        recyclerView.verifyManager()\n        error = view.find(R.id.error)\n        progressBar = view.find(R.id.progress)\n        state = view.find(R.id.state)\n        view.find<FrameLayout>(R.id.adContainer).implBanner(AdsType.EXPLORER_BANNER, true)\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        adapter = ExplorerFilesAdapterMaterial(this, listener)\n        recyclerView.adapter = adapter\n    }\n\n    fun onEmpty() {\n        doOnUI {\n            progressBar.visibility = View.GONE\n            error.visibility = View.VISIBLE\n            state.visibility = View.GONE\n        }\n    }\n\n    fun setListener(listener: SelectedListener) {\n        this.listener = listener\n        adapter?.setListener(listener)\n    }\n\n    interface SelectedListener {\n        fun onSelected(explorerObject: ExplorerObject)\n    }\n\n    companion object {\n\n        const val TAG = \"Files\"\n\n        operator fun get(listener: SelectedListener): FragmentFilesMaterial {\n            val fragmentFiles = FragmentFilesMaterial()\n            fragmentFiles.setListener(listener)\n            return fragmentFiles\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentFilesRoot.kt",
    "content": "package knf.kuma.explorer\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.activityViewModels\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.R\nimport knf.kuma.commons.safeShow\nimport knf.kuma.pojos.ExplorerObject\nimport xdroid.toaster.Toaster\n\n\nclass FragmentFilesRoot : FragmentBase(), FragmentFiles.SelectedListener, FragmentChapters.ClearInterface, FragmentPermission.PermissionListener, ExplorerCreator.EmptyListener {\n\n    private val model: ExplorerFilesModel by activityViewModels()\n    private var files: FragmentFiles = FragmentFiles[this]\n    private val chapters: FragmentChapters = FragmentChapters[this]\n    private val permissions: FragmentPermission = FragmentPermission[this]\n    private var isFiles = true\n    private var name: String? = null\n    private var stateChange: OnFileStateChange? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        retainInstance = true\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return inflater.inflate(R.layout.fragment_explorer_files, container, false)\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        val transaction = childFragmentManager.beginTransaction()\n        if (!files.isAdded)\n            transaction.add(R.id.root, files, FragmentFiles.TAG)\n        if (!chapters.isAdded)\n            transaction.add(R.id.root, chapters, FragmentChapters.TAG)\n        if (!permissions.isAdded)\n            transaction.add(R.id.root, permissions, FragmentPermission.TAG)\n        transaction.commit()\n        super.onViewCreated(view, savedInstanceState)\n    }\n\n    private fun setFragment(isFiles: Boolean, explorerObject: ExplorerObject?) {\n        stateChange?.onChange(isFiles)\n        this.isFiles = isFiles\n        this.name = explorerObject?.name\n        ExplorerCreator.IS_FILES = isFiles\n        ExplorerCreator.FILES_NAME = explorerObject\n        val transaction = childFragmentManager.beginTransaction()\n        transaction.hide(permissions)\n        if (isFiles) {\n            transaction.hide(chapters)\n            transaction.show(files)\n        } else {\n            chapters.setObject(explorerObject)\n            transaction.hide(files)\n            transaction.show(chapters)\n        }\n        transaction.setCustomAnimations(R.anim.fadein, R.anim.fadeout)\n        transaction.commit()\n    }\n\n    private fun showPermissionScreen() {\n        val transaction = childFragmentManager.beginTransaction()\n        transaction.hide(files)\n        transaction.hide(chapters)\n        transaction.show(permissions)\n        transaction.commit()\n    }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        if (savedInstanceState != null) {\n            this.isFiles = savedInstanceState.getBoolean(\"isFiles\", true)\n            this.name = savedInstanceState.getString(\"name\")\n        }\n        setFragment(ExplorerCreator.IS_FILES, ExplorerCreator.FILES_NAME)\n        if (!ExplorerCreator.IS_CREATED)\n            ExplorerCreator.start(model, this)\n    }\n\n    override fun onSaveInstanceState(outState: Bundle) {\n        super.onSaveInstanceState(outState)\n        outState.putBoolean(\"isFiles\", isFiles)\n        outState.putString(\"name\", name)\n    }\n\n    internal fun setStateChange(stateChange: OnFileStateChange?) {\n        this.stateChange = stateChange\n    }\n\n    internal fun onRemoveAll() {\n        if (name != null)\n            activity?.let {\n                MaterialDialog(it).safeShow {\n                    message(text = \"¿Eliminar todos los capitulos de $name?\")\n                    positiveButton(text = \"Eliminar\") { chapters.deleteAll() }\n                    negativeButton(text = \"Cancelar\")\n                }\n            }\n        else\n            Toaster.toast(\"Error al borrar episodios\")\n    }\n\n    override fun onSelected(explorerObject: ExplorerObject) {\n        setFragment(false, explorerObject)\n    }\n\n    override fun onClear() {\n        setFragment(true, null)\n    }\n\n    override fun onEmpty() {\n        files.onEmpty()\n    }\n\n    override fun onPermissionFailed() {\n        showPermissionScreen()\n    }\n\n    override fun onPermission() {\n        setFragment(ExplorerCreator.IS_FILES, ExplorerCreator.FILES_NAME)\n        if (!ExplorerCreator.IS_CREATED)\n            ExplorerCreator.start(model, this)\n    }\n\n    override fun onBackPressed(): Boolean {\n        return if (isFiles) {\n            false\n        } else {\n            setFragment(true, null)\n            true\n        }\n    }\n\n    companion object {\n\n        fun get(): FragmentFilesRoot {\n            return FragmentFilesRoot()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentFilesRootMaterial.kt",
    "content": "package knf.kuma.explorer\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.activityViewModels\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.R\nimport knf.kuma.commons.safeShow\nimport knf.kuma.pojos.ExplorerObject\nimport xdroid.toaster.Toaster\n\n\nclass FragmentFilesRootMaterial : FragmentBase(), FragmentFilesMaterial.SelectedListener, FragmentChaptersMaterial.ClearInterface, ExplorerCreator.EmptyListener,\n    FragmentPermission.PermissionListener {\n\n    private val model: ExplorerFilesModel by activityViewModels()\n    private var files: FragmentFilesMaterial = FragmentFilesMaterial[this]\n    private val chapters: FragmentChaptersMaterial = FragmentChaptersMaterial[this]\n    private val permissions: FragmentPermission = FragmentPermission[this]\n    private var isFiles = true\n    private var name: String? = null\n    private var stateChange: OnFileStateChange? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        retainInstance = true\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        return inflater.inflate(R.layout.fragment_explorer_files, container, false)\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        val transaction = childFragmentManager.beginTransaction()\n        if (!files.isAdded)\n            transaction.add(R.id.root, files, FragmentFiles.TAG)\n        if (!chapters.isAdded)\n            transaction.add(R.id.root, chapters, FragmentChapters.TAG)\n        if (!permissions.isAdded)\n            transaction.add(R.id.root, permissions, FragmentPermission.TAG)\n        transaction.commit()\n        super.onViewCreated(view, savedInstanceState)\n    }\n\n    private fun setFragment(isFiles: Boolean, explorerObject: ExplorerObject?) {\n        stateChange?.onChange(isFiles)\n        this.isFiles = isFiles\n        this.name = explorerObject?.name\n        ExplorerCreator.IS_FILES = isFiles\n        ExplorerCreator.FILES_NAME = explorerObject\n        val transaction = childFragmentManager.beginTransaction()\n        transaction.hide(permissions)\n        if (isFiles) {\n            transaction.hide(chapters)\n            transaction.show(files)\n        } else {\n            chapters.setObject(explorerObject)\n            transaction.hide(files)\n            transaction.show(chapters)\n        }\n        transaction.setCustomAnimations(R.anim.fadein, R.anim.fadeout)\n        transaction.commit()\n    }\n\n    private fun showPermissionScreen() {\n        val transaction = childFragmentManager.beginTransaction()\n        transaction.hide(files)\n        transaction.hide(chapters)\n        transaction.show(permissions)\n        transaction.commit()\n    }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        if (savedInstanceState != null) {\n            this.isFiles = savedInstanceState.getBoolean(\"isFiles\", true)\n            this.name = savedInstanceState.getString(\"name\")\n        }\n        setFragment(ExplorerCreator.IS_FILES, ExplorerCreator.FILES_NAME)\n        if (!ExplorerCreator.IS_CREATED)\n            ExplorerCreator.start(model, this)\n    }\n\n    override fun onSaveInstanceState(outState: Bundle) {\n        super.onSaveInstanceState(outState)\n        outState.putBoolean(\"isFiles\", isFiles)\n        outState.putString(\"name\", name)\n    }\n\n    internal fun setStateChange(stateChange: OnFileStateChange?) {\n        this.stateChange = stateChange\n    }\n\n    internal fun onRemoveAll() {\n        if (name != null)\n            activity?.let {\n                MaterialDialog(it).safeShow {\n                    message(text = \"¿Eliminar todos los capitulos de $name?\")\n                    positiveButton(text = \"Eliminar\") { chapters.deleteAll() }\n                    negativeButton(text = \"Cancelar\")\n                }\n            }\n        else\n            Toaster.toast(\"Error al borrar episodios\")\n    }\n\n    override fun onSelected(explorerObject: ExplorerObject) {\n        setFragment(false, explorerObject)\n    }\n\n    override fun onClear() {\n        setFragment(true, null)\n    }\n\n    override fun onEmpty() {\n        files.onEmpty()\n    }\n\n    override fun onPermissionFailed() {\n        showPermissionScreen()\n    }\n\n    override fun onPermission() {\n        setFragment(ExplorerCreator.IS_FILES, ExplorerCreator.FILES_NAME)\n        if (!ExplorerCreator.IS_CREATED)\n            ExplorerCreator.start(model, this)\n    }\n\n    override fun onBackPressed(): Boolean {\n        return if (isFiles) {\n            false\n        } else {\n            setFragment(true, null)\n            true\n        }\n    }\n\n    companion object {\n\n        fun get(): FragmentFilesRootMaterial {\n            return FragmentFilesRootMaterial()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/FragmentPermission.kt",
    "content": "package knf.kuma.explorer\n\nimport android.Manifest\nimport android.os.Build\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.Toast\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.lifecycleScope\nimport com.google.android.material.button.MaterialButton\nimport knf.kuma.R\nimport knf.kuma.commons.isMIUI\nimport knf.kuma.download.FileAccessHelper\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster\n\nclass FragmentPermission : Fragment() {\n    private lateinit var listener: PermissionListener\n    private val permissionContract = registerForActivityResult(ActivityResultContracts.RequestPermission()) {\n        if (it) {\n            listener.onPermission()\n        } else {\n            Toast.makeText(requireContext(), \"Permiso denegado\", Toast.LENGTH_SHORT).show()\n        }\n    }\n    private val treeChooser = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) {\n        val validation = FileAccessHelper.isUriValid(it)\n        if (!validation.isValid) {\n            Toaster.toast(\"Directorio invalido: $validation\")\n        } else {\n            listener.onPermission()\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(R.layout.fragment_explorer_permission_pending, container, false)\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        view.find<MaterialButton>(R.id.permission).apply {\n            setOnClickListener {\n                lifecycleScope.launch {\n                    if (!FileAccessHelper.isStoragePermissionEnabledAsync()) {\n                        when {\n                            Build.VERSION.SDK_INT < Build.VERSION_CODES.Q -> {\n                                permissionContract.launch(Manifest.permission.READ_EXTERNAL_STORAGE)\n                            }\n                            else -> {\n                                try {\n                                    treeChooser.launch(null)\n                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)\n                                        Toaster.toastLong(\"Por favor selecciona un directorio para las descargas\")\n                                    else\n                                        Toaster.toastLong(\"Por favor selecciona la raiz del almacenamiento\")\n                                } catch (e: Exception) {\n                                    e.printStackTrace()\n                                    if (isMIUI) {\n                                        permissionContract.launch(Manifest.permission.READ_EXTERNAL_STORAGE)\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    fun setListener(listener: PermissionListener) {\n        this.listener = listener\n    }\n\n    interface PermissionListener {\n        fun onPermission()\n    }\n\n    companion object {\n\n        const val TAG = \"Permission\"\n\n        operator fun get(listener: PermissionListener): FragmentPermission {\n            val fragmentFiles = FragmentPermission()\n            fragmentFiles.setListener(listener)\n            return fragmentFiles\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/OnFileStateChange.kt",
    "content": "package knf.kuma.explorer\n\ninterface OnFileStateChange {\n    fun onChange(isFile: Boolean)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/ThumbServer.kt",
    "content": "package knf.kuma.explorer\r\n\r\nimport fi.iki.elonen.NanoHTTPD\r\nimport knf.kuma.commons.Network\r\nimport java.io.File\r\nimport java.io.FileInputStream\r\n\r\nobject ThumbServer {\r\n    private var SERVERINSTANCE: Server? = null\r\n\r\n    fun loadFile(file: File): String? {\r\n        return try {\r\n            //stop()\r\n            //SERVERINSTANCE = Server(file)\r\n            setFile(file)\r\n            \"http://${Network.ipAddress}:4691\"\r\n        } catch (e: Exception) {\r\n            e.printStackTrace()\r\n            null\r\n        }\r\n    }\r\n\r\n    private fun setFile(file: File) {\r\n        if (SERVERINSTANCE == null)\r\n            SERVERINSTANCE = Server(file)\r\n        else\r\n            SERVERINSTANCE?.loadedFile = file\r\n    }\r\n\r\n    fun stop() {\r\n        if (SERVERINSTANCE?.isAlive == true) {\r\n            SERVERINSTANCE?.stop()\r\n            SERVERINSTANCE = null\r\n        }\r\n    }\r\n\r\n    private class Server(var loadedFile: File) : NanoHTTPD(4691) {\r\n        init {\r\n            start(SOCKET_READ_TIMEOUT, false)\r\n        }\r\n\r\n        override fun serve(session: IHTTPSession?): Response {\r\n            return newFixedLengthResponse(Response.Status.OK, \"image/png\", FileInputStream(loadedFile), loadedFile.length())\r\n        }\r\n    }\r\n\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/creator/Creator.kt",
    "content": "package knf.kuma.explorer.creator\r\n\r\nimport knf.kuma.pojos.ExplorerObject\r\n\r\ninterface Creator {\r\n    fun exist(): Boolean\r\n    fun createLinksList(): List<String>\r\n    fun createDirectoryList(progressCallback: (Int, Int) -> Unit): List<ExplorerObject>\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/creator/DocumentFileCreator.kt",
    "content": "package knf.kuma.explorer.creator\r\n\r\nimport androidx.documentfile.provider.DocumentFile\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.ExplorerObject\r\n\r\nclass DocumentFileCreator(private val rootDF: DocumentFile?) : Creator {\r\n\r\n    override fun exist(): Boolean = rootDF?.exists()\r\n            ?: false\r\n\r\n    override fun createLinksList(): List<String> {\r\n        rootDF ?: return emptyList()\r\n        return rootDF.listFiles().filter { it.isDirectory }.mapNotNull { \"https://www3.animeflv.net/anime/${it.name}\" }\r\n    }\r\n\r\n    override fun createDirectoryList(progressCallback: (Int, Int) -> Unit): List<ExplorerObject> {\r\n        rootDF ?: return emptyList()\r\n        val directories = rootDF.listFiles().filter { it.isDirectory }\r\n        val list = mutableListOf<ExplorerObject>()\r\n        var progress = 0\r\n        CacheDB.INSTANCE.animeDAO().getAllByFile(directories.mapNotNull { it.name }.toMutableList()).forEach {\r\n            try {\r\n                progress++\r\n                progressCallback(progress, directories.size)\r\n                list.add(ExplorerObject(it))\r\n            } catch (e: IllegalStateException) {\r\n                e.printStackTrace()\r\n            }\r\n        }\r\n        return list\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/creator/SimpleFileCreator.kt",
    "content": "package knf.kuma.explorer.creator\r\n\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.ExplorerObject\r\nimport java.io.File\r\nimport java.io.FileFilter\r\n\r\nclass SimpleFileCreator(val base: File) : Creator {\r\n\r\n    override fun exist(): Boolean = base.exists()\r\n\r\n    override fun createLinksList(): List<String> {\r\n        return if (base.exists())\r\n            base.listFiles(FileFilter { it.isDirectory })?.map { \"https://www3.animeflv.net/anime/${it.name}\" } ?: emptyList()\r\n        else\r\n            emptyList()\r\n    }\r\n\r\n    override fun createDirectoryList(progressCallback: (Int, Int) -> Unit): List<ExplorerObject> {\r\n        return if (base.exists()) {\r\n            val list = mutableListOf<ExplorerObject>()\r\n            val files = base.listFiles(FileFilter { it.isDirectory })\r\n            if (files != null) {\r\n                var progress = 0\r\n                for (animeObject in CacheDB.INSTANCE.animeDAO().getAllByFile(files.map { it.name }.toMutableList()))\r\n                    try {\r\n                        progress++\r\n                        progressCallback(progress, files.size)\r\n                        list.add(ExplorerObject(animeObject))\r\n                    } catch (e: IllegalStateException) {\r\n                        e.printStackTrace()\r\n                    }\r\n            }\r\n            list\r\n        } else\r\n            emptyList()\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/explorer/creator/SubFile.kt",
    "content": "package knf.kuma.explorer.creator\r\n\r\nimport android.net.Uri\r\n\r\ndata class SubFile(val name: String, private val uri: String) {\r\n\r\n    fun getFileUri(): Uri = Uri.parse(uri)\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/faq/FaqActivity.kt",
    "content": "package knf.kuma.faq\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.net.Uri\r\nimport android.os.Bundle\r\nimport android.view.Menu\r\nimport android.view.MenuItem\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.list.listItems\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.custom.VariantLinearLayoutManager\r\nimport knf.kuma.databinding.RecyclerFaqBinding\r\nimport org.jetbrains.anko.toast\r\n\r\nclass FaqActivity : GenericActivity() {\r\n\r\n    private val binding by lazy { RecyclerFaqBinding.inflate(layoutInflater) }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(binding.root)\r\n        setSupportActionBar(binding.toolbar)\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.title = \"FAQ\"\r\n        binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\r\n        binding.recycler.layoutManager = VariantLinearLayoutManager(this)\r\n        binding.recycler.adapter = FaqAdapter(createFAQList())\r\n    }\r\n\r\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\r\n        menuInflater.inflate(R.menu.menu_bug, menu)\r\n        return super.onCreateOptionsMenu(menu)\r\n    }\r\n\r\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"Reportar problema\")\r\n            listItems(items = listOf(\"Telegram\", \"Facebook\", \"Email\")) { _, index, _ ->\r\n                when (index) {\r\n                    0 -> startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(\"https://t.me/unbarredstream\")))\r\n                    1 -> startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(\"https://www.facebook.com/ukikuapp/\")))\r\n                    2 -> {\r\n                        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(\"mailto:?subject=Problema con UKIKU&to=jordyamc@hotmail.com\"))\r\n                        val chooser = Intent.createChooser(intent, \"Enviar reporte\")\r\n                        if (intent.resolveActivity(packageManager) != null) {\r\n                            startActivity(chooser)\r\n                        } else\r\n                            toast(\"No se encontraron clientes de email\")\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return super.onOptionsItemSelected(item)\r\n    }\r\n\r\n    private fun createFAQList(): List<FaqItem> =\r\n            listOf(\r\n                    FaqItem(\"¿Dónde está el servidor natsuki?\", \"Los servidores vienen de Animeflv, la app no tiene el control de los que aparecen, tan solo extrae los que están disponibles\"),\r\n                    FaqItem(\"¿Por qué no me funcionan los servidores?\", \"Los servidores vienen de Animeflv, son ellos los encargados de re subir los enlaces caídos, la app no puede hacer nada\"),\r\n                    FaqItem(\"¿Para que funcionan las loli-coins?\", \"Sirven para comprar los pasos del easter egg y revelar logros ocultos\"),\r\n                    FaqItem(\"¿Por qué me dice error 403?\", \"Solo presiona la barra roja que aparece\"),\r\n                    FaqItem(\"¿Por qué no está este anime en la app?\", \"La app utiliza Animeflv para obtener la lista de animes, si no te aparece es porque, o no esta en Animeflv o no estas escribiendo el nombre correctamente\"),\r\n                    FaqItem(\"¿Puedo pedir animes?\", \"No, la app utiliza Animeflv, no subimos los animes\"),\r\n                    FaqItem(\"¿Por qué no me aparece el botón de añadir a favoritos?\", \"Es un error muuuuuuy raro, nunca se pudo encontrar una solución, en ese caso puedes añadir y quitar animes a favoritos haciendo click largo en la imagen del anime\"),\r\n                    FaqItem(\"¿Se puede hacer Cast?\", \"Si, la app soporta transmisión por CAST, aparecerá un icono en la parte superior\"),\r\n                    FaqItem(\"¿Por qué no puedo hacer Cast con capítulos Online?\", \"Si tu TV es Samsung entonces es imposible, la TV bloquea los intentos por usar CAST, en ese caso puedes descargar el capítulo y hacer CAST local\"),\r\n                    FaqItem(\"¿Que significa Cloudflare activado?\", \"Es una protección de la página de Animeflv, la app debería poder pasar esa protección automáticamente\"),\r\n                    FaqItem(\"¿Puedo adelantar el OP y ED?\", \"Si, en el reproductor interno hay un botón para saltar 1:30m (Lo que por lo regular dura un OP o ED)\"),\r\n                    FaqItem(\"¿Se le puede hacer PiP (ventana flotante) a un capítulo?\", \"Si, pero solo es compatible con Android 8.1 o superior\"),\r\n                    FaqItem(\"¿Por qué me va muy lenta las descargas?\", \"Esto podría ser por varios factores, tu internet, la velocidad de escritura (mientras más ocupado este el dispositivo más tardará), el servidor que estés usando para la descarga\"),\r\n                    FaqItem(\"¿Hay forma de ver una serie de corrido (ver el siguiente cap sin regresar a los caps)?\", \"Si, puedes añadir los capítulos a la cola y verlos todos\"),\r\n                    FaqItem(\"¿Por qué se me reinicia el capítulo cuando contesto mensajes (salir y entrar a la app)?\", \"Algunos dispositivos no muy potentes necesitan \\\"matar\\\" las aplicaciones en segundo plano para ahorrar memoria, esto sumado a que no todos los servidores soportan el adelantar videos\"),\r\n                    FaqItem(\"¿Puedo añadir un sonido personalizado a las notificaciones?\", \"Si, hay una opción en configuraciones para ello\"),\r\n                    FaqItem(\"¿Qué pasará si animeflv deja de existir?\", \"Se considerara cambiar de página o crear una app desde 0\"),\r\n                    FaqItem(\"¿Puedo guardar mis animes en \\\"favoritos\\\" y \\\"siguiendo\\\"?\", \"Si, las dos secciones son independientes\"),\r\n                    FaqItem(\"¿Cómo puedo ayudar a la app?\", \"Puedes activar los anuncios desde configuracion, ver anuncios de video, donar mediante Paypal, o haciendote Patreon\"),\r\n                    FaqItem(\"¿Para qué sirven los logros?\", \"Para divertirte, se añadieron para que los usuarios tuvieran un objetivo aparte de ver anime\"),\r\n                    FaqItem(\"¿Cómo puedo cambiar de color la app?\", \"Debes resolver el easter egg\"),\r\n                    FaqItem(\"¿Como puedo reportar un error?\", \"Mediante la página de facebook, o mandando un mensaje al desarrollador vía Telegram o email\"),\r\n                    FaqItem(\"¿Que es el modo family friendly?\", \"Este modo inhabilita los animes con genero ecchi\"),\r\n                    FaqItem(\"¿Por qué al abrir la app me dice error de conexión (tiempo de conexión)?\", \"Animeflv podria estar lento, esto suele solucionarse después de unos minutos\"),\r\n                    FaqItem(\"¿Cómo puedo contactar al desarrollador?\", \"Mediante la página de facebook, en Telegram como @UnbarredStream, o al email jordyamc@hotmail.com\"),\r\n                    FaqItem(\"¿Ella en verdad me ama?\", \"NO\")\r\n\r\n            )\r\n\r\n    companion object {\r\n        fun open(context: Context) = context.startActivity(Intent(context, FaqActivity::class.java))\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/faq/FaqActivityMaterial.kt",
    "content": "package knf.kuma.faq\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport android.view.Menu\r\nimport android.view.MenuItem\r\nimport androidx.core.net.toUri\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.list.listItems\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.commons.setSurfaceBars\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.custom.VariantLinearLayoutManager\r\nimport knf.kuma.databinding.RecyclerFaqMaterialBinding\r\nimport org.jetbrains.anko.toast\r\n\r\nclass FaqActivityMaterial : GenericActivity() {\r\n\r\n    private val binding by lazy { RecyclerFaqMaterialBinding.inflate(layoutInflater) }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setSurfaceBars()\r\n        setContentView(binding.root)\r\n        setSupportActionBar(binding.toolbar)\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.title = \"FAQ\"\r\n        binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\r\n        binding.recycler.layoutManager = VariantLinearLayoutManager(this)\r\n        binding.recycler.adapter = FaqAdapter(createFAQList())\r\n    }\r\n\r\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\r\n        menuInflater.inflate(R.menu.menu_bug, menu)\r\n        return super.onCreateOptionsMenu(menu)\r\n    }\r\n\r\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\r\n        MaterialDialog(this).safeShow {\r\n            title(text = \"Reportar problema\")\r\n            listItems(items = listOf(\"Telegram\", \"Facebook\", \"Email\")) { _, index, _ ->\r\n                when (index) {\r\n                    0 -> startActivity(Intent(Intent.ACTION_VIEW, \"https://t.me/unbarredstream\".toUri()))\r\n                    1 -> startActivity(Intent(Intent.ACTION_VIEW, \"https://www.facebook.com/ukikuapp/\".toUri()))\r\n                    2 -> {\r\n                        val intent = Intent(Intent.ACTION_VIEW, \"mailto:?subject=Problema con UKIKU&to=jordyamc@hotmail.com\".toUri())\r\n                        val chooser = Intent.createChooser(intent, \"Enviar reporte\")\r\n                        if (intent.resolveActivity(packageManager) != null) {\r\n                            startActivity(chooser)\r\n                        } else\r\n                            toast(\"No se encontraron clientes de email\")\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return super.onOptionsItemSelected(item)\r\n    }\r\n\r\n    private fun createFAQList(): List<FaqItem> =\r\n            listOf(\r\n                    FaqItem(\"¿Dónde está el servidor natsuki?\", \"Los servidores vienen de Animeflv, la app no tiene el control de los que aparecen, tan solo extrae los que están disponibles\"),\r\n                    FaqItem(\"¿Por qué no me funcionan los servidores?\", \"Los servidores vienen de Animeflv, son ellos los encargados de re subir los enlaces caídos, la app no puede hacer nada\"),\r\n                    FaqItem(\"¿Para que funcionan las loli-coins?\", \"Sirven para comprar los pasos del easter egg y revelar logros ocultos\"),\r\n                    FaqItem(\"¿Por qué me dice error 403?\", \"Solo presiona la barra roja que aparece\"),\r\n                    FaqItem(\"¿Por qué no está este anime en la app?\", \"La app utiliza Animeflv para obtener la lista de animes, si no te aparece es porque, o no esta en Animeflv o no estas escribiendo el nombre correctamente\"),\r\n                    FaqItem(\"¿Puedo pedir animes?\", \"No, la app utiliza Animeflv, no subimos los animes\"),\r\n                    FaqItem(\"¿Por qué no me aparece el botón de añadir a favoritos?\", \"Es un error muuuuuuy raro, nunca se pudo encontrar una solución, en ese caso puedes añadir y quitar animes a favoritos haciendo click largo en la imagen del anime\"),\r\n                    FaqItem(\"¿Se puede hacer Cast?\", \"Si, la app soporta transmisión por CAST, aparecerá un icono en la parte superior\"),\r\n                    FaqItem(\"¿Por qué no puedo hacer Cast con capítulos Online?\", \"Si tu TV es Samsung entonces es imposible, la TV bloquea los intentos por usar CAST, en ese caso puedes descargar el capítulo y hacer CAST local\"),\r\n                    FaqItem(\"¿Que significa Cloudflare activado?\", \"Es una protección de la página de Animeflv, la app debería poder pasar esa protección automáticamente\"),\r\n                    FaqItem(\"¿Puedo adelantar el OP y ED?\", \"Si, en el reproductor interno hay un botón para saltar 1:30m (Lo que por lo regular dura un OP o ED)\"),\r\n                    FaqItem(\"¿Se le puede hacer PiP (ventana flotante) a un capítulo?\", \"Si, pero solo es compatible con Android 8.1 o superior\"),\r\n                    FaqItem(\"¿Por qué me va muy lenta las descargas?\", \"Esto podría ser por varios factores, tu internet, la velocidad de escritura (mientras más ocupado este el dispositivo más tardará), el servidor que estés usando para la descarga\"),\r\n                    FaqItem(\"¿Hay forma de ver una serie de corrido (ver el siguiente cap sin regresar a los caps)?\", \"Si, puedes añadir los capítulos a la cola y verlos todos\"),\r\n                    FaqItem(\"¿Por qué se me reinicia el capítulo cuando contesto mensajes (salir y entrar a la app)?\", \"Algunos dispositivos no muy potentes necesitan \\\"matar\\\" las aplicaciones en segundo plano para ahorrar memoria, esto sumado a que no todos los servidores soportan el adelantar videos\"),\r\n                    FaqItem(\"¿Puedo añadir un sonido personalizado a las notificaciones?\", \"Si, hay una opción en configuraciones para ello\"),\r\n                    FaqItem(\"¿Qué pasará si animeflv deja de existir?\", \"Se considerara cambiar de página o crear una app desde 0\"),\r\n                    FaqItem(\"¿Puedo guardar mis animes en \\\"favoritos\\\" y \\\"siguiendo\\\"?\", \"Si, las dos secciones son independientes\"),\r\n                    FaqItem(\"¿Cómo puedo ayudar a la app?\", \"Puedes activar los anuncios desde configuracion, ver anuncios de video, donar mediante Paypal, o haciendote Patreon\"),\r\n                    FaqItem(\"¿Para qué sirven los logros?\", \"Para divertirte, se añadieron para que los usuarios tuvieran un objetivo aparte de ver anime\"),\r\n                    FaqItem(\"¿Cómo puedo cambiar de color la app?\", \"Debes resolver el easter egg\"),\r\n                    FaqItem(\"¿Como puedo reportar un error?\", \"Mediante la página de facebook, o mandando un mensaje al desarrollador vía Telegram o email\"),\r\n                    FaqItem(\"¿Que es el modo family friendly?\", \"Este modo inhabilita los animes con genero ecchi\"),\r\n                    FaqItem(\"¿Por qué al abrir la app me dice error de conexión (tiempo de conexión)?\", \"Animeflv podria estar lento, esto suele solucionarse después de unos minutos\"),\r\n                    FaqItem(\"¿Cómo puedo contactar al desarrollador?\", \"Mediante la página de facebook, en Telegram como @UnbarredStream, o al email jordyamc@hotmail.com\"),\r\n                    FaqItem(\"¿Ella en verdad me ama?\", \"NO\")\r\n\r\n            )\r\n\r\n    companion object {\r\n        fun open(context: Context) = context.startActivity(Intent(context, FaqActivityMaterial::class.java))\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/faq/FaqAdapter.kt",
    "content": "package knf.kuma.faq\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport com.github.florent37.expansionpanel.ExpansionLayout\r\nimport com.github.florent37.expansionpanel.viewgroup.ExpansionLayoutCollection\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.inflate\r\nimport org.jetbrains.anko.find\r\n\r\nclass FaqAdapter(private val list: List<FaqItem>) : RecyclerView.Adapter<FaqAdapter.ItemHolder>() {\r\n\r\n    private val expansionCollection = ExpansionLayoutCollection().apply {\r\n        openOnlyOne(true)\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder =\r\n            ItemHolder(parent.inflate(R.layout.item_faq))\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\r\n        val item = list[position]\r\n        holder.apply {\r\n            question.text = item.question\r\n            answer.text = item.answer\r\n            expansionLayout.let {\r\n                it.collapse(false)\r\n                expansionCollection.add(it)\r\n            }\r\n        }\r\n    }\r\n\r\n    class ItemHolder(val view: View) : RecyclerView.ViewHolder(view) {\r\n        val question: TextView by lazy { view.find(R.id.question) }\r\n        val answer: TextView by lazy { view.find(R.id.answer) }\r\n        val expansionLayout: ExpansionLayout by lazy { view.find(R.id.expansionLayout) }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/faq/FaqItem.kt",
    "content": "package knf.kuma.faq\r\n\r\ndata class FaqItem(val question: String, val answer: String)"
  },
  {
    "path": "app/src/main/java/knf/kuma/favorite/FavSectionHelper.kt",
    "content": "package knf.kuma.favorite\n\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.database.CacheDB\nimport knf.kuma.favorite.objects.FavSorter\nimport knf.kuma.favorite.objects.InfoContainer\nimport knf.kuma.pojos.FavSection\nimport knf.kuma.pojos.FavoriteObject\nimport org.jetbrains.anko.doAsync\nimport java.util.Collections\n\nobject FavSectionHelper {\n    private val infoContainer = InfoContainer()\n    var currentList: MutableList<FavoriteObject> = ArrayList()\n        private set\n    private val liveData = MutableLiveData<MutableList<FavoriteObject>>()\n\n    private val list: MutableList<FavoriteObject>\n        get() {\n            val list = ArrayList<FavoriteObject>()\n            var currentSection: String? = null\n            var section: MutableList<FavoriteObject> = ArrayList()\n            var noSection: MutableList<FavoriteObject> = ArrayList()\n            for (favoriteObject in CacheDB.INSTANCE.favsDAO().byCategory) {\n                if (currentSection == null || currentSection != favoriteObject.category) {\n                    if (currentSection != null && currentSection != favoriteObject.category) {\n                        if (currentSection != FavoriteObject.CATEGORY_NONE) {\n                            list.add(FavSection(currentSection))\n                            Collections.sort(section, FavSorter())\n                            list.addAll(section)\n                        } else\n                            noSection = ArrayList(section)\n                        section = ArrayList()\n                    }\n                    currentSection = favoriteObject.category\n                    section.add(favoriteObject)\n                } else if (currentSection == favoriteObject.category)\n                    section.add(favoriteObject)\n            }\n            if (currentSection != null)\n                if (currentSection != FavoriteObject.CATEGORY_NONE) {\n                    list.add(FavSection(currentSection))\n                    Collections.sort(section, FavSorter())\n                    list.addAll(section)\n                } else\n                    noSection = ArrayList(section)\n            if (noSection.isNotEmpty()) {\n                list.add(FavSection(FavoriteObject.CATEGORY_NONE))\n                Collections.sort(noSection, FavSorter())\n                list.addAll(noSection)\n            }\n            infoContainer.setLists(currentList, list)\n            currentList = list\n            return list\n        }\n\n    fun init(): LiveData<MutableList<FavoriteObject>> {\n        reload()\n        return getLiveData()\n    }\n\n    fun getInfoContainer(favoriteObject: FavoriteObject?): InfoContainer {\n        infoContainer.reload(favoriteObject)\n        return infoContainer\n    }\n\n    private fun getLiveData(): LiveData<MutableList<FavoriteObject>> {\n        return liveData\n    }\n\n    private fun setLiveData(list: MutableList<FavoriteObject>) {\n        doOnUIGlobal { liveData.value = list }\n    }\n\n    fun reload() {\n        doAsync { setLiveData(list) }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/favorite/FavoriteFragment.kt",
    "content": "package knf.kuma.favorite\n\nimport android.graphics.Color\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.FragmentActivity\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.WhichButton\nimport com.afollestad.materialdialogs.actions.setActionButtonEnabled\nimport com.afollestad.materialdialogs.input.getInputField\nimport com.afollestad.materialdialogs.input.getInputLayout\nimport com.afollestad.materialdialogs.input.input\nimport com.afollestad.materialdialogs.list.listItems\nimport com.afollestad.materialdialogs.list.listItemsMultiChoice\nimport com.afollestad.materialdialogs.list.listItemsSingleChoice\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.FavSection\nimport knf.kuma.pojos.FavoriteObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster\n\nclass FavoriteFragment : BottomFragment(), FavsSectionAdapter.OnMoveListener {\n    lateinit var recyclerView: FastScrollRecyclerView\n    private lateinit var errorLayout: LinearLayout\n    private var edited: FavoriteObject? = null\n    private var manager: RecyclerView.LayoutManager? = null\n    private var adapter: FavsSectionAdapter? = null\n    private var isFirst = true\n\n    private val model: FavoriteViewModel by activityViewModels()\n    private lateinit var liveData: LiveData<MutableList<FavoriteObject>>\n    private lateinit var observer: Observer<MutableList<FavoriteObject>>\n\n    private var count = 0\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_favs\n        } else {\n            R.layout.recycler_favs_grid\n        }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        CacheDB.INSTANCE.favsDAO().all.observe(viewLifecycleOwner, Observer { FavSectionHelper.reload() })\n        activity?.let {\n            observeList(it, Observer { favoriteObjects ->\n                if (favoriteObjects == null || favoriteObjects.isEmpty()) {\n                    errorLayout.visibility = View.VISIBLE\n                    adapter?.updateList(ArrayList())\n                } else if (PrefsUtil.showFavSections()) {\n                    errorLayout.visibility = View.GONE\n                    val container = FavSectionHelper.getInfoContainer(edited)\n                    if (container.needReload) {\n                        adapter?.updateList(favoriteObjects)\n                        if (isFirst) {\n                            isFirst = false\n                            recyclerView.scheduleLayoutAnimation()\n                        }\n                    } else\n                        adapter?.updatePosition(container)\n                } else {\n                    errorLayout.visibility = View.GONE\n                    adapter?.updateList(favoriteObjects)\n                    if (isFirst) {\n                        isFirst = false\n                        recyclerView.scheduleLayoutAnimation()\n                    }\n                }\n                edited = null\n            })\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(layout, container, false)\n        recyclerView = view.find(R.id.recycler)\n        recyclerView.verifyManager()\n        errorLayout = view.find(R.id.error)\n        if (PrefsUtil.layType == \"1\" || !PrefsUtil.isNativeAdsEnabled)\n            lifecycleScope.launch(Dispatchers.IO) {\n                delay(1000)\n                view.find<FrameLayout>(R.id.adContainer).implBanner(AdsType.FAVORITE_BANNER, true)\n            }\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        manager = recyclerView.layoutManager\n        adapter = FavsSectionAdapter(this, recyclerView, PrefsUtil.showFavSections())\n        if (PrefsUtil.layType == \"1\" && PrefsUtil.showFavSections()) {\n            (manager as GridLayoutManager).spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {\n                override fun getSpanSize(position: Int): Int {\n                    return try {\n                        if (FavSectionHelper.currentList[position].isSection)\n                            (manager as GridLayoutManager).spanCount\n                        else\n                            1\n                    } catch (e: Exception) {\n                        1\n                    }\n                }\n            }\n        }\n        recyclerView.adapter = adapter\n        EAHelper.enter1(\"F\")\n    }\n\n    private fun observeList(activity: FragmentActivity, obs: Observer<MutableList<FavoriteObject>>) {\n        adapter?.updateList(mutableListOf())\n        isFirst = true\n        if (::liveData.isInitialized && ::observer.isInitialized)\n            liveData.removeObserver(observer)\n        liveData = model.getData()\n        observer = obs\n        liveData.observe(viewLifecycleOwner, observer)\n    }\n\n    fun onChangeOrder() {\n        activity?.let {\n            observeList(it, Observer { favoriteObjects ->\n                if (favoriteObjects == null || favoriteObjects.isEmpty()) {\n                    adapter?.updateList(ArrayList())\n                    errorLayout.post { errorLayout.visibility = View.VISIBLE }\n                } else {\n                    adapter?.updateList(favoriteObjects)\n                    if (isFirst) {\n                        isFirst = false\n                        recyclerView.scheduleLayoutAnimation()\n                    }\n                }\n            })\n        }\n    }\n\n    fun showNewCategoryDialog(favoriteObject: FavoriteObject?) {\n        edited = favoriteObject\n        showNewCategoryDialog(favoriteObject == null, null)\n    }\n\n    private fun showNewCategoryDialog(isEmpty: Boolean, name: String?) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            val categories = withContext(Dispatchers.IO) { FavoriteObject.getCategories(CacheDB.INSTANCE.favsDAO().categories) }\n            context?.let {\n                MaterialDialog(it).safeShow {\n                    title(text = \"${if (name == null) \"Nueva\" else \"Renombrar\"} categoría\")\n                    input(hint = \"Nombre\", prefill = name, waitForPositiveButton = false) { dialog, charSequence ->\n                        dialog.setActionButtonEnabled(WhichButton.POSITIVE, charSequence.isNotEmpty())\n                    }\n                    getInputField().setBackgroundColor(Color.TRANSPARENT)\n                    getInputLayout().setBoxBackgroundColorResource(android.R.color.transparent)\n                    positiveButton(text = if (name == null) \"Crear\" else \"Renombrar\") { dialog ->\n                        val input = dialog.getInputField().text.toString()\n                        if (categories.contains(input)) {\n                            Toaster.toast(\"Esta categoría ya existe\")\n                            showNewCategoryDialog(isEmpty, name)\n                        } else {\n                            if (isEmpty)\n                                showNewCategoryInit(false, input)\n                            else {\n                                launch(Dispatchers.IO) {\n                                    edited?.let { favObj ->\n                                        favObj.category = input\n                                        CacheDB.INSTANCE.favsDAO().addFav(favObj)\n                                        syncData { favs() }\n                                        edited = null\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    fun showNewCategory(prefill: String? = null) {\n        lifecycleScope.launch(Dispatchers.Main){\n            val categories = withContext(Dispatchers.IO) { FavoriteObject.getCategories(CacheDB.INSTANCE.favsDAO().categories) }\n            context?.let { ctx ->\n                MaterialDialog(ctx).safeShow {\n                    title(text = \"Nueva categoría\")\n                    input(hint = \"Nombre\", prefill = prefill, waitForPositiveButton = false) { dialog, charSequence ->\n                        dialog.setActionButtonEnabled(WhichButton.POSITIVE, charSequence.isNotEmpty())\n                    }\n                    getInputField().setBackgroundColor(Color.TRANSPARENT)\n                    getInputLayout().setBoxBackgroundColorResource(android.R.color.transparent)\n                    positiveButton(text = \"Crear\") { dialog ->\n                        val input = dialog.getInputField().text.toString()\n                        if (categories.contains(input)) {\n                            Toaster.toast(\"Esta categoría ya existe\")\n                            showNewCategory(input)\n                        } else {\n                            doAsync {\n                                edited?.let {\n                                    it.category = input\n                                    CacheDB.INSTANCE.favsDAO().addFav(it)\n                                    syncData { favs() }\n                                }\n                                doOnUI {\n                                    showAddToCategory(edited == null, input)\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private fun showCategoryRename(name: String) {\n        lifecycleScope.launch(Dispatchers.Main){\n            val categories = withContext(Dispatchers.IO) { FavoriteObject.getCategories(CacheDB.INSTANCE.favsDAO().categories) }\n            context?.let {\n                MaterialDialog(it).safeShow {\n                    title(text = \"Renombrar categoría\")\n                    input(hint = \"Nombre\", prefill = name, waitForPositiveButton = false) { dialog, charSequence ->\n                        dialog.setActionButtonEnabled(WhichButton.POSITIVE, charSequence.isNotEmpty())\n                    }\n                    getInputField().setBackgroundColor(Color.TRANSPARENT)\n                    getInputLayout().setBoxBackgroundColorResource(android.R.color.transparent)\n                    positiveButton(text = \"Renombrar\") { dialog ->\n                        val input = dialog.getInputField().text.toString()\n                        if (categories.contains(input)) {\n                            Toaster.toast(\"Esta categoría ya existe\")\n                            showCategoryRename(name)\n                        } else {\n                            doAsync {\n                                val objects = CacheDB.INSTANCE.favsDAO().getAllInCategory(name)\n                                for (favoriteObject in objects) {\n                                    favoriteObject.category = input\n                                }\n                                CacheDB.INSTANCE.favsDAO().addAll(objects)\n                                syncData { favs() }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private fun showAddToCategory(needAnimes: Boolean, name: String) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            val fName = if (name == \"Sin categoría\") FavoriteObject.CATEGORY_NONE else name\n            val favoriteObjects = withContext(Dispatchers.IO) { CacheDB.INSTANCE.favsDAO().getNotInCategory(fName) }\n            if (favoriteObjects.isEmpty()) {\n                if (needAnimes)\n                    Toaster.toast(\"Necesitas favoritos para crear una categoría\")\n                else\n                    Toaster.toast(\"No hay mas animes para agregar\")\n            } else {\n                context?.let {\n                    MaterialDialog(it).safeShow {\n                        title(text = name)\n                        listItemsMultiChoice(items = FavoriteObject.getNames(favoriteObjects)) { _, indices, _ ->\n                            if (needAnimes && indices.isEmpty()) {\n                                Toaster.toast(\"La nueva categoría necesita animes!\")\n                                showAddToCategory(needAnimes, name)\n                            } else {\n                                doAsync {\n                                    edited = null\n                                    val list = ArrayList<FavoriteObject>()\n                                    for (i in indices) {\n                                        val favoriteObject = favoriteObjects[i]\n                                        favoriteObject.category = fName\n                                        list.add(favoriteObject)\n                                    }\n                                    CacheDB.INSTANCE.favsDAO().addAll(list)\n                                    syncData { favs() }\n                                }\n                            }\n                        }\n                        positiveButton(text = \"agregar\")\n                        if (!needAnimes)\n                            negativeButton(text = \"Cancelar\")\n                    }\n                }\n            }\n        }\n    }\n\n    private fun showDeleteCategory(name: String) {\n        context?.let {\n            MaterialDialog(it).safeShow {\n                message(text = \"¿Desea eliminar esta categoría?\")\n                positiveButton(text = \"Eliminar\") {\n                    doAsync {\n                        val objects = CacheDB.INSTANCE.favsDAO().getAllInCategory(name)\n                        for (favoriteObject in objects) {\n                            favoriteObject.category = FavoriteObject.CATEGORY_NONE\n                        }\n                        CacheDB.INSTANCE.favsDAO().addAll(objects)\n                        syncData { favs() }\n                    }\n                }\n                negativeButton(text = \"Cancelar\")\n            }\n        }\n\n    }\n\n    private fun showNewCategoryInit(isEdit: Boolean, name: String) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            val fName = if (name == \"Sin categoría\") FavoriteObject.CATEGORY_NONE else name\n            val favoriteObjects = withContext(Dispatchers.IO) { CacheDB.INSTANCE.favsDAO().getNotInCategory(fName) }\n            if (favoriteObjects.isEmpty()) {\n                Toaster.toast(\"Necesitas favoritos para crear una categoría\")\n            } else {\n                val isNotDefault = isEdit && fName != FavoriteObject.CATEGORY_NONE\n                context?.let {\n                    MaterialDialog(it).safeShow {\n                        title(text = name)\n                        listItemsMultiChoice(items = FavoriteObject.getNames(favoriteObjects)) { _, indices, _ ->\n                            edited = null\n                            val list = ArrayList<FavoriteObject>()\n                            for (i in indices) {\n                                val favoriteObject = favoriteObjects[i]\n                                favoriteObject.category = fName\n                                list.add(favoriteObject)\n                            }\n                            doAsync {\n                                CacheDB.INSTANCE.favsDAO().addAll(list)\n                                syncData { favs() }\n                            }\n                        }\n                        positiveButton(text = \"agregar\")\n                        if (isNotDefault || !isEdit)\n                            negativeButton(text =\n                            when {\n                                isNotDefault -> \"cancelar\"\n                                !isEdit -> \"atras\"\n                                else -> \"\"\n                            }) {\n                                if (isNotDefault)\n                                    MaterialDialog(context).safeShow {\n                                        message(text = \"¿Desea eliminar esta categoría?\")\n                                        positiveButton(text = \"continuar\") {\n                                            edited = null\n                                            doAsync {\n                                                val objects = CacheDB.INSTANCE.favsDAO().getAllInCategory(fName)\n                                                for (favoriteObject in objects) {\n                                                    favoriteObject.category = FavoriteObject.CATEGORY_NONE\n                                                }\n                                                CacheDB.INSTANCE.favsDAO().addAll(objects)\n                                                syncData { favs() }\n                                            }\n                                        }\n                                    }\n                                else if (!isEdit)\n                                    showNewCategoryDialog(true, name)\n                            }\n                        if (!isEdit)\n                            setOnCancelListener { showNewCategoryDialog(true, name) }\n                    }\n                }\n            }\n        }\n    }\n\n    override fun onEdit(category: String) {\n        if (category == \"Sin categoría\")\n            showAddToCategory(false, category)\n        else\n            context?.let {\n                MaterialDialog(it).safeShow {\n                    title(text = category)\n                    listItems(items = listOf(\"Renombrar\", \"Agregar animes\", \"Eliminar sección\")) { _, index, _ ->\n                        when (index) {\n                            0 -> showCategoryRename(category)\n                            1 -> showAddToCategory(false, category)\n                            2 -> showDeleteCategory(category)\n                        }\n                    }\n                }\n            }\n\n        //showNewCategoryInit(true, category)\n    }\n\n    override fun onSelect(favoriteObject: FavoriteObject) {\n        if (favoriteObject !is FavSection) {\n            lifecycleScope.launch(Dispatchers.Main) {\n                val categories = withContext(Dispatchers.IO) { FavoriteObject.getCategories(CacheDB.INSTANCE.favsDAO().categories) }\n                if (categories.size <= 1) {\n                    edited = favoriteObject\n                    showNewCategory(null)\n                } else {\n                    context?.let { context ->\n                        MaterialDialog(context).safeShow {\n                            title(text = \"Mover a...\")\n                            listItemsSingleChoice(items = categories, initialSelection = categories.indexOf(favoriteObject.category)) { _, _, text ->\n                                doAsync {\n                                    if (text != favoriteObject.category) {\n                                        edited = favoriteObject.also {\n                                            it.category = if (text == \"Sin categoría\") \"_NONE_\" else text.toString()\n                                            CacheDB.INSTANCE.favsDAO().addFav(it)\n                                            syncData { favs() }\n                                        }\n                                    } else\n                                        Toaster.toast(\"Error al mover\")\n                                }\n                            }\n                            positiveButton(text = \"mover\")\n                            negativeButton(text = \"nuevo\") {\n                                edited = favoriteObject\n                                showNewCategory(null)\n                            }\n                        }\n                    }\n\n                }\n            }\n        }\n    }\n\n    override fun onReselect() {\n        EAHelper.enter1(\"F\")\n        manager?.let {\n            it.smoothScrollToPosition(recyclerView, null, 0)\n            count++\n            if (count == 3) {\n                lifecycleScope.launch(Dispatchers.IO){\n                    if (adapter != null)\n                        Toaster.toast(\"Tienes \" + CacheDB.INSTANCE.favsDAO().count + \" animes en favoritos\")\n                    count = 0\n                }\n            }\n        }\n    }\n\n    companion object {\n\n        fun get(): FavoriteFragment {\n            return FavoriteFragment()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/favorite/FavoriteFragmentMaterial.kt",
    "content": "package knf.kuma.favorite\n\nimport android.graphics.Color\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.FragmentActivity\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.WhichButton\nimport com.afollestad.materialdialogs.actions.setActionButtonEnabled\nimport com.afollestad.materialdialogs.input.getInputField\nimport com.afollestad.materialdialogs.input.getInputLayout\nimport com.afollestad.materialdialogs.input.input\nimport com.afollestad.materialdialogs.list.listItems\nimport com.afollestad.materialdialogs.list.listItemsMultiChoice\nimport com.afollestad.materialdialogs.list.listItemsSingleChoice\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.FavSection\nimport knf.kuma.pojos.FavoriteObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster\n\nclass FavoriteFragmentMaterial : BottomFragment(), FavsSectionAdapterMaterial.OnMoveListener {\n    lateinit var recyclerView: FastScrollRecyclerView\n    private lateinit var errorLayout: LinearLayout\n    private var edited: FavoriteObject? = null\n    private var manager: RecyclerView.LayoutManager? = null\n    private var adapter: FavsSectionAdapterMaterial? = null\n    private var isFirst = true\n\n    private val model: FavoriteViewModel by activityViewModels()\n    private lateinit var liveData: LiveData<MutableList<FavoriteObject>>\n    private lateinit var observer: Observer<MutableList<FavoriteObject>>\n\n    private var count = 0\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_favs_matertial\n        } else {\n            R.layout.recycler_favs_grid_material\n        }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        CacheDB.INSTANCE.favsDAO().all.observe(viewLifecycleOwner) { FavSectionHelper.reload() }\n        activity?.let {\n            observeList(it, Observer { favoriteObjects ->\n                if (favoriteObjects == null || favoriteObjects.isEmpty()) {\n                    errorLayout.visibility = View.VISIBLE\n                    adapter?.updateList(ArrayList())\n                } else if (PrefsUtil.showFavSections()) {\n                    errorLayout.visibility = View.GONE\n                    val container = FavSectionHelper.getInfoContainer(edited)\n                    if (container.needReload) {\n                        adapter?.updateList(favoriteObjects)\n                        if (isFirst) {\n                            isFirst = false\n                            recyclerView.scheduleLayoutAnimation()\n                        }\n                    } else\n                        adapter?.updatePosition(container)\n                } else {\n                    errorLayout.visibility = View.GONE\n                    adapter?.updateList(favoriteObjects)\n                    if (isFirst) {\n                        isFirst = false\n                        recyclerView.scheduleLayoutAnimation()\n                    }\n                }\n                edited = null\n            })\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(layout, container, false)\n        recyclerView = view.find(R.id.recycler)\n        recyclerView.verifyManager()\n        errorLayout = view.find(R.id.error)\n        if (PrefsUtil.layType == \"1\" || !PrefsUtil.isNativeAdsEnabled)\n            lifecycleScope.launch(Dispatchers.IO) {\n                delay(1000)\n                noCrash {\n                    view.find<FrameLayout>(R.id.adContainer).implBanner(AdsType.FAVORITE_BANNER, true)\n                }\n            }\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        manager = recyclerView.layoutManager\n        adapter = FavsSectionAdapterMaterial(this, recyclerView, PrefsUtil.showFavSections())\n        if (PrefsUtil.layType == \"1\" && PrefsUtil.showFavSections()) {\n            (manager as GridLayoutManager).spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {\n                override fun getSpanSize(position: Int): Int {\n                    return try {\n                        if (FavSectionHelper.currentList[position].isSection)\n                            (manager as GridLayoutManager).spanCount\n                        else\n                            1\n                    } catch (e: Exception) {\n                        1\n                    }\n                }\n            }\n        }\n        recyclerView.adapter = adapter\n        EAHelper.enter1(\"F\")\n    }\n\n    private fun observeList(activity: FragmentActivity, obs: Observer<MutableList<FavoriteObject>>) {\n        adapter?.updateList(mutableListOf())\n        isFirst = true\n        if (::liveData.isInitialized && ::observer.isInitialized)\n            liveData.removeObserver(observer)\n        liveData = model.getData()\n        observer = obs\n        liveData.observe(viewLifecycleOwner, observer)\n    }\n\n    fun onChangeOrder() {\n        activity?.let {\n            observeList(it, Observer { favoriteObjects ->\n                if (favoriteObjects == null || favoriteObjects.isEmpty()) {\n                    adapter?.updateList(ArrayList())\n                    errorLayout.post { errorLayout.visibility = View.VISIBLE }\n                } else {\n                    adapter?.updateList(favoriteObjects)\n                    if (isFirst) {\n                        isFirst = false\n                        recyclerView.scheduleLayoutAnimation()\n                    }\n                }\n            })\n        }\n    }\n\n    fun showNewCategoryDialog(favoriteObject: FavoriteObject?) {\n        edited = favoriteObject\n        showNewCategoryDialog(favoriteObject == null, null)\n    }\n\n    private fun showNewCategoryDialog(isEmpty: Boolean, name: String?) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            val categories = withContext(Dispatchers.IO) { FavoriteObject.getCategories(CacheDB.INSTANCE.favsDAO().categories) }\n            context?.let {\n                MaterialDialog(it).safeShow {\n                    title(text = \"${if (name == null) \"Nueva\" else \"Renombrar\"} categoría\")\n                    input(hint = \"Nombre\", prefill = name, waitForPositiveButton = false) { dialog, charSequence ->\n                        dialog.setActionButtonEnabled(WhichButton.POSITIVE, charSequence.isNotEmpty())\n                    }\n                    getInputField().setBackgroundColor(Color.TRANSPARENT)\n                    getInputLayout().setBoxBackgroundColorResource(android.R.color.transparent)\n                    positiveButton(text = if (name == null) \"Crear\" else \"Renombrar\") { dialog ->\n                        val input = dialog.getInputField().text.toString()\n                        if (categories.contains(input)) {\n                            Toaster.toast(\"Esta categoría ya existe\")\n                            showNewCategoryDialog(isEmpty, name)\n                        } else {\n                            if (isEmpty)\n                                showNewCategoryInit(false, input)\n                            else {\n                                launch(Dispatchers.IO) {\n                                    edited?.let { favObj ->\n                                        favObj.category = input\n                                        CacheDB.INSTANCE.favsDAO().addFav(favObj)\n                                        syncData { favs() }\n                                        edited = null\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    fun showNewCategory(prefill: String? = null) {\n        lifecycleScope.launch(Dispatchers.Main){\n            val categories = withContext(Dispatchers.IO) { FavoriteObject.getCategories(CacheDB.INSTANCE.favsDAO().categories) }\n            context?.let { ctx ->\n                MaterialDialog(ctx).safeShow {\n                    title(text = \"Nueva categoría\")\n                    input(hint = \"Nombre\", prefill = prefill, waitForPositiveButton = false) { dialog, charSequence ->\n                        dialog.setActionButtonEnabled(WhichButton.POSITIVE, charSequence.isNotEmpty())\n                    }\n                    getInputField().setBackgroundColor(Color.TRANSPARENT)\n                    getInputLayout().setBoxBackgroundColorResource(android.R.color.transparent)\n                    positiveButton(text = \"Crear\") { dialog ->\n                        val input = dialog.getInputField().text.toString()\n                        if (categories.contains(input)) {\n                            Toaster.toast(\"Esta categoría ya existe\")\n                            showNewCategory(input)\n                        } else {\n                            doAsync {\n                                edited?.let {\n                                    it.category = input\n                                    CacheDB.INSTANCE.favsDAO().addFav(it)\n                                    syncData { favs() }\n                                }\n                                doOnUI {\n                                    showAddToCategory(edited == null, input)\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private fun showCategoryRename(name: String) {\n        lifecycleScope.launch(Dispatchers.Main){\n            val categories = withContext(Dispatchers.IO) { FavoriteObject.getCategories(CacheDB.INSTANCE.favsDAO().categories) }\n            context?.let {\n                MaterialDialog(it).safeShow {\n                    title(text = \"Renombrar categoría\")\n                    input(hint = \"Nombre\", prefill = name, waitForPositiveButton = false) { dialog, charSequence ->\n                        dialog.setActionButtonEnabled(WhichButton.POSITIVE, charSequence.isNotEmpty())\n                    }\n                    getInputField().setBackgroundColor(Color.TRANSPARENT)\n                    getInputLayout().setBoxBackgroundColorResource(android.R.color.transparent)\n                    positiveButton(text = \"Renombrar\") { dialog ->\n                        val input = dialog.getInputField().text.toString()\n                        if (categories.contains(input)) {\n                            Toaster.toast(\"Esta categoría ya existe\")\n                            showCategoryRename(name)\n                        } else {\n                            doAsync {\n                                val objects = CacheDB.INSTANCE.favsDAO().getAllInCategory(name)\n                                for (favoriteObject in objects) {\n                                    favoriteObject.category = input\n                                }\n                                CacheDB.INSTANCE.favsDAO().addAll(objects)\n                                syncData { favs() }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private fun showAddToCategory(needAnimes: Boolean, name: String) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            val fName = if (name == \"Sin categoría\") FavoriteObject.CATEGORY_NONE else name\n            val favoriteObjects = withContext(Dispatchers.IO) { CacheDB.INSTANCE.favsDAO().getNotInCategory(fName) }\n            if (favoriteObjects.isEmpty()) {\n                if (needAnimes)\n                    Toaster.toast(\"Necesitas favoritos para crear una categoría\")\n                else\n                    Toaster.toast(\"No hay mas animes para agregar\")\n            } else {\n                context?.let {\n                    MaterialDialog(it).safeShow {\n                        title(text = name)\n                        listItemsMultiChoice(items = FavoriteObject.getNames(favoriteObjects)) { _, indices, _ ->\n                            if (needAnimes && indices.isEmpty()) {\n                                Toaster.toast(\"La nueva categoría necesita animes!\")\n                                showAddToCategory(needAnimes, name)\n                            } else {\n                                doAsync {\n                                    edited = null\n                                    val list = ArrayList<FavoriteObject>()\n                                    for (i in indices) {\n                                        val favoriteObject = favoriteObjects[i]\n                                        favoriteObject.category = fName\n                                        list.add(favoriteObject)\n                                    }\n                                    CacheDB.INSTANCE.favsDAO().addAll(list)\n                                    syncData { favs() }\n                                }\n                            }\n                        }\n                        positiveButton(text = \"agregar\")\n                        if (!needAnimes)\n                            negativeButton(text = \"Cancelar\")\n                    }\n                }\n            }\n        }\n    }\n\n    private fun showDeleteCategory(name: String) {\n        context?.let {\n            MaterialDialog(it).safeShow {\n                message(text = \"¿Desea eliminar esta categoría?\")\n                positiveButton(text = \"Eliminar\") {\n                    doAsync {\n                        val objects = CacheDB.INSTANCE.favsDAO().getAllInCategory(name)\n                        for (favoriteObject in objects) {\n                            favoriteObject.category = FavoriteObject.CATEGORY_NONE\n                        }\n                        CacheDB.INSTANCE.favsDAO().addAll(objects)\n                        syncData { favs() }\n                    }\n                }\n                negativeButton(text = \"Cancelar\")\n            }\n        }\n\n    }\n\n    private fun showNewCategoryInit(isEdit: Boolean, name: String) {\n        lifecycleScope.launch(Dispatchers.Main) {\n            val fName = if (name == \"Sin categoría\") FavoriteObject.CATEGORY_NONE else name\n            val favoriteObjects = withContext(Dispatchers.IO) { CacheDB.INSTANCE.favsDAO().getNotInCategory(fName) }\n            if (favoriteObjects.isEmpty()) {\n                Toaster.toast(\"Necesitas favoritos para crear una categoría\")\n            } else {\n                val isNotDefault = isEdit && fName != FavoriteObject.CATEGORY_NONE\n                context?.let {\n                    MaterialDialog(it).safeShow {\n                        title(text = name)\n                        listItemsMultiChoice(items = FavoriteObject.getNames(favoriteObjects)) { _, indices, _ ->\n                            edited = null\n                            val list = ArrayList<FavoriteObject>()\n                            for (i in indices) {\n                                val favoriteObject = favoriteObjects[i]\n                                favoriteObject.category = fName\n                                list.add(favoriteObject)\n                            }\n                            doAsync {\n                                CacheDB.INSTANCE.favsDAO().addAll(list)\n                                syncData { favs() }\n                            }\n                        }\n                        positiveButton(text = \"agregar\")\n                        if (isNotDefault || !isEdit)\n                            negativeButton(text =\n                            when {\n                                isNotDefault -> \"cancelar\"\n                                !isEdit -> \"atras\"\n                                else -> \"\"\n                            }) {\n                                if (isNotDefault)\n                                    MaterialDialog(context).safeShow {\n                                        message(text = \"¿Desea eliminar esta categoría?\")\n                                        positiveButton(text = \"continuar\") {\n                                            edited = null\n                                            doAsync {\n                                                val objects = CacheDB.INSTANCE.favsDAO().getAllInCategory(fName)\n                                                for (favoriteObject in objects) {\n                                                    favoriteObject.category = FavoriteObject.CATEGORY_NONE\n                                                }\n                                                CacheDB.INSTANCE.favsDAO().addAll(objects)\n                                                syncData { favs() }\n                                            }\n                                        }\n                                    }\n                                else if (!isEdit)\n                                    showNewCategoryDialog(true, name)\n                            }\n                        if (!isEdit)\n                            setOnCancelListener { showNewCategoryDialog(true, name) }\n                    }\n                }\n            }\n        }\n    }\n\n    override fun onEdit(category: String) {\n        if (category == \"Sin categoría\")\n            showAddToCategory(false, category)\n        else\n            context?.let {\n                MaterialDialog(it).safeShow {\n                    title(text = category)\n                    listItems(items = listOf(\"Renombrar\", \"Agregar animes\", \"Eliminar sección\")) { _, index, _ ->\n                        when (index) {\n                            0 -> showCategoryRename(category)\n                            1 -> showAddToCategory(false, category)\n                            2 -> showDeleteCategory(category)\n                        }\n                    }\n                }\n            }\n\n        //showNewCategoryInit(true, category)\n    }\n\n    override fun onSelect(favoriteObject: FavoriteObject) {\n        if (favoriteObject !is FavSection) {\n            lifecycleScope.launch(Dispatchers.Main) {\n                val categories = withContext(Dispatchers.IO) { FavoriteObject.getCategories(CacheDB.INSTANCE.favsDAO().categories) }\n                if (categories.size <= 1) {\n                    edited = favoriteObject\n                    showNewCategory(null)\n                } else {\n                    context?.let { context ->\n                        MaterialDialog(context).safeShow {\n                            title(text = \"Mover a...\")\n                            listItemsSingleChoice(items = categories, initialSelection = categories.indexOf(favoriteObject.category)) { _, _, text ->\n                                doAsync {\n                                    if (text != favoriteObject.category) {\n                                        edited = favoriteObject.also {\n                                            it.category = if (text == \"Sin categoría\") \"_NONE_\" else text.toString()\n                                            CacheDB.INSTANCE.favsDAO().addFav(it)\n                                            syncData { favs() }\n                                        }\n                                    } else\n                                        Toaster.toast(\"Error al mover\")\n                                }\n                            }\n                            positiveButton(text = \"mover\")\n                            negativeButton(text = \"nuevo\") {\n                                edited = favoriteObject\n                                showNewCategory(null)\n                            }\n                        }\n                    }\n\n                }\n            }\n        }\n    }\n\n    override fun onReselect() {\n        EAHelper.enter1(\"F\")\n        manager?.let {\n            it.smoothScrollToPosition(recyclerView, null, 0)\n            count++\n            if (count == 3) {\n                lifecycleScope.launch(Dispatchers.IO){\n                    if (adapter != null)\n                        Toaster.toast(\"Tienes \" + CacheDB.INSTANCE.favsDAO().count + \" animes en favoritos\")\n                    count = 0\n                }\n            }\n        }\n    }\n\n    companion object {\n\n        fun get(): FavoriteFragmentMaterial {\n            return FavoriteFragmentMaterial()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/favorite/FavoriteViewModel.kt",
    "content": "package knf.kuma.favorite\n\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.ViewModel\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.FavoriteObject\n\nclass FavoriteViewModel : ViewModel() {\n\n    fun getData(): LiveData<MutableList<FavoriteObject>> {\n        return if (PrefsUtil.showFavSections())\n            FavSectionHelper.init()\n        else\n            when (PrefsUtil.favsOrder) {\n                1 -> CacheDB.INSTANCE.favsDAO().allID\n                else -> CacheDB.INSTANCE.favsDAO().all\n            }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/favorite/FavsSectionAdapter.kt",
    "content": "package knf.kuma.favorite\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageButton\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport knf.kuma.R\nimport knf.kuma.ads.AdCallback\nimport knf.kuma.ads.AdCardItemHolder\nimport knf.kuma.ads.AdFavoriteObject\nimport knf.kuma.ads.AdsUtilsMob\nimport knf.kuma.ads.implAdsFavorite\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.favorite.objects.InfoContainer\nimport knf.kuma.pojos.FavoriteObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\n\n\nclass FavsSectionAdapter(private val fragment: Fragment, private val recyclerView: FastScrollRecyclerView, private val showSections: Boolean) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), FastScrollRecyclerView.SectionedAdapter {\n\n    private val context: Context?\n    private val listener: OnMoveListener\n    private val orderType = PrefsUtil.favsOrder\n    private var list: MutableList<FavoriteObject> = ArrayList()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_fav\n        } else {\n            R.layout.item_fav_grid\n        }\n\n    init {\n        this.listener = fragment as OnMoveListener\n        this.context = fragment.context\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {\n        return when (viewType) {\n            TYPE_HEADER -> HeaderHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_fav_header, parent, false))\n            TYPE_ITEM -> ItemHolder(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n            TYPE_AD -> AdCardItemHolder(parent, AdCardItemHolder.TYPE_FAV).also {\n                it.loadAd(fragment.lifecycleScope, object : AdCallback {\n                    override fun getID(): String = AdsUtilsMob.FAVORITE_BANNER\n                }, 500)\n            }\n            else -> HeaderHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_fav_header, parent, false))\n        }\n    }\n\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\n        val favoriteObject = list[position]\n        if (holder is HeaderHolder) {\n            holder.header.text = favoriteObject.name\n            holder.action.setOnClickListener { listener.onEdit(favoriteObject.name ?: \"\") }\n        } else if (holder is ItemHolder) {\n            holder.imageView.load(PatternUtil.getCover(favoriteObject.aid ?: \"\"))\n            holder.title.text = favoriteObject.name\n            holder.type.text = favoriteObject.type\n            holder.cardView.setOnClickListener { ActivityAnime.open(fragment, favoriteObject, holder.imageView) }\n            if (showSections)\n                holder.cardView.setOnLongClickListener {\n                    listener.onSelect(favoriteObject)\n                    true\n                }\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    override fun getItemViewType(position: Int): Int {\n        return try {\n            if (list[position] is AdFavoriteObject) FavsSectionAdapterMaterial.TYPE_AD else if (list[position].isSection) FavsSectionAdapterMaterial.TYPE_HEADER else FavsSectionAdapterMaterial.TYPE_ITEM\n        } catch (_: Exception) {\n            FavsSectionAdapterMaterial.TYPE_ITEM\n        }\n    }\n\n    override fun getSectionName(position: Int): String {\n        return try {\n            if (showSections)\n                \"\"\n            else\n                when (orderType) {\n                    0 -> {\n                        val name = list[position].name\n                        if (name.isNotEmpty())\n                            name.substring(0, 1).uppercase()\n                        else\n                            name\n                    }\n                    else -> list[position].aid\n                }\n        } catch (_: IllegalStateException) {\n            \"\"\n        }\n    }\n\n    fun updatePosition(container: InfoContainer) {\n        val nlist = container.updated\n        if (!nlist.isNullOrEmpty() && container.from != -1 && container.to != -1) {\n            list = nlist\n            recyclerView.post { notifyItemMoved(container.from, container.to) }\n        }\n    }\n\n    fun updateList(list: MutableList<FavoriteObject>) {\n        fragment.lifecycleScope.launch(Dispatchers.IO) {\n            this@FavsSectionAdapter.list = list\n            if (PrefsUtil.layType == \"0\" && PrefsUtil.isNativeAdsEnabled)\n                this@FavsSectionAdapter.list.implAdsFavorite()\n            recyclerView.post { this@FavsSectionAdapter.notifyDataSetChanged() }\n        }\n    }\n\n    internal interface OnMoveListener {\n        fun onSelect(favoriteObject: FavoriteObject)\n\n        fun onEdit(category: String)\n    }\n\n    internal class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val type: TextView by itemView.bind(R.id.type)\n    }\n\n    internal class HeaderHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val header: TextView by itemView.bind(R.id.header)\n        val action: ImageButton by itemView.bind(R.id.action)\n    }\n\n    companion object {\n        internal const val TYPE_HEADER = 0\n        internal const val TYPE_ITEM = 1\n        internal const val TYPE_AD = 2\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/favorite/FavsSectionAdapterMaterial.kt",
    "content": "package knf.kuma.favorite\n\nimport android.content.Context\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageButton\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport knf.kuma.R\nimport knf.kuma.ads.AdCallback\nimport knf.kuma.ads.AdCardItemHolder\nimport knf.kuma.ads.AdFavoriteObject\nimport knf.kuma.ads.AdsUtilsMob\nimport knf.kuma.ads.implAdsFavorite\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.favorite.objects.InfoContainer\nimport knf.kuma.pojos.FavoriteObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\n\n\nclass FavsSectionAdapterMaterial(private val fragment: Fragment, private val recyclerView: FastScrollRecyclerView, private val showSections: Boolean) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), FastScrollRecyclerView.SectionedAdapter {\n\n    private val context: Context?\n    private val listener: OnMoveListener\n    private val orderType = PrefsUtil.favsOrder\n    private var list: MutableList<FavoriteObject> = ArrayList()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_fav_material\n        } else {\n            R.layout.item_fav_grid_material\n        }\n\n    init {\n        this.listener = fragment as OnMoveListener\n        this.context = fragment.context\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {\n        return when (viewType) {\n            TYPE_HEADER -> HeaderHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_fav_header, parent, false))\n            TYPE_ITEM -> ItemHolder(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n            TYPE_AD -> AdCardItemHolder(parent, AdCardItemHolder.TYPE_FAV).also {\n                it.loadAd(fragment.lifecycleScope, object : AdCallback {\n                    override fun getID(): String = AdsUtilsMob.FAVORITE_BANNER\n                }, 500)\n            }\n            else -> HeaderHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_fav_header, parent, false))\n        }\n    }\n\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\n        if (list.size == 0) return\n        val favoriteObject = list[position]\n        if (holder is HeaderHolder) {\n            holder.header.text = favoriteObject.name\n            holder.action.setOnClickListener { listener.onEdit(favoriteObject.name ?: \"\") }\n        } else if (holder is ItemHolder) {\n            holder.imageView.load(PatternUtil.getCover(favoriteObject.aid ?: \"\"))\n            holder.title.text = favoriteObject.name\n            holder.type.text = favoriteObject.type\n            holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(fragment, favoriteObject, holder.imageView) }\n            if (showSections)\n                holder.cardView.setOnLongClickListener {\n                    listener.onSelect(favoriteObject)\n                    true\n                }\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    override fun getItemViewType(position: Int): Int {\n        return try {\n            if (list[position] is AdFavoriteObject) TYPE_AD else if (list[position].isSection) TYPE_HEADER else TYPE_ITEM\n        } catch (_: Exception) {\n            TYPE_ITEM\n        }\n    }\n\n    override fun getSectionName(position: Int): String {\n        return try {\n            if (showSections)\n                \"\"\n            else\n                when (orderType) {\n                    0 -> {\n                        val name = list[position].name\n                        if (name.isNotEmpty())\n                            name.substring(0, 1).uppercase()\n                        else\n                            name\n                    }\n                    else -> list[position].aid\n                }\n        } catch (_: IllegalStateException) {\n            \"\"\n        }\n    }\n\n    fun updatePosition(container: InfoContainer) {\n        val nlist = container.updated\n        if (!nlist.isNullOrEmpty() && container.from != -1 && container.to != -1) {\n            list = nlist\n            recyclerView.post { notifyItemMoved(container.from, container.to) }\n        }\n    }\n\n    fun updateList(list: MutableList<FavoriteObject>) {\n        fragment.lifecycleScope.launch(Dispatchers.IO) {\n            this@FavsSectionAdapterMaterial.list = list\n            if (PrefsUtil.layType == \"0\" && PrefsUtil.isNativeAdsEnabled)\n                this@FavsSectionAdapterMaterial.list.implAdsFavorite()\n            recyclerView.post { this@FavsSectionAdapterMaterial.notifyDataSetChanged() }\n        }\n    }\n\n    internal interface OnMoveListener {\n        fun onSelect(favoriteObject: FavoriteObject)\n\n        fun onEdit(category: String)\n    }\n\n    internal class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val type: TextView by itemView.bind(R.id.type)\n    }\n\n    internal class HeaderHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val header: TextView by itemView.bind(R.id.header)\n        val action: ImageButton by itemView.bind(R.id.action)\n    }\n\n    companion object {\n        internal const val TYPE_HEADER = 0\n        internal const val TYPE_ITEM = 1\n        internal const val TYPE_AD = 2\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/favorite/objects/FavSorter.kt",
    "content": "package knf.kuma.favorite.objects\n\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.pojos.FavoriteObject\n\nclass FavSorter : Comparator<FavoriteObject> {\n\n    override fun compare(o1: FavoriteObject, o2: FavoriteObject): Int {\n        return when (PrefsUtil.favsOrder) {\n            0 -> o1.name?.compareTo(o2.name ?: \"\") ?: 0\n            1 -> o1.aid?.compareTo(o2.aid ?: \"\") ?: 0\n            else -> o1.name?.compareTo(o2.name ?: \"\") ?: 0\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/favorite/objects/InfoContainer.kt",
    "content": "package knf.kuma.favorite.objects\n\nimport knf.kuma.pojos.FavSection\nimport knf.kuma.pojos.FavoriteObject\n\nclass InfoContainer {\n    var updated: MutableList<FavoriteObject>? = arrayListOf()\n    var needReload = false\n    var from: Int = 0\n    var to: Int = 0\n    private var current: MutableList<FavoriteObject>? = null\n\n    fun setLists(current: MutableList<FavoriteObject>, updated: MutableList<FavoriteObject>) {\n        this.current = ArrayList(current)\n        this.updated = ArrayList(updated)\n    }\n\n    fun reload(favoriteObject: FavoriteObject?) {\n        when {\n            favoriteObject == null -> needReload = true\n            favoriteObject is FavSection -> needReload = true\n            updated?.contains(favoriteObject) == false -> needReload = true\n            current?.size != updated?.size -> needReload = true\n            else -> {\n                needReload = false\n                from = current?.indexOf(favoriteObject) ?: -1\n                to = updated?.indexOf(favoriteObject) ?: -1\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/DirAdapter.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnime\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.directory.DirObject\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass DirAdapter(val fragment: HomeFragment) : UpdateableAdapter<DirAdapter.RecentViewHolder>() {\r\n\r\n    private var list: List<DirObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@DirAdapter.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card))\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        val item = list[position]\r\n        holder.img.load(PatternUtil.getCover(item.aid))\r\n        holder.title.text = item.name\r\n        holder.type?.text = \"\\u2605${item.rate_stars ?: \"?.?\"}\"\r\n        holder.root.onClick { ActivityAnime.open(fragment, item, holder.img, true, true) }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/DirAdapterMaterial.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.directory.DirObject\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass DirAdapterMaterial(val fragment: HomeFragmentMaterial) : UpdateableAdapter<DirAdapterMaterial.RecentViewHolder>() {\r\n\r\n    private var list: List<DirObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@DirAdapterMaterial.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card_material))\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        val item = list[position]\r\n        holder.img.load(PatternUtil.getCover(item.aid))\r\n        holder.title.text = item.name\r\n        holder.type?.text = \"\\u2605${item.rate_stars ?: \"?.?\"}\"\r\n        holder.root.onClick { ActivityAnimeMaterial.open(fragment, item) }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/HomeFragment.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.os.Bundle\r\nimport android.view.LayoutInflater\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.Toast\r\nimport androidx.fragment.app.viewModels\r\nimport androidx.lifecycle.Observer\r\nimport androidx.lifecycle.lifecycleScope\r\nimport com.google.firebase.Firebase\r\nimport com.google.firebase.crashlytics.crashlytics\r\nimport knf.kuma.BottomFragment\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsType\r\nimport knf.kuma.ads.implBanner\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.safeContext\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.databinding.FragmentHomeBinding\r\nimport knf.kuma.pojos.QueueObject\r\nimport knf.kuma.pojos.RecentObject\r\nimport knf.kuma.pojos.SeeingObject\r\nimport knf.kuma.queue.QueueActivity\r\nimport knf.kuma.recents.RecentsActivity\r\nimport knf.kuma.recents.RecentsViewModel\r\nimport knf.kuma.recommended.RecommendActivity\r\nimport knf.kuma.recommended.RecommendHelper\r\nimport knf.kuma.seeing.SeeingActivity\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.flow.drop\r\nimport kotlinx.coroutines.launch\r\nimport org.jetbrains.anko.doAsync\r\n\r\nclass HomeFragment : BottomFragment() {\r\n\r\n    private val viewModel: RecentsViewModel by viewModels()\r\n    private var lastNew: String = \"0\"\r\n    private lateinit var binding: FragmentHomeBinding\r\n\r\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\r\n        EAHelper.enter1(\"R\")\r\n        return inflater.inflate(R.layout.fragment_home, container, false).also {\r\n            binding = FragmentHomeBinding.bind(it)\r\n        }\r\n    }\r\n\r\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\r\n        super.onViewCreated(view, savedInstanceState)\r\n        binding.listNew.apply {\r\n            setAdapter(RecentsAdapter(this@HomeFragment, isLarge = false, showSeen = false))\r\n            setViewAllOnClick {\r\n                PrefsUtil.recentLastHiddenNew = lastNew.toInt()\r\n                binding.listNew.hide()\r\n            }\r\n        }\r\n        binding.listFavUpdated.apply {\r\n            setAdapter(RecentsAdapter(this@HomeFragment, true))\r\n            setViewAllClass(RecentsActivity::class.java)\r\n        }\r\n        binding.listBestEmission.setAdapter(DirAdapter(this))\r\n        binding.listPending.apply {\r\n            setAdapter(QueueAdapter(this@HomeFragment))\r\n            setViewAllClass(QueueActivity::class.java)\r\n        }\r\n        binding.listWaiting.apply {\r\n            setAdapter(WaitingAdapter(this@HomeFragment))\r\n            setViewAllClass(SeeingActivity::class.java)\r\n        }\r\n        binding.listRecommended.apply {\r\n            setAdapter(RecommendedAdapter(activity))\r\n            setViewAllClass(RecommendActivity::class.java)\r\n        }\r\n        binding.listRecommendedStaff.setAdapter(SearchAdapter(this))\r\n        lifecycleScope.launch(Dispatchers.IO) {\r\n            delay(1000)\r\n            binding.adContainer.implBanner(AdsType.RECENT_BANNER, true)\r\n            delay(500)\r\n            binding.adContainer2.implBanner(AdsType.RECENT_BANNER2, true)\r\n        }\r\n        lifecycleScope.launch {\r\n            viewModel.dbFlow.collect { list ->\r\n                if (list.isNotEmpty()) {\r\n                    doAsync {\r\n                        try {\r\n                            binding.listNew.updateList(filterNew(list.filter { it.isNew }))\r\n                            val favFiltered = list.filter { CacheDB.INSTANCE.favsDAO().isFav(it.aid.toInt()) }\r\n                            if (favFiltered.isEmpty()) {\r\n                                binding.listFavUpdated.apply {\r\n                                    setSubheader(\"Ultimos actualizados\")\r\n                                    setError(\"Recientes no actualizados\")\r\n                                    updateList(list)\r\n                                }\r\n                            } else {\r\n                                binding.listFavUpdated.apply {\r\n                                    setSubheader(\"Favoritos actualizados\")\r\n                                    updateList(favFiltered)\r\n                                }\r\n                            }\r\n                        } catch (e: Exception) {\r\n                            Firebase.crashlytics.recordException(e)\r\n                            lifecycleScope.launch(Dispatchers.Main) {\r\n                                Toast.makeText(safeContext, \"Error al mostrar recientes: ${e.message}\", Toast.LENGTH_LONG).show()\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        lifecycleScope.launch {\r\n            CacheDB.INSTANCE.favsDAO().countFlow.drop(1).collect {\r\n                doAsync {\r\n                    val cached = CacheDB.INSTANCE.recentsDAO().all\r\n                    val filtered = cached.filter {\r\n                        CacheDB.INSTANCE.favsDAO().isFav(it.aid.toInt())\r\n                    }\r\n                    binding.listFavUpdated.apply {\r\n                        if (filtered.isEmpty()) {\r\n                            setSubheader(\"Ultimos actualizados\")\r\n                            setError(\"Recientes no actualizados\")\r\n                            updateList(cached)\r\n                        } else {\r\n                            setSubheader(\"Favoritos actualizados\")\r\n                            updateList(filtered)\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        CacheDB.INSTANCE.favsDAO().countLive.observe(viewLifecycleOwner, Observer {\r\n            RecommendHelper.createRecommended {\r\n                binding.listRecommended.updateList(it)\r\n            }\r\n        })\r\n        CacheDB.INSTANCE.animeDAO().emissionVotesLimited.observe(viewLifecycleOwner, Observer {\r\n            binding.listBestEmission.updateList(it)\r\n        })\r\n        CacheDB.INSTANCE.queueDAO().all.observe(viewLifecycleOwner, Observer {\r\n            doAsync { binding.listPending.updateList(QueueObject.takeOne(it)) }\r\n        })\r\n        CacheDB.INSTANCE.seeingDAO().getAllWState(SeeingObject.STATE_CONSIDERING, SeeingObject.STATE_PAUSED).observe(viewLifecycleOwner, Observer {\r\n            binding.listWaiting.updateList(it)\r\n        })\r\n        StaffRecommendations.createList {\r\n            binding.listRecommendedStaff.updateList(it)\r\n        }\r\n        viewModel.reload()\r\n    }\r\n\r\n    private fun filterNew(list: List<RecentObject>): List<RecentObject> {\r\n        if (list.isNotEmpty()) {\r\n            lastNew = list[0].aid\r\n            if (list[0].aid.toInt() == PrefsUtil.recentLastHiddenNew)\r\n                return emptyList()\r\n        }\r\n        return list\r\n    }\r\n\r\n    override fun onReselect() {\r\n        EAHelper.enter1(\"R\")\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/HomeFragmentMaterial.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.os.Bundle\r\nimport android.view.LayoutInflater\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.Toast\r\nimport androidx.fragment.app.viewModels\r\nimport androidx.lifecycle.Observer\r\nimport androidx.lifecycle.lifecycleScope\r\nimport com.google.firebase.Firebase\r\nimport com.google.firebase.crashlytics.crashlytics\r\nimport knf.kuma.BottomFragment\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsType\r\nimport knf.kuma.ads.implBanner\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.noCrashSuspend\r\nimport knf.kuma.commons.safeContext\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.databinding.FragmentHomeMaterialBinding\r\nimport knf.kuma.pojos.QueueObject\r\nimport knf.kuma.pojos.RecentObject\r\nimport knf.kuma.pojos.SeeingObject\r\nimport knf.kuma.queue.QueueActivityMaterial\r\nimport knf.kuma.recents.RecentsModelActivity\r\nimport knf.kuma.recents.RecentsViewModel\r\nimport knf.kuma.recommended.RecommendActivityMaterial\r\nimport knf.kuma.recommended.RecommendHelper\r\nimport knf.kuma.seeing.SeeingActivityMaterial\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.flow.drop\r\nimport kotlinx.coroutines.launch\r\nimport org.jetbrains.anko.doAsync\r\n\r\nclass HomeFragmentMaterial : BottomFragment() {\r\n\r\n    private val viewModel: RecentsViewModel by viewModels()\r\n    private var lastNew: String = \"0\"\r\n    private lateinit var binding: FragmentHomeMaterialBinding\r\n\r\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\r\n        EAHelper.enter1(\"R\")\r\n        return inflater.inflate(R.layout.fragment_home_material, container, false).also {\r\n            binding = FragmentHomeMaterialBinding.bind(it)\r\n        }\r\n    }\r\n\r\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\r\n        super.onViewCreated(view, savedInstanceState)\r\n        binding.listNew.apply {\r\n            setAdapter(RecentsAdapterMaterial(this@HomeFragmentMaterial, isLarge = false, showSeen = false))\r\n            setViewAllOnClick {\r\n                PrefsUtil.recentLastHiddenNew = lastNew.toInt()\r\n                binding.listNew.hide()\r\n            }\r\n        }\r\n        binding.listFavUpdated.apply {\r\n            setAdapter(RecentsAdapterMaterial(this@HomeFragmentMaterial, true))\r\n            setViewAllClass(RecentsModelActivity::class.java)\r\n        }\r\n        binding.listBestEmission.setAdapter(DirAdapterMaterial(this))\r\n        binding.listPending.apply {\r\n            setAdapter(QueueAdapterMaterial(this@HomeFragmentMaterial))\r\n            setViewAllClass(QueueActivityMaterial::class.java)\r\n        }\r\n        binding.listWaiting.apply {\r\n            setAdapter(WaitingAdapterMaterial(this@HomeFragmentMaterial))\r\n            setViewAllClass(SeeingActivityMaterial::class.java)\r\n        }\r\n        binding.listRecommended.apply {\r\n            setAdapter(RecommendedAdapterMaterial(activity))\r\n            setViewAllClass(RecommendActivityMaterial::class.java)\r\n        }\r\n        binding.listRecommendedStaff.setAdapter(SearchAdapterMaterial(this))\r\n        lifecycleScope.launch(Dispatchers.IO) {\r\n            noCrashSuspend {\r\n                delay(1000)\r\n                binding.adContainer.implBanner(AdsType.RECENT_BANNER, true)\r\n                delay(500)\r\n                binding.adContainer2.implBanner(AdsType.RECENT_BANNER2, true)\r\n            }\r\n        }\r\n        lifecycleScope.launch {\r\n            viewModel.dbFlow.collect { list ->\r\n                if (list.isNotEmpty()) {\r\n                    doAsync {\r\n                        try {\r\n                            binding.listNew.updateList(filterNew(list.filter { it.isNew }))\r\n                            val favFiltered = list.filter { CacheDB.INSTANCE.favsDAO().isFav(it.aid.toInt()) }\r\n                            if (favFiltered.isEmpty()) {\r\n                                binding.listFavUpdated.apply {\r\n                                    setSubheader(\"Ultimos actualizados\")\r\n                                    setError(\"Recientes no actualizados\")\r\n                                    updateList(list)\r\n                                }\r\n                            } else {\r\n                                binding.listFavUpdated.apply {\r\n                                    setSubheader(\"Favoritos actualizados\")\r\n                                    updateList(favFiltered)\r\n                                }\r\n                            }\r\n                        } catch (e: Exception) {\r\n                            Firebase.crashlytics.recordException(e)\r\n                            lifecycleScope.launch(Dispatchers.Main) {\r\n                                Toast.makeText(safeContext, \"Error al mostrar recientes: ${e.message}\", Toast.LENGTH_LONG).show()\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        lifecycleScope.launch {\r\n            CacheDB.INSTANCE.favsDAO().countFlow.drop(1).collect {\r\n                doAsync {\r\n                    val cached = CacheDB.INSTANCE.recentsDAO().all\r\n                    val filtered = cached.filter {\r\n                        CacheDB.INSTANCE.favsDAO().isFav(it.aid.toInt())\r\n                    }\r\n                    binding.listFavUpdated.apply {\r\n                        if (filtered.isEmpty()) {\r\n                            setSubheader(\"Ultimos actualizados\")\r\n                            setError(\"Recientes no actualizados\")\r\n                            updateList(cached)\r\n                        } else {\r\n                            setSubheader(\"Favoritos actualizados\")\r\n                            updateList(filtered)\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        CacheDB.INSTANCE.favsDAO().countLive.observe(viewLifecycleOwner, Observer {\r\n            RecommendHelper.createRecommended {\r\n                binding.listRecommended.updateList(it)\r\n            }\r\n        })\r\n        CacheDB.INSTANCE.animeDAO().emissionVotesLimited.observe(viewLifecycleOwner, Observer {\r\n            binding.listBestEmission.updateList(it)\r\n        })\r\n        CacheDB.INSTANCE.queueDAO().all.observe(viewLifecycleOwner, Observer {\r\n            doAsync { binding.listPending.updateList(QueueObject.takeOne(it)) }\r\n        })\r\n        CacheDB.INSTANCE.seeingDAO().getAllWState(SeeingObject.STATE_CONSIDERING, SeeingObject.STATE_PAUSED).observe(viewLifecycleOwner, Observer {\r\n            binding.listWaiting.updateList(it)\r\n        })\r\n        StaffRecommendations.createList {\r\n            binding.listRecommendedStaff.updateList(it)\r\n        }\r\n        viewModel.reload()\r\n    }\r\n\r\n    private fun filterNew(list: List<RecentObject>): List<RecentObject> {\r\n        if (list.isNotEmpty()) {\r\n            lastNew = list[0].aid\r\n            if (list[0].aid.toInt() == PrefsUtil.recentLastHiddenNew)\r\n                return emptyList()\r\n        }\r\n        return list\r\n    }\r\n\r\n    override fun onReselect() {\r\n        EAHelper.enter1(\"R\")\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/QueueAdapter.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.QueueObject\r\nimport knf.kuma.queue.QueueActivity\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\nimport java.util.Locale\r\n\r\nclass QueueAdapter(val fragment: HomeFragment) : UpdateableAdapter<QueueAdapter.RecentViewHolder>() {\r\n\r\n    private var list: List<QueueObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@QueueAdapter.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card))\r\n\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        val item = list[position]\r\n        noCrash {\r\n            holder.img.load(PatternUtil.getCover(item.chapter.aid))\r\n            holder.title.text = item.chapter.name\r\n            holder.type?.text = String.format(Locale.getDefault(), if (item.count == 1) \"%d episodio\" else \"%d episodios\", item.count)\r\n        }\r\n        holder.root.onClick {\r\n            try {\r\n                QueueActivity.open(fragment.context, item.chapter.aid)\r\n            } catch (e: Exception) {\r\n                doAsync {\r\n                    CacheDB.INSTANCE.queueDAO().allRaw.forEach {\r\n                        try {\r\n                            it.chapter.aid\r\n                        } catch (e: Exception) {\r\n                            CacheDB.INSTANCE.queueDAO().remove(it)\r\n                        }\r\n                    }\r\n                    syncData { queue() }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/QueueAdapterMaterial.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.QueueObject\r\nimport knf.kuma.queue.QueueActivityMaterial\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\nimport java.util.Locale\r\n\r\nclass QueueAdapterMaterial(val fragment: HomeFragmentMaterial) : UpdateableAdapter<QueueAdapterMaterial.RecentViewHolder>() {\r\n\r\n    private var list: List<QueueObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@QueueAdapterMaterial.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card_material))\r\n\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        val item = list[position]\r\n        noCrash {\r\n            holder.img.load(PatternUtil.getCover(item.chapter.aid))\r\n            holder.title.text = item.chapter.name\r\n            holder.type?.text = String.format(Locale.getDefault(), if (item.count == 1) \"%d episodio\" else \"%d episodios\", item.count)\r\n        }\r\n        holder.root.onClick {\r\n            try {\r\n                QueueActivityMaterial.open(fragment.context, item.chapter.aid)\r\n            } catch (e: Exception) {\r\n                doAsync {\r\n                    CacheDB.INSTANCE.queueDAO().allRaw.forEach {\r\n                        try {\r\n                            it.chapter.aid\r\n                        } catch (e: Exception) {\r\n                            CacheDB.INSTANCE.queueDAO().remove(it)\r\n                        }\r\n                    }\r\n                    syncData { queue() }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/RecentsAdapter.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnime\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.custom.SeenAnimeOverlay\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.RecentObject\r\nimport knf.kuma.pojos.SeenObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\nimport org.jetbrains.anko.sdk27.coroutines.onLongClick\r\n\r\nclass RecentsAdapter(val fragment: HomeFragment, private val isLarge: Boolean = true, private val showSeen: Boolean = true) : UpdateableAdapter<RecentsAdapter.RecentViewHolder>() {\r\n\r\n    private var list: List<RecentObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@RecentsAdapter.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(if (isLarge) R.layout.item_fav_grid_card else R.layout.item_fav_grid_card_simple))\r\n\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        if (list.isEmpty()) return\r\n        val item = list[position]\r\n        holder.img.load(item.img)\r\n        holder.title.text = item.name\r\n        holder.type?.text = item.chapter\r\n        holder.root.onClick {\r\n            if (item.animeObject != null) {\r\n                ActivityAnime.open(fragment, item.animeObject, holder.img)\r\n            } else {\r\n                fragment.lifecycleScope.launch(Dispatchers.Main) {\r\n                    val animeObject = withContext(Dispatchers.IO) { CacheDB.INSTANCE.animeDAO().getByAid(item.aid) }\r\n                    if (animeObject != null) {\r\n                        ActivityAnime.open(fragment, animeObject, holder.img)\r\n                    } else {\r\n                        ActivityAnime.open(fragment, item, holder.img)\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        if (showSeen) {\r\n            holder.seenOverlay.setSeen(item.isSeen, false)\r\n            holder.root.onLongClick(returnValue = true) {\r\n                if (item.isSeen) {\r\n                    doAsync {\r\n                        CacheDB.INSTANCE.seenDAO().deleteChapter(item.aid, item.chapter)\r\n                    }\r\n                    item.isSeen = false\r\n                    holder.seenOverlay.setSeen(seen = false, animate = true)\r\n                } else {\r\n                    doAsync {\r\n                        CacheDB.INSTANCE.seenDAO().addChapter(SeenObject.fromRecent(item))\r\n                    }\r\n                    item.isSeen = true\r\n                    holder.seenOverlay.setSeen(seen = true, animate = true)\r\n                }\r\n                syncData { seen() }\r\n            }\r\n        }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val seenOverlay: SeenAnimeOverlay by itemView.bind(R.id.seenOverlay)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/RecentsAdapterMaterial.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.custom.SeenAnimeOverlay\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.RecentObject\r\nimport knf.kuma.pojos.SeenObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\nimport org.jetbrains.anko.sdk27.coroutines.onLongClick\r\n\r\nclass RecentsAdapterMaterial(val fragment: HomeFragmentMaterial, private val isLarge: Boolean = true, private val showSeen: Boolean = true) : UpdateableAdapter<RecentsAdapterMaterial.RecentViewHolder>() {\r\n\r\n    private var list: List<RecentObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@RecentsAdapterMaterial.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(if (isLarge) R.layout.item_fav_grid_card_material else R.layout.item_fav_grid_card_simple_material))\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        if (list.isEmpty()) return\r\n        val item = list[position]\r\n        holder.img.load(PatternUtil.getCover(item.aid))\r\n        holder.title.text = item.name\r\n        holder.type?.text = item.chapter\r\n        holder.root.onClick {\r\n            if (item.animeObject != null) {\r\n                ActivityAnimeMaterial.open(fragment, item.animeObject, holder.img)\r\n            } else {\r\n                fragment.lifecycleScope.launch(Dispatchers.Main) {\r\n                    val animeObject = withContext(Dispatchers.IO) { CacheDB.INSTANCE.animeDAO().getByAid(item.aid) }\r\n                    if (animeObject != null) {\r\n                        ActivityAnimeMaterial.open(fragment, animeObject, holder.img)\r\n                    } else {\r\n                        ActivityAnimeMaterial.open(fragment, item, holder.img)\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        if (showSeen) {\r\n            holder.seenOverlay.setSeen(item.isSeen, false)\r\n            holder.root.onLongClick(returnValue = true) {\r\n                if (item.isSeen) {\r\n                    doAsync {\r\n                        CacheDB.INSTANCE.seenDAO().deleteChapter(item.aid, item.chapter)\r\n                    }\r\n                    item.isSeen = false\r\n                    holder.seenOverlay.setSeen(seen = false, animate = true)\r\n                } else {\r\n                    doAsync {\r\n                        CacheDB.INSTANCE.seenDAO().addChapter(SeenObject.fromRecent(item))\r\n                    }\r\n                    item.isSeen = true\r\n                    holder.seenOverlay.setSeen(seen = true, animate = true)\r\n                }\r\n                syncData { seen() }\r\n            }\r\n        }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val seenOverlay: SeenAnimeOverlay by itemView.bind(R.id.seenOverlay)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/RecommendedAdapter.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.app.Activity\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnime\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.recommended.AnimeShortObject\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass RecommendedAdapter(val activity: Activity?) : UpdateableAdapter<RecommendedAdapter.RecentViewHolder>() {\r\n\r\n    private var list: List<AnimeShortObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@RecommendedAdapter.list = list.transform()\r\n            doOnUIGlobal { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card))\r\n\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        val item = list[position]\r\n        holder.img.load(PatternUtil.getCover(item.aid))\r\n        holder.title.text = item.name\r\n        holder.type?.text = item.type\r\n        holder.root.onClick { ActivityAnime.open(activity, item, holder.img, true, true) }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/RecommendedAdapterMaterial.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.app.Activity\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.recommended.AnimeShortObject\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass RecommendedAdapterMaterial(val activity: Activity?) : UpdateableAdapter<RecommendedAdapterMaterial.RecentViewHolder>() {\r\n\r\n    private var list: List<AnimeShortObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@RecommendedAdapterMaterial.list = list.transform()\r\n            doOnUIGlobal { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card_material))\r\n\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        val item = list[position]\r\n        holder.img.load(PatternUtil.getCover(item.aid))\r\n        holder.title.text = item.name\r\n        holder.type?.text = item.type\r\n        holder.root.onClick { ActivityAnimeMaterial.open(activity, item, holder.img, true, true) }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/SearchAdapter.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnime\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.search.SearchAdvObject\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass SearchAdapter(val fragment: HomeFragment) : UpdateableAdapter<SearchAdapter.RecentViewHolder>() {\r\n\r\n    private var list: List<SearchAdvObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@SearchAdapter.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card))\r\n\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        val item = list[position]\r\n        holder.img.load(PatternUtil.getCover(item.aid))\r\n        holder.title.text = item.name\r\n        holder.type?.text = item.type\r\n        holder.root.onClick { ActivityAnime.open(fragment, item, holder.img, true, true) }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/SearchAdapterMaterial.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.optionalBind\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.search.SearchAdvObject\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass SearchAdapterMaterial(val fragment: HomeFragmentMaterial) : UpdateableAdapter<SearchAdapterMaterial.RecentViewHolder>() {\r\n\r\n    private var list: List<SearchAdvObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@SearchAdapterMaterial.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card_material))\r\n\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        val item = list[position]\r\n        holder.img.load(PatternUtil.getCover(item.aid))\r\n        holder.title.text = item.name\r\n        holder.type?.text = item.type\r\n        holder.root.onClick { ActivityAnimeMaterial.open(fragment, item, holder.img, true, true) }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n        val type: TextView? by itemView.optionalBind(R.id.type)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/StaffRecommendations.kt",
    "content": "package knf.kuma.home\r\n\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.directory.DirObject\r\nimport knf.kuma.search.SearchAdvObject\r\nimport org.jetbrains.anko.doAsync\r\n\r\nobject StaffRecommendations {\r\n    private val recommendations: List<String> = listOf(\r\n            \"2928\", \"2597\", \"1279\", \"1615\", \"363\", \"1706\", \"2950\", \"1182\", \"2479\", \"2478\", \"29\", \"30\", \"854\",\r\n            \"2508\", \"2702\", \"1976\", \"2526\", \"5\", \"1290\", \"2852\", \"937\", \"3043\", \"2091\", \"1165\", \"3105\", \"2104\",\r\n            \"108\", \"117\", \"996\", \"92\", \"1739\", \"1740\", \"181\", \"2671\", \"727\", \"1632\", \"2687\", \"3106\", \"1487\",\r\n            \"1488\", \"1019\", \"460\", \"1493\", \"1494\", \"918\", \"1294\", \"2485\", \"2833\", \"2340\", \"3033\", \"1008\", \"869\",\r\n            \"1286\", \"1791\", \"1044\", \"801\", \"901\", \"1048\", \"2279\", \"292\", \"28\", \"284\", \"2305\", \"1899\", \"2834\",\r\n            \"349\", \"1627\", \"312\", \"277\", \"1497\", \"711\", \"150\", \"2748\", \"2901\", \"2639\", \"2860\", \"638\", \"773\",\r\n            \"2959\", \"263\", \"1618\", \"1897\", \"2290\", \"125\", \"1324\", \"2533\", \"2636\", \"2789\", \"2395\", \"1028\", \"904\",\r\n            \"721\", \"1753\", \"2794\", \"1813\", \"3104\", \"1912\", \"853\", \"661\", \"840\", \"2983\", \"310\", \"151\", \"863\",\r\n            \"2382\", \"2599\", \"992\", \"126\", \"609\", \"127\", \"787\", \"880\", \"128\", \"704\", \"1272\", \"31\", \"1347\", \"129\",\r\n            \"1554\", \"1555\", \"419\", \"1082\", \"2094\", \"1320\", \"1634\", \"1629\", \"8\", \"878\", \"1635\", \"2454\", \"1213\",\r\n            \"2229\", \"1638\", \"1443\", \"2150\", \"1486\", \"465\", \"640\", \"966\", \"967\", \"1095\", \"1474\", \"2659\", \"2126\",\r\n            \"978\", \"13\", \"2602\", \"2848\", \"1325\", \"364\", \"556\", \"1064\", \"1132\", \"557\", \"1322\", \"1930\", \"189\",\r\n            \"1209\", \"1427\", \"1001\", \"1681\", \"1617\", \"353\", \"953\", \"951\", \"952\", \"80\", \"860\", \"3001\", \"1222\",\r\n            \"897\", \"1195\", \"1092\", \"1179\", \"1091\", \"133\", \"417\", \"2954\", \"134\", \"1429\", \"42\", \"1196\", \"589\",\r\n            \"366\", \"1958\", \"862\", \"2660\", \"2802\", \"2874\", \"2984\", \"1909\", \"2846\", \"1135\", \"1132\", \"9\", \"1139\",\r\n            \"60\", \"593\", \"2661\", \"2652\", \"1237\", \"1915\", \"1297\", \"2287\", \"2767\", \"2111\", \"2840\", \"1316\", \"6\",\r\n            \"2100\", \"1576\", \"866\", \"849\", \"91\", \"719\", \"1031\", \"1870\", \"2947\", \"2998\", \"778\", \"2762\", \"1900\",\r\n            \"93\", \"2245\", \"2247\", \"174\", \"2491\", \"2657\", \"338\", \"986\", \"2295\", \"2233\", \"1428\", \"26\", \"27\",\r\n            \"1318\", \"2903\", \"49\", \"1620\", \"2536\", \"2895\", \"3065\", \"393\", \"40\", \"39\", \"10\", \"2588\", \"1127\",\r\n            \"118\", \"119\", \"299\", \"267\", \"268\", \"1780\", \"3113\", \"104\", \"639\", \"872\", \"1628\", \"1608\", \"1218\",\r\n            \"34\", \"2496\", \"1793\", \"2457\", \"2876\", \"1002\", \"2089\", \"226\", \"1208\", \"690\", \"2740\", \"2543\", \"2446\",\r\n            \"2586\", \"3137\", \"3011\", \"135\", \"136\", \"2110\"\r\n    )\r\n\r\n    fun randomIds(count: Int): List<String> = recommendations.shuffled().take(count)\r\n\r\n    fun createList(onCreate: (list: List<SearchAdvObject>) -> Unit) {\r\n        doAsync {\r\n            onCreate(CacheDB.INSTANCE.animeDAO().animesWithIDRandom(recommendations))\r\n        }\r\n    }\r\n\r\n    fun createDirList(onCreate: (list: List<DirObject>) -> Unit) {\r\n        doAsync {\r\n            onCreate(CacheDB.INSTANCE.animeDAO().animesDirWithIDRandom(recommendations))\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/UpdateableAdapter.kt",
    "content": "package knf.kuma.home\r\n\r\nimport androidx.recyclerview.widget.RecyclerView\r\n\r\nabstract class UpdateableAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>() {\r\n    abstract fun updateList(list: List<Any>)\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/WaitingAdapter.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnime\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.pojos.SeeingObject\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass WaitingAdapter(val fragment: HomeFragment) : UpdateableAdapter<WaitingAdapter.RecentViewHolder>() {\r\n\r\n    private var list: List<SeeingObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@WaitingAdapter.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card_simple))\r\n\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        noCrash {\r\n            val item = list[position]\r\n            holder.img.load(PatternUtil.getCover(item.aid))\r\n            holder.title.text = item.title\r\n            holder.root.onClick { ActivityAnime.open(fragment.activity, item) }\r\n        }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/home/WaitingAdapterMaterial.kt",
    "content": "package knf.kuma.home\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.bind\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.transform\r\nimport knf.kuma.pojos.SeeingObject\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass WaitingAdapterMaterial(val fragment: HomeFragmentMaterial) : UpdateableAdapter<WaitingAdapterMaterial.RecentViewHolder>() {\r\n\r\n    private var list: List<SeeingObject> = emptyList()\r\n\r\n    override fun updateList(list: List<Any>) {\r\n        doAsync {\r\n            this@WaitingAdapterMaterial.list = list.transform()\r\n            fragment.doOnUI { notifyDataSetChanged() }\r\n        }\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecentViewHolder = RecentViewHolder(parent.inflate(R.layout.item_fav_grid_card_simple_material))\r\n\r\n\r\n    override fun getItemCount(): Int = list.size\r\n\r\n    override fun onBindViewHolder(holder: RecentViewHolder, position: Int) {\r\n        noCrash {\r\n            val item = list[position]\r\n            holder.img.load(PatternUtil.getCover(item.aid))\r\n            holder.title.text = item.title\r\n            holder.root.onClick { ActivityAnimeMaterial.open(fragment.activity, item) }\r\n        }\r\n    }\r\n\r\n    class RecentViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val root: View by itemView.bind(R.id.card)\r\n        val img: ImageView by itemView.bind(R.id.img)\r\n        val title: TextView by itemView.bind(R.id.title)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/jobscheduler/BackUpWork.kt",
    "content": "package knf.kuma.jobscheduler\r\n\r\nimport android.content.Context\r\nimport androidx.work.BackoffPolicy\r\nimport androidx.work.ExistingPeriodicWorkPolicy\r\nimport androidx.work.PeriodicWorkRequestBuilder\r\nimport androidx.work.WorkManager\r\nimport androidx.work.Worker\r\nimport androidx.work.WorkerParameters\r\nimport knf.kuma.App\r\nimport knf.kuma.backup.Backups\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.safeContext\r\nimport knf.kuma.pojos.AutoBackupObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.runBlocking\r\nimport java.util.concurrent.TimeUnit\r\n\r\nclass BackUpWork(val context: Context, workerParameters: WorkerParameters) : Worker(context, workerParameters) {\r\n    override fun doWork(): Result {\r\n        val service = Backups.createService()\r\n        return if (service?.isLoggedIn == true) {\r\n            val backupObject = runBlocking(Dispatchers.IO) {\r\n                service.search(Backups.keyAutoBackup)\r\n            }\r\n            if (backupObject != null) {\r\n                if (backupObject == AutoBackupObject(context))\r\n                    Backups.backupAll()\r\n                else\r\n                    WorkManager.getInstance(context).cancelAllWorkByTag(TAG)\r\n            }\r\n            Result.success()\r\n        } else\r\n            Result.failure()\r\n    }\r\n\r\n    companion object {\r\n        internal const val TAG = \"backupObj-job\"\r\n\r\n        fun checkInit() {\r\n            GlobalScope.launch(Dispatchers.IO) {\r\n                val service = Backups.createService()\r\n                if (service?.isLoggedIn == true) {\r\n                    val obj = service.search(Backups.keyAutoBackup) as? AutoBackupObject\r\n                    val localObj = AutoBackupObject(App.context)\r\n                    if (obj == localObj) {\r\n                        val days = obj.value\r\n                        if (days.isNullOrBlank())\r\n                            service.backup(localObj, Backups.keyAutoBackup)\r\n                        else if (days != PrefsUtil.autoBackupTime) {\r\n                            PrefsUtil.autoBackupTime = days\r\n                            reSchedule(days.toInt())\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        fun reSchedule(days: Int) {\r\n            WorkManager.getInstance(safeContext).cancelAllWorkByTag(TAG)\r\n            if (days > 0) {\r\n                PeriodicWorkRequestBuilder<BackUpWork>(days.toLong(), TimeUnit.DAYS, 1, TimeUnit.HOURS).apply {\r\n                    setConstraints(networkConnectedConstraints())\r\n                    setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 5, TimeUnit.MINUTES)\r\n                    addTag(TAG)\r\n                }.build().enqueueUnique(TAG, ExistingPeriodicWorkPolicy.REPLACE)\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/jobscheduler/DirUpdateWork.kt",
    "content": "package knf.kuma.jobscheduler\r\n\r\nimport android.content.Context\r\nimport androidx.preference.PreferenceManager\r\nimport androidx.work.ExistingPeriodicWorkPolicy\r\nimport androidx.work.OneTimeWorkRequestBuilder\r\nimport androidx.work.PeriodicWorkRequestBuilder\r\nimport androidx.work.WorkManager\r\nimport androidx.work.Worker\r\nimport androidx.work.WorkerParameters\r\nimport knf.kuma.commons.Network\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.safeContext\r\nimport knf.kuma.directory.DirectoryService\r\nimport knf.kuma.directory.DirectoryUpdateService\r\nimport xdroid.toaster.Toaster\r\nimport java.util.concurrent.TimeUnit\r\n\r\nclass DirUpdateWork(val context: Context, workerParameters: WorkerParameters) : Worker(context, workerParameters) {\r\n    override fun doWork(): Result {\r\n        if (PrefsUtil.isDirectoryFinished && !DirectoryUpdateService.isRunning && !DirectoryService.isRunning)\r\n            DirectoryUpdateService.run(context)\r\n        return Result.success()\r\n    }\r\n\r\n    companion object {\r\n        const val TAG = \"dir-update-work-unique\"\r\n\r\n        fun schedule(context: Context) {\r\n            WorkManager.getInstance(context).cancelAllWorkByTag(\"dir-update-job\")\r\n            WorkManager.getInstance(context).cancelAllWorkByTag(\"dir-update-work\")\r\n            val preferences = PreferenceManager.getDefaultSharedPreferences(context)\r\n            val time = (preferences.getString(\"dir_update_time\", \"7\") ?: \"7\").toLong()\r\n            if (PrefsUtil.isDirectoryFinished && time > 0)\r\n                PeriodicWorkRequestBuilder<DirUpdateWork>(time, TimeUnit.DAYS, 1, TimeUnit.HOURS).apply {\r\n                    setConstraints(networkConnectedConstraints())\r\n                    addTag(TAG)\r\n                }.build().enqueueUnique(TAG, ExistingPeriodicWorkPolicy.KEEP)\r\n        }\r\n\r\n        fun reSchedule(value: Int) {\r\n            if (value > 0)\r\n                PeriodicWorkRequestBuilder<DirUpdateWork>(value.toLong(), TimeUnit.DAYS, 1, TimeUnit.HOURS).apply {\r\n                    setConstraints(networkConnectedConstraints())\r\n                    addTag(TAG)\r\n                }.build().enqueueUnique(TAG, ExistingPeriodicWorkPolicy.REPLACE)\r\n            else\r\n                WorkManager.getInstance(safeContext).cancelAllWorkByTag(TAG)\r\n        }\r\n\r\n        fun runNow() {\r\n            if (Network.isConnected) {\r\n                OneTimeWorkRequestBuilder<DirUpdateWork>().apply {\r\n                    addTag(TAG)\r\n                    setConstraints(networkConnectedConstraints())\r\n                }.build().enqueue()\r\n            } else {\r\n                Toaster.toast(\"Se necesita internet\")\r\n            }\r\n        }\r\n    }\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/jobscheduler/RecentsWork.kt",
    "content": "package knf.kuma.jobscheduler\r\n\r\nimport android.app.NotificationManager\r\nimport android.app.PendingIntent\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.graphics.Bitmap\r\nimport android.net.Uri\r\nimport android.os.Build\r\nimport android.util.Log\r\nimport androidx.core.app.NotificationCompat\r\nimport androidx.core.content.ContextCompat\r\nimport androidx.core.content.FileProvider\r\nimport androidx.preference.PreferenceManager\r\nimport androidx.tvprovider.media.tv.PreviewChannelHelper\r\nimport androidx.work.CoroutineWorker\r\nimport androidx.work.ExistingPeriodicWorkPolicy\r\nimport androidx.work.ForegroundInfo\r\nimport androidx.work.OneTimeWorkRequestBuilder\r\nimport androidx.work.PeriodicWorkRequestBuilder\r\nimport androidx.work.WorkManager\r\nimport androidx.work.WorkerParameters\r\nimport com.bumptech.glide.Glide\r\nimport knf.kuma.App\r\nimport knf.kuma.BuildConfig\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.DesignUtils\r\nimport knf.kuma.commons.Network\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.create\r\nimport knf.kuma.commons.isFullMode\r\nimport knf.kuma.commons.jsoupCookies\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.download.DownloadDialogActivity\r\nimport knf.kuma.download.FileAccessHelper\r\nimport knf.kuma.pojos.AnimeObject\r\nimport knf.kuma.pojos.NotificationObj\r\nimport knf.kuma.pojos.RecentObject\r\nimport knf.kuma.pojos.Recents\r\nimport knf.kuma.recents.RecentsNotReceiver\r\nimport knf.kuma.search.SearchAdvObject\r\nimport knf.kuma.tv.ChannelUtils\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.withContext\r\nimport org.jetbrains.anko.notificationManager\r\nimport pl.droidsonroids.jspoon.Jspoon\r\nimport java.util.concurrent.TimeUnit\r\nimport kotlin.random.Random\r\n\r\nclass RecentsWork(val context: Context, workerParameters: WorkerParameters) :\r\n    CoroutineWorker(context, workerParameters) {\r\n    private val RECENTS_GROUP = \"recents-group\"\r\n    private val recentsDAO = CacheDB.INSTANCE.recentsDAO()\r\n    private val favsDAO = CacheDB.INSTANCE.favsDAO()\r\n    private val seeingDAO = CacheDB.INSTANCE.seeingDAO()\r\n    private val animeDAO = CacheDB.INSTANCE.animeDAO()\r\n    private val notificationDAO = CacheDB.INSTANCE.notificationDAO()\r\n    private val manager: NotificationManager by lazy { context.notificationManager }\r\n\r\n    private val summaryBroadcast: Intent\r\n        get() = Intent(context, RecentsNotReceiver::class.java).putExtra(\"mode\", 1)\r\n\r\n    override suspend fun doWork(): Result {\r\n        if (!Network.isConnected) return Result.success().also { Log.e(\"Recents\", \"No Network\") }\r\n        //setForeground(createForegroundInfo())\r\n        try {\r\n            val recents = withContext(Dispatchers.IO) {\r\n                Jspoon.create().adapter(Recents::class.java)\r\n                    .fromHtml(jsoupCookies(\"https://www3.animeflv.net/\").get().outerHtml())\r\n            }\r\n            val objects = RecentObject.create(recents.list ?: listOf())\r\n            for ((i, recentObject) in objects.withIndex())\r\n                recentObject.key = i\r\n            notifyChannel(objects)\r\n            val local = recentsDAO.all\r\n            if (local.isEmpty() && !BuildConfig.DEBUG)\r\n                return Result.success()\r\n            if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(\"notify_favs\", false)) {\r\n                notifyFavChaps(local, objects)\r\n            } else {\r\n                notifyAllChaps(local, objects)\r\n            }\r\n            recentsDAO.setCache(objects)\r\n            return Result.success()\r\n        } catch (e: Exception) {\r\n            e.printStackTrace()\r\n            return Result.failure()\r\n        }\r\n    }\r\n\r\n    private fun createForegroundInfo(): ForegroundInfo =\r\n        ForegroundInfo(\r\n            Random.nextInt(1000, 9999),\r\n            NotificationCompat.Builder(context, CHANNEL_RECENTS)\r\n                .setSmallIcon(R.drawable.ic_recents_group)\r\n                .setColor(ContextCompat.getColor(context, R.color.colorAccent))\r\n                .setContentText(\"Buscando nuevos episodios\")\r\n                .setProgress(100, 0, true)\r\n                .build()\r\n        )\r\n\r\n    private fun notifyTest() {\r\n        manager.notify(\r\n            Random.nextInt(),\r\n            NotificationCompat.Builder(context, CHANNEL_RECENTS)\r\n                .setSmallIcon(R.drawable.ic_recents_group)\r\n                .setColor(ContextCompat.getColor(context, R.color.colorAccent))\r\n                .setContentText(\"Test notification, ${System.currentTimeMillis()}\")\r\n                .build()\r\n        )\r\n    }\r\n\r\n    @Throws(Exception::class)\r\n    private fun notifyAllChaps(\r\n        local: MutableList<RecentObject>,\r\n        objects: MutableList<RecentObject>\r\n    ) {\r\n        for (recentObject in objects) {\r\n            if (!local.contains(recentObject)) {\r\n                notifyRecent(recentObject)\r\n            }\r\n        }\r\n    }\r\n\r\n    @Throws(Exception::class)\r\n    private fun notifyFavChaps(\r\n        local: MutableList<RecentObject>,\r\n        objects: MutableList<RecentObject>\r\n    ) {\r\n        for (recentObject in objects) {\r\n            if (!local.contains(recentObject) && (favsDAO.isFav(Integer.parseInt(recentObject.aid)) || seeingDAO.isSeeing(\r\n                    recentObject.aid\r\n                ))\r\n            ) {\r\n                notifyRecent(recentObject)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun notifyChannel(objects: List<RecentObject>) {\r\n        if (!context.resources.getBoolean(R.bool.isTv) || !PrefsUtil.tvRecentsChannelCreated) return\r\n        val lastNotified =\r\n            objects.indexOf(objects.find { it.eid == PrefsUtil.tvRecentsChannelLastEid })\r\n        if (lastNotified != 0) {\r\n            with(PreviewChannelHelper(context)) {\r\n                PrefsUtil.tvRecentsChannelIds?.forEach {\r\n                    deletePreviewProgram(it.toLong())\r\n                }\r\n            }\r\n            val newIds = mutableSetOf<String>()\r\n            objects.forEach {\r\n                newIds.add(ChannelUtils.addProgram(context, it).toString())\r\n            }\r\n            PrefsUtil.tvRecentsChannelIds = newIds\r\n            PrefsUtil.tvRecentsChannelLastEid = objects.first().eid\r\n        }\r\n    }\r\n\r\n    @Throws(Exception::class)\r\n    private fun notifyRecent(recentObject: RecentObject) {\r\n        val animeObject = getAnime(recentObject)\r\n        val obj = NotificationObj(\r\n            \"${recentObject.aid}${recentObject.chapter}\".hashCode(),\r\n            NotificationObj.RECENT\r\n        )\r\n        val notification = NotificationCompat.Builder(context, CHANNEL_RECENTS).create {\r\n            setSmallIcon(R.drawable.ic_new_recent)\r\n            color = ContextCompat.getColor(context, R.color.colorAccent)\r\n            setContentTitle(recentObject.name)\r\n            setContentText(recentObject.chapter)\r\n            priority = NotificationCompat.PRIORITY_MAX\r\n            val tone = FileAccessHelper.toneFile\r\n            if (tone.exists())\r\n                setSound(\r\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {\r\n                        val uri: Uri = FileProvider.getUriForFile(\r\n                            context,\r\n                            \"${context.packageName}.fileprovider\",\r\n                            tone\r\n                        )\r\n                        context.grantUriPermission(\r\n                            \"com.android.systemui\",\r\n                            uri,\r\n                            Intent.FLAG_GRANT_READ_URI_PERMISSION\r\n                        )\r\n                        uri\r\n                    } else\r\n                        Uri.fromFile(tone)\r\n                )\r\n            setLargeIcon(getBitmap(recentObject))\r\n            setAutoCancel(true)\r\n            setOnlyAlertOnce(true)\r\n            setContentIntent(\r\n                PendingIntent.getActivity(\r\n                    context,\r\n                    System.currentTimeMillis().toInt(),\r\n                    getAnimeIntent(animeObject, obj),\r\n                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\r\n                )\r\n            )\r\n            setDeleteIntent(\r\n                PendingIntent.getBroadcast(\r\n                    context,\r\n                    System.currentTimeMillis().toInt(),\r\n                    obj.getBroadcast(context),\r\n                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\r\n                )\r\n            )\r\n            if (isFullMode && !PrefsUtil.isFamilyFriendly)\r\n                addAction(\r\n                    android.R.drawable.stat_sys_download_done,\r\n                    \"Acciones\",\r\n                    PendingIntent.getActivity(\r\n                        context,\r\n                        System.currentTimeMillis().toInt(),\r\n                        getChapIntent(recentObject, obj),\r\n                        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\r\n                    )\r\n                )\r\n            setGroup(RECENTS_GROUP)\r\n            setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)\r\n        }.build()\r\n        notificationDAO.add(obj)\r\n        manager.notify(obj.key, notification)\r\n        notifySummary()\r\n    }\r\n\r\n    private fun getBitmap(recentObject: RecentObject): Bitmap? {\r\n        return try {\r\n            if (PrefsUtil.showRecentImage) Glide.with(context).asBitmap().load(PatternUtil.getCover(recentObject.aid)).submit().get() else null\r\n        } catch (e: Exception) {\r\n            null\r\n        }\r\n\r\n    }\r\n\r\n    @Throws(Exception::class)\r\n    private fun getAnime(recentObject: RecentObject): SearchAdvObject {\r\n        var animeObject: SearchAdvObject? = animeDAO.getByAid(recentObject.aid)\r\n        if (animeObject == null) {\r\n            val tmp = AnimeObject(recentObject.anime, Jspoon.create().adapter(AnimeObject.WebInfo::class.java).fromHtml(jsoupCookies(recentObject.anime).get().outerHtml()))\r\n            animeObject = SearchAdvObject().apply {\r\n                key = tmp.key\r\n                name = tmp.name\r\n                link = tmp.link\r\n                aid = tmp.aid\r\n                type = tmp.type\r\n                img = tmp.img\r\n            }\r\n            animeDAO.insert(tmp)\r\n        }\r\n        return animeObject\r\n    }\r\n\r\n    private fun getAnimeIntent(animeObject: SearchAdvObject, notificationObj: NotificationObj): Intent {\r\n        return Intent(context, DesignUtils.infoClass)\r\n                .setData(Uri.parse(animeObject.link))\r\n                .putExtras(notificationObj.getBroadcast(context))\r\n                .putExtra(\"title\", animeObject.name)\r\n                .putExtra(\"aid\", animeObject.aid)\r\n                .putExtra(\"img\", animeObject.img)\r\n                .putExtra(\"notification\", true)\r\n                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\r\n    }\r\n\r\n    private fun getChapIntent(recentObject: RecentObject, notificationObj: NotificationObj): Intent {\r\n        return Intent(context, DownloadDialogActivity::class.java)\r\n                .setData(Uri.parse(recentObject.url))\r\n                .putExtras(notificationObj.getBroadcast(context))\r\n                .putExtra(\"notification\", true)\r\n                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\r\n    }\r\n\r\n    private fun notifySummary() {\r\n        val notification = NotificationCompat.Builder(context, CHANNEL_RECENTS)\r\n            .setSmallIcon(R.drawable.ic_recents_group)\r\n            .setColor(ContextCompat.getColor(context, R.color.colorAccent))\r\n            .setContentTitle(\"Nuevos capitulos\")\r\n            .setContentText(\"Hay nuevos capitulos recientes!!\")\r\n            .setGroupSummary(true)\r\n            .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN)\r\n            .setGroup(RECENTS_GROUP)\r\n            .setAutoCancel(true)\r\n            .setContentIntent(\r\n                PendingIntent.getActivity(\r\n                    context,\r\n                    0,\r\n                    Intent(context, DesignUtils.mainClass),\r\n                    PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_IMMUTABLE\r\n                )\r\n            )\r\n            .setDeleteIntent(\r\n                PendingIntent.getBroadcast(\r\n                    context,\r\n                    System.currentTimeMillis().toInt(),\r\n                    summaryBroadcast,\r\n                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\r\n                )\r\n            )\r\n                .build()\r\n        if (PrefsUtil.isGroupingEnabled)\r\n            manager.notify(KEY_SUMMARY, notification)\r\n    }\r\n\r\n    companion object {\r\n        const val CHANNEL_RECENTS = \"channel.RECENTS\"\r\n        const val KEY_SUMMARY = 55971\r\n        internal const val TAG = \"recents-job\"\r\n\r\n        fun schedule(context: Context) {\r\n            val preferences = PreferenceManager.getDefaultSharedPreferences(context)\r\n            val time = (preferences.getString(\"recents_time\", \"1\") ?: \"1\").toInt() * 15\r\n            PeriodicWorkRequestBuilder<RecentsWork>(\r\n                time.coerceAtLeast(15).toLong(),\r\n                TimeUnit.MINUTES,\r\n                5,\r\n                TimeUnit.MINUTES\r\n            ).apply {\r\n                setInitialDelay(15L, TimeUnit.MINUTES)\r\n                //setConstraints(networkConnectedConstraints())\r\n                //setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)\r\n                addTag(TAG)\r\n            }.build().enqueueUnique(TAG, ExistingPeriodicWorkPolicy.KEEP)\r\n            /*WorkManager.getInstance(context).getWorkInfosByTagLiveData(TAG).let { ld ->\r\n                lateinit var observer: Observer<List<WorkInfo>>\r\n                doOnUI {\r\n                    ld.observeForever(Observer<List<WorkInfo>> {\r\n                        ld.removeObserver(observer)\r\n                        if (it.isEmpty())\r\n                            doAsync {\r\n                                val preferences = PreferenceManager.getDefaultSharedPreferences(context)\r\n                                val time = (preferences.getString(\"recents_time\", \"1\")\r\n                                        ?: \"1\").toInt() * 15\r\n                                if (time > 0)\r\n                                    PeriodicWorkRequestBuilder<RecentsWork>(time.coerceAtLeast(15).toLong(), TimeUnit.MINUTES).apply {\r\n                                        setInitialDelay(15L, TimeUnit.MINUTES)\r\n                                        //setConstraints(networkConnectedConstraints())\r\n                                        //setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)\r\n                                        addTag(TAG)\r\n                                    }.build().enqueueUnique(TAG, ExistingPeriodicWorkPolicy.REPLACE)\r\n                            }\r\n                    }.also { observer = it })\r\n                }\r\n            }*/\r\n        }\r\n\r\n        fun reSchedule(time: Int) {\r\n            WorkManager.getInstance(App.context).cancelAllWorkByTag(TAG)\r\n            if (time > 0)\r\n                PeriodicWorkRequestBuilder<RecentsWork>(\r\n                    time.coerceAtLeast(15).toLong(),\r\n                    TimeUnit.MINUTES\r\n                ).apply {\r\n                    //setConstraints(networkConnectedConstraints())\r\n                    //setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES)\r\n                    addTag(TAG)\r\n                }.build().enqueueUnique(TAG, ExistingPeriodicWorkPolicy.UPDATE)\r\n        }\r\n\r\n        fun run() = OneTimeWorkRequestBuilder<RecentsWork>().build().enqueue()\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/jobscheduler/UpdateWork.kt",
    "content": "package knf.kuma.jobscheduler\r\n\r\nimport android.app.PendingIntent\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport androidx.core.app.NotificationCompat\r\nimport androidx.core.content.ContextCompat\r\nimport androidx.preference.PreferenceManager\r\nimport androidx.work.ExistingPeriodicWorkPolicy\r\nimport androidx.work.PeriodicWorkRequestBuilder\r\nimport androidx.work.Worker\r\nimport androidx.work.WorkerParameters\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.Network\r\nimport knf.kuma.commons.isFullMode\r\nimport knf.kuma.updater.UpdateActivity\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.notificationManager\r\nimport org.jsoup.Jsoup\r\nimport java.util.concurrent.TimeUnit\r\n\r\nclass UpdateWork(val context: Context, workerParameters: WorkerParameters) : Worker(context, workerParameters) {\r\n    override fun doWork(): Result {\r\n        if (Network.isConnected && isFullMode)\r\n            try {\r\n                val document =\r\n                    Jsoup.connect(\"https://raw.githubusercontent.com/jordyamc/UKIKU/master/version.num\")\r\n                        .get()\r\n                val nCode =\r\n                    Integer.parseInt(document.select(\"body\").first().ownText().trim { it <= ' ' })\r\n                val sCode = PreferenceManager.getDefaultSharedPreferences(context)\r\n                    .getInt(\"last_notified_update\", 0)\r\n                if (nCode <= sCode)\r\n                    return Result.success()\r\n                val oCode =\r\n                    context.packageManager.getPackageInfo(context.packageName, 0).versionCode\r\n                if (nCode > oCode) {\r\n                    showNotification()\r\n                    PreferenceManager.getDefaultSharedPreferences(context).edit()\r\n                        .putInt(\"last_notified_update\", nCode).apply()\r\n                }\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n            }\r\n        return Result.success()\r\n    }\r\n\r\n    private fun showNotification() {\r\n        try {\r\n            val notification = NotificationCompat.Builder(context, CHANNEL).apply {\r\n                setSmallIcon(R.drawable.ic_not_update)\r\n                setContentTitle(\"UKIKU\")\r\n                setContentText(\"Nueva versión disponible\")\r\n                setContentIntent(\r\n                    PendingIntent.getActivity(\r\n                        context,\r\n                        5598,\r\n                        Intent(context, UpdateActivity::class.java),\r\n                        PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\r\n                    )\r\n                )\r\n                color = ContextCompat.getColor(context, R.color.colorAccent)\r\n            }.build()\r\n            context.notificationManager.notify(954857, notification)\r\n        } catch (e: Exception) {\r\n            e.printStackTrace()\r\n        }\r\n\r\n    }\r\n\r\n    companion object {\r\n        const val TAG = \"update-job\"\r\n        const val CHANNEL = \"app-updater\"\r\n\r\n        fun schedule() {\r\n            doAsync {\r\n                PeriodicWorkRequestBuilder<UpdateWork>(6, TimeUnit.HOURS, 1, TimeUnit.HOURS).apply {\r\n                    setConstraints(networkConnectedConstraints())\r\n                    addTag(TAG)\r\n                }.build().enqueueUnique(TAG, ExistingPeriodicWorkPolicy.KEEP)\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/jobscheduler/WorkExt.kt",
    "content": "package knf.kuma.jobscheduler\r\n\r\nimport androidx.work.Constraints\r\nimport androidx.work.ExistingPeriodicWorkPolicy\r\nimport androidx.work.NetworkType\r\nimport androidx.work.PeriodicWorkRequest\r\nimport androidx.work.WorkManager\r\nimport androidx.work.WorkRequest\r\nimport knf.kuma.App\r\n\r\nfun networkConnectedConstraints(): Constraints = Constraints.Builder().apply { setRequiredNetworkType(NetworkType.CONNECTED) }.build()\r\n\r\nfun WorkRequest.enqueue() = WorkManager.getInstance(App.context).enqueue(this)\r\n\r\nfun PeriodicWorkRequest.enqueueUnique(tag: String, type: ExistingPeriodicWorkPolicy) = WorkManager.getInstance(App.context).enqueueUniquePeriodicWork(tag, type, this)"
  },
  {
    "path": "app/src/main/java/knf/kuma/news/MaterialNewsActivity.kt",
    "content": "package knf.kuma.news\r\n\r\nimport android.annotation.SuppressLint\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport android.util.Log\r\nimport android.view.Menu\r\nimport android.view.MenuItem\r\nimport android.view.View\r\nimport androidx.activity.viewModels\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.swiperefreshlayout.widget.SwipeRefreshLayout\r\nimport com.afollestad.materialdialogs.LayoutMode\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.bottomsheets.BottomSheet\r\nimport com.afollestad.materialdialogs.bottomsheets.setPeekHeight\r\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\r\nimport com.afollestad.materialdialogs.list.listItemsSingleChoice\r\nimport com.google.android.material.snackbar.Snackbar\r\nimport ir.mahdiparastesh.chlm.SpacingItemDecoration\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsType\r\nimport knf.kuma.ads.implBanner\r\nimport knf.kuma.ads.showRandomInterstitial\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.Network\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.asPx\r\nimport knf.kuma.commons.setSurfaceBars\r\nimport knf.kuma.commons.showSnackbar\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.databinding.ActivityNewsMaterialBinding\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.launch\r\n\r\nclass MaterialNewsActivity : GenericActivity(), SwipeRefreshLayout.OnRefreshListener {\r\n    val model: NewsViewModel by viewModels()\r\n    private val binding by lazy { ActivityNewsMaterialBinding.inflate(layoutInflater) }\r\n    val adapter: MaterialNewsAdapter by lazy { MaterialNewsAdapter(this) }\r\n    var snack: Snackbar? = null\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setSurfaceBars()\r\n        setContentView(binding.root)\r\n        binding.toolbar.title = \"Recientes\"\r\n        setSupportActionBar(binding.toolbar)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\r\n        binding.refresh.setColorSchemeResources(EAHelper.getThemeColor(), EAHelper.getThemeColorLight(), R.color.colorPrimary)\r\n        binding.refresh.setOnRefreshListener(this)\r\n        binding.refresh.isRefreshing = true\r\n        binding.recycler.adapter = adapter\r\n        binding.recycler.addItemDecoration(SpacingItemDecoration(0, 20.asPx))\r\n        loadList()\r\n        lifecycleScope.launch(Dispatchers.IO) {\r\n            delay(500)\r\n            binding.adContainer.implBanner(AdsType.NEWS_BANNER, true)\r\n        }\r\n        showRandomInterstitial(this, PrefsUtil.fullAdsExtraProbability)\r\n    }\r\n\r\n    private fun loadList() {\r\n        snack?.dismiss()\r\n        if (Network.isConnected)\r\n            lifecycleScope.launch {\r\n                NewsRepository.getNews(getCategory()) { isEmpty, cause ->\r\n                    if (isEmpty) {\r\n                        Log.e(\"News\", \"Error loading: $cause\")\r\n                        binding.error.visibility = View.VISIBLE\r\n                        snack = binding.recycler.showSnackbar(\"Error al cargar noticias: $cause\", Snackbar.LENGTH_INDEFINITE, \"reintentar\") {\r\n                            loadList()\r\n                        }\r\n                    } else {\r\n                        binding.error.visibility = View.GONE\r\n                        binding.recycler.scheduleLayoutAnimation()\r\n                    }\r\n                    runOnUiThread { binding.refresh.isRefreshing = false }\r\n                }.collect {\r\n                    adapter.submitData(it)\r\n                }\r\n            }\r\n        else {\r\n            snack = binding.recycler.showSnackbar(\"Sin internet\", Snackbar.LENGTH_INDEFINITE)\r\n        }\r\n    }\r\n\r\n    private fun getCategory(): String {\r\n        return when (model.selectedFilter) {\r\n            1 -> \"noticias/anime\"\r\n            2 -> \"noticias/cultura-otaku\"\r\n            3 -> \"noticias/japon\"\r\n            4 -> \"noticias/live-action\"\r\n            5 -> \"noticias/manga\"\r\n            6 -> \"noticias/mercancia-de-anime\"\r\n            7 -> \"noticias/novelas-ligeras\"\r\n            8 -> \"noticias/videojuegos\"\r\n            9 -> \"noticias/resenas\"\r\n            else -> \"noticias/\"\r\n        }\r\n    }\r\n\r\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\r\n        menuInflater.inflate(R.menu.menu_news_filters, menu)\r\n        return super.onCreateOptionsMenu(menu)\r\n    }\r\n\r\n    @SuppressLint(\"CheckResult\")\r\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\r\n        MaterialDialog(this, BottomSheet(LayoutMode.WRAP_CONTENT)).show {\r\n            lifecycleOwner(this@MaterialNewsActivity)\r\n            title(text = \"Filtros\")\r\n            setPeekHeight(99999999)\r\n            listItemsSingleChoice(\r\n                items = model.filtersList,\r\n                initialSelection = model.selectedFilter,\r\n                waitForPositiveButton = false\r\n            ) { _, index, name ->\r\n                binding.refresh.isRefreshing = true\r\n                supportActionBar?.title = name\r\n                model.selectedFilter = index\r\n                loadList()\r\n            }\r\n        }\r\n        return super.onOptionsItemSelected(item)\r\n    }\r\n\r\n    override fun onRefresh() {\r\n        binding.refresh.isRefreshing = true\r\n        loadList()\r\n    }\r\n\r\n    companion object {\r\n        fun open(context: Context) {\r\n            context.startActivity(Intent(context, MaterialNewsActivity::class.java))\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/news/MaterialNewsAdapter.kt",
    "content": "package knf.kuma.news\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ProgressBar\r\nimport android.widget.TextView\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.paging.PagingDataAdapter\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport com.google.android.material.imageview.ShapeableImageView\r\nimport knf.kuma.R\r\nimport knf.kuma.achievements.AchievementManager\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.noCrash\r\nimport org.jetbrains.anko.find\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass MaterialNewsAdapter(val activity: AppCompatActivity) : PagingDataAdapter<NewsItem, MaterialNewsAdapter.NewsViewHolder>(NewsItem.DIFF) {\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsViewHolder =\r\n            NewsViewHolder(parent.inflate(R.layout.item_news_material))\r\n\r\n    override fun onBindViewHolder(holder: NewsViewHolder, position: Int) {\r\n        val item = getItem(position)\r\n        if (item == null)\r\n            holder.apply {\r\n                root.setOnClickListener(null)\r\n                image.setImageDrawable(null)\r\n                progress.visibility = View.VISIBLE\r\n                type.text = null\r\n                title.text = null\r\n                date.text = null\r\n            }\r\n        else\r\n            holder.apply {\r\n                root.onClick {\r\n                    AchievementManager.onNewsOpened()\r\n                    openNews(activity, item)\r\n                }\r\n                noCrash { image.load(item.image) }\r\n                progress.visibility = View.GONE\r\n                type.text = item.type\r\n                title.text = item.title\r\n                date.text = item.date\r\n            }\r\n    }\r\n\r\n    class NewsViewHolder(view: View) : RecyclerView.ViewHolder(view) {\r\n        val root: View = itemView.find(R.id.root)\r\n        val image: ShapeableImageView = itemView.find(R.id.image)\r\n        val progress: ProgressBar = itemView.find(R.id.progress)\r\n        val type: TextView = itemView.find(R.id.type)\r\n        val title: TextView = itemView.find(R.id.title)\r\n        val date: TextView = itemView.find(R.id.date)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/news/NewsActivity.kt",
    "content": "package knf.kuma.news\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport android.view.View\r\nimport androidx.swiperefreshlayout.widget.SwipeRefreshLayout\r\nimport ir.mahdiparastesh.chlm.SpacingItemDecoration\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsType\r\nimport knf.kuma.ads.implBanner\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.asPx\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.databinding.ActivityNewsBinding\r\n\r\nclass NewsActivity : GenericActivity(), SwipeRefreshLayout.OnRefreshListener {\r\n    private val binding by lazy { ActivityNewsBinding.inflate(layoutInflater) }\r\n    val adapter: NewsAdapter by lazy { NewsAdapter(this) }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(binding.root)\r\n        binding.toolbar.title = \"Noticias\"\r\n        setSupportActionBar(binding.toolbar)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() }\r\n        binding.refresh.setColorSchemeResources(EAHelper.getThemeColor(), EAHelper.getThemeColorLight(), R.color.colorPrimary)\r\n        binding.refresh.setOnRefreshListener(this)\r\n        binding.refresh.isRefreshing = true\r\n        binding.recycler.adapter = adapter\r\n        binding.recycler.addItemDecoration(SpacingItemDecoration(0, 10.asPx))\r\n        NewsCreator.createNews().observe(this) {\r\n            if (it == null || it.isEmpty())\r\n                binding.error.visibility = View.VISIBLE\r\n            else {\r\n                binding.error.visibility = View.GONE\r\n\r\n                adapter.update(it)\r\n                binding.recycler.scheduleLayoutAnimation()\r\n            }\r\n            binding.refresh.isRefreshing = false\r\n        }\r\n        if (!PrefsUtil.isNativeAdsEnabled)\r\n            binding.adContainer.implBanner(AdsType.NEWS_BANNER)\r\n    }\r\n\r\n    override fun onRefresh() {\r\n        binding.refresh.isRefreshing = true\r\n        NewsCreator.reload()\r\n    }\r\n\r\n    override fun onDestroy() {\r\n        super.onDestroy()\r\n        NewsCreator.destroy()\r\n    }\r\n\r\n    companion object {\r\n        fun open(context: Context) {\r\n            context.startActivity(Intent(context, NewsActivity::class.java))\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/news/NewsAdapter.kt",
    "content": "package knf.kuma.news\r\n\r\nimport android.view.LayoutInflater\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.TextView\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport com.google.android.material.card.MaterialCardView\r\nimport knf.kuma.R\r\nimport knf.kuma.achievements.AchievementManager\r\nimport knf.kuma.ads.AdCallback\r\nimport knf.kuma.ads.AdCardItemHolder\r\nimport knf.kuma.ads.AdsUtilsMob\r\nimport knf.kuma.ads.implAdsNews\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.isSameContent\r\nimport knf.kuma.commons.noCrashLet\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport org.jetbrains.anko.find\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass NewsAdapter(val activity: AppCompatActivity) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {\r\n\r\n    var list: List<NewsObject> = listOf()\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {\r\n        if (viewType == 1)\r\n            return AdCardItemHolder(parent, AdCardItemHolder.TYPE_NEWS).also {\r\n                it.loadAd(activity.lifecycleScope, object : AdCallback {\r\n                    override fun getID(): String = AdsUtilsMob.NEWS_BANNER\r\n                }, 500)\r\n            }\r\n        return NewsHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_news, parent, false))\r\n    }\r\n\r\n    override fun getItemCount(): Int {\r\n        return list.size\r\n    }\r\n\r\n    override fun getItemViewType(position: Int): Int {\r\n        return noCrashLet { if (list[position] is AdNewsObject) 1 else 0 } ?: 1\r\n    }\r\n\r\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\r\n        val newsObject = list[position]\r\n        if (holder is NewsHolder) {\r\n            holder.metadata.text = newsObject.metaData()\r\n            holder.title.text = newsObject.title\r\n            holder.description.text = newsObject.description\r\n            holder.card.onClick {\r\n                AchievementManager.onNewsOpened()\r\n                NewsCreator.openNews(activity, newsObject)\r\n            }\r\n        }\r\n    }\r\n\r\n    fun update(list: MutableList<NewsObject>) {\r\n        activity.lifecycleScope.launch(Dispatchers.IO) {\r\n            if (PrefsUtil.isNativeAdsEnabled)\r\n                list.implAdsNews()\r\n            if (this@NewsAdapter.list isSameContent list)\r\n                return@launch\r\n            this@NewsAdapter.list = list\r\n            launch(Dispatchers.Main) {\r\n                notifyDataSetChanged()\r\n            }\r\n        }\r\n    }\r\n\r\n    class NewsHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\r\n        val card: MaterialCardView = itemView.find(R.id.card)\r\n        val metadata: TextView = itemView.find(R.id.metadata)\r\n        val title: TextView = itemView.find(R.id.title)\r\n        val description: TextView = itemView.find(R.id.description)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/news/NewsCreator.kt",
    "content": "package knf.kuma.news\r\n\r\nimport android.content.ActivityNotFoundException\r\nimport android.content.Intent\r\nimport android.net.Uri\r\nimport android.os.Build\r\nimport android.text.Html\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.lifecycle.LiveData\r\nimport androidx.lifecycle.MutableLiveData\r\nimport knf.kuma.ads.AdCallback\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.toast\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jsoup.Jsoup\r\nimport org.jsoup.nodes.Element\r\nimport org.jsoup.parser.Parser\r\nimport org.jsoup.select.Elements\r\nimport java.text.SimpleDateFormat\r\nimport java.util.Locale\r\nimport java.util.regex.Pattern\r\n\r\nobject NewsCreator {\r\n    private val liveData = MutableLiveData<MutableList<NewsObject>?>()\r\n    fun createNews(): LiveData<MutableList<NewsObject>?> {\r\n        reload()\r\n        return liveData\r\n    }\r\n\r\n    fun reload() {\r\n        doAsync {\r\n            try {\r\n                val document = Jsoup.connect(\"https://somoskudasai.com/feed/\").parser(Parser.xmlParser()).get()\r\n                val items = document.select(\"item\")\r\n                val news = mutableListOf<NewsObject>()\r\n                items.forEach {\r\n                    val title = it.select(\"title\").first().noCDText()\r\n                    val link = it.select(\"link\").first().noCDText()\r\n                    val author = it.select(\"dc|creator\").first().noCDText()\r\n                    val date = it.select(\"pubDate\").first().noCDText()\r\n                    val categories = it.select(\"category\").getAllStringNoCD()\r\n                    val description = it.select(\"description\").first().noCDText()\r\n                    val content = it.select(\"content|encoded\").first().noCDHtml()\r\n                    news.add(NewsObject(\r\n                            title, link, date, author, categories, description, content\r\n                    ))\r\n                }\r\n                doOnUIGlobal {\r\n                    liveData.value = news\r\n                }\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n                doOnUIGlobal {\r\n                    liveData.value = null\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    fun destroy() {\r\n        doOnUIGlobal {\r\n            liveData.value = null\r\n        }\r\n    }\r\n\r\n    fun openNews(activity: AppCompatActivity, newsObject: NewsObject) {\r\n        try {\r\n            //CustomTabsIntent.Builder().build().launchUrl(activity, Uri.parse(newsObject.link))\r\n            NewsDialog.show(activity, newsObject.link)\r\n        } catch (e: ActivityNotFoundException) {\r\n            try {\r\n                activity.startActivity(Intent(Intent.ACTION_VIEW).setData(Uri.parse(newsObject.link)))\r\n            } catch (anfe: ActivityNotFoundException) {\r\n                \"No se encontró ningun navegador para abrir noticia\".toast()\r\n            }\r\n        } catch (ex: Exception) {\r\n            \"Error al abrir noticia\".toast()\r\n        }\r\n    }\r\n\r\n    private fun Element.noCDText(): String {\r\n        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)\r\n            Html.fromHtml(text().cdRemoved(), Html.FROM_HTML_MODE_LEGACY).toString()\r\n        else\r\n            Html.fromHtml(text().cdRemoved()).toString()\r\n    }\r\n\r\n    private fun Element.noCDHtml(): String {\r\n        return text().cdRemoved()\r\n    }\r\n\r\n    private fun Elements.getAllStringNoCD(): List<String> {\r\n        val list = mutableListOf<String>()\r\n        this.forEach {\r\n            list.add(it.noCDText())\r\n        }\r\n        return list\r\n    }\r\n\r\n    private fun String.cdRemoved(): String {\r\n        if (!this.trim().startsWith(\"<![CDATA[\"))\r\n            return this.trim()\r\n        val pattern = Pattern.compile(\r\n                if (this.contains(\"se publicó primero en\"))\r\n                    if (this.contains(\"Saber más\"))\r\n                        \"<!\\\\[CDATA\\\\[(.*\\\\.\\\\.\\\\.) <a.*\\\\s?]]>\"\r\n                    else\r\n                        \"<!\\\\[CDATA\\\\[(.*)<p>La entrada <a.*\\\\s?]]>\"\r\n                else\r\n                    \"<!\\\\[CDATA\\\\[(.*)\\\\s?]]>\")\r\n        val matcher = pattern.matcher(this)\r\n        matcher.find()\r\n        return matcher.group(1).trim()\r\n    }\r\n}\r\n\r\nopen class NewsObject(\r\n        val title: String,\r\n        val link: String,\r\n        val date: String,\r\n        val author: String,\r\n        val categories: List<String>,\r\n        val description: String,\r\n        val content: String\r\n) {\r\n\r\n    fun metaData(): String {\r\n        val dateFormat = SimpleDateFormat(\"EEE, dd MMM yyyy kk:mm:ss Z\", Locale.ENGLISH)\r\n        val formated = dateFormat.parse(date)\r\n        //return \"$author — ${TimeAgo.using(formated.time)}\"\r\n        val simpleDate = SimpleDateFormat(\"EEE, dd MMM hh:mmaa\", Locale.getDefault())\r\n        return \"$author — ${simpleDate.format(formated)}\"\r\n    }\r\n\r\n    override fun equals(other: Any?): Boolean {\r\n        return other is NewsObject && other.link == link\r\n    }\r\n\r\n    override fun hashCode(): Int {\r\n        return link.hashCode()\r\n    }\r\n}\r\n\r\nclass AdNewsObject(private val adId: String) : NewsObject(\"\", \"\", \"\", \"\", emptyList(), \"\", \"\"), AdCallback {\r\n    override fun getID(): String = adId\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/news/NewsDialog.kt",
    "content": "package knf.kuma.news\n\nimport android.annotation.SuppressLint\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.webkit.WebView\nimport android.webkit.WebViewClient\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentManager\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleObserver\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.OnLifecycleEvent\nimport com.google.android.material.bottomsheet.BottomSheetDialogFragment\nimport knf.kuma.R\nimport knf.kuma.commons.doOnUI\nimport org.jetbrains.anko.find\n\nclass NewsDialog : BottomSheetDialogFragment(), LifecycleObserver {\n    private var link: String = \"about:blank\"\n\n    @SuppressLint(\"SetJavaScriptEnabled\")\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val rootView = inflater.inflate(R.layout.lay_news, container, false)\n        doOnUI {\n            rootView.find<WebView>(R.id.webview).apply {\n                setInitialScale(1)\n                settings.useWideViewPort = true\n                settings.loadWithOverviewMode = true\n                settings.javaScriptEnabled = true\n                webViewClient = WebViewClient()\n                loadUrl(link)\n            }\n        }\n        return rootView\n    }\n\n    fun setUpOwner(owner: LifecycleOwner) {\n        owner.lifecycle.addObserver(this)\n    }\n\n    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)\n    fun onPaused() {\n        safeDismiss()\n    }\n\n    fun safeShow(manager: FragmentManager, tag: String) {\n        try {\n            show(manager, tag)\n        } catch (e: Exception) {\n            //\n        }\n\n    }\n\n    private fun safeDismiss() {\n        try {\n            dismiss()\n        } catch (e: Exception) {\n            //\n        }\n    }\n\n    companion object {\n\n        fun show(activity: AppCompatActivity, link: String) {\n            NewsDialog().apply {\n                this.link = link\n                setUpOwner(activity)\n            }.safeShow(activity.supportFragmentManager, \"BottomSheetDialog\")\n        }\n\n        fun show(fragment: Fragment, link: String) {\n            NewsDialog().apply {\n                this.link = link\n                setUpOwner(fragment)\n            }.safeShow(fragment.childFragmentManager, \"BottomSheetDialog\")\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/news/NewsObjects.kt",
    "content": "package knf.kuma.news\r\n\r\nimport android.content.ActivityNotFoundException\r\nimport android.content.ClipData\r\nimport android.content.ClipboardManager\r\nimport android.content.Intent\r\nimport android.net.Uri\r\nimport androidx.annotation.Keep\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.core.content.getSystemService\r\nimport androidx.paging.Pager\r\nimport androidx.paging.PagingConfig\r\nimport androidx.paging.PagingData\r\nimport androidx.paging.PagingSource\r\nimport androidx.paging.PagingState\r\nimport androidx.recyclerview.widget.DiffUtil\r\nimport knf.kuma.commons.NoSSLOkHttpClient\r\nimport knf.kuma.commons.safeContext\r\nimport knf.kuma.commons.toast\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.flow.Flow\r\nimport kotlinx.coroutines.withContext\r\nimport org.jsoup.nodes.Element\r\nimport pl.droidsonroids.jspoon.ElementConverter\r\nimport pl.droidsonroids.jspoon.annotation.Selector\r\nimport pl.droidsonroids.retrofit2.JspoonConverterFactory\r\nimport retrofit2.Call\r\nimport retrofit2.Retrofit\r\nimport retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory\r\nimport retrofit2.http.GET\r\nimport retrofit2.http.Path\r\n\r\n@Keep\r\nclass NewsItem {\r\n    @Selector(\"header h3\", defValue = \"\")\r\n    lateinit var title: String\r\n\r\n    @Selector(\"header p\", defValue = \"\")\r\n    lateinit var type: String\r\n\r\n    @Selector(\":root\", converter = DateConverter::class)\r\n    lateinit var date: String\r\n\r\n    @Selector(\":root\", converter = ImageConverter::class)\r\n    lateinit var image: String\r\n\r\n    @Selector(\"header h3 a\", attr = \"href\", defValue = \"\")\r\n    lateinit var link: String\r\n\r\n    class ImageConverter : ElementConverter<String> {\r\n        override fun convert(node: Element, selector: Selector): String {\r\n            val image = node.select(\"figure img,figure amp-img\").ifEmpty { return \"\" }.first()\r\n            return when {\r\n                image.hasAttr(\"data-src\") -> image.attr(\"data-src\")\r\n                image.hasAttr(\"src\") -> image.attr(\"src\")\r\n                else -> \"\"\r\n            }\r\n        }\r\n    }\r\n\r\n    class DateConverter : ElementConverter<String> {\r\n        override fun convert(node: Element, selector: Selector): String {\r\n            val date = node.select(\"footer > span:last-of-type\").first()\r\n            return date.text().substringBeforeLast(\" por \")\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        val DIFF = object : DiffUtil.ItemCallback<NewsItem>() {\r\n            override fun areItemsTheSame(oldItem: NewsItem, newItem: NewsItem): Boolean =\r\n                oldItem.link == newItem.link\r\n\r\n            override fun areContentsTheSame(oldItem: NewsItem, newItem: NewsItem): Boolean =\r\n                oldItem.title == newItem.title && oldItem.date == newItem.date\r\n        }\r\n    }\r\n}\r\n\r\nclass NewsPage {\r\n    @Selector(\"article:has(figure):has(h3):not(.logo):not(.grid)\")\r\n    var newsList: List<NewsItem> = emptyList()\r\n}\r\n\r\nclass NewsDataSource(private val newsFactory: NewsFactory, val category: String, val onInit: (isEmpty: Boolean, cause: String?) -> Unit) : PagingSource<Int, NewsItem>() {\r\n\r\n    override fun getRefreshKey(state: PagingState<Int, NewsItem>): Int? = state.anchorPosition?.let {\r\n        state.closestPageToPosition(it)?.prevKey?.plus(1)\r\n            ?: state.closestPageToPosition(it)?.nextKey?.minus(1)\r\n    }\r\n\r\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, NewsItem> {\r\n        val page = params.key?:1\r\n        try {\r\n            val response = withContext(Dispatchers.IO) {\r\n                when (category) {\r\n                    \"noticias/\" -> newsFactory.getLatestPage().execute()\r\n                    else -> newsFactory.getNewsPage(category, page).execute()\r\n                }\r\n            }\r\n            if (response.isSuccessful){\r\n                response.body()?.let {\r\n                    if (page == 1)\r\n                        onInit(false, null)\r\n                    return LoadResult.Page(it.newsList, null, if (it.newsList.size < 12 || category == \"noticias/\") null else page + 1)\r\n                } ?: run{\r\n                    if (page == 1)\r\n                        onInit(true, \"Empty body\")\r\n                }\r\n            }\r\n            val errorString = withContext(Dispatchers.IO) { response.errorBody()?.string() }\r\n            if (page == 1)\r\n                onInit(true, \"$errorString\")\r\n            return LoadResult.Error(IllegalStateException())\r\n        }catch (e:Exception){\r\n            if (page == 1) {\r\n                onInit(true, \"${e.message}\")\r\n                safeContext.getSystemService<ClipboardManager>()?.apply {\r\n                    setPrimaryClip(ClipData.newPlainText(\"News\", e.stackTraceToString()))\r\n                }\r\n            }\r\n            return LoadResult.Error(e)\r\n        }\r\n    }\r\n}\r\n\r\ninterface NewsFactory {\r\n    @GET(\"{category}/{page}/\")\r\n    fun getNewsPage(@Path(\"category\") category: String, @Path(\"page\") page: Int): Call<NewsPage>\r\n\r\n    @GET(\"noticias/\")\r\n    fun getLatestPage(): Call<NewsPage>\r\n}\r\n\r\nobject NewsRepository {\r\n    fun getNews(category: String, onInit: (isEmpty: Boolean, cause: String?) -> Unit): Flow<PagingData<NewsItem>> {\r\n        return Pager(\r\n            config = PagingConfig(12),\r\n            pagingSourceFactory = { NewsDataSource(getFactory(), category, onInit) }\r\n        ).flow\r\n    }\r\n\r\n    private fun getFactory(): NewsFactory {\r\n        val retrofit = Retrofit.Builder()\r\n                .baseUrl(\"https://somoskudasai.com/\")\r\n                .client(NoSSLOkHttpClient.get())\r\n                .addConverterFactory(JspoonConverterFactory.create())\r\n                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())\r\n                .build()\r\n        return retrofit.create(NewsFactory::class.java)\r\n    }\r\n}\r\n\r\nfun openNews(activity: AppCompatActivity, newsItem: NewsItem) {\r\n    try {\r\n        NewsDialog.show(activity, newsItem.link)\r\n        //CommentariesDialog.show(activity, newsItem.link)\r\n        //CustomTabsIntent.Builder().build().launchUrl(activity, newsItem.link.toUri())\r\n    } catch (e: ActivityNotFoundException) {\r\n        try {\r\n            activity.startActivity(Intent(Intent.ACTION_VIEW).setData(Uri.parse(newsItem.link)))\r\n        } catch (anfe: ActivityNotFoundException) {\r\n            \"No se encontró ningun navegador para abrir noticia\".toast()\r\n        }\r\n    } catch (ex: Exception) {\r\n        \"Error al abrir noticia\".toast()\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/news/NewsViewModel.kt",
    "content": "package knf.kuma.news\r\n\r\nimport androidx.lifecycle.ViewModel\r\n\r\nclass NewsViewModel : ViewModel(){\r\n    var selectedFilter = 0\r\n\r\n    val filtersList: List<String> = mutableListOf<String>().apply{\r\n        add(\"Recientes\")\r\n        add(\"Anime\")\r\n        add(\"Cultura Otaku\")\r\n        add(\"Japón\")\r\n        add(\"Live Action\")\r\n        add(\"Manga\")\r\n        add(\"Mercancía / Figuras\")\r\n        add(\"Novelas Ligeras\")\r\n        add(\"VideoJuegos\")\r\n        add(\"Reseñas\")\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/player/AudioFocusWrapper.kt",
    "content": "package knf.kuma.player\n\nimport android.annotation.TargetApi\nimport android.media.AudioAttributes\nimport android.media.AudioFocusRequest\nimport android.media.AudioManager\nimport android.os.Build\nimport android.util.Log\nimport androidx.annotation.RequiresApi\nimport androidx.media.AudioAttributesCompat\nimport com.google.android.exoplayer2.ExoPlayer\nimport com.google.android.exoplayer2.SimpleExoPlayer\n\n/**\n * Wrapper around a [SimpleExoPlayer] simplifies playback by automatically handling\n * audio focus using [AudioFocusRequest] on Oreo+ devices, and an\n * [AudioManager.OnAudioFocusChangeListener] on previous versions.\n */\nclass AudioFocusWrapper(\n    private val audioAttributes: AudioAttributesCompat,\n    private val audioManager: AudioManager,\n    private val player: ExoPlayer\n) : ExoPlayer by player {\n    private var shouldPlayWhenReady = false\n\n    private val audioFocusListener = AudioManager.OnAudioFocusChangeListener { focusChange ->\n        when (focusChange) {\n            AudioManager.AUDIOFOCUS_GAIN -> {\n                if (shouldPlayWhenReady || player.playWhenReady) {\n                    player.playWhenReady = true\n                    player.volume = MEDIA_VOLUME_DEFAULT\n                }\n                shouldPlayWhenReady = false\n            }\n            AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {\n                if (player.playWhenReady) {\n                    player.volume = MEDIA_VOLUME_DUCK\n                }\n            }\n            AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {\n                shouldPlayWhenReady = player.playWhenReady\n                player.playWhenReady = false\n            }\n            AudioManager.AUDIOFOCUS_LOSS -> {\n                abandonAudioFocus()\n            }\n        }\n    }\n\n    @get:RequiresApi(Build.VERSION_CODES.O)\n    private val audioFocusRequest by lazy { buildFocusRequest() }\n\n    override fun setPlayWhenReady(playWhenReady: Boolean) {\n        if (playWhenReady) requestAudioFocus() else abandonAudioFocus()\n    }\n\n    private fun requestAudioFocus() {\n        val result = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            requestAudioFocusOreo()\n        } else {\n            @Suppress(\"deprecation\")\n            audioManager.requestAudioFocus(audioFocusListener,\n                    audioAttributes.legacyStreamType,\n                    AudioManager.AUDIOFOCUS_GAIN)\n        }\n\n        // Call the listener whenever focus is granted - even the first time!\n        if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {\n            shouldPlayWhenReady = true\n            audioFocusListener.onAudioFocusChange(AudioManager.AUDIOFOCUS_GAIN)\n        } else {\n            Log.e(\"Player\", \"Playback not started: Audio focus request denied\")\n        }\n    }\n\n    private fun abandonAudioFocus() {\n        player.playWhenReady = false\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n            abandonAudioFocusOreo()\n        } else {\n            @Suppress(\"deprecation\")\n            audioManager.abandonAudioFocus(audioFocusListener)\n        }\n    }\n\n    @RequiresApi(Build.VERSION_CODES.O)\n    private fun requestAudioFocusOreo(): Int = audioManager.requestAudioFocus(audioFocusRequest)\n\n    @RequiresApi(Build.VERSION_CODES.O)\n    private fun abandonAudioFocusOreo() = audioManager.abandonAudioFocusRequest(audioFocusRequest)\n\n    @TargetApi(Build.VERSION_CODES.O)\n    private fun buildFocusRequest(): AudioFocusRequest =\n            AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)\n                    .setAudioAttributes(audioAttributes.unwrap() as AudioAttributes)\n                    .setOnAudioFocusChangeListener(audioFocusListener)\n                    .build()\n}\n\nprivate const val MEDIA_VOLUME_DEFAULT = 1.0f\nprivate const val MEDIA_VOLUME_DUCK = 0.2f"
  },
  {
    "path": "app/src/main/java/knf/kuma/player/BVListener.kt",
    "content": "package knf.kuma.player\r\n\r\nimport android.content.Context\r\nimport android.graphics.Point\r\nimport android.media.AudioManager\r\nimport android.view.MotionEvent\r\nimport android.view.View\r\nimport androidx.appcompat.app.AppCompatActivity\r\n\r\n\r\nclass BVListener(val activity: AppCompatActivity) : View.OnTouchListener {\r\n\r\n    private val audioManager: AudioManager = activity.getSystemService(Context.AUDIO_SERVICE) as AudioManager\r\n    private val screenSize: Point\r\n    private val sWidth: Int\r\n    private val sHeight: Int\r\n    private var intLeft: Boolean = false\r\n    private var intRight: Boolean = false\r\n    private var downX: Float = 0.toFloat()\r\n    private var downY: Float = 0.toFloat()\r\n    private var diffX: Long = 0\r\n    private var diffY: Long = 0\r\n\r\n    private val window = activity.window\r\n    private val params = activity.window.attributes\r\n    private var currentBrightness = params.screenBrightness\r\n\r\n\r\n    init {\r\n        val display = activity.windowManager.defaultDisplay\r\n        screenSize = Point()\r\n        display.getSize(screenSize)\r\n        sWidth = screenSize.x\r\n        sHeight = screenSize.y\r\n    }\r\n\r\n    override fun onTouch(v: View?, event: MotionEvent?): Boolean {\r\n        when (event?.action) {\r\n            MotionEvent.ACTION_DOWN -> {\r\n\r\n                //touch is start\r\n                downX = event.x\r\n                downY = event.y\r\n                if (event.x < sWidth / 2) {\r\n\r\n                    //here check touch is screen left or right side\r\n                    intLeft = true\r\n                    intRight = false\r\n\r\n                } else if (event.x > sWidth / 2) {\r\n\r\n                    //here check touch is screen left or right side\r\n                    intLeft = false\r\n                    intRight = true\r\n                }\r\n                v?.performClick()\r\n            }\r\n\r\n            MotionEvent.ACTION_UP,\r\n            MotionEvent.ACTION_MOVE -> {\r\n\r\n                if (event.action == MotionEvent.ACTION_UP)\r\n                    v?.performClick()\r\n\r\n                //finger move to screen\r\n                //val x2 = event.x\r\n                val y2 = event.y\r\n\r\n                diffX = Math.ceil((event.x - downX).toDouble()).toLong()\r\n                diffY = Math.ceil((event.y - downY).toDouble()).toLong()\r\n\r\n                if (Math.abs(diffY) > Math.abs(diffX)) {\r\n                    if (intLeft) {\r\n                        //if left its for brightness\r\n                        if (downY < y2) {\r\n                            //down swipe brightness decrease\r\n                            currentBrightness -= 0.1f\r\n                            if (currentBrightness < 0) currentBrightness = 0f\r\n                            params.screenBrightness = currentBrightness\r\n                            window.attributes = params\r\n                        } else if (downY > y2) {\r\n                            //up  swipe brightness increase\r\n                            currentBrightness += 0.1f\r\n                            if (currentBrightness > 1) currentBrightness = 1f\r\n                            params.screenBrightness = currentBrightness\r\n                            window.attributes = params\r\n                        }\r\n\r\n                    } else if (intRight) {\r\n\r\n                        //if right its for audio\r\n                        if (downY < y2) {\r\n\r\n                            //down swipe volume decrease\r\n                            audioManager.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_PLAY_SOUND)\r\n\r\n                        } else if (downY > y2) {\r\n\r\n                            //up  swipe volume increase\r\n                            audioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_PLAY_SOUND)\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        return true\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/player/CustomExoPlayer.kt",
    "content": "package knf.kuma.player\n\nimport android.annotation.TargetApi\nimport android.app.PictureInPictureParams\nimport android.content.Intent\nimport android.content.pm.ActivityInfo\nimport android.content.pm.PackageManager\nimport android.content.res.Configuration\nimport android.graphics.Color\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport android.view.View\nimport android.webkit.MimeTypeMap\nimport android.widget.TextView\nimport androidx.annotation.RequiresApi\nimport androidx.lifecycle.lifecycleScope\nimport androidx.preference.PreferenceManager\nimport com.google.android.exoplayer2.C\nimport com.google.android.exoplayer2.ExoPlayer\nimport com.google.android.exoplayer2.MediaItem\nimport com.google.android.exoplayer2.PlaybackException\nimport com.google.android.exoplayer2.PlaybackParameters\nimport com.google.android.exoplayer2.Player\nimport com.google.android.exoplayer2.Timeline\nimport com.google.android.exoplayer2.source.MediaSource\nimport com.google.android.exoplayer2.source.ProgressiveMediaSource\nimport com.google.android.exoplayer2.source.hls.HlsMediaSource\nimport com.google.android.exoplayer2.ui.AspectRatioFrameLayout\nimport com.google.android.exoplayer2.upstream.DefaultHttpDataSource\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport knf.kuma.R\nimport knf.kuma.commons.BypassUtil\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.SSLSkipper\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.noCrash\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.ExoPlayerBinding\nimport knf.kuma.pojos.QueueObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster\n\nclass CustomExoPlayer : GenericActivity(), Player.Listener {\n    private var exoPlayer: ExoPlayer? = null\n    private var playerState: PlayerState = PlayerState()\n    private var isEnding = false\n    private var playList: List<QueueObject> = ArrayList()\n    private val binding by lazy { ExoPlayerBinding.inflate(layoutInflater) }\n\n    private val resizeMode: Int\n        get() {\n            return when (PreferenceManager.getDefaultSharedPreferences(this).getString(\"player_resize\", \"0\")) {\n                \"0\" -> AspectRatioFrameLayout.RESIZE_MODE_FIT\n                \"1\" -> AspectRatioFrameLayout.RESIZE_MODE_FILL\n                \"2\" -> AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH\n                \"3\" -> AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT\n                else -> AspectRatioFrameLayout.RESIZE_MODE_FIT\n            }\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE\n        setContentView(binding.root)\n        window.decorView.setBackgroundColor(Color.BLACK)\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE))\n            find<View>(R.id.pip).visibility = View.VISIBLE\n        find<View>(R.id.pip).setOnClickListener { onPip() }\n        find<View>(R.id.skip).setOnClickListener { onSkip() }\n        hideUI()\n        binding.player.resizeMode = resizeMode\n        binding.player.requestFocus()\n        lifecycleScope.launch(Dispatchers.Main) {\n            playerState = withContext(Dispatchers.IO) {\n                CacheDB.INSTANCE.playerStateDAO().find(intent.getStringExtra(\"title\") ?: \"???\")\n                    ?: PlayerState()\n            }\n            if (savedInstanceState != null) {\n                playerState.position = savedInstanceState.getLong(\"position\", C.TIME_UNSET)\n                playerState.window = savedInstanceState.getInt(\"listPosition\", 0)\n            }\n            checkPlaylist(intent)\n            initPlayer(intent)\n        }\n    }\n\n    override fun onSaveInstanceState(outState: Bundle) {\n        super.onSaveInstanceState(outState)\n        outState.putLong(\"position\", playerState.position)\n        if (playerState.window != 0)\n            outState.putInt(\"listPosition\", playerState.window)\n    }\n\n    private fun hideUI() {\n        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION\n                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN\n                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION\n                or View.SYSTEM_UI_FLAG_FULLSCREEN\n                or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)\n    }\n\n    private fun initPlayer(intent: Intent) {\n        if (exoPlayer == null) {\n            SSLSkipper.skip()\n            lifecycleScope.launch(Dispatchers.Main) {\n                find<TextView>(R.id.video_title).text = intent.getStringExtra(\"title\")\n                exoPlayer = ExoPlayer.Builder(this@CustomExoPlayer).build()\n                binding.player.player = exoPlayer\n                exoPlayer?.addListener(this@CustomExoPlayer)\n                addMedia(exoPlayer, intent)\n                exoPlayer?.prepare()\n                val canResume = playerState.window >= 0 && playerState.position != C.TIME_UNSET\n                if (canResume)\n                    exoPlayer?.seekTo(playerState.window, playerState.position)\n                exoPlayer?.playWhenReady = true\n                /*disposable = Observable.interval(1, TimeUnit.SECONDS).map { exoPlayer?.currentPosition?:0 }\n                        .subscribeOn(AndroidSchedulers.from(exoPlayer?.applicationLooper, false))\n                        .subscribe {\n                            if (it > 0)\n                                lastPosition = it\n                        }*/\n            }\n        }\n    }\n\n    private suspend fun addMedia(player: ExoPlayer?, intent: Intent) {\n        player?: return\n        if (intent.getBooleanExtra(\"isPlayList\", false)) {\n            val sourceList = ArrayList<MediaSource>()\n            playList = withContext(Dispatchers.IO) {\n                CacheDB.INSTANCE.queueDAO()\n                        .getAllByAid(intent.getStringExtra(\"playlist\") ?: \"empty\")\n                }\n                noCrash { find<TextView>(R.id.video_title).text = playList[0].title() }\n                DefaultHttpDataSource.Factory()\n                for (queueObject in playList) {\n                    sourceList.add(\n                        ProgressiveMediaSource.Factory(\n                            DefaultHttpDataSource.Factory().apply {\n                                setUserAgent(BypassUtil.userAgent)\n                            }\n                        ).createMediaSource(MediaItem.fromUri(queueObject.createUri()))\n                    )\n                }\n                player.addMediaSources(sourceList)\n            } else {\n                if (intent.getBooleanExtra(\"isFile\", false) || !intent.hasExtra(\"headers\")) {\n                    player.addMediaItem(MediaItem.fromUri(intent.data ?: Uri.parse(\"\")))\n                } else {\n                    val httpFactory = DefaultHttpDataSource.Factory().apply {\n                        setAllowCrossProtocolRedirects(true)\n                        intent.getStringArrayExtra(\"headers\") ?.let { headerArray ->\n                            val slices = headerArray.toList().chunked(2)\n                            val headers = mutableMapOf<String, String>()\n                            slices.forEach {\n                                headers[it[0]] = it[1]\n                            }\n                            setDefaultRequestProperties(headers)\n                            if (headers.contains(\"User-Agent\")) {\n                                setUserAgent(headers[\"User-Agent\"])\n                            } else {\n                                setUserAgent(BypassUtil.userAgent)\n                            }\n                        }?: setUserAgent(BypassUtil.userAgent)\n                    }\n                    val factory = when(MimeTypeMap.getFileExtensionFromUrl(intent.data?.toString())) {\n                        \"m3u8\" -> HlsMediaSource.Factory(httpFactory)\n                        else -> ProgressiveMediaSource.Factory(httpFactory)\n                    }\n                    player.addMediaSource(\n                        factory.createMediaSource(\n                            MediaItem.fromUri(\n                                intent.data ?: Uri.parse(\"\")\n                            )\n                        )\n                    )\n                }\n            }\n    }\n\n    private fun releasePlayer() {\n        exoPlayer?.stop()\n        exoPlayer?.release()\n        exoPlayer = null\n    }\n\n    @TargetApi(Build.VERSION_CODES.N)\n    internal fun onPip() {\n        try {\n            if (!isInPictureInPictureMode) {\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {\n                    playerState.position = exoPlayer?.currentPosition ?: 0\n                    val params = PictureInPictureParams.Builder()\n                            //.setAspectRatio(Rational(player.width, player.height))\n                            .build()\n                    enterPictureInPictureMode(params)\n                }\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n\n    }\n\n    private fun onSkip() {\n        exoPlayer?.seekTo(\n            exoPlayer?.currentWindowIndex ?: 0, (exoPlayer?.currentPosition\n                ?: 0) + 85000\n        )\n    }\n\n    @RequiresApi(Build.VERSION_CODES.O)\n    override fun onPictureInPictureModeChanged(\n        isInPictureInPictureMode: Boolean,\n        newConfig: Configuration\n    ) {\n        super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)\n        if (!isInPictureInPictureMode) {\n            runOnUiThread {\n                find<View>(R.id.lay_top).visibility = View.VISIBLE\n                find<View>(R.id.lay_bottom).visibility = View.VISIBLE\n                binding.player.useController = true\n            }\n            /*getApplication().startActivity(new Intent(this, getClass())\n                    .putExtra(\"isReorder\", true)\n                    .addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));*/\n        } else {\n            runOnUiThread {\n                find<View>(R.id.lay_top).visibility = View.GONE\n                find<View>(R.id.lay_bottom).visibility = View.GONE\n                find<View>(R.id.progress).visibility = View.GONE\n                binding.player.useController = false\n            }\n        }\n    }\n\n    private fun checkPlaylist(intent: Intent) {\n        if (!intent.getBooleanExtra(\"isPlayList\", false)) {\n            find<View>(com.google.android.exoplayer2.R.id.exo_next).visibility = View.GONE\n            find<View>(com.google.android.exoplayer2.R.id.exo_prev).visibility = View.GONE\n        } else {\n            find<View>(com.google.android.exoplayer2.R.id.exo_next).visibility = View.VISIBLE\n            find<View>(com.google.android.exoplayer2.R.id.exo_prev).visibility = View.VISIBLE\n        }\n    }\n\n    override fun onUserLeaveHint() {\n        super.onUserLeaveHint()\n        exoPlayer?.playWhenReady = false\n    }\n\n    override fun onNewIntent(intent: Intent) {\n        setIntent(intent)\n        releasePlayer()\n        playerState.window = C.INDEX_UNSET\n        playerState.position = 0\n        checkPlaylist(intent)\n        initPlayer(intent)\n        super.onNewIntent(intent)\n    }\n\n    override fun onResume() {\n        doOnUI { hideUI() }\n        exoPlayer?.playWhenReady = true\n        super.onResume()\n    }\n\n    override fun onPause() {\n        super.onPause()\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInPictureInPictureMode)\n            return\n        val state = playerState.apply {\n            title = find<TextView>(R.id.video_title).text.toString()\n            position = if (!isEnding) {\n                exoPlayer?.currentPosition ?: 0\n            } else\n                0\n        }\n        doAsync {\n            CacheDB.INSTANCE.playerStateDAO().set(state)\n        }\n        if (!isFinishing)\n            exoPlayer?.pause()\n        else\n            exoPlayer?.stop()\n    }\n\n    override fun onDestroy() {\n        releasePlayer()\n        super.onDestroy()\n    }\n\n    override fun onTimelineChanged(timeline: Timeline, reason: Int) {\n\n    }\n\n    override fun onLoadingChanged(isLoading: Boolean) {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInPictureInPictureMode)\n            return\n        find<View>(R.id.progress).post { find<View>(R.id.progress).visibility = if (isLoading) View.VISIBLE else View.GONE }\n    }\n\n    override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {\n        if (playbackState == Player.STATE_READY)\n            doOnUI { hideUI() }\n        if (playbackState == Player.STATE_ENDED) {\n            isEnding = true\n            finish()\n        }\n    }\n\n    override fun onRepeatModeChanged(repeatMode: Int) {\n\n    }\n\n    override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {\n\n    }\n\n    override fun onPlayerError(error: PlaybackException) {\n        Toaster.toast(\n            \"Error al reproducir: \" + error.message?.replace(\"%\", \"%%\"),\n            emptyArray<Any>()\n        )\n        /*MaterialDialog(this).show {\n            message(text = error.stackTraceToString().also {\n                (getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager)?.setPrimaryClip(ClipData.newPlainText(\"stack\", it))\n            })\n            positiveButton(text = \"OK\")\n        }*/\n        FirebaseCrashlytics.getInstance().recordException(error)\n        finish()\n    }\n\n    /*override fun onPositionDiscontinuity(reason: Int) {\n        try {\n            val latestPosition = exoPlayer?.currentWindowIndex ?: 0\n            if (latestPosition != listPosition) {\n                val state = PlayerState().apply {\n                    title = playList[listPosition].title()\n                    if (reason == 0) {\n                        position = 0\n                    } else if (reason in 1..2) {\n                        position = lastPosition\n                    }\n                }\n                doAsync {\n                    CacheDB.INSTANCE.playerStateDAO().set(state)\n                }\n                listPosition = latestPosition\n                video_title.text = playList[listPosition].title()\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }*/\n\n    override fun onPositionDiscontinuity(\n        oldPosition: Player.PositionInfo,\n        newPosition: Player.PositionInfo,\n        reason: Int\n    ) {\n        try {\n            val latestPosition = newPosition.windowIndex\n            if (latestPosition != playerState.window) {\n                val state = playerState.apply {\n                    title = playList[playerState.window].title()\n                    if (reason == 0) {\n                        position = 0\n                    } else if (reason in 1..2) {\n                        position = oldPosition.positionMs\n                    }\n                }\n                doAsync {\n                    CacheDB.INSTANCE.playerStateDAO().set(state)\n                }\n                playerState.window = latestPosition\n                find<TextView>(R.id.video_title).text = playList[playerState.window].title()\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }\n\n    override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/player/MediaCatalog.kt",
    "content": "package knf.kuma.player\n\nimport android.content.Intent\nimport android.support.v4.media.MediaDescriptionCompat\nimport androidx.core.os.bundleOf\nimport knf.kuma.pojos.QueueObject\n\n/**\n * Manages a set of media metadata that is used to create a playlist for [VideoActivity].\n */\n\nopen class MediaCatalog(private val list: MutableList<MediaDescriptionCompat>, private val intent: Intent, playList: List<QueueObject>) :\n        MutableList<MediaDescriptionCompat> by list {\n\n    companion object : MediaCatalog(mutableListOf(), Intent(), emptyList())\n\n    init {\n        if (intent.getBooleanExtra(\"isPlayList\", false)) {\n            var count = 1\n            playList.forEach {\n                list.add(\n                        with(MediaDescriptionCompat.Builder()) {\n                            setTitle(it.title())\n                            setMediaId(count.toString())\n                            setMediaUri(it.createUri())\n                            build()\n                        })\n                count++\n            }\n        } else\n            list.add(\n                    with(MediaDescriptionCompat.Builder()) {\n                        setTitle(intent.getStringExtra(\"title\"))\n                        setMediaId(\"1\")\n                        setMediaUri(intent.data)\n                        setExtras(bundleOf(\"headers\" to intent.getStringArrayExtra(\"headers\")))\n                        build()\n                    })\n    }\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/player/Player.kt",
    "content": "package knf.kuma.player\n\nimport android.content.ClipData\nimport android.content.ClipboardManager\nimport android.content.Context\nimport android.content.Intent\nimport android.media.AudioManager\nimport android.net.Uri\nimport android.support.v4.media.MediaDescriptionCompat\nimport android.webkit.MimeTypeMap\nimport androidx.media.AudioAttributesCompat\nimport androidx.room.Entity\nimport androidx.room.Ignore\nimport androidx.room.PrimaryKey\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.android.exoplayer2.ExoPlayer\nimport com.google.android.exoplayer2.MediaItem\nimport com.google.android.exoplayer2.PlaybackException\nimport com.google.android.exoplayer2.Player\nimport com.google.android.exoplayer2.source.MediaSource\nimport com.google.android.exoplayer2.source.ProgressiveMediaSource\nimport com.google.android.exoplayer2.source.hls.HlsMediaSource\nimport com.google.android.exoplayer2.ui.PlayerView\nimport com.google.android.exoplayer2.upstream.DefaultHttpDataSource\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport io.reactivex.rxjava3.disposables.Disposable\nimport knf.kuma.commons.BypassUtil\nimport knf.kuma.commons.noCrashLetNullable\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.QueueObject\nimport org.jetbrains.anko.doAsync\nimport xdroid.toaster.Toaster\n\n@Entity\ndata class PlayerState(\n        @PrimaryKey\n        var title: String = \"\",\n        var position: Long = 0,\n        @Ignore\n        var window: Int = 0,\n        @Ignore\n        var whenReady: Boolean = true,\n        @Ignore\n        var isFinishing: Boolean = false)\n\nclass PlayerHolder(\n    private val context: Context,\n    private val playerState: PlayerState,\n    private val playerView: PlayerView,\n    private val intent: Intent,\n    private val playList: List<QueueObject>\n) {\n    val audioFocusPlayer: ExoPlayer\n    val playerCallback: PlayerCallback\n    private var listPosition = 0\n    private val mediaCatalog: MediaCatalog\n    private var disposable: Disposable? = null\n    private var lastPosition = 0L\n\n    // Create the exoPlayer instance.\n    init {\n        val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager\n        val audioAttributes = AudioAttributesCompat.Builder()\n                .setContentType(AudioAttributesCompat.CONTENT_TYPE_MOVIE)\n                .setUsage(AudioAttributesCompat.USAGE_MEDIA)\n                .build()\n        playerCallback = context as PlayerCallback\n        mediaCatalog = MediaCatalog(mutableListOf(), intent, playList)\n        playerCallback.onChangeTitle((mediaCatalog[listPosition].title ?: \"\").toString())\n        mediaCatalog[listPosition].title?.let { playerState.title = it.toString() }\n        if (mediaCatalog.size == 1) playerCallback.onChangeTitle(mediaCatalog[0].title.toString())\n        audioFocusPlayer = AudioFocusWrapper(\n                audioAttributes,\n                audioManager,\n            ExoPlayer.Builder(context).build()\n                        .also { player ->\n                            playerView.player = player\n                        }\n        )\n        /*disposable = Observable.interval(1, TimeUnit.SECONDS).map { audioFocusPlayer.currentPosition }\n                .subscribeOn(AndroidSchedulers.from(audioFocusPlayer.applicationLooper, false))\n                .subscribe {\n                    if (it > 0)\n                        lastPosition = it\n                }*/\n    }\n\n    private fun buildMediaSource(): List<MediaData> {\n        return mediaCatalog.mapNotNull { noCrashLetNullable { createExtractorMediaSource(it) } }\n    }\n\n    private fun createExtractorMediaSource(descriptor: MediaDescriptionCompat): MediaData {\n        val item = MediaItem.fromUri(descriptor.mediaUri?: Uri.EMPTY)\n        if (intent.getBooleanExtra(\"isFile\", false)) return MediaData(item)\n        val httpFactory = DefaultHttpDataSource.Factory().apply {\n            descriptor.extras?.getStringArray(\"headers\")?.let { headerArray ->\n                val headers = headerArray.toList().chunked(2).associate { Pair(it[0], it[1]) }\n                setDefaultRequestProperties(headers)\n                if (headers.contains(\"User-Agent\")) {\n                    setUserAgent(headers[\"User-Agent\"])\n                } else {\n                    setUserAgent(BypassUtil.userAgent)\n                }\n            } ?: setUserAgent(BypassUtil.userAgent)\n        }\n        val factory = when(MimeTypeMap.getFileExtensionFromUrl(descriptor.mediaUri?.toString())) {\n            \"m3u8\" -> HlsMediaSource.Factory(httpFactory)\n            else -> ProgressiveMediaSource.Factory(httpFactory)\n        }\n        return MediaData(factory.createMediaSource(item))\n    }\n\n    class MediaData {\n        constructor(media: MediaSource) {\n            mediaSource = media\n        }\n\n        constructor(media: MediaItem) {\n            mediaItem = media\n        }\n        private lateinit var mediaSource: MediaSource\n        private lateinit var mediaItem: MediaItem\n        fun addMedia(exoPlayer: ExoPlayer) {\n            if (::mediaSource.isInitialized) {\n                exoPlayer.addMediaSource(mediaSource)\n            }\n            if (::mediaItem.isInitialized) {\n                exoPlayer.addMediaItem(mediaItem)\n            }\n        }\n    }\n\n    // Prepare playback.\n    fun start() {\n        // Load media.\n        buildMediaSource().forEach {\n            it.addMedia(audioFocusPlayer)\n        }\n        //audioFocusPlayer.setMediaItems(buildMediaSource())\n        audioFocusPlayer.prepare()\n        // Restore state (after onResume()/onStart())\n        with(playerState) {\n            // Start playback when media has buffered enough\n            // (whenReady is true by default).\n            audioFocusPlayer.seekTo(window, position)\n            audioFocusPlayer.playWhenReady = whenReady\n            // Add logging.\n            attachLogging(audioFocusPlayer)\n        }\n    }\n\n    // Stop playback and release resources, but re-use the exoPlayer instance.\n    fun stop() {\n        with(audioFocusPlayer) {\n            // Save state\n            saveState()\n            // Stop the exoPlayer (and release it's resources). The exoPlayer instance can be reused.\n            stop()\n            clearMediaItems()\n        }\n    }\n\n    fun skip() {\n        with(audioFocusPlayer) {\n            seekTo(currentMediaItemIndex, currentPosition + 85000)\n        }\n    }\n\n    fun saveState() {\n        with(audioFocusPlayer) {\n            with(playerState) {\n                position = currentPosition\n                window = currentMediaItemIndex\n                whenReady = playWhenReady\n            }\n        }\n    }\n\n    // Destroy the exoPlayer instance.\n    fun release() {\n        audioFocusPlayer.release() // exoPlayer instance can't be used again.\n        disposable?.dispose()\n    }\n\n    /**\n     * For more info on ExoPlayer logging, please review this\n     * [codelab](https://codelabs.developers.google.com/codelabs/exoplayer-intro/#5).\n     */\n    private fun attachLogging(exoPlayer: ExoPlayer) {\n        // Show toasts on state changes.\n        exoPlayer.addListener(object : Player.Listener {\n            override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {\n                when (playbackState) {\n                    Player.STATE_ENDED -> {\n                        playerCallback.onFinish()\n                    }\n                }\n            }\n\n            override fun onPlayerError(error: PlaybackException) {\n                Toaster.toast(\"Error al reproducir: \" + error.message?.replace(\"%\", \"%%\"))\n                MaterialDialog(this@PlayerHolder.context).show {\n                    message(text = error.stackTraceToString().also {\n                        (this@PlayerHolder.context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager)?.setPrimaryClip(\n                            ClipData.newPlainText(\"stack\", it)\n                        )\n                    })\n                    positiveButton(text = \"OK\")\n                }\n                FirebaseCrashlytics.getInstance().recordException(error)\n                playerCallback.onFinish()\n            }\n\n            override fun onLoadingChanged(isLoading: Boolean) {\n                playerCallback.onLoadingChange(isLoading)\n            }\n\n            override fun onPositionDiscontinuity(\n                oldPosition: Player.PositionInfo,\n                newPosition: Player.PositionInfo,\n                reason: Int\n            ) {\n                try {\n                    val latestPosition = newPosition.mediaItemIndex\n                    if (latestPosition != oldPosition.mediaItemIndex) {\n                        playerState.apply {\n                            title = playList[listPosition].title()\n                            if (reason == 0) {\n                                position = 0\n                            } else if (reason in 1..2) {\n                                position = oldPosition.positionMs\n                            }\n                        }\n                        doAsync {\n                            CacheDB.INSTANCE.playerStateDAO().set(playerState)\n                        }\n                        listPosition = latestPosition\n                        playerCallback.onChangeTitle(\n                            (mediaCatalog[listPosition].title\n                                ?: \"\").toString()\n                        )\n                    }\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n            }\n\n            /*override fun onPositionDiscontinuity(reason: Int) {\n                try {\n                    val latestPosition = audioFocusPlayer.currentWindowIndex\n                    if (latestPosition != listPosition) {\n                        playerState.apply {\n                            title = playList[listPosition].title()\n                            if (reason == 0) {\n                                position = 0\n                            } else if (reason in 1..2) {\n                                position = lastPosition\n                            }\n                        }\n                        doAsync {\n                                CacheDB.INSTANCE.playerStateDAO().set(playerState)\n                        }\n                        listPosition = latestPosition\n                        playerCallback.onChangeTitle((mediaCatalog[listPosition].title\n                                ?: \"\").toString())\n                        setUpRetriever(mediaCatalog[listPosition])\n                    }\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n            }*/\n        })\n        // Write to log on state changes.\n        exoPlayer.addListener(object : Player.Listener {\n            override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {\n                //Log.i(\"Player\", \"playerStateChanged: ${getStateString(playbackState)}, $playWhenReady\")\n                playerCallback.onPlayerStateChanged(playbackState, playWhenReady)\n            }\n\n            fun getStateString(state: Int): String {\n                return when (state) {\n                    Player.STATE_BUFFERING -> \"STATE_BUFFERING\"\n                    Player.STATE_ENDED -> \"STATE_ENDED\"\n                    Player.STATE_IDLE -> \"STATE_IDLE\"\n                    Player.STATE_READY -> \"STATE_READY\"\n                    else -> \"?\"\n                }\n            }\n\n\n        })\n\n    }\n\n    interface PlayerCallback {\n        fun onChangeTitle(title: String)\n        fun onLoadingChange(loading: Boolean)\n        fun onPlayerStateChanged(state: Int, playWhenReady: Boolean)\n        fun onFinish()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/player/VideoActivity.kt",
    "content": "package knf.kuma.player\n\nimport android.app.PictureInPictureParams\nimport android.content.pm.ActivityInfo\nimport android.content.pm.PackageManager\nimport android.content.res.Configuration\nimport android.graphics.Color\nimport android.media.AudioManager\nimport android.os.Build\nimport android.os.Bundle\nimport android.support.v4.media.session.MediaSessionCompat\nimport android.view.View\nimport android.view.animation.AnimationUtils\nimport android.widget.TextView\nimport androidx.annotation.RequiresApi\nimport androidx.core.view.isVisible\nimport androidx.lifecycle.lifecycleScope\nimport androidx.preference.PreferenceManager\nimport com.github.vkay94.dtpv.youtube.YouTubeOverlay\nimport com.google.android.exoplayer2.Player\nimport com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector\nimport com.google.android.exoplayer2.ui.AspectRatioFrameLayout\nimport knf.kuma.R\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.SSLSkipper\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.noCrash\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.PlayerViewBinding\nimport knf.kuma.pojos.QueueObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.find\nimport org.jetbrains.anko.sdk27.coroutines.onClick\n\n/**\n * Allows playback of videos that are in a playlist, using [PlayerHolder] to load the and render\n * it to the [com.google.android.exoplayer2.ui.PlayerView] to render the video output. Supports\n * [MediaSessionCompat] and picture in picture as well.\n */\n\nclass VideoActivity : GenericActivity(), PlayerHolder.PlayerCallback {\n    private val mediaSession: MediaSessionCompat by lazy { createMediaSession() }\n    private val mediaSessionConnector: MediaSessionConnector by lazy {\n        createMediaSessionConnector()\n    }\n    private val binding by lazy { PlayerViewBinding.inflate(layoutInflater) }\n    private lateinit var playerState: PlayerState\n    private lateinit var playerHolder: PlayerHolder\n    var playList: List<QueueObject> = emptyList()\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE\n        setContentView(binding.root)\n        window.decorView.setBackgroundColor(Color.BLACK)\n        volumeControlStream = AudioManager.STREAM_MUSIC\n        hideUI()\n        SSLSkipper.skip()\n        binding.player.resizeMode = getResizeMode()\n        find<View>(R.id.exit).onClick { onBackPressedDispatcher.onBackPressed() }\n        find<View>(R.id.lock).onClick { lock() }\n        find<View>(R.id.skip).setOnClickListener { playerHolder.skip() }\n        binding.unlock.onClick { unlock() }\n        binding.youtubeOverlay.performListener(object : YouTubeOverlay.PerformListener {\n            override fun onAnimationEnd() {\n                binding.youtubeOverlay.startAnimation(AnimationUtils.loadAnimation(this@VideoActivity, R.anim.fadeout))\n                binding.youtubeOverlay.isVisible = false\n                find<View>(R.id.exo_ll_controls).isVisible = true\n            }\n\n            override fun onAnimationStart() {\n                binding.youtubeOverlay.isVisible = true\n                binding.youtubeOverlay.startAnimation(AnimationUtils.loadAnimation(this@VideoActivity, R.anim.fadein))\n                find<View>(R.id.exo_ll_controls).isVisible = false\n            }\n        })\n        if (!intent.getBooleanExtra(\"isPlayList\", false)) {\n            find<View>(R.id.lay_next).isVisible = false\n            find<View>(R.id.lay_prev).isVisible = false\n        }\n        lifecycleScope.launch(Dispatchers.IO) {\n            playList = CacheDB.INSTANCE.queueDAO().getAllByAid(intent.getStringExtra(\"playlist\") ?: \"empty\")\n            playerState = CacheDB.INSTANCE.playerStateDAO().find(intent.getStringExtra(\"title\") ?: \"???\") ?: PlayerState()\n            if (savedInstanceState != null) {\n                playerState.position = savedInstanceState.getLong(\"position\", 0)\n                playerState.window = savedInstanceState.getInt(\"window\", 0)\n                playerState.whenReady = savedInstanceState.getBoolean(\"playWhenReady\", true)\n            }\n            //createMediaSession()\n            withContext(Dispatchers.Main) {\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isInPictureInPictureMode)\n                    binding.player.useController = false\n                createPlayer()\n                playerHolder.start()\n                activateMediaSession()\n            }\n        }\n    }\n\n    override fun onSaveInstanceState(outState: Bundle) {\n        super.onSaveInstanceState(outState)\n        if (::playerHolder.isInitialized) {\n            playerHolder.saveState()\n            outState.putInt(\"window\", playerState.window)\n            outState.putLong(\"position\", playerState.position)\n            outState.putBoolean(\"playWhenReady\", playerState.whenReady)\n        }\n    }\n\n    private fun lock() {\n        binding.player.hideController()\n        binding.layLocked.isVisible = true\n    }\n\n    private fun unlock() {\n        binding.player.showController()\n        binding.layLocked.isVisible = false\n    }\n\n    private fun hideUI() {\n        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE\n                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION\n                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN\n                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION\n                or View.SYSTEM_UI_FLAG_FULLSCREEN\n                or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)\n        window.addFlags(View.KEEP_SCREEN_ON)\n    }\n\n    private fun getResizeMode(): Int {\n        return when (PreferenceManager.getDefaultSharedPreferences(this).getString(\"player_resize\", \"0\")) {\n            \"0\" -> AspectRatioFrameLayout.RESIZE_MODE_FIT\n            \"1\" -> AspectRatioFrameLayout.RESIZE_MODE_FILL\n            \"2\" -> AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH\n            \"3\" -> AspectRatioFrameLayout.RESIZE_MODE_FIXED_HEIGHT\n            else -> AspectRatioFrameLayout.RESIZE_MODE_FIT\n        }\n    }\n\n    override fun onStart() {\n        super.onStart()\n        if (::playerHolder.isInitialized) {\n            startPlayer()\n            activateMediaSession()\n        }\n    }\n\n    override fun onResume() {\n        super.onResume()\n        doOnUI { hideUI() }\n        resumePlayer()\n    }\n\n    override fun onPause() {\n        super.onPause()\n        if (Build.VERSION.SDK_INT >= 24 && isInPictureInPictureMode)\n            resumePlayer()\n        else {\n            if (::playerHolder.isInitialized)\n                if (!playerState.isFinishing) {\n                    playerHolder.saveState()\n                    playerState.title = find<TextView>(R.id.video_title).text.toString()\n                    saveState()\n                }\n            if (!isFinishing)\n                pausePlayer()\n            else\n                stopPlayer()\n        }\n    }\n\n    override fun onStop() {\n        deactivateMediaSession()\n        super.onStop()\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n        stopPlayer()\n        releasePlayer()\n        releaseMediaSession()\n    }\n\n    private fun saveState() {\n        GlobalScope.launch(Dispatchers.IO) {\n            CacheDB.INSTANCE.playerStateDAO().set(playerState)\n        }\n    }\n\n    // MediaSession related functions.\n    private fun createMediaSession(): MediaSessionCompat = MediaSessionCompat(this, packageName).apply {\n        setFlags(MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS)\n        setCallback(object : MediaSessionCompat.Callback() {\n            override fun onPlay() {\n                super.onPlay()\n                with(playerHolder.audioFocusPlayer) {\n                    playWhenReady = true\n                }\n            }\n\n            override fun onPause() {\n                super.onPause()\n                with(playerHolder.audioFocusPlayer) {\n                    playWhenReady = false\n                }\n            }\n\n            override fun onSkipToNext() {\n                super.onSkipToNext()\n                with(playerHolder.audioFocusPlayer) {\n                    if (hasNext())\n                        next()\n                }\n            }\n\n            override fun onSkipToPrevious() {\n                super.onSkipToPrevious()\n                with(playerHolder.audioFocusPlayer) {\n                    if (hasPrevious())\n                        previous()\n                }\n            }\n        })\n    }\n\n    private fun createMediaSessionConnector(): MediaSessionConnector =\n            MediaSessionConnector(mediaSession).apply {\n                // If QueueNavigator isn't set, then mediaSessionConnector will not handle following\n                // MediaSession actions (and they won't show up in the minimized PIP activity):\n                // [ACTION_SKIP_PREVIOUS], [ACTION_SKIP_NEXT], [ACTION_SKIP_TO_QUEUE_ITEM]\n                /*setQueueNavigator(object : TimelineQueueNavigator(mediaSession) {\n                    override fun getMediaDescription(player: Player, windowIndex: Int): MediaDescriptionCompat {\n\n                    }\n                })*/\n            }\n\n\n    // MediaSession related functions.\n    private fun activateMediaSession() {\n        // Note: do not pass a null to the 3rd param below, it will cause a NullPointerException.\n        // To pass Kotlin arguments to Java varargs, use the Kotlin spread operator `*`.\n        mediaSessionConnector.setPlayer(playerHolder.audioFocusPlayer)\n        mediaSession.isActive = true\n    }\n\n    private fun deactivateMediaSession() {\n        mediaSessionConnector.setPlayer(null)\n        mediaSession.isActive = false\n    }\n\n    private fun releaseMediaSession() {\n        mediaSession.release()\n    }\n\n    // ExoPlayer related functions.\n    private fun createPlayer() {\n        playerHolder = PlayerHolder(this, playerState, binding.player, intent, playList)\n        binding.youtubeOverlay.player(playerHolder.audioFocusPlayer)\n        if (!intent.getBooleanExtra(\"isPlayList\", false)) {\n            find<View>(com.google.android.exoplayer2.R.id.exo_next).visibility = View.GONE\n            find<View>(com.google.android.exoplayer2.R.id.exo_prev).visibility = View.GONE\n        }\n        //exoPlayer.overlayFrameLayout.setOnTouchListener(BVListener(this))\n    }\n\n    private fun startPlayer() {\n        if (::playerHolder.isInitialized)\n            playerHolder.start()\n    }\n\n    private fun stopPlayer() {\n        if (::playerHolder.isInitialized)\n            playerHolder.stop()\n    }\n\n    private fun resumePlayer() {\n        if (::playerHolder.isInitialized)\n            with(playerHolder.audioFocusPlayer) {\n                playWhenReady = true\n            }\n    }\n\n    private fun pausePlayer() {\n        if (::playerHolder.isInitialized)\n            with(playerHolder.audioFocusPlayer) {\n                playWhenReady = false\n            }\n    }\n\n    private fun releasePlayer() {\n        if (::playerHolder.isInitialized)\n            playerHolder.release()\n    }\n\n    // Picture in Picture related functions.\n    override fun onUserLeaveHint() {\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && ::playerHolder.isInitialized && playerHolder.audioFocusPlayer.playWhenReady && packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)) {\n            noCrash {\n                enterPictureInPictureMode(\n                    with(PictureInPictureParams.Builder()) {\n                        //setAspectRatio(Rational(16, 9))\n                        build()\n                    })\n            }\n        }\n    }\n\n    @RequiresApi(Build.VERSION_CODES.O)\n    override fun onPictureInPictureModeChanged(\n        isInPictureInPictureMode: Boolean,\n        newConfig: Configuration\n    ) {\n        super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)\n        if (::playerHolder.isInitialized)\n            playerHolder.saveState()\n        binding.player.useController = !isInPictureInPictureMode\n    }\n\n    override fun onChangeTitle(title: String) {\n        lifecycleScope.launch(Dispatchers.Main) { find<TextView>(R.id.video_title).text = title }\n    }\n\n    override fun onLoadingChange(loading: Boolean) {\n        with(find<View>(R.id.progress)) {\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInPictureInPictureMode)\n                post { visibility = View.GONE }\n            post { visibility = if (loading) View.VISIBLE else View.GONE }\n        }\n    }\n\n    override fun onPlayerStateChanged(state: Int, playWhenReady: Boolean) {\n        if (state == Player.STATE_READY)\n            doOnUI { hideUI() }\n    }\n\n\n    override fun onFinish() {\n        playerState.apply {\n            title = find<TextView>(R.id.video_title).text.toString()\n            position = 0\n            isFinishing = true\n        }\n        saveState()\n        unlock()\n        //finish()\n    }\n\n\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/player/WebPlayerActivity.kt",
    "content": "package knf.kuma.player\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.graphics.Color\r\nimport android.graphics.drawable.ColorDrawable\r\nimport android.net.Uri\r\nimport android.os.Bundle\r\nimport android.view.View\r\nimport android.webkit.CookieManager\r\nimport android.webkit.WebResourceRequest\r\nimport android.webkit.WebView\r\nimport android.webkit.WebViewClient\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.core.view.isVisible\r\nimport knf.kuma.databinding.ActivityBrowserBinding\r\nimport org.jetbrains.anko.longToast\r\n\r\nclass WebPlayerActivity : AppCompatActivity() {\r\n    val binding by lazy { ActivityBrowserBinding.inflate(layoutInflater) }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        window.setBackgroundDrawable(ColorDrawable(Color.BLACK))\r\n        try {\r\n            CookieManager.getInstance()\r\n        } catch (_: Exception) {\r\n            longToast(\"Webview no está disponible en tu dispositivo\")\r\n            finish()\r\n            return\r\n        }\r\n        setContentView(binding.root)\r\n        binding.webview.apply {\r\n            setBackgroundColor(Color.TRANSPARENT)\r\n            settings.apply {\r\n                javaScriptEnabled = true\r\n                domStorageEnabled = true\r\n            }\r\n            webViewClient = object : WebViewClient() {\r\n                @Deprecated(\"Deprecated in Java\")\r\n                override fun shouldOverrideUrlLoading(\r\n                    view: WebView?,\r\n                    request: WebResourceRequest?\r\n                ): Boolean {\r\n                    return true\r\n                }\r\n               /* override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {\r\n                    //view?.loadUrl(url ?: return true)\r\n                    return true\r\n                }*/\r\n\r\n                override fun onPageFinished(view: WebView?, url: String?) {\r\n                    binding.loading.isVisible = false\r\n                }\r\n            }\r\n            //loadUrl(intent.dataString?:\"about:blank\")\r\n            intent.dataString?.let {\r\n                loadData(framed(it), \"text/html; charset=utf-8\", \"UTF-8\")\r\n            } ?: finish()\r\n        }\r\n        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE\r\n                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION\r\n                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN\r\n                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION\r\n                or View.SYSTEM_UI_FLAG_FULLSCREEN\r\n                or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)\r\n    }\r\n}\r\n\r\nfun framed(link: String): String =\r\n    \"<html><body style='margin:0;padding:0;'><iframe src=\\\"$link\\\" scrolling=\\\"no\\\" allowfullscreen=\\\"\\\" width=\\\"100%\\\" height=\\\"100%\\\" frameborder=\\\"0\\\"></iframe></body></html>\"\r\n\r\nfun openWebPlayer(context: Context, link: String){\r\n    context.startActivity(Intent(context,WebPlayerActivity::class.java).apply {\r\n        data = Uri.parse(link)\r\n    })\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/Achievement.kt",
    "content": "package knf.kuma.pojos\r\n\r\nimport android.content.Context\r\nimport android.graphics.Color\r\nimport android.graphics.drawable.Drawable\r\nimport androidx.annotation.Keep\r\nimport androidx.core.content.ContextCompat\r\nimport androidx.core.graphics.drawable.DrawableCompat\r\nimport androidx.room.Entity\r\nimport androidx.room.PrimaryKey\r\nimport androidx.room.TypeConverters\r\nimport com.google.firebase.firestore.IgnoreExtraProperties\r\nimport com.google.gson.annotations.SerializedName\r\nimport knf.kuma.R\r\nimport knf.kuma.achievements.AchievementManager\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.custom.AchievementUnlocked\r\nimport knf.kuma.database.BaseConverter\r\nimport java.text.SimpleDateFormat\r\nimport java.util.Calendar\r\nimport java.util.Locale\r\n\r\n@Keep\r\n@Entity\r\n@TypeConverters(BaseConverter::class)\r\n@IgnoreExtraProperties\r\nopen class Achievement(\r\n        @SerializedName(\"key\")\r\n        @PrimaryKey\r\n        var key: Long = -1,\r\n        @SerializedName(\"name\")\r\n        var name: String = \"\",\r\n        @SerializedName(\"description\")\r\n        var description: String = \"\",\r\n        @SerializedName(\"points\")\r\n        var points: Int = -1,\r\n        @SerializedName(\"isSecret\")\r\n        var isSecret: Boolean = false,\r\n        @SerializedName(\"group\")\r\n        var group: String? = null,\r\n        @SerializedName(\"time\")\r\n        var time: Long = 0,\r\n        @SerializedName(\"count\")\r\n        var count: Int = 0,\r\n        @SerializedName(\"goal\")\r\n        var goal: Int = 0,\r\n        @SerializedName(\"isUnlocked\")\r\n        var isUnlocked: Boolean = false,\r\n        @SerializedName(\"isRevealed\")\r\n        var isRevealed: Boolean = false\r\n) {\r\n\r\n    fun getState(): String {\r\n        return if (isUnlocked) {\r\n            val dateFormat = SimpleDateFormat(\"dd/MM/yyyy\", Locale.getDefault())\r\n            val calendar = Calendar.getInstance().also {\r\n                it.timeInMillis = time\r\n            }\r\n            dateFormat.format(calendar.time)\r\n        } else\r\n            \"Bloqueado\"\r\n    }\r\n\r\n    fun usableName(): String {\r\n        return if (isSecret && !isUnlocked && !isRevealed)\r\n            \"Logro secreto\"\r\n        else\r\n            name\r\n    }\r\n\r\n    fun usableDescription(): String {\r\n        return if (isSecret && !isUnlocked && !isRevealed)\r\n            \"Usa mas la app para desbloquear\"\r\n        else\r\n            description\r\n    }\r\n\r\n    fun usableIcon(): Int {\r\n        return if (isSecret && !isUnlocked && !isRevealed)\r\n            R.drawable.ic_locked\r\n        else\r\n            AchievementManager.getIcon(key)\r\n    }\r\n\r\n    private fun tintedIcon(context: Context): Drawable? {\r\n        return try {\r\n            val drawable = ContextCompat.getDrawable(context, AchievementManager.getIcon(key))\r\n                    ?: return null\r\n            val drawableWrap = DrawableCompat.wrap(drawable)\r\n            DrawableCompat.setTint(drawableWrap, Color.WHITE)\r\n            drawableWrap\r\n        } catch (e: Exception) {\r\n            e.printStackTrace()\r\n            null\r\n        }\r\n    }\r\n\r\n    fun achievementData(context: Context): AchievementUnlocked.AchievementData {\r\n        return AchievementUnlocked.AchievementData()\r\n                .setTitle(name)\r\n                .setSubtitle(description)\r\n                .setIcon(tintedIcon(context))\r\n                .setTextColor(Color.WHITE)\r\n                .setBackgroundColor(ContextCompat.getColor(context, EAHelper.getThemeColor()))\r\n                .setIconBackgroundColor(ContextCompat.getColor(context, EAHelper.getThemeColorLight()))\r\n        //.setPopUpOnClickListener { context.startActivity(Intent(context,)) }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/AchievementAd.kt",
    "content": "package knf.kuma.pojos\r\n\r\nimport knf.kuma.ads.AdCallback\r\n\r\nclass AchievementAd(private val adId: String) : Achievement(0, \"\", \"\", 0, false), AdCallback {\r\n    override fun getID(): String = adId\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/Anime.java",
    "content": "package knf.kuma.pojos;\n\nimport pl.droidsonroids.jspoon.annotation.Selector;\n\npublic class Anime {\n    @Selector(\"html\")\n    public AnimeObject.WebInfo object;\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/AnimeObject.java",
    "content": "package knf.kuma.pojos;\n\nimport static java.lang.Math.abs;\n\nimport android.text.TextUtils;\n\nimport androidx.annotation.Keep;\nimport androidx.annotation.NonNull;\nimport androidx.core.graphics.drawable.IconCompat;\nimport androidx.room.ColumnInfo;\nimport androidx.room.Embedded;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.Index;\nimport androidx.room.PrimaryKey;\nimport androidx.room.TypeConverter;\nimport androidx.room.TypeConverters;\n\nimport com.google.gson.Gson;\nimport com.google.gson.annotations.SerializedName;\nimport com.google.gson.reflect.TypeToken;\n\nimport org.jetbrains.annotations.NotNull;\nimport org.jsoup.nodes.Element;\n\nimport java.io.Serializable;\nimport java.lang.reflect.Type;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Calendar;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.Locale;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport knf.kuma.animeinfo.AnimeInfo;\nimport knf.kuma.animeinfo.ktx.ExtensionsKt;\nimport knf.kuma.commons.ExtensionUtilsKt;\nimport knf.kuma.commons.FileWrapper;\nimport knf.kuma.commons.PatternUtil;\nimport knf.kuma.commons.PrefsUtil;\nimport knf.kuma.database.CacheDB;\nimport pl.droidsonroids.jspoon.ElementConverter;\nimport pl.droidsonroids.jspoon.annotation.Selector;\n\n@Entity(indices = @Index(value = {\"name\", \"link\", \"aid\", \"type\", \"state\", \"fileName\"}, unique = true))\n@TypeConverters(AnimeObject.Converter.class)\npublic class AnimeObject implements Comparable<AnimeObject>, Serializable {\n    @PrimaryKey\n    @SerializedName(\"key\")\n    public int key;\n    @SerializedName(\"link\")\n    public String link;\n    @SerializedName(\"sid\")\n    public String sid;\n    @SerializedName(\"name\")\n    public String name;\n    @SerializedName(\"fileName\")\n    public String fileName;\n    @Embedded\n    @SerializedName(\"webInfo\")\n    public WebInfo webInfo;\n    @Ignore\n    @NonNull\n    public transient String aid = \"\";\n    @Ignore\n    public transient String img;\n    @Ignore\n    public transient String description;\n    @SerializedName(\"type\")\n    public String type;\n    @SerializedName(\"state\")\n    public String state;\n    @SerializedName(\"day\")\n    public Day day;\n    @Ignore\n    public transient String followers;\n    @Ignore\n    public transient String rate_stars;\n    @Ignore\n    public transient String rate_count;\n    @Ignore\n    public transient List<String> genres;\n    @Ignore\n    public transient List<WebInfo.AnimeRelated> related;\n    @SerializedName(\"chapters\")\n    public List<WebInfo.AnimeChapter> chapters;\n    @Ignore\n    public transient IconCompat icon;\n\n    @Ignore\n    public AnimeObject() {\n\n    }\n\n    public AnimeObject(int key, String link, String sid, String name, String fileName, WebInfo webInfo, String type, String state, Day day) {\n        this.key = key;\n        this.link = link;\n        this.sid = sid;\n        this.name = name;\n        this.fileName = fileName;\n        this.webInfo = webInfo;\n        this.type = type;\n        this.state = state;\n        this.day = day;\n        populate(webInfo);\n    }\n\n    @Ignore\n    public AnimeObject(int key, String link, String sid, String name, String fileName, String type, String state, Day day, List<WebInfo.AnimeChapter> chapters) {\n        this.key = key;\n        this.link = link;\n        this.sid = sid;\n        this.name = name;\n        this.fileName = fileName;\n        this.type = type;\n        this.state = state;\n        this.day = day;\n        this.chapters = chapters;\n    }\n\n    @Ignore\n    public AnimeObject(String link, WebInfo webInfo) {\n        this.link = link;\n        this.fileName = PatternUtil.INSTANCE.getRootFileName(link);\n        this.sid = extract(link);\n        this.webInfo = webInfo;\n        populate(webInfo);\n    }\n\n    private void populate(WebInfo webInfo) {\n        this.key = Integer.parseInt(webInfo.aid);\n        this.webInfo = webInfo;\n        this.aid = webInfo.aid;\n        this.name = PatternUtil.INSTANCE.fromHtml(webInfo.name);\n        this.img = \"https://www3.animeflv.net\" + webInfo.img;\n        this.description = PatternUtil.INSTANCE.fromHtml(webInfo.description);\n        this.type = getType(webInfo.type);\n        this.state = getState(webInfo.state);\n        this.day = webInfo.emisionDay;\n        this.followers = webInfo.followers;\n        this.rate_stars = webInfo.rate_stars;\n        this.rate_count = webInfo.rate_count;\n        this.genres = webInfo.genres;\n        this.related = webInfo.related;\n        completeInfo(webInfo.scripts);\n    }\n\n    private void completeInfo(List<Element> scripts) {\n        try {\n            Element element = findDataScript(scripts);\n            if (element != null) {\n                AnimeInfo animeInfo = new AnimeInfo(element.html());\n                //this.name = PatternUtil.fromHtml(animeInfo.title);\n                this.day = animeInfo.getDay();\n                this.chapters = WebInfo.AnimeChapter.create(animeInfo);\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n    }\n\n    private Element findDataScript(List<Element> scripts) {\n        try {\n            for (Element element : scripts)\n                if (element.html().contains(\"var anime_info\"))\n                    return element;\n            return null;\n        } catch (Exception e) {\n            return null;\n        }\n    }\n\n    private String extract(String link) {\n        return link.substring(link.lastIndexOf(\"/\") + 1);\n    }\n\n    private String getType(String className) {\n        switch (className) {\n            default:\n            case \"Type tv\":\n                return \"Anime\";\n            case \"Type ova\":\n                return \"OVA\";\n            case \"Type special\":\n                return \"Especial\";\n            case \"Type movie\":\n                return \"Película\";\n        }\n    }\n\n    private String getState(String className) {\n        switch (className) {\n            case \"AnmStts\":\n                return \"En emisión\";\n            case \"AnmStts A\":\n                return \"Finalizado\";\n            default:\n                return \"Próximamente\";\n        }\n    }\n\n    public String getFileName() {\n        if (PrefsUtil.INSTANCE.getSaveWithName())\n            return fileName;\n        else\n            return aid;\n    }\n\n    public String getGenresString() {\n        if (genres.size() == 0)\n            return \"Sin generos\";\n        StringBuilder builder = new StringBuilder();\n        for (String genre : genres) {\n            builder.append(genre)\n                    .append(\", \");\n        }\n        String g = builder.toString();\n        return g.substring(0, g.lastIndexOf(\",\"));\n    }\n\n    public Boolean checkIntegrity() {\n        try {\n            return chapters != null && (chapters.size() == 0 || (chapters.get(0).aid != null && chapters.get(0).eid != null));\n        } catch (Exception e) {\n            return false;\n        }\n    }\n\n    @Override\n    public int hashCode() {\n        return aid.hashCode();\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        return obj instanceof AnimeObject && aid.equals(((AnimeObject) obj).aid) && day.equals(((AnimeObject) obj).day) && state.equals(((AnimeObject) obj).state);\n    }\n\n    @Override\n    public int compareTo(@NonNull AnimeObject o) {\n        return name.compareTo(o.name);\n    }\n\n    public enum Day {\n        MONDAY(2),\n        TUESDAY(3),\n        WEDNESDAY(4),\n        THURSDAY(5),\n        FRIDAY(6),\n        SATURDAY(7),\n        SUNDAY(1),\n        NONE(0);\n        public final int value;\n\n        Day(int value) {\n            this.value = value;\n        }\n\n        public static Day fromValue(int value) {\n            for (Day day : values()) {\n                if (day.value == value) {\n                    return day;\n                }\n            }\n            return NONE;\n        }\n    }\n\n    public static class WebInfo {\n        @Selector(value = \"div.Image img[src]\", attr = \"src\", format = \"/(\\\\d+)[/.]\")\n        @SerializedName(\"aid\")\n        public String aid;\n        @Selector(value = \"h1.Title\", defValue = \"Error\")\n        @ColumnInfo(name = \"web_name\")\n        @SerializedName(\"web_name\")\n        public String name;\n        @Selector(value = \"div.Image img[src]\", attr = \"src\")\n        @SerializedName(\"img\")\n        public String img;\n        @Selector(value = \"div.Description\", defValue = \"Sin descripcion\")\n        @SerializedName(\"description\")\n        public String description;\n        @Selector(value = \"span[class^=Type]\", attr = \"class\", defValue = \"Desconocido\")\n        @ColumnInfo(name = \"web_type\")\n        @SerializedName(\"web_type\")\n        public String type;\n        @Selector(value = \"aside.SidebarA.BFixed p\", attr = \"class\", defValue = \"Desconocido\")\n        @ColumnInfo(name = \"web_state\")\n        @SerializedName(\"web_state\")\n        public String state;\n        @Selector(value = \"div.Title:contains(Seguidores) span\", defValue = \"0\")\n        @SerializedName(\"followers\")\n        public String followers = \"0\";\n        @Selector(value = \"span.vtprmd\", defValue = \"0.0\")\n        @SerializedName(\"rate_starts\")\n        public String rate_stars;\n        @Selector(value = \"span#votes_nmbr\", defValue = \"0\")\n        @SerializedName(\"rate_count\")\n        public String rate_count;\n        @Selector(value = \"span.Date.fa-calendar\", converter = DayConverter.class)\n        @SerializedName(\"emissionDay\")\n        public Day emisionDay;\n        @Selector(\"nav.Nvgnrs a[href]\")\n        @SerializedName(\"genres\")\n        public List<String> genres = new ArrayList<>();\n        @Selector(\"ul.ListAnmRel li:has(a[href~=^\\\\/[a-z]+\\\\/.+$])\")\n        @SerializedName(\"related\")\n        public List<AnimeRelated> related = new ArrayList<>();\n        @Ignore\n        @Selector(\"script:not([src])\")\n        transient List<Element> scripts;\n        /*@Selector(\"ul.ListCaps li,ul.ListEpisodes li,ul#episodeList li\")\n        public List<Element> chapters = new ArrayList<>();*/\n\n        @Keep\n        public static class AnimeRelated {\n            @Selector(value = \"a\", attr = \"href\")\n            @SerializedName(\"link\")\n            public String link;\n            @Selector(value = \"a\", converter = AidGetter.class)\n            @SerializedName(\"aid\")\n            public String aid;\n            @Selector(\"a\")\n            @SerializedName(\"name\")\n            public String name;\n            @Selector(value = \"li\", format = \"\\\\((.*)\\\\)\")\n            @SerializedName(\"relation\")\n            public String relation;\n\n            public static class AidGetter implements ElementConverter<String> {\n                @Keep\n                public AidGetter() {\n\n                }\n\n                @Override\n                public String convert(@NotNull Element node, @NotNull Selector selector) {\n                    String aid = CacheDB.Companion.getINSTANCE().animeDAO().findAidByName(node.text());\n                    if (aid != null)\n                        return aid;\n                    else\n                        return \"null\";\n                }\n            }\n        }\n\n        @Entity\n        @Keep\n        public static class AnimeChapter implements Comparable<AnimeChapter>, Serializable {\n            @SerializedName(\"chapter_key\")\n            @PrimaryKey\n            public int key;\n            @SerializedName(\"chapter_number\")\n            public String number;\n            @SerializedName(\"chapter_eid\")\n            public String eid;\n            @SerializedName(\"chapter_link\")\n            public String link;\n            @SerializedName(\"chapter_name\")\n            public String name;\n            @SerializedName(\"chapter_aid\")\n            public String aid;\n            @SerializedName(\"chapter_img\")\n            @Ignore\n            public String img;\n            @SerializedName(\"chapter_Type\")\n            @Ignore\n            public transient ChapterType chapterType;\n            @SerializedName(\"chapter_ isDownloaded\")\n            @Ignore\n            private transient FileWrapper fileWrapper;\n\n            public AnimeChapter() {\n            }\n\n            public AnimeChapter(int key, String number, String eid, String link, String name, String aid) {\n                this.key = key;\n                this.number = number;\n                this.eid = eid;\n                this.link = link;\n                this.name = name;\n                this.aid = aid;\n                this.fileWrapper = FileWrapper.Companion.create(ExtensionsKt.getFilePath(this));\n            }\n\n            @Ignore\n            public AnimeChapter(String name, String aid, Element element) {\n                this.name = name;\n                if (element.select(\"img\").first() == null) {\n                    this.chapterType = ChapterType.OLD;\n                    String full = element.select(\"a\").first().text();\n                    this.number = \"Episodio \" + extract(full, \"^.* (\\\\d+\\\\.?\\\\d*):?.*$\");\n                    this.link = \"https://www3.animeflv.net\" + element.select(\"a\").first().attr(\"href\");\n                    this.eid = String.valueOf(abs((aid + number).hashCode()));\n                } else {\n                    this.chapterType = ChapterType.NEW;\n                    this.number = element.select(\"p\").first().ownText();\n                    this.link = \"https://www3.animeflv.net\" + element.select(\"a\").first().attr(\"href\");\n                    this.eid = String.valueOf(abs((aid + number).hashCode()));\n                    this.img = element.select(\"img.lazy\").first().attr(\"src\");\n                }\n                this.aid = aid;\n                this.key = (aid + number).hashCode();\n                this.fileWrapper = FileWrapper.Companion.create(ExtensionsKt.getFilePath(this));\n            }\n\n            @Ignore\n            public AnimeChapter(AnimeInfo info, String num, String sid) {\n                this.name = info.getTitle();\n                this.chapterType = ChapterType.NEW;\n                this.aid = info.getAid();\n                this.number = \"Episodio \" + num;\n                this.link = \"https://www3.animeflv.net/ver/\" + info.getSid() + \"-\" + num;\n                this.eid = String.valueOf(abs((aid + number).hashCode()));\n                this.img = \"https://cdn.animeflv.net/screenshots/\" + info.getAid() + \"/\" + num + \"/th_3.jpg\";\n                this.key = (aid + number).hashCode();\n                this.fileWrapper = FileWrapper.Companion.create(ExtensionsKt.getFilePath(this));\n            }\n\n            @NonNull\n            public FileWrapper fileWrapper() {\n                if (fileWrapper == null)\n                    this.fileWrapper = FileWrapper.Companion.create(ExtensionsKt.getFilePath(this));\n                return fileWrapper;\n            }\n\n            @Ignore\n            public static AnimeChapter fromData(String aid, String chapter, String eid, String url, String name) {\n                return new AnimeChapter((aid + chapter).hashCode(), chapter, eid, url, name, aid);\n            }\n\n            @Ignore\n            public static AnimeChapter fromRecent(RecentObject object) {\n                return new AnimeChapter((object.aid + object.chapter).hashCode(), object.chapter, object.eid, object.url, object.name, object.aid);\n            }\n\n            @Ignore\n            public static AnimeChapter fromDownloaded(ExplorerObject.FileDownObj object) {\n                return new AnimeChapter((object.aid + \"Episodio \" + object.chapter).hashCode(), \"Episodio \" + object.chapter, object.eid, object.link, object.title, object.aid);\n            }\n\n            public static List<AnimeChapter> create(String name, String aid, List<Element> elements) {\n                List<AnimeChapter> chapters = new ArrayList<>();\n                for (Element element : elements) {\n                    try {\n                        chapters.add(new AnimeChapter(name, aid, element));\n                    } catch (Exception e) {\n                        e.printStackTrace();\n                    }\n                }\n                return chapters;\n            }\n\n            public static List<AnimeChapter> create(AnimeInfo info) {\n                List<AnimeChapter> chapters = new ArrayList<>();\n                try {\n                    for (Map.Entry<String, String> entry : info.getEpMap().entrySet()) {\n                        try {\n                            chapters.add(new AnimeChapter(info, entry.getKey(), entry.getValue()));\n                        } catch (Exception e) {\n                            e.printStackTrace();\n                        }\n                    }\n                    Collections.sort(chapters);\n                } catch (Exception e) {\n                    e.printStackTrace();\n                }\n                return chapters;\n            }\n\n            public String commentariesLink(String version) {\n                try {\n                    return \"https://disqus.com/embed/comments/?base=default&f=https-animeflv-net&t_u=\" + ExtensionUtilsKt.urlEncode(ExtensionUtilsKt.resolveRedirection(link, 0)) + \"&s_o=default#version=\" + version;\n                } catch (Exception e) {\n                    try {\n                        return \"https://disqus.com/embed/comments/?base=default&f=https-animeflv-net&t_u=\" + ExtensionUtilsKt.urlEncode(link) + \"&s_o=default#version=\" + version;\n                    } catch (Exception ex) {\n                        return link;\n                    }\n                }\n\n            }\n\n            @Override\n            public int compareTo(@NonNull AnimeChapter animeChapter) {\n                double num1 = Double.valueOf(number.substring(number.lastIndexOf(\" \") + 1));\n                double num2 = Double.valueOf(animeChapter.number.substring(animeChapter.number.lastIndexOf(\" \") + 1));\n                return Double.compare(num2, num1);\n            }\n\n            @Override\n            public boolean equals(Object obj) {\n                return obj instanceof AnimeChapter && eid.equals(((AnimeChapter) obj).eid);\n            }\n\n            @Override\n            public int hashCode() {\n                return name.hashCode() + number.hashCode();\n            }\n\n            private String extract(String st, String regex) {\n                Matcher matcher = Pattern.compile(regex).matcher(st);\n                matcher.find();\n                return matcher.group(1);\n            }\n\n            public enum ChapterType {\n                @SerializedName(\"NEW\")\n                NEW(0),\n                @SerializedName(\"OLD\")\n                OLD(1);\n                public int value;\n\n                ChapterType(int value) {\n                    this.value = value;\n                }\n            }\n        }\n    }\n\n    public static class Converter {\n\n        @TypeConverter\n        public List<String> stringToList(String json) {\n            return Arrays.asList(json.split(\";\"));\n        }\n\n        @TypeConverter\n        public String listToString(List<String> list) {\n            return TextUtils.join(\";\", list);\n        }\n\n        @TypeConverter\n        public List<WebInfo.AnimeRelated> stringToRelated(String json) {\n            try {\n                Gson gson = new Gson();\n                Type type = new TypeToken<List<WebInfo.AnimeRelated>>() {\n                }.getType();\n                return gson.fromJson(json, type);\n            } catch (Exception e) {\n                return new ArrayList<>();\n            }\n        }\n\n        @TypeConverter\n        public String relatedToString(List<WebInfo.AnimeRelated> list) {\n            Gson gson = new Gson();\n            Type type = new TypeToken<List<WebInfo.AnimeRelated>>() {\n            }.getType();\n            return gson.toJson(list, type);\n        }\n\n        @TypeConverter\n        public List<WebInfo.AnimeChapter> stringToChapters(String json) {\n            Gson gson = new Gson();\n            Type type = new TypeToken<List<WebInfo.AnimeChapter>>() {\n            }.getType();\n            return gson.fromJson(json, type);\n        }\n\n        @TypeConverter\n        public String chaptersToString(List<WebInfo.AnimeChapter> list) {\n            try {\n                Gson gson = new Gson();\n                Type type = new TypeToken<List<WebInfo.AnimeChapter>>() {\n                }.getType();\n                return gson.toJson(list, type);\n            } catch (Throwable e) {\n                return \"{}\";\n            }\n        }\n\n        @TypeConverter\n        public Day intToDay(int day) {\n            return Day.fromValue(day);\n        }\n\n        @TypeConverter\n        public int dayToInt(Day day) {\n            if (day == null) {\n                return 0;\n            }\n            return day.value;\n        }\n    }\n\n    public static class DayConverter implements ElementConverter<Day> {\n        @Keep\n        public DayConverter() {\n        }\n\n        @Override\n        public Day convert(@NotNull Element node, @NotNull Selector selector) {\n            try {\n                Element element = node.select(selector.value()).first();\n                if (element == null)\n                    return Day.NONE;\n                String date = element.ownText().trim();\n                Calendar calendar = Calendar.getInstance();\n                calendar.setTime(new SimpleDateFormat(\"yyyy-MM-dd\", Locale.getDefault()).parse(date));\n                switch (calendar.get(Calendar.DAY_OF_WEEK)) {\n                    case 2:\n                        return Day.MONDAY;\n                    case 3:\n                        return Day.TUESDAY;\n                    case 4:\n                        return Day.WEDNESDAY;\n                    case 5:\n                        return Day.THURSDAY;\n                    case 6:\n                        return Day.FRIDAY;\n                    case 7:\n                        return Day.SATURDAY;\n                    case 1:\n                        return Day.SUNDAY;\n                    default:\n                        return Day.NONE;\n                }\n            } catch (Exception e) {\n                //e.printStackTrace();\n                return Day.NONE;\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/AutoBackupObject.kt",
    "content": "package knf.kuma.pojos\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.provider.Settings\nimport androidx.preference.PreferenceManager\nimport com.google.gson.annotations.SerializedName\nimport com.jaredrummler.android.device.DeviceName\nimport knf.kuma.backup.objects.BackupObject\nimport knf.kuma.commons.noCrashLet\n\nopen class AutoBackupObject() : BackupObject<Any>() {\n    @SerializedName(\"name\")\n    var name: String? = \"\"\n    @SerializedName(\"device_id\")\n    var device_id: String? = \"\"\n    @SerializedName(\"value\")\n    var value: String? = null\n\n    @SuppressLint(\"HardwareIds\")\n    constructor(context: Context?) : this() {\n        if (context != null) {\n            this.name = DeviceName.getDeviceName()\n            this.device_id = Settings.Secure.getString(context.applicationContext.contentResolver, Settings.Secure.ANDROID_ID)\n            this.value = PreferenceManager.getDefaultSharedPreferences(context).getString(\"auto_backup\", \"0\")\n        }\n    }\n\n    @SuppressLint(\"HardwareIds\")\n    constructor(context: Context?, newValue: String?) : this() {\n        if (context != null) {\n            this.name = DeviceName.getDeviceName()\n            this.device_id = Settings.Secure.getString(context.applicationContext.contentResolver, Settings.Secure.ANDROID_ID)\n            this.value = newValue\n        }\n    }\n\n    override fun toString(): String {\n        return \"$name ID: $device_id\"\n    }\n\n    override fun hashCode(): Int {\n        return (name + device_id).hashCode()\n    }\n\n    override fun equals(other: Any?): Boolean {\n        return noCrashLet {\n            other is AutoBackupObject &&\n                    name == other.name &&\n                    device_id == other.device_id\n        } ?: false\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/DirectoryPage.kt",
    "content": "package knf.kuma.pojos\n\nimport android.util.Log\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.database.CacheDB\nimport knf.kuma.database.dao.AnimeDAO\nimport pl.droidsonroids.jspoon.Jspoon\nimport pl.droidsonroids.jspoon.annotation.Selector\n\nclass DirectoryPage {\n    @Selector(value = \"article.Anime.alt.B a.Button.Vrnmlk\", attr = \"href\")\n    var links: List<String> = listOf()\n\n    fun getAnimes(animeDAO: AnimeDAO, jspoon: Jspoon, updateInterface: UpdateInterface, isCloudflareActive: Boolean): List<AnimeObject> {\n        val animeObjects = ArrayList<AnimeObject>()\n        for (link in links) {\n            if (Network.isConnected) {\n                if (!animeDAO.existLink(\"%animeflv.net$link\")) {\n                    try {\n                        val response = jsoupCookies(\"https://www3.animeflv.net$link\", true).execute()\n                        val body = response.body()\n                        if (response.statusCode() == 200 && body != null) {\n                            val webInfo =\n                                jspoon.adapter(AnimeObject.WebInfo::class.java).fromHtml(body)\n                            if (isFullMode && !PrefsUtil.isFamilyFriendly) {\n                                animeObjects.add(AnimeObject(\"https://www3.animeflv.net$link\", webInfo))\n                                Log.e(\"Directory Getter\", \"Added: https://www3.animeflv.net$link\")\n                            } else {\n                                if (webInfo.genres.contains(\"Ecchi\"))\n                                    Log.e(\"Directory Getter\", \"Skip: https://www3.animeflv.net$link\")\n                                else {\n                                    animeObjects.add(\n                                        AnimeObject(\n                                            \"https://www3.animeflv.net$link\",\n                                            webInfo\n                                        )\n                                    )\n                                    Log.e(\"Directory Getter\", \"Added: https://www3.animeflv.net$link\")\n                                }\n                            }\n                            updateInterface.onAdd()\n                        } else if (response.statusCode() == 404) {\n                            CacheDB.INSTANCE.animeDAO().allLinksInEmission\n                        } else check(response.statusCode() < 400) { \"Response code: ${response.statusCode()}\" }\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                        Log.e(\"Directory Getter\", \"Error adding: https://www3.animeflv.net\" + link + \"\\nCause: \" + e.message)\n                        updateInterface.onError()\n                    }\n                    if (isCloudflareActive)\n                        Thread.sleep(5000)\n                }\n            } else {\n                Log.e(\"Directory Getter\", \"Abort: No internet\")\n                break\n            }\n        }\n        return animeObjects\n    }\n\n    fun getAnimesRecreate(jspoon: Jspoon, updateInterface: UpdateInterface, isCloudflareActive: Boolean): List<AnimeObject> {\n        val animeObjects = ArrayList<AnimeObject>()\n        for (link in links) {\n            if (Network.isConnected) {\n                try {\n                    val webInfo = jspoon.adapter(AnimeObject.WebInfo::class.java).fromHtml(jsoupCookies(\"https://www3.animeflv.net$link\").get().outerHtml())\n                    if (isFullMode && !PrefsUtil.isFamilyFriendly) {\n                        animeObjects.add(AnimeObject(\"https://www3.animeflv.net$link\", webInfo))\n                        Log.e(\"Directory Getter\", \"Replaced: https://www3.animeflv.net$link\")\n                    } else {\n                        if (webInfo.genres.contains(\"Ecchi\"))\n                            Log.e(\"Directory Getter\", \"Skip: https://www3.animeflv.net$link\")\n                        else {\n                            animeObjects.add(AnimeObject(\"https://www3.animeflv.net$link\", webInfo))\n                            Log.e(\"Directory Getter\", \"Replaced: https://www3.animeflv.net$link\")\n                        }\n                    }\n                    updateInterface.onAdd()\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                    Log.e(\"Directory Getter\", \"Error replacing: https://www3.animeflv.net\" + link + \"\\nCause: \" + e.message)\n                    updateInterface.onError()\n                }\n                if (isCloudflareActive)\n                    Thread.sleep(5000)\n            } else {\n                Log.e(\"Directory Getter\", \"Abort: No internet\")\n                break\n            }\n        }\n        return animeObjects\n    }\n\n    interface UpdateInterface {\n        fun onAdd()\n\n        fun onError()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/DownloadObject.java",
    "content": "package knf.kuma.pojos;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.PrimaryKey;\nimport androidx.room.TypeConverters;\n\nimport java.util.Locale;\nimport java.util.concurrent.TimeUnit;\n\nimport knf.kuma.animeinfo.ktx.ExtensionsKt;\nimport knf.kuma.commons.PatternUtil;\nimport knf.kuma.database.BaseConverter;\nimport knf.kuma.recents.RecentModel;\nimport knf.kuma.videoservers.Headers;\n\n@Entity\n@TypeConverters({BaseConverter.class})\npublic class DownloadObject {\n    @Ignore\n    public static final int PAUSED = -2;\n    @Ignore\n    public static final int PENDING = -1;\n    @Ignore\n    public static final int DOWNLOADING = 0;\n    @Ignore\n    public static final int COMPLETED = 4;\n    @PrimaryKey(autoGenerate = true)\n    public int key;\n    public String eid;\n    public String file;\n    public String link;\n    public String name;\n    public String chapter;\n    public String did;\n    public String eta;\n    public String speed;\n    public String server;\n    public Headers headers;\n    @Ignore\n    public String title;\n    @Ignore\n    public boolean addQueue = false;\n    public int progress;\n    public long d_bytes;\n    public long t_bytes;\n    public long time;\n    public boolean canResume;\n    public int state;\n\n    public DownloadObject(int key, String eid, String file, String link, String name, String chapter, String did, String eta, String speed, String server, Headers headers, int progress, long d_bytes, long t_bytes, boolean canResume, int state) {\n        this.key = key;\n        this.eid = eid;\n        this.file = file;\n        this.link = link;\n        this.name = PatternUtil.INSTANCE.fromHtml(name);\n        this.chapter = chapter;\n        this.did = did;\n        this.eta = eta;\n        this.speed = speed;\n        this.server = server;\n        this.headers = headers;\n        this.title = name + chapter.substring(chapter.lastIndexOf(\" \"));\n        this.progress = progress;\n        this.d_bytes = d_bytes;\n        this.t_bytes = t_bytes;\n        this.canResume = canResume;\n        this.state = state;\n    }\n\n    @Ignore\n    public DownloadObject(String eid, String file, String name, String chapter, boolean addQueue) {\n        this.eid = eid;\n        this.file = file;\n        this.name = PatternUtil.INSTANCE.fromHtml(name);\n        this.addQueue = addQueue;\n        this.chapter = chapter;\n        this.did = \"0\";\n        this.eta = \"-1\";\n        this.speed = \"0\";\n        this.title = name + chapter.substring(chapter.lastIndexOf(\" \"));\n        this.progress = 0;\n        this.d_bytes = 0;\n        this.t_bytes = -1;\n        this.time = System.currentTimeMillis();\n        this.canResume = false;\n        this.state = PENDING;\n    }\n\n    @NonNull\n    public static DownloadObject fromRecent(RecentObject object) {\n        return new DownloadObject(object.eid, object.getFileName(), PatternUtil.INSTANCE.fromHtml(object.name), object.chapter, false);\n    }\n\n    @NonNull\n    public static DownloadObject fromRecentModel(RecentModel object) {\n        return new DownloadObject(object.extras.getEid(), object.extras.getFileName(), PatternUtil.INSTANCE.fromHtml(object.name), object.chapter, false);\n    }\n\n    @NonNull\n    public static DownloadObject fromChapter(AnimeObject.WebInfo.AnimeChapter chapter, boolean addQueue) {\n        return new DownloadObject(chapter.eid, ExtensionsKt.getFileName(chapter), PatternUtil.INSTANCE.fromHtml(chapter.name), chapter.number, addQueue);\n    }\n\n    public boolean isDownloading() {\n        return state == DOWNLOADING || state == PENDING ;\n    }\n\n    public boolean isDownloadingOrPaused() {\n        return state == DOWNLOADING || state == PAUSED || state == PENDING ;\n    }\n\n    public int getDid() {\n        if (did == null) return 0;\n        return Integer.parseInt(did);\n    }\n\n    public void setDid(int did) {\n        this.did = String.valueOf(did);\n    }\n\n    public long getEta() {\n        if (eta == null) return -1;\n        return Long.parseLong(eta);\n    }\n\n    public void setEta(long eta) {\n        this.eta = String.valueOf(eta);\n    }\n\n    private String getSpeed() {\n        if (speed == null) return \"0kB/s\";\n        long s = Long.parseLong(speed);\n        if (s < 1024)\n            return s + \"B/s\";\n        else if (s < 1024000)\n            return String.format(Locale.getDefault(), \"%.0fkB/s\", s / 1024f);\n        else\n            return String.format(Locale.getDefault(), \"%.1fMB/s\", s / 1024000f);\n    }\n\n    public void setSpeed(long speed) {\n        this.speed = String.valueOf(speed);\n    }\n\n    public String getTime() {\n        try {\n            long duration = getEta();\n            long hours = TimeUnit.MILLISECONDS.toHours(duration);\n            long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));\n            long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));\n            StringBuilder builder = new StringBuilder();\n            if (hours > 0) {\n                builder.append(hours);\n                builder.append(\"h\");\n            }\n            if (minutes > 0) {\n                if (minutes <= 9)\n                    builder.append(\"0\");\n                builder.append(minutes);\n                builder.append(\"m\");\n            }\n            if (seconds <= 9) {\n                builder.append(\"0\");\n            }\n            builder.append(seconds);\n            builder.append(\"s\");\n            return builder.toString();\n        } catch (Exception e) {\n            e.printStackTrace();\n            return \"\";\n        }\n    }\n\n    public String getSubtext() {\n        if (!canResume)\n            return getSize();\n        long duration = getEta();\n        if (duration == -1)\n            return \"Desconocido\";\n        else if (duration == -2)\n            return \"Moviendo...\";\n        else {\n            return getTime() + \", \" + getSpeed();\n        }\n    }\n\n    public String getSize() {\n        /*if (t_bytes == -1)\n            return \"\";\n        String size = formatSize(t_bytes);\n        if (size.endsWith(\".0\"))\n            size = size.substring(0, size.lastIndexOf(\".\"));\n        return size;*/\n        return progress + \"%\";\n    }\n\n    public String getDownloadServer() {\n        if (\"\".equals(server.trim()))\n            return \"Desconocido\";\n        else\n            return server;\n    }\n\n    private String formatSize(long v) {\n        if (v < 1024) return v + \" B\";\n        int z = (63 - Long.numberOfLeadingZeros(v)) / 10;\n        return String.format(Locale.US, \"%.1f%sB\", (double) v / (1L << (z * 10)), \" KMGTPE\".charAt(z));\n    }\n\n    @Override\n    public int hashCode() {\n        return (file + link + key + state + eta + speed + progress + d_bytes + t_bytes).hashCode();\n    }\n\n    @Override\n    public boolean equals(@Nullable Object obj) {\n        return obj instanceof DownloadObject\n                && key == ((DownloadObject) obj).key\n                && state == ((DownloadObject) obj).state\n                && file.equals(((DownloadObject) obj).file)\n                && link.equals(((DownloadObject) obj).link)\n                && eta.equals(((DownloadObject) obj).eta)\n                && speed.equals(((DownloadObject) obj).speed)\n                && progress == ((DownloadObject) obj).progress\n                && d_bytes == ((DownloadObject) obj).d_bytes\n                && t_bytes == ((DownloadObject) obj).t_bytes;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/EAObject.kt",
    "content": "package knf.kuma.pojos\n\nimport androidx.annotation.Keep\nimport androidx.room.Entity\nimport androidx.room.PrimaryKey\n\n@Keep\n@Entity\ndata class EAObject(\n        @PrimaryKey\n        var code: Int = -1\n)\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/ExplorerObject.java",
    "content": "package knf.kuma.pojos;\n\nimport android.content.Context;\nimport android.media.MediaMetadataRetriever;\nimport android.net.Uri;\nimport android.os.AsyncTask;\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.util.Log;\n\nimport androidx.annotation.NonNull;\nimport androidx.annotation.Nullable;\nimport androidx.lifecycle.LifecycleOwner;\nimport androidx.lifecycle.LiveData;\nimport androidx.lifecycle.MutableLiveData;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.PrimaryKey;\nimport androidx.room.TypeConverter;\nimport androidx.room.TypeConverters;\n\nimport com.google.firebase.crashlytics.FirebaseCrashlytics;\nimport com.google.gson.Gson;\nimport com.google.gson.reflect.TypeToken;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\nimport knf.kuma.commons.PatternUtil;\nimport knf.kuma.database.CacheDBWrap;\nimport knf.kuma.download.FileAccessHelper;\nimport knf.kuma.emision.AnimeSubObject;\nimport knf.kuma.explorer.ThumbServer;\nimport knf.kuma.explorer.creator.SubFile;\nimport xdroid.toaster.Toaster;\n\n@Entity\n@TypeConverters(ExplorerObject.Converter.class)\npublic class ExplorerObject {\n    @PrimaryKey\n    public int key;\n    public String img;\n    public String link;\n    public String fileName;\n    public String name;\n    public String aid;\n    public int count;\n    public String path;\n    public List<FileDownObj> chapters = new ArrayList<>();\n    @Ignore\n    private final MutableLiveData<List<FileDownObj>> liveData = new MutableLiveData<>();\n    @Ignore\n    private boolean isProcessed = false;\n    @Ignore\n    private boolean isProcessing = false;\n    @Ignore\n    private List<SubFile> file_list;\n\n    public ExplorerObject(int key, String img, String link, String fileName, String name, String aid, int count, String path, List<FileDownObj> chapters) {\n        this.key = key;\n        this.img = img;\n        this.link = link;\n        this.fileName = fileName;\n        this.name = name;\n        this.aid = aid;\n        this.count = count;\n        this.path = path;\n        this.file_list = FileAccessHelper.INSTANCE.getDownloadsDirectoryFiles(fileName);\n        this.chapters = chapters;\n    }\n\n    @Ignore\n    public ExplorerObject(ExplorerObject item) {\n        this.key = item.key;\n        this.img = item.img;\n        this.link = item.link;\n        this.fileName = item.fileName;\n        this.name = item.name;\n        this.aid = item.aid;\n        this.count = item.count;\n        this.path = item.path;\n        this.file_list = FileAccessHelper.INSTANCE.getDownloadsDirectoryFiles(fileName);\n        this.chapters = item.chapters;\n    }\n\n    @Ignore\n    public ExplorerObject(@Nullable AnimeSubObject object) throws IllegalStateException {\n        if (object == null)\n            throw new IllegalStateException(\"Anime not found!!!\");\n        this.key = object.getKey();\n        this.img = PatternUtil.INSTANCE.getCover(object.getAid());\n        this.link = object.getLink();\n        this.fileName = object.getFinalName();\n        this.name = object.getName();\n        this.aid = object.getAid();\n        file_list = FileAccessHelper.INSTANCE.getDownloadsDirectoryFiles(object.getFileName());\n        if (file_list.size() == 0) {\n            throw new IllegalStateException(\"Directory empty: \" + object.getFinalName());\n        }\n        this.count = file_list.size();\n        this.path = \"\";\n    }\n\n    private void process(Context context) {\n        isProcessing = true;\n        AsyncTask.execute(() -> {\n            try {\n                chapters = new ArrayList<>();\n                this.file_list = FileAccessHelper.INSTANCE.getDownloadsDirectoryFiles(fileName);\n                for (SubFile chap : file_list)\n                    try {\n                        String file_name = chap.getName();\n                        chapters.add(new FileDownObj(context, name, aid, PatternUtil.INSTANCE.getNumFromFile(file_name), file_name, chap));\n                    } catch (Exception e) {\n                        e.printStackTrace();\n                    }\n                this.count = chapters.size();\n                if (count == 0)\n                    Log.e(\"Directory empty\", fileName);\n                Collections.sort(chapters);\n                isProcessed = true;\n                isProcessing = false;\n                new Handler(Looper.getMainLooper()).post(() -> liveData.setValue(chapters));\n                CacheDBWrap.INSTANCE.explorerDAO().update(this);\n            } catch (Exception e) {\n                e.printStackTrace();\n                FirebaseCrashlytics.getInstance().recordException(e);\n                Toaster.toast(\"Error al obtener lista de episodios\");\n                isProcessed = true;\n                isProcessing = false;\n            }\n        });\n    }\n\n    @NonNull\n    public LiveData<List<FileDownObj>> getLiveData(Context context) {\n        if (!isProcessed && !isProcessing) process(context);\n        else if (isProcessed || chapters.size() > 0)\n            new Handler(Looper.getMainLooper()).post(() -> liveData.setValue(chapters));\n        return liveData;\n    }\n\n    public void clearLiveData(LifecycleOwner owner) {\n        liveData.removeObservers(owner);\n    }\n\n    public static class FileDownObj implements Comparable<FileDownObj> {\n        public String title;\n        public String chapter;\n        public String aid;\n        public String eid;\n        public SubFile file;\n        public String time;\n        public String fileName;\n        public String link;\n        public File thumb;\n\n        FileDownObj(Context context, String title, String aid, String chapter, String name, SubFile file) {\n            this.title = title;\n            this.chapter = chapter;\n            this.aid = aid;\n            this.eid = PatternUtil.INSTANCE.getEidFromFile(name);\n            this.fileName = name;\n            this.file = file;\n            this.time = getTime(context, file);\n            if (time.equals(\"\"))\n                throw new IllegalStateException(\"No duration\");\n            this.link = \"https://www3.animeflv.net/ver/\" + fileName.substring(fileName.indexOf(\"$\") + 1).replace(\".mp4\", \"\");\n        }\n\n        public static String[] getTitles(List<FileDownObj> list) {\n            List<String> names = new ArrayList<>();\n            for (FileDownObj file : list) {\n                names.add(file.getChapTitle());\n            }\n            return names.toArray(new String[]{});\n        }\n\n        public static Uri[] getUris(List<FileDownObj> list) {\n            List<Uri> uris = new ArrayList<>();\n            for (FileDownObj file : list) {\n                uris.add(Uri.fromFile(FileAccessHelper.INSTANCE.getFile(file.fileName)));\n            }\n            return uris.toArray(new Uri[]{});\n        }\n\n        public String getChapTitle() {\n            return title + \" \" + chapter;\n        }\n\n        public String getChapPreviewLink() {\n            if (thumb == null)\n                return \"https://www3.animeflv.net/uploads/animes/screenshots/\" + aid + \"/\" + chapter + \"/th_2.jpg\";\n            else\n                return ThumbServer.INSTANCE.loadFile(thumb);\n        }\n\n        private String getTime(Context context, SubFile file) {\n            try {\n                MediaMetadataRetriever retriever = new MediaMetadataRetriever();\n                retriever.setDataSource(context, file.getFileUri());\n                long duration = Long.parseLong(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));\n                long hours = TimeUnit.MILLISECONDS.toHours(duration);\n                long minutes = TimeUnit.MILLISECONDS.toMinutes(duration) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(duration));\n                long seconds = TimeUnit.MILLISECONDS.toSeconds(duration) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration));\n                StringBuilder builder = new StringBuilder();\n                if (hours > 0) {\n                    builder.append(hours);\n                    builder.append(\":\");\n                }\n                if (minutes <= 9) {\n                    builder.append(\"0\");\n                }\n                builder.append(minutes);\n                builder.append(\":\");\n                if (seconds <= 9) {\n                    builder.append(\"0\");\n                }\n                builder.append(seconds);\n                return builder.toString();\n            } catch (Exception e) {\n                e.printStackTrace();\n                return \"??:??\";\n            }\n        }\n\n        @Override\n        public int compareTo(@NonNull FileDownObj o) {\n            double num1 = Double.valueOf(chapter.substring(chapter.lastIndexOf(\" \") + 1));\n            double num2 = Double.valueOf(o.chapter.substring(o.chapter.lastIndexOf(\" \") + 1));\n            return Double.compare(num1, num2);\n        }\n    }\n\n    public static class Converter {\n        @TypeConverter\n        public List<FileDownObj> StringToList(String s) {\n            return new Gson().fromJson(s, new TypeToken<List<FileDownObj>>() {\n            }.getType());\n        }\n\n        @TypeConverter\n        public String ListToString(List<FileDownObj> list) {\n            return new Gson().toJson(list, new TypeToken<List<FileDownObj>>() {\n            }.getType());\n        }\n\n        @TypeConverter\n        public String UriToString(Uri uri) {\n            return uri.toString();\n        }\n\n        @TypeConverter\n        public Uri StringToUri(String text) {\n            return Uri.parse(text);\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/FakeAutoBackup.java",
    "content": "package knf.kuma.pojos;\n\npublic class FakeAutoBackup extends AutoBackupObject {\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/FavSection.java",
    "content": "package knf.kuma.pojos;\n\nimport knf.kuma.search.SearchAdvObject;\n\npublic class FavSection extends FavoriteObject {\n    private FavSection(int key, String aid, String name, String img, String type, String link, String category) {\n        super(key, aid, name, img, type, link, category);\n    }\n\n    private FavSection(AnimeObject object) {\n        super(object);\n    }\n\n    public FavSection(String name) {\n        super((SearchAdvObject) null);\n        if (name.equals(CATEGORY_NONE))\n            this.name = \"Sin categoría\";\n        else\n            this.name = name;\n        this.isSection = true;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/FavoriteObject.java",
    "content": "package knf.kuma.pojos;\n\nimport androidx.annotation.Keep;\nimport androidx.annotation.NonNull;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.PrimaryKey;\n\nimport com.google.gson.annotations.SerializedName;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport knf.kuma.search.SearchAdvObject;\n\n@Keep\n@Entity\npublic class FavoriteObject implements Comparable<FavoriteObject> {\n    @SerializedName(\"CATEGORY_NONE\")\n    @Ignore\n    public static final String CATEGORY_NONE = \"_NONE_\";\n    @SerializedName(\"key\")\n    @PrimaryKey\n    public int key;\n    @SerializedName(\"aid\")\n    public String aid;\n    @SerializedName(\"name\")\n    public String name;\n    @SerializedName(\"img\")\n    public String img;\n    @SerializedName(\"type\")\n    public String type;\n    @SerializedName(\"link\")\n    public String link;\n    @SerializedName(\"category\")\n    public String category;\n    @SerializedName(\"isSection\")\n    @Ignore\n    public boolean isSection = false;\n\n    @Ignore\n    public FavoriteObject() {\n\n    }\n\n    public FavoriteObject(int key, String aid, String name, String img, String type, String link, String category) {\n        this.key = key;\n        this.aid = aid;\n        this.name = name;\n        this.img = img;\n        this.type = type;\n        this.link = link;\n        this.category = category;\n    }\n\n    @Ignore\n    public FavoriteObject(AnimeObject object) {\n        if (object != null) {\n            this.key = object.key;\n            this.aid = object.aid;\n            this.name = object.name;\n            this.img = object.img;\n            this.type = object.type;\n            this.link = object.link;\n            this.category = CATEGORY_NONE;\n        }\n    }\n\n    @Ignore\n    public FavoriteObject(SearchAdvObject object) {\n        if (object != null) {\n            this.key = object.getKey();\n            this.aid = object.getAid();\n            this.name = object.getName();\n            this.img = object.getImg();\n            this.type = object.getType();\n            this.link = object.getLink();\n            this.category = CATEGORY_NONE;\n        }\n    }\n\n    public static List<String> getNames(List<FavoriteObject> list) {\n        List<String> strings = new ArrayList<>();\n        for (FavoriteObject object : list) {\n            strings.add(object.name);\n        }\n        return strings;\n    }\n\n    public static List<String> getCategories(List<FavoriteObject> list) {\n        List<String> strings = new ArrayList<>();\n        for (FavoriteObject object : list) {\n            if (object.category.equals(CATEGORY_NONE))\n                strings.add(\"Sin categoría\");\n            else\n                strings.add(object.category);\n        }\n        return strings;\n    }\n\n    public static Integer[] getIndex(List<FavoriteObject> list, String category) {\n        List<Integer> index = new ArrayList<>();\n        int i = 0;\n        for (FavoriteObject object : list) {\n            if (object.category.equals(category))\n                index.add(i);\n            i++;\n        }\n        return index.toArray(new Integer[0]);\n    }\n\n    public void setCategory(String category) {\n        if (category == null)\n            this.category = CATEGORY_NONE;\n        else\n            this.category = category;\n    }\n\n    @Override\n    public int hashCode() {\n        return name.hashCode() + (isSection ? 1 : -1);\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        return (obj instanceof FavSection || obj instanceof FavoriteObject) && name.equals(((FavoriteObject) obj).name);\n    }\n\n    @Override\n    public int compareTo(@NonNull FavoriteObject o) {\n        return name.compareTo(o.name);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/GenreStatusObject.java",
    "content": "package knf.kuma.pojos;\n\nimport androidx.annotation.Keep;\nimport androidx.annotation.NonNull;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.PrimaryKey;\n\nimport com.google.firebase.firestore.IgnoreExtraProperties;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Created by jordy on 26/03/2018.\n */\n@Keep\n@Entity\n@IgnoreExtraProperties\npublic class GenreStatusObject implements Comparable<GenreStatusObject> {\n    public String name;\n    public int count;\n    @PrimaryKey\n    public int key;\n\n    public GenreStatusObject() {\n        this.key = 0;\n        this.name = \"\";\n        this.count = 0;\n    }\n\n    public GenreStatusObject(int key, String name, int count) {\n        this.key = key;\n        this.name = name;\n        this.count = count;\n    }\n\n    @Ignore\n    public GenreStatusObject(String name) {\n        this.key = Math.abs(name.hashCode());\n        this.name = name;\n        this.count = 0;\n    }\n\n    public static List<String> names(List<GenreStatusObject> list) {\n        List<String> names = new ArrayList<>();\n        for (GenreStatusObject object : list)\n            names.add(object.name);\n        return names;\n    }\n\n    public boolean isBlocked() {\n        return count < 0;\n    }\n\n    public void add(int number) {\n        count += number;\n    }\n\n    public void sub(int number) {\n        count -= number;\n        if (count < 0) count = 0;\n    }\n\n    public void block() {\n        count = -1;\n    }\n\n    public void reset() {\n        count = 0;\n    }\n\n    @Override\n    public int compareTo(@NonNull GenreStatusObject o) {\n        return name.compareTo(o.name);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/NotificationObj.java",
    "content": "package knf.kuma.pojos;\n\nimport android.content.Context;\nimport android.content.Intent;\n\nimport androidx.annotation.NonNull;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.PrimaryKey;\n\nimport knf.kuma.recents.RecentsNotReceiver;\n\n@Entity\npublic class NotificationObj {\n    @Ignore\n    public static final int RECENT=0;\n    @PrimaryKey\n    public int key;\n    public int type;\n\n    public NotificationObj(int key, int type) {\n        this.key = key;\n        this.type = type;\n    }\n\n    @NonNull\n    public static NotificationObj fromIntent(Intent intent){\n        return new NotificationObj(intent.getIntExtra(\"key\",-1),intent.getIntExtra(\"type\",-1));\n    }\n\n    public Intent getBroadcast(Context context) {\n        return new Intent(context, RecentsNotReceiver.class).putExtra(\"key\", key).putExtra(\"type\", type);\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        return obj instanceof NotificationObj && key==((NotificationObj)obj).key;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/QueueObject.java",
    "content": "package knf.kuma.pojos;\n\nimport android.net.Uri;\n\nimport androidx.annotation.Keep;\nimport androidx.room.Embedded;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.PrimaryKey;\nimport androidx.room.RoomWarnings;\nimport androidx.room.TypeConverters;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport knf.kuma.database.BaseConverter;\nimport knf.kuma.database.CacheDBWrap;\n\n@Keep\n@Entity\n@TypeConverters({BaseConverter.class})\n@SuppressWarnings(RoomWarnings.PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED)\npublic class QueueObject implements Serializable {\n    @PrimaryKey\n    public int id;\n    public boolean isFile;\n    public String uri;\n    public long time;\n    @Embedded\n    public AnimeObject.WebInfo.AnimeChapter chapter;\n    @Ignore\n    public int count = -1;\n\n    public QueueObject() {\n        this.id = 0;\n        this.isFile = false;\n        this.uri = \"\";\n        this.time = 0;\n        this.chapter = null;\n    }\n\n    public QueueObject(int id, boolean isFile, String uri, long time, AnimeObject.WebInfo.AnimeChapter chapter) {\n        this.id = id;\n        this.isFile = isFile;\n        this.uri = uri;\n        this.time = time;\n        this.chapter = chapter;\n    }\n\n    @Ignore\n    public QueueObject(Uri uri, boolean isFile, AnimeObject.WebInfo.AnimeChapter chapter) {\n        this.id = chapter.key;\n        this.uri = uri.toString();\n        this.isFile = isFile;\n        this.time = System.currentTimeMillis();\n        this.chapter = chapter;\n    }\n\n    public static Uri[] uris(List<QueueObject> list) {\n        List<Uri> uris = new ArrayList<>();\n        for (QueueObject object : list)\n            uris.add(object.createUri());\n        return uris.toArray(new Uri[]{});\n    }\n\n    public static List<QueueObject> takeOne(List<QueueObject> list) {\n        List<String> aids = new ArrayList<>();\n        List<QueueObject> n_list = new ArrayList<>();\n        for (QueueObject object : list) {\n            if (!aids.contains(object.chapter.aid)) {\n                aids.add(object.chapter.aid);\n                object.count = CacheDBWrap.INSTANCE.queueDAO().countAlone(object.chapter.aid);\n                n_list.add(object);\n            }\n        }\n        return n_list;\n    }\n\n    public static String[] getTitles(List<QueueObject> list) {\n        List<String> titles = new ArrayList<>();\n        for (QueueObject object : list)\n            titles.add(object.title());\n        return titles.toArray(new String[]{});\n    }\n\n    public Uri createUri() {\n        return Uri.parse(uri);\n    }\n\n    public String title() {\n        try {\n            return chapter.name + chapter.number.substring(chapter.number.lastIndexOf(\" \"));\n        } catch (Exception e) {\n            return chapter.name;\n        }\n    }\n\n    @Override\n    public int hashCode() {\n        return chapter.eid.hashCode();\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        return obj instanceof QueueObject && chapter.eid.equals(((QueueObject) obj).chapter.eid);\n    }\n\n    public boolean equalsAnime(Object obj) {\n        return obj instanceof QueueObject && chapter.aid.equals(((QueueObject) obj).chapter.aid);\n    }\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/RecentObject.java",
    "content": "package knf.kuma.pojos;\n\nimport static java.lang.Math.abs;\n\nimport androidx.annotation.NonNull;\nimport androidx.room.Embedded;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.PrimaryKey;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport knf.kuma.commons.FileWrapper;\nimport knf.kuma.commons.PatternUtil;\nimport knf.kuma.commons.PrefsUtil;\nimport knf.kuma.database.CacheDBWrap;\nimport knf.kuma.database.dao.AnimeDAO;\nimport knf.kuma.search.SearchObject;\nimport pl.droidsonroids.jspoon.annotation.Selector;\n\n@Entity\npublic class RecentObject {\n    @PrimaryKey\n    public int key;\n    @Ignore\n    @NonNull\n    public String aid = \"\";\n    @Ignore\n    @NonNull\n    public String eid = \"\";\n    @Ignore\n    @NonNull\n    public String name = \"\";\n    @Ignore\n    @NonNull\n    public String chapter = \"\";\n    @Ignore\n    @NonNull\n    public String url = \"\";\n    @Ignore\n    @NonNull\n    public String anime = \"\";\n    @Ignore\n    @NonNull\n    public String img = \"\";\n    @Ignore\n    public boolean isNew;\n    @Ignore\n    public boolean isDownloading;\n    @Ignore\n    public boolean isFav;\n    @Ignore\n    public boolean isSeen;\n    @Ignore\n    private FileWrapper fileWrapper;\n    @Ignore\n    public int downloadState;\n    @Ignore\n    public SearchObject animeObject;\n    @Embedded\n    public WebInfo webInfo;\n\n    @Ignore\n    public RecentObject() {\n\n    }\n\n    public RecentObject(int key, WebInfo webInfo) {\n        this.key = key;\n        populate(webInfo);\n    }\n\n    private RecentObject(AnimeDAO dao, WebInfo webInfo) {\n        this.webInfo = webInfo;\n        populate(dao, webInfo);\n    }\n\n    public static List<RecentObject> create(List<WebInfo> infos) {\n        AnimeDAO dao = CacheDBWrap.INSTANCE.animeDAO();\n        List<RecentObject> objects = new ArrayList<>();\n        for (WebInfo info : infos) {\n            try {\n                objects.add(new RecentObject(dao, info));\n            } catch (Exception e) {\n                e.printStackTrace();\n            }\n        }\n        return objects;\n    }\n\n    public String getFileName() {\n        if (PrefsUtil.INSTANCE.getSaveWithName())\n            return eid + \"$\" + PatternUtil.INSTANCE.getFileName(url);\n        else\n            return eid + \"$\" + aid + \"-\" + chapter.substring(chapter.lastIndexOf(\" \") + 1) + \".mp4\";\n    }\n\n    public String getFilePath() {\n        if (PrefsUtil.INSTANCE.getSaveWithName())\n            return \"$\" + PatternUtil.INSTANCE.getFileName(url);\n        else\n            return \"$\" + aid + \"-\" + chapter.substring(chapter.lastIndexOf(\" \") + 1) + \".mp4\";\n    }\n\n    public String getEpTitle() {\n        return name + chapter.substring(chapter.lastIndexOf(\" \"));\n    }\n\n    public FileWrapper fileWrapper() {\n        if (fileWrapper == null)\n            fileWrapper = FileWrapper.Companion.create(getFilePath());\n        return fileWrapper;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        return obj instanceof RecentObject && (\n                eid.equals(((RecentObject) obj).eid) ||\n                        (name.equals(((RecentObject) obj).name) && chapter.equals(((RecentObject) obj).chapter)));\n    }\n\n    @Override\n    public int hashCode() {\n        return name.hashCode() + chapter.hashCode();\n    }\n\n    private void populate(WebInfo webInfo) {\n        this.key = (webInfo.aid + webInfo.chapter).hashCode();\n        this.aid = webInfo.aid;\n        this.chapter = webInfo.chapter.trim();\n        this.eid = String.valueOf(abs((aid + chapter).hashCode()));\n        this.name = PatternUtil.INSTANCE.fromHtml(webInfo.name);\n        this.url = \"https://www3.animeflv.net\" + webInfo.url;\n        this.img = \"https://www3.animeflv.net\" + webInfo.img.replace(\"thumbs\", \"covers\");\n        this.isNew = chapter.matches(\"^.* [10]$\");\n        this.anime = PatternUtil.INSTANCE.getAnimeUrl(this.url, this.aid);\n        //File file = FileAccessHelper.INSTANCE.findFile(getFilePath());\n        DownloadObject downloadObject = CacheDBWrap.INSTANCE.downloadsDAO().getByEid(eid);\n        this.isDownloading = downloadObject != null && downloadObject.state == DownloadObject.DOWNLOADING;\n        if (downloadObject != null) {\n            this.downloadState = downloadObject.state;\n        } else {\n            this.downloadState = -8;\n        }\n        this.animeObject = CacheDBWrap.INSTANCE.animeDAO().getSOByAid(aid);\n        this.isFav = CacheDBWrap.INSTANCE.favsDAO().isFav(Integer.parseInt(aid));\n        this.isSeen = CacheDBWrap.INSTANCE.seenDAO().chapterIsSeen(aid, chapter);\n    }\n\n    private void populate(AnimeDAO dao, WebInfo webInfo) {\n        if (isNotNumeric(webInfo.aid))\n            throw new IllegalStateException(\"Aid must be number\");\n        populate(webInfo);\n        this.animeObject = dao.getSOByAid(aid);\n        this.isFav = CacheDBWrap.INSTANCE.favsDAO().isFav(Integer.parseInt(aid));\n        this.isSeen = CacheDBWrap.INSTANCE.seenDAO().chapterIsSeen(aid, chapter);\n    }\n\n    private boolean isNotNumeric(String number) {\n        try {\n            Integer.parseInt(number);\n            return false;\n        } catch (Exception e) {\n            e.printStackTrace();\n            return true;\n        }\n    }\n\n    public static class WebInfo {\n        @Selector(value = \"img[src]\", attr = \"src\", format = \"/(\\\\d+)\\\\.\\\\w+\")\n        public String aid;\n        @Selector(value = \"a\", attr = \"href\", format = \"/(.*)$\")\n        public String eid;\n        @Selector(value = \".Title\")\n        public String name;\n        @Selector(\".Capi\")\n        public String chapter;\n        @Selector(value = \"a\", attr = \"href\")\n        public String url;\n        @Selector(value = \"img[src]\", attr = \"src\")\n        public String img;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/RecentWrap.kt",
    "content": "package knf.kuma.pojos\r\n\r\nimport knf.kuma.database.CacheDB\r\n\r\nclass RecentWrap(val obj: RecentObject) {\r\n    var isSeen = CacheDB.INSTANCE.seenDAO().chapterIsSeen(obj.aid,obj.chapter)\r\n    var isFav = CacheDB.INSTANCE.favsDAO().isFav(obj.aid.toInt())\r\n}\r\n\r\nfun RecentObject.wrap(): RecentWrap = RecentWrap(this)"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/Recents.java",
    "content": "package knf.kuma.pojos;\n\nimport java.util.List;\n\nimport pl.droidsonroids.jspoon.annotation.Selector;\n\npublic class Recents {\n    @Selector(\"ul.ListEpisodios li:not(article), ul.List-Episodes li:not(article)\")\n    public List<RecentObject.WebInfo> list;\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/RecordObject.java",
    "content": "package knf.kuma.pojos;\n\nimport androidx.annotation.Keep;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.PrimaryKey;\n\nimport com.google.gson.annotations.SerializedName;\n\nimport knf.kuma.database.CacheDBWrap;\nimport knf.kuma.recents.RecentModel;\nimport knf.kuma.search.SearchObject;\n\n@Keep\n@Entity\npublic class RecordObject {\n    @SerializedName(\"key\")\n    @PrimaryKey\n    public int key;\n    @SerializedName(\"name\")\n    public String name;\n    @SerializedName(\"chapter\")\n    public String chapter;\n    @SerializedName(\"aid\")\n    public String aid;\n    @SerializedName(\"eid\")\n    public String eid;\n    @SerializedName(\"date\")\n    public long date;\n    @SerializedName(\"animeObject\")\n    @Ignore\n    public transient SearchObject animeObject;\n\n    public RecordObject(int key, String name, String chapter, String aid, String eid, long date) {\n        this.key = key;\n        this.name = name;\n        this.chapter = chapter;\n        this.aid = aid;\n        this.eid = eid;\n        this.date = date;\n        this.animeObject = CacheDBWrap.INSTANCE.animeDAO().getByAidSimple(aid);\n    }\n\n    @Ignore\n    private RecordObject() {\n    }\n\n    @Ignore\n    public static RecordObject fromRecent(RecentObject recentObject) {\n        RecordObject object = new RecordObject();\n        object.key = Integer.parseInt(recentObject.aid);\n        object.name = recentObject.name;\n        object.chapter = recentObject.chapter;\n        object.aid = recentObject.aid;\n        object.eid = recentObject.eid;\n        object.date = System.currentTimeMillis();\n        return object;\n    }\n\n    @Ignore\n    public static RecordObject fromRecentModel(RecentModel recentObject) {\n        RecordObject object = new RecordObject();\n        object.key = Integer.parseInt(recentObject.aid);\n        object.name = recentObject.name;\n        object.chapter = recentObject.chapter;\n        object.aid = recentObject.aid;\n        object.eid = recentObject.extras.getEid();\n        object.date = System.currentTimeMillis();\n        return object;\n    }\n\n    @Ignore\n    public static RecordObject fromDownloaded(ExplorerObject.FileDownObj downloadedObject) {\n        RecordObject object = new RecordObject();\n        object.key = Integer.parseInt(downloadedObject.aid);\n        object.name = downloadedObject.title;\n        object.chapter = \"Episodio \" + downloadedObject.chapter;\n        object.aid = downloadedObject.aid;\n        object.eid = downloadedObject.eid;\n        object.date = System.currentTimeMillis();\n        return object;\n    }\n\n    @Ignore\n    public static RecordObject fromChapter(AnimeObject.WebInfo.AnimeChapter chapter) {\n        RecordObject object = new RecordObject();\n        object.key = Integer.parseInt(chapter.aid);\n        object.name = chapter.name;\n        object.chapter = chapter.number;\n        object.aid = chapter.aid;\n        object.eid = chapter.eid;\n        object.date = System.currentTimeMillis();\n        return object;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/SeeingObject.java",
    "content": "package knf.kuma.pojos;\n\nimport androidx.annotation.Keep;\nimport androidx.annotation.NonNull;\nimport androidx.recyclerview.widget.DiffUtil;\nimport androidx.room.Entity;\nimport androidx.room.Ignore;\nimport androidx.room.PrimaryKey;\n\nimport com.google.gson.annotations.SerializedName;\n\nimport knf.kuma.database.CacheDBWrap;\nimport knf.kuma.seeing.FavToSeeing;\n\n@Keep\n@Entity\npublic class SeeingObject {\n    @SerializedName(\"STATE_WATCHING\")\n    @Ignore\n    public static final int STATE_WATCHING = 1;\n    @SerializedName(\"STATE_CONSIDERING\")\n    @Ignore\n    public static final int STATE_CONSIDERING = 2;\n    @SerializedName(\"STATE_COMPLETED\")\n    @Ignore\n    public static final int STATE_COMPLETED = 3;\n    @SerializedName(\"STATE_DROPPED\")\n    @Ignore\n    public static final int STATE_DROPPED = 4;\n    @SerializedName(\"STATE_PAUSED\")\n    @Ignore\n    public static final int STATE_PAUSED = 5;\n\n    @SerializedName(\"key\")\n    @PrimaryKey\n    public int key;\n    @SerializedName(\"img\")\n    public String img;\n    @SerializedName(\"link\")\n    public String link;\n    @SerializedName(\"aid\")\n    public String aid;\n    @SerializedName(\"title\")\n    public String title;\n    @SerializedName(\"chapter\")\n    public String chapter;\n    @SerializedName(\"state\")\n    public int state;\n    @SerializedName(\"lastChapter\")\n    @Ignore\n    public SeenObject lastChapter;\n    @Ignore\n    public static DiffUtil.ItemCallback<SeeingObject> diffCallback = new DiffUtil.ItemCallback<SeeingObject>() {\n        @Override\n        public boolean areItemsTheSame(@NonNull SeeingObject oldItem, @NonNull SeeingObject newItem) {\n            return oldItem.aid.equals(newItem.aid) && oldItem.key == newItem.key;\n        }\n\n        @Override\n        public boolean areContentsTheSame(@NonNull SeeingObject oldItem, @NonNull SeeingObject newItem) {\n            return oldItem.state == newItem.state && oldItem.chapter.equals(newItem.chapter);\n        }\n    };\n\n    public SeeingObject(int key, String img, String link, String aid, String title, String chapter, int state) {\n        this.key = key;\n        this.img = img;\n        this.link = link;\n        this.aid = aid;\n        this.title = title;\n        this.chapter = chapter;\n        this.lastChapter = FavToSeeing.INSTANCE.getLast(CacheDBWrap.INSTANCE.seenDAO().getAllByAid(aid));\n        this.state = state;\n    }\n\n    @Ignore\n    private SeeingObject() {\n    }\n\n    @Ignore\n    public static SeeingObject fromAnime(FavoriteObject favoriteObject) {\n        SeeingObject item = new SeeingObject();\n        item.key = Integer.parseInt(favoriteObject.aid);\n        item.img = favoriteObject.img;\n        item.link = favoriteObject.link;\n        item.aid = favoriteObject.aid;\n        item.title = favoriteObject.name;\n        item.chapter = \"No empezado\";\n        return item;\n    }\n\n    @Ignore\n    public static SeeingObject fromAnime(AnimeObject animeObject, int state) {\n        SeeingObject item = new SeeingObject();\n        item.key = Integer.parseInt(animeObject.aid);\n        item.img = animeObject.img;\n        item.link = animeObject.link;\n        item.aid = animeObject.aid;\n        item.title = animeObject.name;\n        item.chapter = \"No empezado\";\n        item.state = state;\n        return item;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/pojos/SeenObject.kt",
    "content": "package knf.kuma.pojos\r\n\r\nimport android.util.Log\r\nimport androidx.annotation.Keep\r\nimport androidx.room.Entity\r\nimport androidx.room.PrimaryKey\r\nimport knf.kuma.commons.noCrashLetNullable\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.recents.RecentModel\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.launch\r\nimport java.util.Locale\r\n\r\n@Keep\r\n@Entity\r\ndata class SeenObject(@PrimaryKey val eid: String = \"\", val aid: String = \"\", val number: String = \"\") {\r\n    companion object {\r\n        fun fromChapter(chapter: AnimeObject.WebInfo.AnimeChapter): SeenObject = SeenObject(chapter.eid, chapter.aid, chapter.number)\r\n        fun fromRecent(recent: RecentObject): SeenObject = SeenObject(recent.eid, recent.aid, recent.chapter)\r\n        fun fromRecentModel(recent: RecentModel): SeenObject = SeenObject(recent.extras.eid, recent.aid, recent.chapter)\r\n        fun fromDownloaded(download: ExplorerObject.FileDownObj) = SeenObject(download.eid, download.aid, String.format(Locale.getDefault(), \"Episodio %s\", download.chapter))\r\n    }\r\n}\r\n\r\nfun migrateSeen() {\r\n    GlobalScope.launch(Dispatchers.IO) {\r\n        if (CacheDB.INSTANCE.chaptersDAO().count != 0) {\r\n            var total: Int\r\n            CacheDB.INSTANCE.seenDAO().addAll(CacheDB.INSTANCE.chaptersDAO().all.mapNotNull { noCrashLetNullable { SeenObject.fromChapter(it) } }.also { total = it.size })\r\n            CacheDB.INSTANCE.chaptersDAO().clear()\r\n            Log.e(\"Seen\", \"Migrated $total\")\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/preferences/AdsPreferenceActivity.kt",
    "content": "package knf.kuma.preferences\r\n\r\nimport android.os.Bundle\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.databinding.ActivityAdsSettingsBinding\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\n\r\nclass AdsPreferenceActivity : GenericActivity() {\r\n\r\n    private val binding by lazy { ActivityAdsSettingsBinding.inflate(layoutInflater) }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(binding.root)\r\n        setSupportActionBar(binding.toolbar)\r\n        supportActionBar?.title = \"Configuracion de anuncios\"\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        binding.switchNative.isChecked = PrefsUtil.isNativeAdsEnabled\r\n        binding.preferenceNative.onClick {\r\n            binding.switchNative.toggle()\r\n            PrefsUtil.isNativeAdsEnabled = binding.switchNative.isChecked\r\n        }\r\n        binding.switchFull.isChecked = PrefsUtil.isFullAdsEnabled\r\n        binding.preferenceFullText.isEnabled = binding.switchFull.isChecked\r\n        binding.preferenceFullTextExtra.isEnabled = binding.switchFull.isChecked\r\n        binding.sliderFull.isEnabled = binding.switchFull.isChecked\r\n        binding.sliderFullExtra.isEnabled = binding.switchFull.isChecked\r\n        binding.probabilityFull.isEnabled = binding.switchFull.isChecked\r\n        binding.probabilityFullExtra.isEnabled = binding.switchFull.isChecked\r\n        binding.preferenceFull.onClick {\r\n            binding.switchFull.toggle()\r\n            PrefsUtil.isFullAdsEnabled = binding.switchFull.isChecked\r\n            binding.preferenceFullText.isEnabled = binding.switchFull.isChecked\r\n            binding.preferenceFullTextExtra.isEnabled = binding.switchFull.isChecked\r\n            binding.sliderFull.isEnabled = binding.switchFull.isChecked\r\n            binding.sliderFullExtra.isEnabled = binding.switchFull.isChecked\r\n            binding.probabilityFull.isEnabled = binding.switchFull.isChecked\r\n            binding.probabilityFullExtra.isEnabled = binding.switchFull.isChecked\r\n        }\r\n        binding.sliderFull.value = PrefsUtil.fullAdsProbability\r\n        binding.sliderFullExtra.value = PrefsUtil.fullAdsExtraProbability\r\n        binding.probabilityFull.text = \"${PrefsUtil.fullAdsProbability.toInt()}%\"\r\n        binding.probabilityFullExtra.text = \"${PrefsUtil.fullAdsExtraProbability.toInt()}%\"\r\n        binding.sliderFull.addOnChangeListener { _, value, _ ->\r\n            binding.probabilityFull.text = \"${value.toInt()}%\"\r\n            PrefsUtil.fullAdsProbability = value\r\n        }\r\n        binding.sliderFullExtra.addOnChangeListener { _, value, _ ->\r\n            binding.probabilityFullExtra.text = \"${value.toInt()}%\"\r\n            PrefsUtil.fullAdsExtraProbability = value\r\n        }\r\n    }\r\n\r\n    override fun onSupportNavigateUp(): Boolean {\r\n        onBackPressedDispatcher.onBackPressed()\r\n        return super.onSupportNavigateUp()\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/preferences/BottomPreferencesFragment.kt",
    "content": "package knf.kuma.preferences\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.commons.EAHelper\n\nclass BottomPreferencesFragment : BottomFragment() {\n\n    var count = 1\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        EAHelper.enter1(\"C\")\n        return inflater.inflate(R.layout.fragment_preferences, container, false)\n    }\n\n    override fun onReselect() {\n        EAHelper.enter1(\"C\")\n        count++\n        if (count == 20) AchievementManager.unlock(listOf(40))\n    }\n\n    companion object {\n\n        fun get(): BottomPreferencesFragment {\n            return BottomPreferencesFragment()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/preferences/BottomPreferencesMaterialFragment.kt",
    "content": "package knf.kuma.preferences\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.commons.EAHelper\n\nclass BottomPreferencesMaterialFragment : BottomFragment() {\n\n    var count = 1\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        EAHelper.enter1(\"C\")\n        return inflater.inflate(R.layout.fragment_preferences_material, container, false)\n    }\n\n    override fun onReselect() {\n        EAHelper.enter1(\"C\")\n        count++\n        if (count == 20) AchievementManager.unlock(listOf(40))\n    }\n\n    companion object {\n\n        fun get(): BottomPreferencesMaterialFragment {\n            return BottomPreferencesMaterialFragment()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/preferences/ConfigurationFragment.kt",
    "content": "package knf.kuma.preferences\n\nimport android.app.Activity\nimport android.content.ActivityNotFoundException\nimport android.content.Intent\nimport android.graphics.Color\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport android.provider.Settings\nimport android.view.View\nimport android.widget.ListView\nimport androidx.appcompat.app.AppCompatDelegate\nimport androidx.core.view.ViewCompat\nimport androidx.lifecycle.Observer\nimport androidx.preference.ListPreference\nimport androidx.preference.Preference\nimport androidx.preference.PreferenceCategory\nimport androidx.preference.PreferenceManager\nimport androidx.preference.SwitchPreference\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.callbacks.onCancel\nimport com.afollestad.materialdialogs.input.getInputField\nimport com.afollestad.materialdialogs.input.getInputLayout\nimport com.afollestad.materialdialogs.input.input\nimport com.afollestad.materialdialogs.list.listItems\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport knf.kuma.App\nimport knf.kuma.BuildConfig\nimport knf.kuma.Main\nimport knf.kuma.R\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.backup.Backups\nimport knf.kuma.backup.firestore.FirestoreManager\nimport knf.kuma.commons.DesignUtils\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.FileUtil\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.admFile\nimport knf.kuma.commons.canGroupNotifications\nimport knf.kuma.commons.decrypt\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.encryptOrThrow\nimport knf.kuma.commons.ffFile\nimport knf.kuma.commons.getPackage\nimport knf.kuma.commons.isNull\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.safeContext\nimport knf.kuma.commons.safeDelete\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.PreferenceFragmentCompat\nimport knf.kuma.database.CacheDB\nimport knf.kuma.directory.DirManager\nimport knf.kuma.directory.DirectoryService\nimport knf.kuma.directory.DirectoryUpdateService\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.jobscheduler.BackUpWork\nimport knf.kuma.jobscheduler.DirUpdateWork\nimport knf.kuma.jobscheduler.RecentsWork\nimport knf.kuma.pojos.AutoBackupObject\nimport knf.kuma.widgets.emision.WEmisionProvider\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.support.v4.toast\nimport xdroid.toaster.Toaster\nimport java.io.FileOutputStream\n\n\nclass ConfigurationFragment : PreferenceFragmentCompat() {\n\n    companion object {\n        private const val keyCustomTone = \"custom_tone\"\n        private const val keyAutoBackup = \"auto_backup\"\n        private const val keyMaxParallelDownloads = \"max_parallel_downloads\"\n        private const val keyBufferSize = \"buffer_size\"\n        private const val keyThemeColor = \"theme_color\"\n        private const val keyAchievementsPermissions = \"achievements_permissions\"\n        private const val keyAdsEnabled = \"ads_enabled_new\"\n    }\n\n    private var uaChangeListener: UAChangeListener? = null\n\n    override fun onAttach(activity: Activity) {\n        uaChangeListener = activity as? UAChangeListener\n        super.onAttach(activity)\n    }\n\n    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {\n        if (activity != null && context != null)\n            doOnUI {\n                addPreferencesFromResource(R.xml.preferences)\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)\n                    preferenceScreen.findPreference<Preference>(keyCustomTone)?.summary = \"Abrir configuración\"\n                else if (FileAccessHelper.toneFile.exists())\n                    preferenceScreen.findPreference<Preference>(keyCustomTone)?.summary = \"Personalizado\"\n                if (!DesignUtils.isFlat)\n                    preferenceScreen.findPreference<ListPreference>(\"recentActionType\")?.isVisible = false\n                preferenceScreen.findPreference<Preference>(keyCustomTone)?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)\n                        noCrash {\n                            startActivity(\n                                    Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)\n                                            .putExtra(Settings.EXTRA_CHANNEL_ID, RecentsWork.CHANNEL_RECENTS)\n                                            .putExtra(Settings.EXTRA_APP_PACKAGE, this@ConfigurationFragment.context?.packageName)\n                            )\n                        }\n                    else\n                        activity?.let {\n                            MaterialDialog(it).safeShow {\n                                title(text = \"Tono de notificación\")\n                                listItems(items = listOf(\"Cambiar tono\", \"Tono de sistema\")) { _, index, _ ->\n                                    when (index) {\n                                        0 -> startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT)\n                                                .addCategory(Intent.CATEGORY_OPENABLE)\n                                                .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)\n                                                .setType(\"audio/*\"), 4784)\n                                        1 -> {\n                                            FileAccessHelper.toneFile.safeDelete()\n                                            preferenceScreen.findPreference<Preference>(keyCustomTone)?.summary = \"Sistema\"\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    true\n                }\n                if (Backups.type == Backups.Type.DROPBOX) {\n                    if (Network.isConnected) {\n                        activity?.let {\n                            preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"Cargando...\"\n                            Backups.search(null, Backups.keyAutoBackup) {\n                                doOnUI {\n                                    try {\n                                        val autoBackupObject = it as? AutoBackupObject\n                                        if (autoBackupObject != null) {\n                                            if (autoBackupObject == AutoBackupObject(activity))\n                                                preferenceScreen.findPreference<Preference>(\n                                                    keyAutoBackup\n                                                )?.summary = \"%s\"\n                                            else\n                                                preferenceScreen.findPreference<Preference>(\n                                                    keyAutoBackup\n                                                )?.summary = \"Solo \" + autoBackupObject.name\n                                            if (autoBackupObject.value == null)\n                                                GlobalScope.launch(Dispatchers.Main) {\n                                                    Backups.createService()?.backup(\n                                                        AutoBackupObject(App.context),\n                                                        Backups.keyAutoBackup\n                                                    )\n                                                    preferenceScreen.findPreference<Preference>(\n                                                        keyAutoBackup\n                                                    )?.summary = \"%s\"\n                                                }\n                                            else\n                                                preferenceManager.sharedPreferences?.edit()\n                                                    ?.putString(\n                                                        keyAutoBackup,\n                                                        autoBackupObject.value\n                                                    )?.apply()\n                                        } else {\n                                            preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"%s (NE)\"\n                                        }\n                                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.isEnabled = true\n                                    } catch (e: Exception) {\n                                        FirebaseCrashlytics.getInstance().recordException(e)\n                                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"Error al buscar archivo: ${e.message}\"\n                                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.isEnabled = true\n                                    }\n                                }\n                            }\n                        }\n                    } else {\n                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"Sin internet\"\n                    }\n                } else if (Backups.type == Backups.Type.NONE) {\n                    preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"Sin cuenta para respaldos\"\n                } else {\n                    preferenceScreen.findPreference<Preference>(keyAutoBackup)?.isVisible = false\n                }\n                preferenceScreen.findPreference<Preference>(keyAutoBackup)?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    BackUpWork.reSchedule(Integer.valueOf((newValue as? String) ?: \"0\"))\n                    GlobalScope.launch(Dispatchers.Main) {\n                        Backups.createService()?.backup(AutoBackupObject(App.context, (newValue as? String)\n                                ?: \"0\"), Backups.keyAutoBackup)\n                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"%s\"\n                    }\n                    true\n                }\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                    preferenceScreen.removePreferenceRecursively(\"download_type\")\n                    val preferenceDownloads = preferenceScreen.findPreference<Preference>(\"download_type_q\")\n                    preferenceDownloads?.summary = PrefsUtil.storageType\n                    preferenceDownloads?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                        FileAccessHelper.openTreeChooser(this@ConfigurationFragment)\n                        Toaster.toastLong(\"Por favor selecciona la raiz del almacenamiento\")\n                        true\n                    }\n                } else {\n                    preferenceScreen.removePreferenceRecursively(\"download_type_q\")\n                    preferenceScreen.findPreference<Preference>(\"download_type\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                        if (newValue == \"1\" && !FileAccessHelper.canDownload(\n                                this@ConfigurationFragment,\n                                newValue as? String\n                            )\n                        )\n                            Toaster.toast(\"Por favor selecciona la raiz de tu SD\")\n                        else\n                            PreferenceManager.getDefaultSharedPreferences(requireContext()).edit()\n                                .putString(\"tree_uri\", null).apply()\n                        true\n                    }\n                }\n                if (PrefsUtil.downloaderType == 0) {\n                    preferenceScreen.findPreference<Preference>(keyMaxParallelDownloads)?.isEnabled = false\n                    preferenceScreen.findPreference<Preference>(keyBufferSize)?.isEnabled = true\n                } else {\n                    preferenceScreen.findPreference<Preference>(keyMaxParallelDownloads)?.isEnabled = true\n                    preferenceScreen.findPreference<Preference>(keyBufferSize)?.isEnabled = false\n                }\n                preferenceScreen.findPreference<Preference>(\"downloader_type\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    if (newValue == \"0\") {\n                        preferenceScreen.findPreference<Preference>(keyMaxParallelDownloads)?.isEnabled = false\n                        preferenceScreen.findPreference<Preference>(keyBufferSize)?.isEnabled = true\n                    } else {\n                        preferenceScreen.findPreference<Preference>(keyMaxParallelDownloads)?.isEnabled = true\n                        preferenceScreen.findPreference<Preference>(keyBufferSize)?.isEnabled = false\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"default_useragent\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    GlobalScope.launch(Dispatchers.Main) {\n                        delay(1000)\n                        uaChangeListener?.onUAChange()\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"theme_option\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    AppCompatDelegate.setDefaultNightMode(((newValue as? String) ?: \"0\").toInt())\n                    PreferenceManager.getDefaultSharedPreferences(safeContext).edit().putString(\"theme_value\", newValue.toString()).apply()\n                    WEmisionProvider.update(safeContext)\n                    activity?.recreate()\n                    true\n                }\n                preferenceScreen.findPreference<SwitchPreference>(\"ads_enabled_new\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    if (BuildConfig.DEBUG || PrefsUtil.isSubscriptionEnabled) return@OnPreferenceChangeListener true\n                    if (newValue == false) {\n                        context?.let { FirestoreManager.doSignOut(it) }\n                        Backups.type = Backups.Type.NONE\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference, newValue ->\n                    if (newValue == true) {\n                        activity?.let {\n                            MaterialDialog(it).safeShow {\n                                title(text = \"Configurar contraseña\")\n                                input { _, inputText ->\n                                    MaterialDialog(it).safeShow {\n                                        title(text = \"Repetir contraseña\")\n                                        input { _, input ->\n                                            if (input.toString() == inputText.toString())\n                                                doOnUI(onLog = {\n                                                    PrefsUtil.isFamilyFriendly = false\n                                                    preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = false\n                                                    toast(\"Error al encriptar\")\n                                                }) {\n                                                    val encrypted = input.toString().encryptOrThrow()\n                                                    check(encrypted.decrypt() == input.toString())\n                                                    PrefsUtil.ffPass = encrypted\n                                                    val file = ffFile\n                                                    file.parentFile?.mkdirs()\n                                                    if (!file.exists())\n                                                        file.createNewFile()\n                                                    file.writeText(encrypted)\n                                                    doAsync { CacheDB.INSTANCE.animeDAO().nukeEcchi() }\n                                                }\n                                            else {\n                                                toast(\"Las contraseñas no coinciden\")\n                                                PrefsUtil.isFamilyFriendly = false\n                                                preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = false\n                                            }\n                                        }\n                                        getInputLayout().boxBackgroundColor = Color.TRANSPARENT\n                                        getInputField().setBackgroundColor(Color.TRANSPARENT)\n                                        onCancel {\n                                            PrefsUtil.isFamilyFriendly = false\n                                            preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = false\n                                        }\n                                    }\n                                }\n                                getInputLayout().boxBackgroundColor = Color.TRANSPARENT\n                                getInputField().setBackgroundColor(Color.TRANSPARENT)\n                                onCancel {\n                                    PrefsUtil.isFamilyFriendly = false\n                                    preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = false\n                                }\n                            }\n                        }\n                    } else {\n                        activity?.let {\n                            MaterialDialog(it).safeShow {\n                                title(text = \"Ingresa contraseña\")\n                                input { _, input ->\n                                    doOnUI(onLog = {\n                                        PrefsUtil.isFamilyFriendly = true\n                                        preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = true\n                                        toast(\"Error al desencriptar\")\n                                    }) {\n                                        val file = ffFile\n                                        if (file.exists() && !admFile.exists()) {\n                                            val text = file.readText()\n                                            val decrypt = text.decrypt()\n                                            if (decrypt == input.toString()) {\n                                                PrefsUtil.ffPass = \"\"\n                                                file.delete()\n                                                DirectoryUpdateService.run(context)\n                                            } else {\n                                                PrefsUtil.isFamilyFriendly = true\n                                                preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = true\n                                                Toaster.toast(\"Contraseña incorrecta\")\n                                            }\n                                        } else if (admFile.exists()) {\n                                            PrefsUtil.ffPass = \"\"\n                                            file.delete()\n                                            DirectoryUpdateService.run(context)\n                                        } else {\n                                            if (PrefsUtil.ffPass != \"\") {\n                                                val decrypt = PrefsUtil.ffPass.decrypt()\n                                                if (decrypt == null || decrypt != input.toString()) {\n                                                    file.createNewFile()\n                                                    file.writeText(PrefsUtil.ffPass)\n                                                    PrefsUtil.isFamilyFriendly = true\n                                                    preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = true\n                                                    Toaster.toast(\"Contraseña incorrecta\")\n                                                } else {\n                                                    PrefsUtil.ffPass = \"\"\n                                                    DirectoryUpdateService.run(context)\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                                getInputLayout().boxBackgroundColor = Color.TRANSPARENT\n                                getInputField().setBackgroundColor(Color.TRANSPARENT)\n                                onCancel {\n                                    PrefsUtil.isFamilyFriendly = true\n                                    preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = true\n                                }\n                            }\n                        }\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"recents_time\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    preferenceScreen.findPreference<Preference>(\"notify_favs\")?.isEnabled = \"0\" != newValue\n                    RecentsWork.reSchedule(newValue.toString().toInt() * 15)\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"dir_update_time\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    DirUpdateWork.reSchedule(newValue.toString().toInt() * 15)\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"security_blocking_firestore\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    FirestoreManager.start()\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"dir_update\")?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                    try {\n                        if (!DirectoryUpdateService.isRunning && !DirectoryService.isRunning)\n                            DirectoryUpdateService.run(App.context)\n                        else if (DirectoryUpdateService.isRunning)\n                            Toaster.toast(\"Ya se esta actualizando\")\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                    }\n\n                    false\n                }\n                if (!canGroupNotifications)\n                    preferenceScreen.removePreference(preferenceScreen.findPreference(\"group_notifications\")!!)\n                preferenceScreen.findPreference<Preference>(\"dir_destroy\")?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                    try {\n                        if (!DirectoryUpdateService.isRunning && !DirectoryService.isRunning)\n                            activity?.let { safe ->\n                                MaterialDialog(safe).safeShow {\n                                    message(text = \"¿Desea recrear el directorio?\")\n                                    positiveButton(text = \"continuar\") {\n                                        doAsync {\n                                            CacheDB.INSTANCE.animeDAO().nuke()\n                                            PrefsUtil.isDirectoryFinished = false\n                                            DirManager.checkPreDir()\n                                            DirectoryService.run(safeContext)\n                                        }\n                                    }\n                                    negativeButton(text = \"cancelar\")\n                                }\n                            }\n                        else if (DirectoryService.isRunning)\n                            Toaster.toast(\"Ya se esta creando\")\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                    }\n\n                    false\n                }\n                when (EAHelper.phase) {\n                    4 ->\n                        preferenceScreen.findPreference<Preference>(keyThemeColor)?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                            startActivity(Intent(activity, Main::class.java).putExtra(\"start_position\", 3))\n                            activity?.finish()\n                            true\n                        }\n                    0 -> {\n                        val category =\n                            preferenceScreen.findPreference(\"category_design\") as? PreferenceCategory\n                        category?.removePreference(preferenceScreen.findPreference(keyThemeColor)!!)\n                        val pref = Preference(requireContext())\n                        pref.title = \"Color de tema\"\n                        pref.summary = \"Resuelve el secreto para desbloquear\"\n                        pref.setIcon(R.drawable.ic_palette)\n                        pref.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                            Toaster.toast(EAHelper.eaMessage)\n                            true\n                        }\n                        category?.addPreference(pref)\n                    }\n                    else -> {\n                        preferenceScreen.findPreference<Preference>(keyThemeColor)?.summary = \"Resuelve el secreto para desbloquear\"\n                        preferenceScreen.findPreference<Preference>(keyThemeColor)?.isEnabled = false\n                    }\n                }\n                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(this@ConfigurationFragment.context))\n                    (preferenceScreen.findPreference(keyAchievementsPermissions) as? SwitchPreference)?.apply {\n                        isChecked = true\n                        isEnabled = false\n                    }\n                else if (!Settings.canDrawOverlays(this@ConfigurationFragment.context)) {\n                    (preferenceScreen.findPreference(keyAchievementsPermissions) as? SwitchPreference)?.apply {\n                        isChecked = false\n                        isEnabled = true\n                    }\n                }\n                preferenceScreen.findPreference<Preference>(keyAchievementsPermissions)?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, _ ->\n                    try {\n                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)\n                            startActivityForResult(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION).setData(Uri.parse(\"package:${getPackage()}\")), 5879)\n                    } catch (e: ActivityNotFoundException) {\n                        Toaster.toast(\"No se pudo abrir la configuracion\")\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"hide_chaps\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    if (!FileAccessHelper.NOMEDIA_CREATING) {\n                        FileAccessHelper.checkNoMedia(newValue as? Boolean == true)\n                        true\n                    } else {\n                        (preferenceScreen.findPreference(\"hide_chaps\") as? SwitchPreference)?.isChecked = newValue as? Boolean != true\n                        false\n                    }\n                }\n                preferenceScreen.findPreference<Preference>(\"max_parallel_downloads\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    DownloadManagerCentral.setParallelDownloads(newValue as? String)\n                    true\n                }\n                preferenceScreen.findPreference<SwitchPreference>(\"remember_server\")?.apply {\n                    val lastServer = PrefsUtil.lastServer\n                    if (lastServer.isNull())\n                        isEnabled = false\n                    else {\n                        summary = lastServer\n                        onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference, newValue ->\n                            if (newValue as? Boolean == false) {\n                                PrefsUtil.lastServer = null\n                                preference.summary = null\n                                preference.isEnabled = false\n                            }\n                            true\n                        }\n                    }\n                }\n                preferenceScreen.findPreference<SwitchPreference>(keyAdsEnabled)?.apply {\n                    isChecked = PrefsUtil.isAdsEnabled\n                    isEnabled = PrefsUtil.isSubscriptionEnabled || !AdsUtils.remoteConfigs.getBoolean(\"ads_forced\")\n                    if (!isEnabled)\n                        summary = \"Estas en una prueba temporal!\"\n                    setOnPreferenceChangeListener { _, newValue ->\n                        preferenceScreen.findPreference<Preference>(\"ads_settings\")?.isEnabled = newValue == true\n                        true\n                    }\n                }\n                preferenceScreen.findPreference<Preference>(\"ads_settings\")?.apply {\n                    isEnabled = PrefsUtil.isAdsEnabled\n                    setOnPreferenceClickListener {\n                        startActivity(Intent(requireContext(), AdsPreferenceActivity::class.java))\n                        true\n                    }\n                }\n                if (BuildConfig.DEBUG) {\n                    preferenceScreen.findPreference<Preference>(\"reset_recents\")?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                        doAsync {\n                            CacheDB.INSTANCE.recentsDAO().clear()\n                            RecentsWork.run()\n                        }\n                        true\n                    }\n                }\n            }\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        view.findViewById<ListView>(android.R.id.list)?.let {\n            ViewCompat.setNestedScrollingEnabled(it, true)\n        }\n        super.onViewCreated(view, savedInstanceState)\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        noCrash {\n            if (requestCode == FileAccessHelper.SD_REQUEST && resultCode == Activity.RESULT_OK) {\n                val validation = FileAccessHelper.isUriValid(data?.data)\n                if (!validation.isValid) {\n                    Toaster.toast(\"Directorio invalido: $validation\")\n                    FileAccessHelper.openTreeChooser(this)\n                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)\n                    preferenceScreen.findPreference<Preference>(\"download_type_q\")?.summary = PrefsUtil.storageType\n            } else if (requestCode == 4784 && resultCode == Activity.RESULT_OK) {\n                if (!FileAccessHelper.toneFile.exists())\n                    FileAccessHelper.toneFile.createNewFile()\n                FileUtil.moveFile(\n                        safeContext.contentResolver,\n                        data?.data,\n                        FileOutputStream(FileAccessHelper.toneFile), false)\n                        .observe(this, Observer {\n                            try {\n                                if (it != null) {\n                                    if (it.second) {\n                                        if (it.first == -1) {\n                                            FileAccessHelper.toneFile.safeDelete()\n                                            Toaster.toast(\"Error al copiar\")\n                                        } else {\n                                            Toaster.toast(\"Tono seleccionado!\")\n                                        }\n                                    }\n                                }\n                            } catch (e: Exception) {\n                                Toaster.toast(\"Error al importar\")\n                            }\n                        })\n            } else if (requestCode == 5879) {\n                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context))\n                    (preferenceScreen.findPreference(\"achievements_permissions\") as? SwitchPreference)?.apply {\n                        isChecked = true\n                        isEnabled = false\n                    }\n                else\n                    (preferenceScreen.findPreference(\"achievements_permissions\") as? SwitchPreference)?.apply {\n                        isChecked = false\n                        isEnabled = true\n                    }\n            }\n        }\n    }\n\n    interface UAChangeListener {\n        fun onUAChange()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/preferences/ConfigurationFragmentMaterial.kt",
    "content": "package knf.kuma.preferences\n\nimport android.app.Activity\nimport android.content.ActivityNotFoundException\nimport android.content.Intent\nimport android.graphics.Color\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport android.provider.Settings\nimport android.util.Log\nimport android.view.View\nimport android.widget.ListView\nimport androidx.appcompat.app.AppCompatDelegate\nimport androidx.core.view.ViewCompat\nimport androidx.preference.ListPreference\nimport androidx.preference.Preference\nimport androidx.preference.PreferenceCategory\nimport androidx.preference.PreferenceManager\nimport androidx.preference.SwitchPreference\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.callbacks.onCancel\nimport com.afollestad.materialdialogs.input.getInputField\nimport com.afollestad.materialdialogs.input.getInputLayout\nimport com.afollestad.materialdialogs.input.input\nimport com.afollestad.materialdialogs.list.listItems\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport knf.kuma.App\nimport knf.kuma.BuildConfig\nimport knf.kuma.MainMaterial\nimport knf.kuma.R\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.backup.Backups\nimport knf.kuma.backup.firestore.FirestoreManager\nimport knf.kuma.commons.DesignUtils\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.FileUtil\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.admFile\nimport knf.kuma.commons.canGroupNotifications\nimport knf.kuma.commons.decrypt\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.ffFile\nimport knf.kuma.commons.getPackage\nimport knf.kuma.commons.isNull\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.safeContext\nimport knf.kuma.commons.safeDelete\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.PreferenceFragmentCompat\nimport knf.kuma.database.CacheDB\nimport knf.kuma.directory.DirManager\nimport knf.kuma.directory.DirectoryService\nimport knf.kuma.directory.DirectoryUpdateService\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.jobscheduler.BackUpWork\nimport knf.kuma.jobscheduler.DirUpdateWork\nimport knf.kuma.jobscheduler.RecentsWork\nimport knf.kuma.pojos.AutoBackupObject\nimport knf.kuma.widgets.emision.WEmisionProvider\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.support.v4.toast\nimport xdroid.toaster.Toaster\nimport java.io.FileOutputStream\n\n\nclass ConfigurationFragmentMaterial : PreferenceFragmentCompat() {\n\n    companion object {\n        private const val keyCustomTone = \"custom_tone\"\n        private const val keyAutoBackup = \"auto_backup\"\n        private const val keyMaxParallelDownloads = \"max_parallel_downloads\"\n        private const val keyBufferSize = \"buffer_size\"\n        private const val keyThemeColor = \"theme_color\"\n        private const val keyAchievementsPermissions = \"achievements_permissions\"\n        private const val keyAdsEnabled = \"ads_enabled_new\"\n    }\n\n    private var uaChangeListener: UAChangeListener? = null\n\n    override fun onAttach(activity: Activity) {\n        uaChangeListener = activity as? UAChangeListener\n        super.onAttach(activity)\n    }\n\n\n    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {\n        if (activity != null && context != null)\n            doOnUI {\n                addPreferencesFromResource(R.xml.preferences)\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)\n                    preferenceScreen.findPreference<Preference>(keyCustomTone)?.summary =\n                        \"Abrir configuración\"\n                else if (FileAccessHelper.toneFile.exists())\n                    preferenceScreen.findPreference<Preference>(keyCustomTone)?.summary =\n                        \"Personalizado\"\n                if (!DesignUtils.isFlat)\n                    preferenceScreen.findPreference<ListPreference>(\"recentActionType\")?.isVisible =\n                        false\n                preferenceScreen.findPreference<Preference>(keyCustomTone)?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)\n                        noCrash {\n                            startActivity(\n                                    Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)\n                                            .putExtra(Settings.EXTRA_CHANNEL_ID, RecentsWork.CHANNEL_RECENTS)\n                                            .putExtra(Settings.EXTRA_APP_PACKAGE, this@ConfigurationFragmentMaterial.context?.packageName)\n                            )\n                        }\n                    else\n                        activity?.let {\n                            MaterialDialog(it).safeShow {\n                                title(text = \"Tono de notificación\")\n                                listItems(items = listOf(\"Cambiar tono\", \"Tono de sistema\")) { _, index, _ ->\n                                    when (index) {\n                                        0 -> startActivityForResult(Intent(Intent.ACTION_OPEN_DOCUMENT)\n                                                .addCategory(Intent.CATEGORY_OPENABLE)\n                                                .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION)\n                                                .setType(\"audio/*\"), 4784)\n                                        1 -> {\n                                            FileAccessHelper.toneFile.safeDelete()\n                                            preferenceScreen.findPreference<Preference>(keyCustomTone)?.summary = \"Sistema\"\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    true\n                }\n                if (Backups.type == Backups.Type.DROPBOX) {\n                    if (Network.isConnected) {\n                        activity?.let {\n                            preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"Cargando...\"\n                            Backups.search(null, Backups.keyAutoBackup) {\n                                doOnUI {\n                                    try {\n                                        val autoBackupObject = it as? AutoBackupObject\n                                        if (autoBackupObject != null) {\n                                            if (autoBackupObject == AutoBackupObject(activity))\n                                                preferenceScreen.findPreference<Preference>(\n                                                    keyAutoBackup\n                                                )?.summary = \"%s\"\n                                            else\n                                                preferenceScreen.findPreference<Preference>(\n                                                    keyAutoBackup\n                                                )?.summary = \"Solo \" + autoBackupObject.name\n                                            if (autoBackupObject.value == null)\n                                                GlobalScope.launch(Dispatchers.Main) {\n                                                    Backups.createService()?.backup(\n                                                        AutoBackupObject(App.context),\n                                                        Backups.keyAutoBackup\n                                                    )\n                                                    preferenceScreen.findPreference<Preference>(\n                                                        keyAutoBackup\n                                                    )?.summary = \"%s\"\n                                                }\n                                            else\n                                                preferenceManager.sharedPreferences?.edit()\n                                                    ?.putString(\n                                                        keyAutoBackup,\n                                                        autoBackupObject.value\n                                                    )?.apply()\n                                        } else {\n                                            preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"%s (NE)\"\n                                        }\n                                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.isEnabled = true\n                                    } catch (e: Exception) {\n                                        FirebaseCrashlytics.getInstance().recordException(e)\n                                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"Error al buscar archivo: ${e.message}\"\n                                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.isEnabled = true\n                                    }\n                                }\n                            }\n                        }\n                    } else {\n                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"Sin internet\"\n                    }\n                } else if (Backups.type == Backups.Type.NONE) {\n                    preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"Sin cuenta para respaldos\"\n                } else {\n                    preferenceScreen.findPreference<Preference>(keyAutoBackup)?.isVisible = false\n                }\n                preferenceScreen.findPreference<Preference>(keyAutoBackup)?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    BackUpWork.reSchedule(Integer.valueOf((newValue as? String) ?: \"0\"))\n                    GlobalScope.launch(Dispatchers.Main) {\n                        Backups.createService()?.backup(AutoBackupObject(App.context, (newValue as? String)\n                                ?: \"0\"), Backups.keyAutoBackup)\n                        preferenceScreen.findPreference<Preference>(keyAutoBackup)?.summary = \"%s\"\n                    }\n                    true\n                }\n                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                    preferenceScreen.removePreferenceRecursively(\"download_type\")\n                    val preferenceDownloads = preferenceScreen.findPreference<Preference>(\"download_type_q\")\n                    preferenceDownloads?.summary = PrefsUtil.storageType\n                    preferenceDownloads?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                        FileAccessHelper.openTreeChooser(this@ConfigurationFragmentMaterial)\n                        Toaster.toastLong(\"Por favor selecciona la raiz del almacenamiento\")\n                        true\n                    }\n                } else {\n                    preferenceScreen.removePreferenceRecursively(\"download_type_q\")\n                    preferenceScreen.findPreference<Preference>(\"download_type\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                        if (newValue == \"1\" && !FileAccessHelper.canDownload(\n                                this@ConfigurationFragmentMaterial,\n                                newValue as? String\n                            )\n                        )\n                            Toaster.toast(\"Por favor selecciona la raiz de tu SD\")\n                        else\n                            PreferenceManager.getDefaultSharedPreferences(requireContext()).edit()\n                                .putString(\"tree_uri\", null).apply()\n                        true\n                    }\n                }\n                if (PrefsUtil.downloaderType == 0) {\n                    preferenceScreen.findPreference<Preference>(keyMaxParallelDownloads)?.isEnabled = false\n                    preferenceScreen.findPreference<Preference>(keyBufferSize)?.isEnabled = true\n                } else {\n                    preferenceScreen.findPreference<Preference>(keyMaxParallelDownloads)?.isEnabled = true\n                    preferenceScreen.findPreference<Preference>(keyBufferSize)?.isEnabled = false\n                }\n                preferenceScreen.findPreference<Preference>(\"downloader_type\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    if (newValue == \"0\") {\n                        preferenceScreen.findPreference<Preference>(keyMaxParallelDownloads)?.isEnabled = false\n                        preferenceScreen.findPreference<Preference>(keyBufferSize)?.isEnabled = true\n                    } else {\n                        preferenceScreen.findPreference<Preference>(keyMaxParallelDownloads)?.isEnabled = true\n                        preferenceScreen.findPreference<Preference>(keyBufferSize)?.isEnabled = false\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"default_useragent\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    GlobalScope.launch(Dispatchers.Main) {\n                        delay(1000)\n                        uaChangeListener?.onUAChange()\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"theme_option\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    AppCompatDelegate.setDefaultNightMode(((newValue as? String) ?: \"0\").toInt())\n                    PreferenceManager.getDefaultSharedPreferences(safeContext).edit().putString(\"theme_value\", newValue.toString()).apply()\n                    WEmisionProvider.update(safeContext)\n                    activity?.recreate()\n                    true\n                }\n                preferenceScreen.findPreference<SwitchPreference>(\"ads_enabled_new\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    if (BuildConfig.DEBUG || PrefsUtil.isSubscriptionEnabled) return@OnPreferenceChangeListener true\n                    if (newValue == false) {\n                        context?.let { FirestoreManager.doSignOut(it) }\n                        Backups.type = Backups.Type.NONE\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference, newValue ->\n                    if (newValue == true) {\n                        activity?.let {\n                            MaterialDialog(it).safeShow {\n                                title(text = \"Configurar contraseña\")\n                                input { _, inputText ->\n                                    MaterialDialog(it).safeShow {\n                                        title(text = \"Repetir contraseña\")\n                                        input { _, input ->\n                                            if (input.toString() == inputText.toString())\n                                                doOnUI(onLog = {\n                                                    PrefsUtil.isFamilyFriendly = false\n                                                    preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = false\n                                                    toast(\"Error al encriptar\")\n                                                }) {\n                                                    val encrypted = input.toString().hashCode().toString()\n                                                    PrefsUtil.ffPass = encrypted\n                                                    val file = ffFile\n                                                    file.parentFile?.mkdirs()\n                                                    if (!file.exists())\n                                                        file.createNewFile()\n                                                    file.writeText(encrypted)\n                                                    doAsync { CacheDB.INSTANCE.animeDAO().nukeEcchi() }\n                                                }\n                                            else {\n                                                toast(\"Las contraseñas no coinciden\")\n                                                PrefsUtil.isFamilyFriendly = false\n                                                preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = false\n                                            }\n                                        }\n                                        getInputLayout().boxBackgroundColor = Color.TRANSPARENT\n                                        getInputField().setBackgroundColor(Color.TRANSPARENT)\n                                        onCancel {\n                                            PrefsUtil.isFamilyFriendly = false\n                                            preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = false\n                                        }\n                                    }\n                                }\n                                getInputLayout().boxBackgroundColor = Color.TRANSPARENT\n                                getInputField().setBackgroundColor(Color.TRANSPARENT)\n                                onCancel {\n                                    PrefsUtil.isFamilyFriendly = false\n                                    preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = false\n                                }\n                            }\n                        }\n                    } else {\n                        activity?.let {\n                            MaterialDialog(it).safeShow {\n                                title(text = \"Ingresa contraseña\")\n                                input { _, input ->\n                                    doOnUI(onLog = {\n                                        PrefsUtil.isFamilyFriendly = true\n                                        preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = true\n                                        toast(\"Error al desencriptar\")\n                                    }) {\n                                        val file = ffFile\n                                        if (file.exists() && !admFile.exists()) {\n                                            val text = file.readText()\n                                            Log.e(\"Compare pass\",\"$text == ${input.toString().hashCode()}\")\n                                            if (text == input.toString().hashCode().toString() || text.decrypt() == input.toString()) {\n                                                PrefsUtil.ffPass = \"\"\n                                                file.delete()\n                                                DirectoryUpdateService.run(context)\n                                            } else {\n                                                PrefsUtil.isFamilyFriendly = true\n                                                preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = true\n                                                Toaster.toast(\"Contraseña incorrecta\")\n                                            }\n                                        } else if (admFile.exists()) {\n                                            PrefsUtil.ffPass = \"\"\n                                            file.delete()\n                                            DirectoryUpdateService.run(context)\n                                        } else {\n                                            if (PrefsUtil.ffPass != \"\") {\n                                                val isCorrect = input.hashCode().toString() == PrefsUtil.ffPass || PrefsUtil.ffPass.decrypt() == input.toString()\n                                                if (!isCorrect) {\n                                                    file.createNewFile()\n                                                    file.writeText(PrefsUtil.ffPass)\n                                                    PrefsUtil.isFamilyFriendly = true\n                                                    preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = true\n                                                    Toaster.toast(\"Contraseña incorrecta\")\n                                                } else {\n                                                    PrefsUtil.ffPass = \"\"\n                                                    DirectoryUpdateService.run(context)\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                                getInputLayout().boxBackgroundColor = Color.TRANSPARENT\n                                getInputField().setBackgroundColor(Color.TRANSPARENT)\n                                onCancel {\n                                    PrefsUtil.isFamilyFriendly = true\n                                    preferenceScreen.findPreference<SwitchPreference>(\"family_friendly_enabled\")?.isChecked = true\n                                }\n                            }\n                        }\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"recents_time\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    preferenceScreen.findPreference<Preference>(\"notify_favs\")?.isEnabled = \"0\" != newValue\n                    RecentsWork.reSchedule(newValue.toString().toInt() * 15)\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"dir_update_time\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    DirUpdateWork.reSchedule(newValue.toString().toInt() * 15)\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"security_blocking_firestore\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    FirestoreManager.start()\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"dir_update\")?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                    try {\n                        if (!DirectoryUpdateService.isRunning && !DirectoryService.isRunning)\n                            DirectoryUpdateService.run(App.context)\n                        else if (DirectoryUpdateService.isRunning)\n                            Toaster.toast(\"Ya se esta actualizando\")\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                    }\n\n                    false\n                }\n                if (!canGroupNotifications)\n                    preferenceScreen.removePreference(preferenceScreen.findPreference(\"group_notifications\")!!)\n                preferenceScreen.findPreference<Preference>(\"dir_destroy\")?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                    try {\n                        if (!DirectoryUpdateService.isRunning && !DirectoryService.isRunning)\n                            activity?.let { safe ->\n                                MaterialDialog(safe).safeShow {\n                                    message(text = \"¿Desea recrear el directorio?\")\n                                    positiveButton(text = \"continuar\") {\n                                        doAsync {\n                                            CacheDB.INSTANCE.animeDAO().nuke()\n                                            PrefsUtil.isDirectoryFinished = false\n                                            DirManager.checkPreDir()\n                                            DirectoryService.run(safeContext)\n                                        }\n                                    }\n                                    negativeButton(text = \"cancelar\")\n                                }\n                            }\n                        else if (DirectoryService.isRunning)\n                            Toaster.toast(\"Ya se esta creando\")\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                    }\n\n                    false\n                }\n                when (EAHelper.phase) {\n                    4 ->\n                        preferenceScreen.findPreference<Preference>(keyThemeColor)?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                            startActivity(Intent(activity, MainMaterial::class.java).putExtra(\"start_position\", 3))\n                            activity?.finish()\n                            true\n                        }\n                    0 -> {\n                        val category =\n                            preferenceScreen.findPreference(\"category_design\") as? PreferenceCategory\n                        category?.removePreference(preferenceScreen.findPreference(keyThemeColor)!!)\n                        val pref = Preference(requireContext())\n                        pref.title = \"Color de tema\"\n                        pref.summary = \"Resuelve el secreto para desbloquear\"\n                        pref.setIcon(R.drawable.ic_palette)\n                        pref.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                            Toaster.toast(EAHelper.eaMessage)\n                            true\n                        }\n                        category?.addPreference(pref)\n                    }\n                    else -> {\n                        preferenceScreen.findPreference<Preference>(keyThemeColor)?.summary = \"Resuelve el secreto para desbloquear\"\n                        preferenceScreen.findPreference<Preference>(keyThemeColor)?.isEnabled = false\n                    }\n                }\n                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(this@ConfigurationFragmentMaterial.context))\n                    (preferenceScreen.findPreference(keyAchievementsPermissions) as? SwitchPreference)?.apply {\n                        isChecked = true\n                        isEnabled = false\n                    }\n                else if (!Settings.canDrawOverlays(this@ConfigurationFragmentMaterial.context)) {\n                    (preferenceScreen.findPreference(keyAchievementsPermissions) as? SwitchPreference)?.apply {\n                        isChecked = false\n                        isEnabled = true\n                    }\n                }\n                preferenceScreen.findPreference<Preference>(keyAchievementsPermissions)?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, _ ->\n                    try {\n                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)\n                            startActivityForResult(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION).setData(Uri.parse(\"package:${getPackage()}\")), 5879)\n                    } catch (e: ActivityNotFoundException) {\n                        Toaster.toast(\"No se pudo abrir la configuracion\")\n                    }\n                    true\n                }\n                preferenceScreen.findPreference<Preference>(\"hide_chaps\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    if (!FileAccessHelper.NOMEDIA_CREATING) {\n                        FileAccessHelper.checkNoMedia(newValue as? Boolean == true)\n                        true\n                    } else {\n                        (preferenceScreen.findPreference(\"hide_chaps\") as? SwitchPreference)?.isChecked = newValue as? Boolean != true\n                        false\n                    }\n                }\n                preferenceScreen.findPreference<Preference>(\"max_parallel_downloads\")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->\n                    DownloadManagerCentral.setParallelDownloads(newValue as? String)\n                    true\n                }\n                preferenceScreen.findPreference<SwitchPreference>(\"remember_server\")?.apply {\n                    val lastServer = PrefsUtil.lastServer\n                    if (lastServer.isNull())\n                        isEnabled = false\n                    else {\n                        summary = lastServer\n                        onPreferenceChangeListener = Preference.OnPreferenceChangeListener { preference, newValue ->\n                            if (newValue as? Boolean == false) {\n                                PrefsUtil.lastServer = null\n                                preference.summary = null\n                                preference.isEnabled = false\n                            }\n                            true\n                        }\n                    }\n                }\n                preferenceScreen.findPreference<SwitchPreference>(keyAdsEnabled)?.apply {\n                    isChecked = PrefsUtil.isAdsEnabled\n                    isEnabled = PrefsUtil.isSubscriptionEnabled || !AdsUtils.remoteConfigs.getBoolean(\"ads_forced\")\n                    if (!isEnabled)\n                        summary = \"Estas en una prueba temporal!\"\n                    setOnPreferenceChangeListener { _, newValue ->\n                        preferenceScreen.findPreference<Preference>(\"ads_settings\")?.isEnabled = newValue == true\n                        true\n                    }\n                }\n                preferenceScreen.findPreference<Preference>(\"ads_settings\")?.apply {\n                    isEnabled = PrefsUtil.isAdsEnabled\n                    setOnPreferenceClickListener {\n                        startActivity(Intent(requireContext(), AdsPreferenceActivity::class.java))\n                        true\n                    }\n                }\n                if (BuildConfig.DEBUG) {\n                    preferenceScreen.findPreference<Preference>(\"reset_recents\")?.onPreferenceClickListener = Preference.OnPreferenceClickListener {\n                        doAsync {\n                            CacheDB.INSTANCE.recentsDAO().clear()\n                            RecentsWork.run()\n                        }\n                        true\n                    }\n                }\n            }\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        view.findViewById<ListView>(android.R.id.list)?.let {\n            ViewCompat.setNestedScrollingEnabled(it, true)\n        }\n        super.onViewCreated(view, savedInstanceState)\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        noCrash {\n            if (requestCode == FileAccessHelper.SD_REQUEST && resultCode == Activity.RESULT_OK) {\n                val validation = FileAccessHelper.isUriValid(data?.data)\n                if (!validation.isValid) {\n                    Toaster.toast(\"Directorio invalido: $validation\")\n                    FileAccessHelper.openTreeChooser(this)\n                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)\n                    preferenceScreen.findPreference<Preference>(\"download_type_q\")?.summary = PrefsUtil.storageType\n            } else if (requestCode == 4784 && resultCode == Activity.RESULT_OK) {\n                if (!FileAccessHelper.toneFile.exists())\n                    FileAccessHelper.toneFile.createNewFile()\n                FileUtil.moveFile(\n                        safeContext.contentResolver,\n                        data?.data,\n                        FileOutputStream(FileAccessHelper.toneFile), false)\n                        .observe(this, {\n                            try {\n                                if (it != null) {\n                                    if (it.second) {\n                                        if (it.first == -1) {\n                                            FileAccessHelper.toneFile.safeDelete()\n                                            Toaster.toast(\"Error al copiar\")\n                                        } else {\n                                            Toaster.toast(\"Tono seleccionado!\")\n                                        }\n                                    }\n                                }\n                            } catch (e: Exception) {\n                                Toaster.toast(\"Error al importar\")\n                            }\n                        })\n            } else if (requestCode == 5879) {\n                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context))\n                    (preferenceScreen.findPreference(\"achievements_permissions\") as? SwitchPreference)?.apply {\n                        isChecked = true\n                        isEnabled = false\n                    }\n                else\n                    (preferenceScreen.findPreference(\"achievements_permissions\") as? SwitchPreference)?.apply {\n                        isChecked = false\n                        isEnabled = true\n                    }\n            }\n        }\n    }\n\n    interface UAChangeListener {\n        fun onUAChange()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/profile/TopActivity.kt",
    "content": "package knf.kuma.profile\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.graphics.Color\r\nimport android.os.Bundle\r\nimport android.view.Menu\r\nimport android.view.MenuItem\r\nimport androidx.recyclerview.widget.DividerItemDecoration\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.input.getInputField\r\nimport com.afollestad.materialdialogs.input.getInputLayout\r\nimport com.afollestad.materialdialogs.input.input\r\nimport com.google.android.material.snackbar.Snackbar\r\nimport com.google.firebase.auth.UserProfileChangeRequest\r\nimport com.google.firebase.firestore.ListenerRegistration\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsUtils\r\nimport knf.kuma.ads.FullscreenAdLoader\r\nimport knf.kuma.ads.getFAdLoaderInterstitial\r\nimport knf.kuma.ads.getFAdLoaderRewarded\r\nimport knf.kuma.backup.firestore.FirestoreManager\r\nimport knf.kuma.backup.firestore.data.TopData\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.Economy\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.diceOf\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.databinding.RecyclerLoaderBinding\r\nimport org.jetbrains.anko.doAsync\r\nimport org.jetbrains.anko.toast\r\nimport kotlin.contracts.ExperimentalContracts\r\n\r\nclass TopActivity : GenericActivity() {\r\n\r\n    private lateinit var listener: ListenerRegistration\r\n\r\n    private var snackbar: Snackbar? = null\r\n    private var isEditing = false\r\n\r\n    private val topAdapter: TopAdapter by lazy { TopAdapter() }\r\n\r\n    private val rewardedAd: FullscreenAdLoader by lazy { getFAdLoaderRewarded(this) }\r\n    private var interstitial: FullscreenAdLoader = getFAdLoaderInterstitial(this)\r\n\r\n    private var topList: List<TopData> = emptyList()\r\n    private val binding by lazy { RecyclerLoaderBinding.inflate(layoutInflater) }\r\n\r\n    private fun showAd() {\r\n        diceOf<() -> Unit> {\r\n            put({ rewardedAd.show() }, AdsUtils.remoteConfigs.getDouble(\"rewarded_percent\"))\r\n            put({ interstitial.show() }, AdsUtils.remoteConfigs.getDouble(\"interstitial_percent\"))\r\n        }()\r\n    }\r\n\r\n    @OptIn(ExperimentalContracts::class)\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(binding.root)\r\n        setSupportActionBar(binding.toolbar)\r\n        title = \"Videos vistos\"\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        binding.toolbar.setNavigationOnClickListener { finish() }\r\n        binding.recycler.apply {\r\n            addItemDecoration(DividerItemDecoration(this@TopActivity, DividerItemDecoration.VERTICAL))\r\n            adapter = topAdapter\r\n        }\r\n        binding.loading.show()\r\n        listener = FirestoreManager.listenTop { topList ->\r\n            this.topList = topList\r\n            reload()\r\n        }\r\n        rewardedAd.load()\r\n        interstitial.load()\r\n    }\r\n\r\n    private fun reload() {\r\n        doOnUI { binding.loading.show() }\r\n        doAsync {\r\n            val sorted = topList.sortedByDescending { it.number }\r\n            val list = sorted.take(PrefsUtil.topCount).mapIndexed { index, topData -> TopItem(index + 1, topData) }.toMutableList()\r\n            val current = FirestoreManager.uid?.let { uid -> sorted.find { it.uid == uid } }\r\n            val currentPosition = current?.let { sorted.indexOf(it) } ?: 999\r\n            if (current != null && currentPosition > PrefsUtil.topCount - 1)\r\n                list.add(TopItem(currentPosition + 1, current))\r\n            doOnUI {\r\n                binding.loading.hide()\r\n                topAdapter.submitList(list)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun showSnackbar(text: String, duration: Int = Snackbar.LENGTH_SHORT) {\r\n        snackbar?.dismiss()\r\n        snackbar = Snackbar.make(binding.recycler, text, duration).also { it.show() }\r\n    }\r\n\r\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\r\n        menuInflater.inflate(R.menu.menu_top, menu)\r\n        when (PrefsUtil.topCount) {\r\n            25 -> menu.findItem(R.id.top25)?.isChecked = true\r\n            50 -> menu.findItem(R.id.top50)?.isChecked = true\r\n            75 -> menu.findItem(R.id.top75)?.isChecked = true\r\n            100 -> menu.findItem(R.id.top100)?.isChecked = true\r\n        }\r\n        return super.onCreateOptionsMenu(menu)\r\n    }\r\n\r\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\r\n        when (item.itemId) {\r\n            R.id.coins -> {\r\n                Economy.showWallet(this) { showAd() }\r\n            }\r\n            R.id.editName -> {\r\n                if (!isEditing)\r\n                    MaterialDialog(this).safeShow {\r\n                        title(text = \"Editar nombre\")\r\n                        input(prefill = FirestoreManager.user?.displayName\r\n                                ?: PrefsUtil.instanceName, maxLength = 30) { _, text ->\r\n                            val checked = text.replace(\"[^\\\\wA-zÀ-ú &\\\\-()\\\\[\\\\]\\\"#\\$!¿?¡%{}@_/]*\".toRegex(), \"\").trim()\r\n                            if (checked.isEmpty() || checked.length <= 3) {\r\n                                if (checked.isEmpty())\r\n                                    toast(\"El nombre no puede estar vacío o con caracteres invalidos\")\r\n                                else if (checked.length <= 3)\r\n                                    toast(\"El nombre debe tener mas de 3 caracteres\")\r\n                                return@input\r\n                            }\r\n                            if (FirestoreManager.isLoggedIn) {\r\n                                isEditing = true\r\n                                FirestoreManager.user?.updateProfile(UserProfileChangeRequest.Builder().setDisplayName(checked).build())?.apply {\r\n                                    addOnSuccessListener {\r\n                                        isEditing = false\r\n                                        showSnackbar(\"Nombre editado exitosamente\")\r\n                                        FirestoreManager.updateTop()\r\n                                    }\r\n                                    addOnFailureListener {\r\n                                        isEditing = false\r\n                                        showSnackbar(\"Error al editar nombre\\n${it.message}\", Snackbar.LENGTH_LONG)\r\n                                    }\r\n                                } ?: showSnackbar(\"Error al editar nombre\")\r\n                                showSnackbar(\"Editando nombre...\", Snackbar.LENGTH_INDEFINITE)\r\n                            } else {\r\n                                PrefsUtil.instanceName = checked\r\n                                showSnackbar(\"Nombre editado exitosamente\")\r\n                                FirestoreManager.updateTop()\r\n                            }\r\n                        }\r\n                        getInputLayout().boxBackgroundColor = Color.TRANSPARENT\r\n                        getInputField().setBackgroundColor(Color.TRANSPARENT)\r\n                    }\r\n            }\r\n            R.id.top25 -> {\r\n                PrefsUtil.topCount = 25\r\n                reload()\r\n                invalidateOptionsMenu()\r\n            }\r\n            R.id.top50 -> {\r\n                PrefsUtil.topCount = 50\r\n                reload()\r\n                invalidateOptionsMenu()\r\n            }\r\n            R.id.top75 -> {\r\n                PrefsUtil.topCount = 75\r\n                reload()\r\n                invalidateOptionsMenu()\r\n            }\r\n            R.id.top100 -> {\r\n                PrefsUtil.topCount = 100\r\n                reload()\r\n                invalidateOptionsMenu()\r\n            }\r\n        }\r\n        return super.onOptionsItemSelected(item)\r\n    }\r\n\r\n    override fun onDestroy() {\r\n        super.onDestroy()\r\n        if (::listener.isInitialized)\r\n            listener.remove()\r\n    }\r\n\r\n    companion object {\r\n        fun open(context: Context) {\r\n            context.startActivity(Intent(context, TopActivity::class.java))\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/profile/TopActivityMaterial.kt",
    "content": "package knf.kuma.profile\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.graphics.Color\r\nimport android.os.Bundle\r\nimport android.view.Menu\r\nimport android.view.MenuItem\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.recyclerview.widget.DividerItemDecoration\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.input.getInputField\r\nimport com.afollestad.materialdialogs.input.getInputLayout\r\nimport com.afollestad.materialdialogs.input.input\r\nimport com.google.android.material.snackbar.Snackbar\r\nimport com.google.firebase.auth.UserProfileChangeRequest\r\nimport com.google.firebase.firestore.ListenerRegistration\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsUtils\r\nimport knf.kuma.ads.FullscreenAdLoader\r\nimport knf.kuma.ads.getFAdLoaderInterstitial\r\nimport knf.kuma.ads.getFAdLoaderRewarded\r\nimport knf.kuma.backup.firestore.FirestoreManager\r\nimport knf.kuma.backup.firestore.data.TopData\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.Economy\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.diceOf\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.commons.setSurfaceBars\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.databinding.RecyclerLoaderMaterialBinding\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport org.jetbrains.anko.toast\r\nimport kotlin.contracts.ExperimentalContracts\r\n\r\nclass TopActivityMaterial : GenericActivity() {\r\n\r\n    private lateinit var listener: ListenerRegistration\r\n\r\n    private var snackbar: Snackbar? = null\r\n    private var isEditing = false\r\n\r\n    private val topAdapter: TopAdapter by lazy { TopAdapter() }\r\n\r\n    private val rewardedAd: FullscreenAdLoader by lazy { getFAdLoaderRewarded(this) }\r\n    private var interstitial: FullscreenAdLoader = getFAdLoaderInterstitial(this)\r\n    private val binding by lazy { RecyclerLoaderMaterialBinding.inflate(layoutInflater) }\r\n    private var topList: List<TopData> = emptyList()\r\n\r\n    private val sync: String? by lazy { FirestoreManager.updateTopSync() }\r\n\r\n    private fun showAd() {\r\n        diceOf<() -> Unit> {\r\n            put({ rewardedAd.show() }, AdsUtils.remoteConfigs.getDouble(\"rewarded_percent\"))\r\n            put({ interstitial.show() }, AdsUtils.remoteConfigs.getDouble(\"interstitial_percent\"))\r\n        }()\r\n    }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setSurfaceBars()\r\n        setContentView(binding.root)\r\n        setSupportActionBar(binding.toolbar)\r\n        title = \"Videos vistos\"\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        supportActionBar?.setDisplayShowHomeEnabled(false)\r\n        binding.toolbar.setNavigationOnClickListener { finish() }\r\n        binding.recycler.apply {\r\n            addItemDecoration(DividerItemDecoration(this@TopActivityMaterial, DividerItemDecoration.VERTICAL))\r\n            adapter = topAdapter\r\n        }\r\n        binding.loading.show()\r\n        listen()\r\n        rewardedAd.load()\r\n        interstitial.load()\r\n    }\r\n\r\n    @OptIn(ExperimentalContracts::class)\r\n    private fun listen() {\r\n        if (::listener.isInitialized)\r\n            listener.remove()\r\n        listener = FirestoreManager.listenTop { topList ->\r\n            this.topList = topList\r\n            reload()\r\n        }\r\n    }\r\n\r\n    private fun reload() {\r\n        lifecycleScope.launch(Dispatchers.IO) {\r\n            sync\r\n            launch(Dispatchers.Main) { binding.loading.show() }\r\n            val sorted = topList.sortedByDescending { it.number }\r\n            val list = sorted.take(PrefsUtil.topCount).mapIndexed { index, topData -> TopItem(index + 1, topData) }.toMutableList()\r\n            val current = FirestoreManager.uid?.let { uid -> sorted.find { it.uid == uid } }\r\n            val currentPosition = current?.let { sorted.indexOf(it) } ?: 999\r\n            if (current != null && currentPosition > PrefsUtil.topCount - 1)\r\n                list.add(TopItem(currentPosition + 1, current))\r\n            launch(Dispatchers.Main) {\r\n                binding.loading.hide()\r\n                topAdapter.submitList(list)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun showSnackbar(text: String, duration: Int = Snackbar.LENGTH_SHORT) {\r\n        snackbar?.dismiss()\r\n        snackbar = Snackbar.make(binding.recycler, text, duration).also { it.show() }\r\n    }\r\n\r\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\r\n        menuInflater.inflate(R.menu.menu_top, menu)\r\n        when (PrefsUtil.topCount) {\r\n            25 -> menu.findItem(R.id.top25)?.isChecked = true\r\n            50 -> menu.findItem(R.id.top50)?.isChecked = true\r\n            75 -> menu.findItem(R.id.top75)?.isChecked = true\r\n            100 -> menu.findItem(R.id.top100)?.isChecked = true\r\n        }\r\n        return super.onCreateOptionsMenu(menu)\r\n    }\r\n\r\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\r\n        when (item.itemId) {\r\n            R.id.coins -> {\r\n                Economy.showWallet(this) { showAd() }\r\n            }\r\n            R.id.editName -> {\r\n                if (!isEditing)\r\n                    MaterialDialog(this).safeShow {\r\n                        title(text = \"Editar nombre\")\r\n                        input(prefill = FirestoreManager.user?.displayName\r\n                                ?: PrefsUtil.instanceName, maxLength = 30) { _, text ->\r\n                            val checked = text.replace(\"[^\\\\wA-zÀ-ú &\\\\-()\\\\[\\\\]\\\"#\\$!¿?¡%{}@_/]*\".toRegex(), \"\").trim()\r\n                            if (checked.isEmpty() || checked.length <= 3) {\r\n                                if (checked.isEmpty())\r\n                                    toast(\"El nombre no puede estar vacío o con caracteres invalidos\")\r\n                                else if (checked.length <= 3)\r\n                                    toast(\"El nombre debe tener mas de 3 caracteres\")\r\n                                return@input\r\n                            }\r\n                            if (FirestoreManager.isLoggedIn) {\r\n                                isEditing = true\r\n                                FirestoreManager.user?.updateProfile(UserProfileChangeRequest.Builder().setDisplayName(checked).build())?.apply {\r\n                                    addOnSuccessListener {\r\n                                        isEditing = false\r\n                                        showSnackbar(\"Nombre editado exitosamente\")\r\n                                        FirestoreManager.updateTop()\r\n                                    }\r\n                                    addOnFailureListener {\r\n                                        isEditing = false\r\n                                        showSnackbar(\"Error al editar nombre\\n${it.message}\", Snackbar.LENGTH_LONG)\r\n                                    }\r\n                                } ?: showSnackbar(\"Error al editar nombre\")\r\n                                showSnackbar(\"Editando nombre...\", Snackbar.LENGTH_INDEFINITE)\r\n                            } else {\r\n                                PrefsUtil.instanceName = checked\r\n                                showSnackbar(\"Nombre editado exitosamente\")\r\n                                FirestoreManager.updateTop()\r\n                            }\r\n                        }\r\n                        getInputLayout().boxBackgroundColor = Color.TRANSPARENT\r\n                        getInputField().setBackgroundColor(Color.TRANSPARENT)\r\n                    }\r\n            }\r\n            R.id.top25 -> {\r\n                PrefsUtil.topCount = 25\r\n                reload()\r\n                invalidateOptionsMenu()\r\n            }\r\n            R.id.top50 -> {\r\n                PrefsUtil.topCount = 50\r\n                reload()\r\n                invalidateOptionsMenu()\r\n            }\r\n            R.id.top75 -> {\r\n                PrefsUtil.topCount = 75\r\n                reload()\r\n                invalidateOptionsMenu()\r\n            }\r\n            R.id.top100 -> {\r\n                PrefsUtil.topCount = 100\r\n                reload()\r\n                invalidateOptionsMenu()\r\n            }\r\n        }\r\n        return super.onOptionsItemSelected(item)\r\n    }\r\n\r\n    override fun onDestroy() {\r\n        super.onDestroy()\r\n        if (::listener.isInitialized)\r\n            listener.remove()\r\n    }\r\n\r\n    companion object {\r\n        fun open(context: Context) {\r\n            context.startActivity(Intent(context, TopActivityMaterial::class.java))\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/profile/TopAdapter.kt",
    "content": "package knf.kuma.profile\r\n\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.recyclerview.widget.ListAdapter\r\nimport androidx.recyclerview.widget.RecyclerView\r\nimport knf.kuma.R\r\nimport knf.kuma.backup.firestore.FirestoreManager\r\nimport knf.kuma.commons.inflate\r\nimport org.jetbrains.anko.find\r\n\r\nclass TopAdapter : ListAdapter<TopItem, TopAdapter.ItemHolder>(TopItem.diffCallback) {\r\n\r\n    private val uid = FirestoreManager.uid\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder =\r\n            when (viewType) {\r\n                1 -> ItemHolder(parent.inflate(R.layout.item_top))\r\n                else -> ItemHolder(parent.inflate(R.layout.item_top_current))\r\n            }\r\n\r\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\r\n        holder.bind(getItem(position), position)\r\n    }\r\n\r\n    override fun getItemViewType(position: Int): Int = if (getItem(position).data.uid == uid) 0 else 1\r\n\r\n    class ItemHolder(val view: View) : RecyclerView.ViewHolder(view) {\r\n        fun bind(item: TopItem, position: Int) {\r\n            view.find<TextView>(R.id.ranking).text = \"#${item.position}\"\r\n            view.find<TextView>(R.id.name).text = item.data.name\r\n            view.find<TextView>(R.id.counter).text = item.data.number.toString()\r\n            view.find<ImageView>(R.id.trophy).apply {\r\n                visibility = if (position in 0..2) {\r\n                    setImageResource(when (position) {\r\n                        0 -> R.drawable.ic_trophy_gold\r\n                        1 -> R.drawable.ic_trophy_silver\r\n                        else -> R.drawable.ic_trophy_bronze\r\n                    })\r\n                    View.VISIBLE\r\n                } else View.INVISIBLE\r\n            }\r\n        }\r\n\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/profile/TopItem.kt",
    "content": "package knf.kuma.profile\r\n\r\nimport androidx.recyclerview.widget.DiffUtil\r\nimport knf.kuma.backup.firestore.data.TopData\r\n\r\ndata class TopItem(val position: Int, val data: TopData) {\r\n    companion object {\r\n        val diffCallback = object : DiffUtil.ItemCallback<TopItem>() {\r\n            override fun areItemsTheSame(oldItem: TopItem, newItem: TopItem): Boolean = oldItem.data.uid == newItem.data.uid\r\n\r\n            override fun areContentsTheSame(oldItem: TopItem, newItem: TopItem): Boolean {\r\n                return oldItem.position == newItem.position && oldItem.data.name == newItem.data.name && oldItem.data.number == newItem.data.number\r\n            }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/ItemTouchHelperAdapter.kt",
    "content": "package knf.kuma.queue\n\ninterface ItemTouchHelperAdapter {\n    fun onItemMove(fromPosition: Int, toPosition: Int)\n\n    fun onItemDismiss(position: Int)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/NoTouchHelperCallback.kt",
    "content": "package knf.kuma.queue\n\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.RecyclerView\n\nclass NoTouchHelperCallback : ItemTouchHelper.Callback() {\n\n    override fun isLongPressDragEnabled(): Boolean {\n        return false\n    }\n\n    override fun isItemViewSwipeEnabled(): Boolean {\n        return false\n    }\n\n    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {\n        return makeMovementFlags(0, 0)\n    }\n\n    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {\n        return false\n    }\n\n    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {\n\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/QueueActivity.kt",
    "content": "package knf.kuma.queue\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.view.animation.AnimationUtils\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport androidx.activity.addCallback\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.widget.Toolbar\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.preference.PreferenceManager\nimport androidx.recyclerview.widget.DividerItemDecoration\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.android.material.bottomsheet.BottomSheetBehavior\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.gridColumns\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.custom.VariantGridLayoutManager\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.QueueObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster\n\nclass QueueActivity : GenericActivity(), QueueAnimesAdapter.OnAnimeSelectedListener, QueueAllAdapter.OnStartDragListener {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    val recyclerView: RecyclerView by bind(R.id.recycler)\n    private val listToolbar: Toolbar by bind(R.id.list_toolbar)\n    private val listRecyclerView: RecyclerView by bind(R.id.list_recycler)\n    val cardView: MaterialCardView by bind(R.id.bottom_card)\n    val errorView: View by bind(R.id.error)\n    internal var bottomSheetBehavior: BottomSheetBehavior<MaterialCardView>? = null\n    private var listAdapter: QueueListAdapter? = null\n\n    private var mItemTouchHelper: ItemTouchHelper? = null\n\n    private var current: QueueObject? = null\n\n    private var currentData: LiveData<MutableList<QueueObject>> = MutableLiveData()\n\n    private var isFirst = true\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.activity_queue\n        } else {\n            R.layout.activity_queue_grid\n        }\n\n    @SuppressLint(\"CheckResult\")\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(layout)\n        toolbar.title = \"Pendientes\"\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        toolbar.setNavigationOnClickListener { finish() }\n        menuInflater.inflate(R.menu.menu_play_queue, listToolbar.menu)\n        listToolbar.setOnMenuItemClickListener { item ->\n            when (item.itemId) {\n                R.id.play -> {\n                    bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n                    QueueManager.startQueue(applicationContext, listAdapter?.list ?: listOf())\n                }\n                R.id.clear ->\n                    MaterialDialog(this@QueueActivity).safeShow {\n                        message(text = \"¿Remover los episodios pendientes?\")\n                        positiveButton(text = \"remover\") {\n                            bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n                            QueueManager.remove(listAdapter?.list ?: mutableListOf())\n                        }\n                        negativeButton(text = \"cancelar\")\n                    }\n            }\n            true\n        }\n        bottomSheetBehavior = BottomSheetBehavior.from(cardView)\n        bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n        val backCallback = onBackPressedDispatcher.addCallback(this, false) {\n            bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n        }\n        bottomSheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {\n            override fun onStateChanged(bottomSheet: View, newState: Int) {\n                backCallback.isEnabled = newState == BottomSheetBehavior.STATE_EXPANDED\n                if (newState == BottomSheetBehavior.STATE_HIDDEN)\n                    current = null\n            }\n\n            override fun onSlide(bottomSheet: View, slideOffset: Float) {\n\n            }\n        })\n        setLayoutManager(!PreferenceManager.getDefaultSharedPreferences(this).getBoolean(\"queue_is_grouped\", true))\n        listRecyclerView.addItemDecoration(DividerItemDecoration(this, LinearLayout.VERTICAL))\n        listAdapter = QueueListAdapter { closeSheet() }\n        listRecyclerView.adapter = listAdapter\n        find<FrameLayout>(R.id.adContainer).implBanner(AdsType.QUEUE_BANNER, true)\n        /*Aesthetic.get().colorAccent().take(1).subscribe {\n            listToolbar.backgroundColor = it\n        }*/\n        reload()\n        if (savedInstanceState != null && savedInstanceState.getBoolean(\"isOpen\", false))\n            onSelect(savedInstanceState.getSerializable(\"current\") as QueueObject)\n    }\n\n    private fun reload() {\n        currentData.removeObservers(this@QueueActivity)\n        if (PreferenceManager.getDefaultSharedPreferences(this@QueueActivity).getBoolean(\"queue_is_grouped\", true)) {\n            currentData = CacheDB.INSTANCE.queueDAO().all\n            currentData.observe(this@QueueActivity, Observer { list ->\n                errorView.visibility = if (list.isEmpty()) View.VISIBLE else View.GONE\n                val animesAdapter = QueueAnimesAdapter(this@QueueActivity)\n                recyclerView.adapter = animesAdapter\n                dettachHelper()\n                mItemTouchHelper = ItemTouchHelper(NoTouchHelperCallback())\n                mItemTouchHelper?.attachToRecyclerView(recyclerView)\n                doAsync {\n                    animesAdapter.update(QueueObject.takeOne(list))\n                    if (isFirst) {\n                        isFirst = false\n                        openInitial(list)\n                    }\n                }\n\n            })\n        } else {\n            currentData = CacheDB.INSTANCE.queueDAO().allAsort\n            currentData.observe(this@QueueActivity, object : Observer<MutableList<QueueObject>> {\n                override fun onChanged(value: MutableList<QueueObject>) {\n                    isFirst = false\n                    clearInterfaces()\n                    errorView.visibility = if (value.isEmpty()) View.VISIBLE else View.GONE\n                    val allAdapter = QueueAllAdapter(this@QueueActivity)\n                    recyclerView.adapter = allAdapter\n                    dettachHelper()\n                    mItemTouchHelper = ItemTouchHelper(SimpleItemTouchHelperCallback(allAdapter))\n                    mItemTouchHelper?.attachToRecyclerView(recyclerView)\n                    allAdapter.update(value)\n                    currentData.removeObserver(this)\n                }\n            })\n        }\n    }\n\n    private fun openInitial(list: List<QueueObject>) {\n        val initialID = intent.getStringExtra(\"initial\") ?: return\n        list.forEach {\n            if (it.chapter.aid == initialID) {\n                onSelect(it)\n                return@forEach\n            }\n        }\n    }\n\n    private fun dettachHelper() {\n        if (mItemTouchHelper != null)\n            mItemTouchHelper?.attachToRecyclerView(null)\n    }\n\n    private fun clearInterfaces() {\n        if (recyclerView.adapter is QueueAnimesAdapter)\n            (recyclerView.adapter as QueueAnimesAdapter).clear()\n    }\n\n    private fun setLayoutManager(isFull: Boolean) {\n        if (isFull || PrefsUtil.layType == \"0\") {\n            recyclerView.layoutManager = VariantLinearLayoutManager(this)\n            recyclerView.layoutAnimation = AnimationUtils.loadLayoutAnimation(this, R.anim.layout_fall_down)\n        } else {\n            recyclerView.layoutManager = VariantGridLayoutManager(this, gridColumns())\n            recyclerView.layoutAnimation = AnimationUtils.loadLayoutAnimation(this, R.anim.grid_fall_down)\n        }\n    }\n\n    override fun onSelect(queueObject: QueueObject) {\n        if (queueObject.equalsAnime(current)) {\n            closeSheet()\n        } else {\n            doOnUI {\n                try {\n                    listToolbar.title = queueObject.chapter.name\n                    lifecycleScope.launch(Dispatchers.Main) {\n                        val list = withContext(Dispatchers.IO) { CacheDB.INSTANCE.queueDAO().getByAidUnique(queueObject.chapter.aid) }\n                        if (list.isEmpty())\n                            bottomSheetBehavior?.setState(BottomSheetBehavior.STATE_HIDDEN)\n                        else {\n                            listAdapter?.update(\n                                    queueObject.chapter.aid,\n                                    withContext(Dispatchers.IO) {\n                                        try {\n                                            list.sortedBy { it.chapter.number.substringAfterLast(\" \").toFloat() }.toMutableList()\n                                        } catch (_: Exception) {\n                                            list\n                                        }\n                                    }\n                            )\n                            bottomSheetBehavior?.setState(BottomSheetBehavior.STATE_EXPANDED)\n                        }\n                        current = queueObject\n                    }\n                } catch (_: Exception) {\n                    doAsync {\n                        CacheDB.INSTANCE.queueDAO().allRaw.forEach {\n                            try {\n                                it.chapter.aid\n                            } catch (_: Exception) {\n                                CacheDB.INSTANCE.queueDAO().remove(it)\n                            }\n                        }\n                        syncData { queue() }\n                    }\n                }\n            }\n        }\n    }\n\n    private fun closeSheet() {\n        current = null\n        bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n    }\n\n    override fun onStartDrag(holder: RecyclerView.ViewHolder) {\n        mItemTouchHelper?.startDrag(holder)\n    }\n\n    override fun onListCleared() {\n        errorView.post { errorView.visibility = View.VISIBLE }\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(\"queue_is_grouped\", true))\n            menuInflater.inflate(R.menu.menu_queue_group, menu)\n        else\n            menuInflater.inflate(R.menu.menu_queue_list, menu)\n        val preferences = PreferenceManager.getDefaultSharedPreferences(this)\n        if (!preferences.getBoolean(\"is_queue_info_shown\", false)) {\n            preferences.edit().putBoolean(\"is_queue_info_shown\", true).apply()\n            onOptionsItemSelected(menu.findItem(R.id.info))\n        }\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n        when (item.itemId) {\n            R.id.info ->\n                MaterialDialog(this).safeShow {\n                    message(text = \"Los episodios añadidos desde servidor podrían dejar de funcionar después de días sin reproducir\")\n                    positiveButton(text = \"OK\")\n                }\n            R.id.queue_group -> {\n                PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean(\"queue_is_grouped\", true).apply()\n                setLayoutManager(false)\n                reload()\n                invalidateOptionsMenu()\n            }\n            R.id.queue_list -> {\n                PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean(\"queue_is_grouped\", false).apply()\n                setLayoutManager(true)\n                reload()\n                invalidateOptionsMenu()\n            }\n            R.id.play -> {\n                bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n                val list = (recyclerView.adapter as? QueueAllAdapter)?.list ?: mutableListOf()\n                if (list.size > 0)\n                    QueueManager.startQueue(applicationContext, list)\n                else\n                    Toaster.toast(\"La lista esta vacia\")\n            }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    override fun onSaveInstanceState(outState: Bundle) {\n        super.onSaveInstanceState(outState)\n        if (current != null) {\n            outState.putSerializable(\"current\", current)\n            outState.putBoolean(\"isOpen\", true)\n        } else\n            outState.putBoolean(\"isOpen\", false)\n    }\n\n    companion object {\n\n        fun open(context: Context?) {\n            context ?: return\n            context.startActivity(Intent(context, QueueActivity::class.java))\n        }\n\n        fun open(context: Context?, aid: String) {\n            context ?: return\n            context.startActivity(Intent(context, QueueActivity::class.java).apply {\n                putExtra(\"initial\", aid)\n            })\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/QueueActivityMaterial.kt",
    "content": "package knf.kuma.queue\n\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.view.animation.AnimationUtils\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport androidx.activity.addCallback\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.widget.Toolbar\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.preference.PreferenceManager\nimport androidx.recyclerview.widget.DividerItemDecoration\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.android.material.bottomsheet.BottomSheetBehavior\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.gridColumns\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.custom.VariantGridLayoutManager\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.QueueObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster\n\nclass QueueActivityMaterial : GenericActivity(), QueueAnimesAdapterMaterial.OnAnimeSelectedListener, QueueAllAdapterMaterial.OnStartDragListener {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    val recyclerView: RecyclerView by bind(R.id.recycler)\n    private val listToolbar: Toolbar by bind(R.id.list_toolbar)\n    private val listRecyclerView: RecyclerView by bind(R.id.list_recycler)\n    val cardView: MaterialCardView by bind(R.id.bottom_card)\n    val errorView: View by bind(R.id.error)\n    internal var bottomSheetBehavior: BottomSheetBehavior<MaterialCardView>? = null\n    private var listAdapter: QueueListAdapter? = null\n\n    private var mItemTouchHelper: ItemTouchHelper? = null\n\n    private var current: QueueObject? = null\n\n    private var currentData: LiveData<MutableList<QueueObject>> = MutableLiveData()\n\n    private var isFirst = true\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.activity_queue_material\n        } else {\n            R.layout.activity_queue_grid_material\n        }\n\n    @SuppressLint(\"CheckResult\")\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(layout)\n        toolbar.title = \"Pendientes\"\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        toolbar.setNavigationOnClickListener { finish() }\n        menuInflater.inflate(R.menu.menu_play_queue, listToolbar.menu)\n        listToolbar.setOnMenuItemClickListener { item ->\n            when (item.itemId) {\n                R.id.play -> {\n                    bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n                    QueueManager.startQueue(applicationContext, listAdapter?.list ?: listOf())\n                }\n                R.id.clear ->\n                    MaterialDialog(this@QueueActivityMaterial).safeShow {\n                        message(text = \"¿Remover los episodios pendientes?\")\n                        positiveButton(text = \"remover\") {\n                            bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n                            QueueManager.remove(listAdapter?.list ?: mutableListOf())\n                        }\n                        negativeButton(text = \"cancelar\")\n                    }\n            }\n            true\n        }\n        bottomSheetBehavior = BottomSheetBehavior.from(cardView)\n        bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n        val backCallback = onBackPressedDispatcher.addCallback(this, false) {\n            bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n        }\n        bottomSheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {\n            override fun onStateChanged(bottomSheet: View, newState: Int) {\n                backCallback.isEnabled = newState == BottomSheetBehavior.STATE_EXPANDED\n                if (newState == BottomSheetBehavior.STATE_HIDDEN)\n                    current = null\n            }\n\n            override fun onSlide(bottomSheet: View, slideOffset: Float) {\n\n            }\n        })\n        setLayoutManager(!PreferenceManager.getDefaultSharedPreferences(this).getBoolean(\"queue_is_grouped\", true))\n        listRecyclerView.addItemDecoration(DividerItemDecoration(this, LinearLayout.VERTICAL))\n        listAdapter = QueueListAdapter { closeSheet() }\n        listRecyclerView.adapter = listAdapter\n        find<FrameLayout>(R.id.adContainer).implBanner(AdsType.QUEUE_BANNER, true)\n        /*Aesthetic.get().colorAccent().take(1).subscribe {\n            listToolbar.backgroundColor = it\n        }*/\n        reload()\n        if (savedInstanceState != null && savedInstanceState.getBoolean(\"isOpen\", false))\n            onSelect(savedInstanceState.getSerializable(\"current\") as QueueObject)\n    }\n\n    private fun reload() {\n        currentData.removeObservers(this@QueueActivityMaterial)\n        if (PreferenceManager.getDefaultSharedPreferences(this@QueueActivityMaterial).getBoolean(\"queue_is_grouped\", true)) {\n            currentData = CacheDB.INSTANCE.queueDAO().all\n            currentData.observe(this@QueueActivityMaterial, Observer { list ->\n                errorView.visibility = if (list.isEmpty()) View.VISIBLE else View.GONE\n                val animesAdapter = QueueAnimesAdapterMaterial(this@QueueActivityMaterial)\n                recyclerView.adapter = animesAdapter\n                dettachHelper()\n                mItemTouchHelper = ItemTouchHelper(NoTouchHelperCallback())\n                mItemTouchHelper?.attachToRecyclerView(recyclerView)\n                doAsync {\n                    animesAdapter.update(QueueObject.takeOne(list))\n                    if (isFirst) {\n                        isFirst = false\n                        openInitial(list)\n                    }\n                }\n\n            })\n        } else {\n            currentData = CacheDB.INSTANCE.queueDAO().allAsort\n            currentData.observe(this@QueueActivityMaterial, object : Observer<MutableList<QueueObject>> {\n                override fun onChanged(value: MutableList<QueueObject>) {\n                    isFirst = false\n                    clearInterfaces()\n                    errorView.visibility = if (value.isEmpty()) View.VISIBLE else View.GONE\n                    val allAdapter = QueueAllAdapterMaterial(this@QueueActivityMaterial)\n                    recyclerView.adapter = allAdapter\n                    dettachHelper()\n                    mItemTouchHelper = ItemTouchHelper(SimpleItemTouchHelperCallback(allAdapter))\n                    mItemTouchHelper?.attachToRecyclerView(recyclerView)\n                    allAdapter.update(value)\n                    currentData.removeObserver(this)\n                }\n            })\n        }\n    }\n\n    private fun openInitial(list: List<QueueObject>) {\n        val initialID = intent.getStringExtra(\"initial\") ?: return\n        list.forEach {\n            if (it.chapter.aid == initialID) {\n                onSelect(it)\n                return@forEach\n            }\n        }\n    }\n\n    private fun dettachHelper() {\n        if (mItemTouchHelper != null)\n            mItemTouchHelper?.attachToRecyclerView(null)\n    }\n\n    private fun clearInterfaces() {\n        if (recyclerView.adapter is QueueAnimesAdapterMaterial)\n            (recyclerView.adapter as QueueAnimesAdapterMaterial).clear()\n    }\n\n    private fun setLayoutManager(isFull: Boolean) {\n        if (isFull || PrefsUtil.layType == \"0\") {\n            recyclerView.layoutManager = VariantLinearLayoutManager(this)\n            recyclerView.layoutAnimation = AnimationUtils.loadLayoutAnimation(this, R.anim.layout_fall_down)\n        } else {\n            recyclerView.layoutManager = VariantGridLayoutManager(this, gridColumns())\n            recyclerView.layoutAnimation = AnimationUtils.loadLayoutAnimation(this, R.anim.grid_fall_down)\n        }\n    }\n\n    override fun onSelect(queueObject: QueueObject) {\n        if (queueObject.equalsAnime(current)) {\n            closeSheet()\n        } else {\n            doOnUI {\n                try {\n                    listToolbar.title = queueObject.chapter.name\n                    lifecycleScope.launch(Dispatchers.Main) {\n                        val list = withContext(Dispatchers.IO) { CacheDB.INSTANCE.queueDAO().getByAidUnique(queueObject.chapter.aid) }\n                        if (list.isEmpty())\n                            bottomSheetBehavior?.setState(BottomSheetBehavior.STATE_HIDDEN)\n                        else {\n                            listAdapter?.update(\n                                    queueObject.chapter.aid,\n                                    withContext(Dispatchers.IO) {\n                                        try {\n                                            list.sortedBy { it.chapter.number.substringAfterLast(\" \").toInt() }.toMutableList()\n                                        } catch (_: Exception) {\n                                            list\n                                        }\n                                    }\n                            )\n                            bottomSheetBehavior?.setState(BottomSheetBehavior.STATE_EXPANDED)\n                        }\n                        current = queueObject\n                    }\n                } catch (_: Exception) {\n                    doAsync {\n                        CacheDB.INSTANCE.queueDAO().allRaw.forEach {\n                            try {\n                                it.chapter.aid\n                            } catch (_: Exception) {\n                                CacheDB.INSTANCE.queueDAO().remove(it)\n                            }\n                        }\n                        syncData { queue() }\n                    }\n                }\n            }\n        }\n    }\n\n    private fun closeSheet() {\n        current = null\n        bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n    }\n\n    override fun onStartDrag(holder: RecyclerView.ViewHolder) {\n        mItemTouchHelper?.startDrag(holder)\n    }\n\n    override fun onListCleared() {\n        errorView.post { errorView.visibility = View.VISIBLE }\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(\"queue_is_grouped\", true))\n            menuInflater.inflate(R.menu.menu_queue_group, menu)\n        else\n            menuInflater.inflate(R.menu.menu_queue_list, menu)\n        val preferences = PreferenceManager.getDefaultSharedPreferences(this)\n        if (!preferences.getBoolean(\"is_queue_info_shown\", false)) {\n            preferences.edit().putBoolean(\"is_queue_info_shown\", true).apply()\n            onOptionsItemSelected(menu.findItem(R.id.info))\n        }\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n        when (item.itemId) {\n            R.id.info ->\n                MaterialDialog(this).safeShow {\n                    message(text = \"Los episodios añadidos desde servidor podrían dejar de funcionar después de días sin reproducir\")\n                    positiveButton(text = \"OK\")\n                }\n            R.id.queue_group -> {\n                PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean(\"queue_is_grouped\", true).apply()\n                setLayoutManager(false)\n                reload()\n                invalidateOptionsMenu()\n            }\n            R.id.queue_list -> {\n                PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean(\"queue_is_grouped\", false).apply()\n                setLayoutManager(true)\n                reload()\n                invalidateOptionsMenu()\n            }\n            R.id.play -> {\n                bottomSheetBehavior?.state = BottomSheetBehavior.STATE_HIDDEN\n                val list = (recyclerView.adapter as? QueueAllAdapterMaterial)?.list ?: mutableListOf()\n                if (list.size > 0)\n                    QueueManager.startQueue(applicationContext, list)\n                else\n                    Toaster.toast(\"La lista esta vacia\")\n            }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    override fun onSaveInstanceState(outState: Bundle) {\n        super.onSaveInstanceState(outState)\n        if (current != null) {\n            outState.putSerializable(\"current\", current)\n            outState.putBoolean(\"isOpen\", true)\n        } else\n            outState.putBoolean(\"isOpen\", false)\n    }\n\n    companion object {\n\n        fun open(context: Context?) {\n            context ?: return\n            context.startActivity(Intent(context, QueueActivityMaterial::class.java))\n        }\n\n        fun open(context: Context?, aid: String) {\n            context ?: return\n            context.startActivity(Intent(context, QueueActivityMaterial::class.java).apply {\n                putExtra(\"initial\", aid)\n            })\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/QueueAllAdapter.kt",
    "content": "package knf.kuma.queue\n\nimport android.annotation.SuppressLint\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.MotionEvent\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.pojos.QueueObject\nimport org.jetbrains.anko.find\nimport java.util.Collections\n\ninternal class QueueAllAdapter internal constructor(activity: Activity) : RecyclerView.Adapter<QueueAllAdapter.AnimeHolder>(), ItemTouchHelperAdapter {\n\n    private val dragListener: OnStartDragListener = activity as OnStartDragListener\n    var list: MutableList<QueueObject> = ArrayList()\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AnimeHolder {\n        return AnimeHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_queue_full, parent, false))\n    }\n\n    @SuppressLint(\"ClickableViewAccessibility\")\n    override fun onBindViewHolder(holder: AnimeHolder, position: Int) {\n        val queueObject = list[position]\n        holder.title.text = PatternUtil.fromHtml(queueObject.chapter.name)\n        holder.chapter.text = queueObject.chapter.number\n        holder.state.setImageResource(if (queueObject.isFile) R.drawable.ic_queue_file else R.drawable.ic_web)\n        holder.dragView.setOnTouchListener { _, event ->\n            if (event.action == MotionEvent.ACTION_DOWN) {\n                dragListener.onStartDrag(holder)\n            }\n            false\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(list: MutableList<QueueObject>) {\n        if (this.list notSameContent list) {\n            this.list = list\n            notifyDataSetChanged()\n        }\n    }\n\n    override fun onItemMove(fromPosition: Int, toPosition: Int) {\n        if (fromPosition < toPosition) {\n            for (i in fromPosition until toPosition) {\n                val fromTime = list[i].time\n                list[i].time = list[i + 1].time\n                list[i + 1].time = fromTime\n                QueueManager.update(list[i], list[i + 1])\n                Collections.swap(list, i, i + 1)\n            }\n        } else {\n            for (i in fromPosition downTo toPosition + 1) {\n                val fromTime = list[i].time\n                list[i].time = list[i - 1].time\n                list[i - 1].time = fromTime\n                QueueManager.update(list[i], list[i - 1])\n                Collections.swap(list, i, i - 1)\n            }\n        }\n        notifyItemMoved(fromPosition, toPosition)\n    }\n\n    override fun onItemDismiss(position: Int) {\n        QueueManager.remove(list[position])\n        list.removeAt(position)\n        notifyItemRemoved(position)\n        if (list.size == 0)\n            dragListener.onListCleared()\n    }\n\n    internal interface OnStartDragListener {\n        fun onStartDrag(holder: RecyclerView.ViewHolder)\n\n        fun onListCleared()\n    }\n\n    internal class AnimeHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView = itemView.find(R.id.card)\n        val dragView: ImageView = itemView.find(R.id.drag)\n        val title: TextView = itemView.find(R.id.title)\n        val chapter: TextView = itemView.find(R.id.chapter)\n        val state: ImageView = itemView.find(R.id.state)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/QueueAllAdapterMaterial.kt",
    "content": "package knf.kuma.queue\n\nimport android.annotation.SuppressLint\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.MotionEvent\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.pojos.QueueObject\nimport org.jetbrains.anko.find\nimport java.util.Collections\n\ninternal class QueueAllAdapterMaterial internal constructor(activity: Activity) : RecyclerView.Adapter<QueueAllAdapterMaterial.AnimeHolder>(), ItemTouchHelperAdapter {\n\n    private val dragListener: OnStartDragListener = activity as OnStartDragListener\n    var list: MutableList<QueueObject> = ArrayList()\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AnimeHolder {\n        return AnimeHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_queue_full_material, parent, false))\n    }\n\n    @SuppressLint(\"ClickableViewAccessibility\")\n    override fun onBindViewHolder(holder: AnimeHolder, position: Int) {\n        val queueObject = list[position]\n        noCrash {\n            holder.title.text = PatternUtil.fromHtml(queueObject.chapter.name)\n            holder.chapter.text = queueObject.chapter.number\n        }\n        holder.state.setImageResource(if (queueObject.isFile) R.drawable.ic_queue_file else R.drawable.ic_web)\n        holder.dragView.setOnTouchListener { _, event ->\n            if (event.action == MotionEvent.ACTION_DOWN) {\n                dragListener.onStartDrag(holder)\n            }\n            false\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(list: MutableList<QueueObject>) {\n        if (this.list notSameContent list) {\n            this.list = list\n            notifyDataSetChanged()\n        }\n    }\n\n    override fun onItemMove(fromPosition: Int, toPosition: Int) {\n        if (fromPosition < toPosition) {\n            for (i in fromPosition until toPosition) {\n                val fromTime = list[i].time\n                list[i].time = list[i + 1].time\n                list[i + 1].time = fromTime\n                QueueManager.update(list[i], list[i + 1])\n                Collections.swap(list, i, i + 1)\n            }\n        } else {\n            for (i in fromPosition downTo toPosition + 1) {\n                val fromTime = list[i].time\n                list[i].time = list[i - 1].time\n                list[i - 1].time = fromTime\n                QueueManager.update(list[i], list[i - 1])\n                Collections.swap(list, i, i - 1)\n            }\n        }\n        notifyItemMoved(fromPosition, toPosition)\n    }\n\n    override fun onItemDismiss(position: Int) {\n        QueueManager.remove(list[position])\n        list.removeAt(position)\n        notifyItemRemoved(position)\n        if (list.size == 0)\n            dragListener.onListCleared()\n    }\n\n    internal interface OnStartDragListener {\n        fun onStartDrag(holder: RecyclerView.ViewHolder)\n\n        fun onListCleared()\n    }\n\n    internal class AnimeHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val dragView: ImageView = itemView.find(R.id.drag)\n        val title: TextView = itemView.find(R.id.title)\n        val chapter: TextView = itemView.find(R.id.chapter)\n        val state: ImageView = itemView.find(R.id.state)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/QueueAnimesAdapter.kt",
    "content": "package knf.kuma.queue\n\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.load\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.pojos.QueueObject\nimport java.util.Locale\n\ninternal class QueueAnimesAdapter internal constructor(private val activity: Activity) : RecyclerView.Adapter<QueueAnimesAdapter.AnimeHolder>() {\n    private var listener: OnAnimeSelectedListener? = null\n    private var list: MutableList<QueueObject> = ArrayList()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\")\n            R.layout.item_anim_queue\n        else\n            R.layout.item_anim_queue_grid\n\n    init {\n        this.listener = activity as OnAnimeSelectedListener\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AnimeHolder {\n        return AnimeHolder(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: AnimeHolder, position: Int) {\n        val queueObject = list[position]\n        val img = PatternUtil.getCover(queueObject.chapter.aid)\n        holder.imageView.load(img)\n        holder.title.text = PatternUtil.fromHtml(queueObject.chapter.name)\n        holder.type.text = String.format(Locale.getDefault(), if (queueObject.count == 1) \"%d episodio\" else \"%d episodios\", queueObject.count)\n        holder.cardView.setOnClickListener { listener?.onSelect(queueObject) }\n        holder.cardView.setOnLongClickListener {\n            ActivityAnime.open(activity, queueObject, holder.imageView)\n            true\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(list: MutableList<QueueObject>) {\n        if (this.list notSameContent list) {\n            this.list = list\n            doOnUIGlobal { notifyDataSetChanged() }\n        }\n    }\n\n    fun clear() {\n        listener = null\n    }\n\n    internal interface OnAnimeSelectedListener {\n        fun onSelect(queueObject: QueueObject)\n    }\n\n    internal class AnimeHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val type: TextView by itemView.bind(R.id.type)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/QueueAnimesAdapterMaterial.kt",
    "content": "package knf.kuma.queue\n\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.load\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.pojos.QueueObject\nimport java.util.Locale\n\ninternal class QueueAnimesAdapterMaterial internal constructor(private val activity: Activity) : RecyclerView.Adapter<QueueAnimesAdapterMaterial.AnimeHolder>() {\n    private var listener: OnAnimeSelectedListener? = null\n    private var list: MutableList<QueueObject> = ArrayList()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\")\n            R.layout.item_anim_queue_material\n        else\n            R.layout.item_anim_queue_grid_material\n\n    init {\n        this.listener = activity as OnAnimeSelectedListener\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AnimeHolder {\n        return AnimeHolder(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: AnimeHolder, position: Int) {\n        val queueObject = list[position]\n        noCrash {\n            holder.imageView.load(PatternUtil.getCover(queueObject.chapter.aid))\n            holder.title.text = PatternUtil.fromHtml(queueObject.chapter.name)\n        }\n        holder.type.text = String.format(Locale.getDefault(), if (queueObject.count == 1) \"%d episodio\" else \"%d episodios\", queueObject.count)\n        holder.cardView.setOnClickListener { listener?.onSelect(queueObject) }\n        holder.cardView.setOnLongClickListener {\n            ActivityAnimeMaterial.open(activity, queueObject, holder.imageView)\n            true\n        }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(list: MutableList<QueueObject>) {\n        if (this.list notSameContent list) {\n            this.list = list\n            doOnUIGlobal { notifyDataSetChanged() }\n        }\n    }\n\n    fun clear() {\n        listener = null\n    }\n\n    internal interface OnAnimeSelectedListener {\n        fun onSelect(queueObject: QueueObject)\n    }\n\n    internal class AnimeHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val type: TextView by itemView.bind(R.id.type)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/QueueListAdapter.kt",
    "content": "package knf.kuma.queue\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageButton\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.QueueObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.find\n\ninternal class QueueListAdapter(val callback: () -> Unit) : RecyclerView.Adapter<QueueListAdapter.ListItemHolder>() {\n    private var current = \"0000\"\n    var list: MutableList<QueueObject> = ArrayList()\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListItemHolder {\n        return ListItemHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_queue, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ListItemHolder, position: Int) {\n        val queueObject = list[position]\n        holder.chapter.text = queueObject.chapter.number\n        holder.icon.setImageResource(if (queueObject.isFile) R.drawable.ic_chap_down else R.drawable.ic_web)\n        holder.actionDelete.setOnClickListener { remove(holder.adapterPosition) }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(aid: String, list: MutableList<QueueObject>) {\n        if (current != aid && this.list notSameContent list) {\n            current = aid\n            this.list = list\n            notifyDataSetChanged()\n        }\n    }\n\n    fun remove(position: Int) {\n        if (position != -1) {\n            GlobalScope.launch(Dispatchers.Main){\n                withContext(Dispatchers.IO) { CacheDB.INSTANCE.queueDAO().remove(list[position]) }\n                list.removeAt(position)\n                notifyItemRemoved(position)\n                if (list.isEmpty()) callback.invoke()\n            }\n        }\n    }\n\n    internal class ListItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val chapter: TextView = itemView.find(R.id.chapter)\n        val icon: ImageView = itemView.find(R.id.icon)\n        val actionDelete: ImageButton = itemView.find(R.id.action_delete)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/QueueManager.kt",
    "content": "package knf.kuma.queue\n\nimport android.content.Context\nimport android.content.Intent\nimport android.content.pm.PackageManager\nimport android.net.Uri\nimport androidx.preference.PreferenceManager\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.animeinfo.ktx.fileName\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.FileWrapper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.database.CacheDB\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.pojos.ExplorerObject\nimport knf.kuma.pojos.QueueObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeenObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport xdroid.toaster.Toaster\n\n\nobject QueueManager {\n    suspend fun isInQueue(eid: String): Boolean {\n        return withContext(Dispatchers.IO) {\n            CacheDB.INSTANCE.queueDAO().isInQueue(eid)\n        }\n    }\n\n    fun add(uri: Uri, isFile: Boolean, chapter: AnimeObject.WebInfo.AnimeChapter?) {\n        if (chapter == null) return\n        doAsync {\n            CacheDB.INSTANCE.queueDAO().add(QueueObject(uri, isFile, chapter))\n            syncData { queue() }\n            Toaster.toast(\"Episodio añadido a cola\")\n        }\n    }\n\n    fun add(wrapper: FileWrapper<*>, dobject: DownloadObject?, isFile: Boolean, chapter: AnimeObject.WebInfo.AnimeChapter?) {\n        if (chapter == null) return\n        doAsync {\n            val file = wrapper.file() ?: wrapper.let { it.reset(); it.file() }\n            ?: dobject?.let { FileWrapper.fromFileName(it.file) } ?: return@doAsync\n            CacheDB.INSTANCE.queueDAO().add(QueueObject(Uri.fromFile(file), isFile, chapter))\n            syncData { queue() }\n            Toaster.toast(\"Episodio añadido a cola\")\n        }\n    }\n\n    fun remove(queueObject: QueueObject) {\n        doAsync {\n            CacheDB.INSTANCE.queueDAO().remove(queueObject)\n            syncData { queue() }\n        }\n    }\n\n    fun update(vararg objects: QueueObject) {\n        doAsync {\n            CacheDB.INSTANCE.queueDAO().update(*objects)\n            syncData { queue() }\n        }\n    }\n\n    fun remove(list: MutableList<QueueObject>) {\n        doAsync {\n            CacheDB.INSTANCE.queueDAO().remove(list)\n            syncData { queue() }\n        }\n    }\n\n    fun remove(eid: String?) {\n        if (eid == null) return\n        doAsync {\n            CacheDB.INSTANCE.queueDAO().removeByEID(eid)\n            syncData { queue() }\n        }\n    }\n\n    fun removeAll(aid: String) {\n        CacheDB.INSTANCE.queueDAO().removeByID(aid)\n    }\n\n    fun nuke() {\n        doAsync {\n            CacheDB.INSTANCE.queueDAO().nuke()\n            syncData {\n                queue()\n            }\n        }\n    }\n\n    internal fun startQueue(context: Context, list: List<QueueObject>) {\n        if (list.isNotEmpty()) {\n            AchievementManager.onPlayQueue(list.size)\n            markAllSeen(list)\n            if (PreferenceManager.getDefaultSharedPreferences(context).getString(\"player_type\", \"0\") == \"0\" || isMxInstalled(context) == null)\n                startQueueInternal(context, list)\n            else\n                startQueueExternal(context, list)\n        } else\n            Toaster.toast(\"La lista esta vacía\")\n    }\n\n    internal suspend fun startQueueDownloaded(context: Context?, list: List<ExplorerObject.FileDownObj>) {\n        if (context == null) return\n        if (list.isNotEmpty()) {\n            markAllSeenDownloaded(list)\n            if (PreferenceManager.getDefaultSharedPreferences(context).getString(\"player_type\", \"0\") == \"0\" || isMxInstalled(context) == null)\n                startQueueInternalDownloaded(context, list)\n            else\n                startQueueExternalDownloaded(context, list)\n        } else\n            Toaster.toast(\"La lista esta vacía\")\n    }\n\n    private fun startQueueInternal(context: Context, list: List<QueueObject>) {\n        val intent = PrefsUtil.getPlayerIntent()\n                .putExtra(\"isPlayList\", true)\n                .putExtra(\"playlist\", list[0].chapter.aid)\n                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n        context.startActivity(intent)\n    }\n\n    private fun startQueueInternalDownloaded(context: Context, list: List<ExplorerObject.FileDownObj>) {\n        doAsync {\n            for (file in list)\n                CacheDB.INSTANCE.queueDAO().add(\n                        QueueObject(\n                                FileAccessHelper.getFileUri(file.fileName),\n                                true,\n                                AnimeObject.WebInfo.AnimeChapter.fromDownloaded(file)))\n            val intent = PrefsUtil.getPlayerIntent()\n                    .putExtra(\"isPlayList\", true)\n                    .putExtra(\"playlist\", list[0].aid)\n                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n            context.startActivity(intent)\n        }\n    }\n\n    private fun startQueueExternal(context: Context, list: List<QueueObject>) {\n        val startUri = if (list[0].isFile) FileAccessHelper.getDataUri(list[0].chapter.fileName) else list[0].createUri()\n        val titles = QueueObject.getTitles(list)\n        val uris = QueueObject.uris(list)\n        uris[0] = startUri ?: Uri.EMPTY\n        val intent = Intent(Intent.ACTION_VIEW)\n                .setPackage(isMxInstalled(context))\n                .setDataAndType(startUri, \"video/mp4\")\n                .putExtra(\"title\", titles[0])\n                .putExtra(\"video_list_is_explicit\", true)\n                .putExtra(\"video_list\", uris)\n                .putExtra(\"video_list.name\", titles)\n                .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or\n                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION or\n                        Intent.FLAG_ACTIVITY_NEW_TASK)\n        context.startActivity(intent)\n    }\n\n    private fun startQueueExternalDownloaded(context: Context, list: List<ExplorerObject.FileDownObj>) {\n        val startUri = FileAccessHelper.getDataUri(list[0].fileName)\n        val titles = ExplorerObject.FileDownObj.getTitles(list)\n        val uris = ExplorerObject.FileDownObj.getUris(list)\n        uris[0] = startUri ?: Uri.EMPTY\n        val intent = Intent(Intent.ACTION_VIEW)\n                .setPackage(isMxInstalled(context))\n                .setDataAndType(startUri, \"video/mp4\")\n                .putExtra(\"title\", titles[0])\n                .putExtra(\"video_list_is_explicit\", true)\n                .putExtra(\"video_list\", uris)\n                .putExtra(\"video_list.name\", titles)\n                .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or\n                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION or\n                        Intent.FLAG_ACTIVITY_NEW_TASK)\n        context.startActivity(intent)\n    }\n\n    private fun isMxInstalled(context: Context): String? {\n        val pm = context.packageManager\n        try {\n            pm.getPackageInfo(\"com.mxtech.videoplayer.pro\", PackageManager.GET_ACTIVITIES)\n            return \"com.mxtech.videoplayer.pro\"\n        } catch (e: PackageManager.NameNotFoundException) {\n        }\n        try {\n            pm.getPackageInfo(\"com.mxtech.videoplayer.ad\", PackageManager.GET_ACTIVITIES)\n            return \"com.mxtech.videoplayer.ad\"\n        } catch (e: PackageManager.NameNotFoundException) {\n        }\n        return null\n    }\n\n    private fun markAllSeen(list: List<QueueObject>) {\n        if (list.isNotEmpty())\n            doAsync {\n                CacheDB.INSTANCE.seenDAO().addAll(list.map { SeenObject.fromChapter(it.chapter) })\n                CacheDB.INSTANCE.recordsDAO().add(RecordObject.fromChapter(list.last().chapter))\n                syncData {\n                    history()\n                    seen()\n                }\n            }\n    }\n\n    suspend fun markAllSeenDownloaded(list: List<ExplorerObject.FileDownObj>) {\n        if (list.isNotEmpty()){\n            CacheDB.INSTANCE.seenDAO().addAll(list.map { SeenObject.fromDownloaded(it) })\n            CacheDB.INSTANCE.recordsDAO().add(RecordObject.fromChapter(AnimeObject.WebInfo.AnimeChapter.fromDownloaded(list.last())))\n            syncData {\n                history()\n                seen()\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/queue/SimpleItemTouchHelperCallback.kt",
    "content": "package knf.kuma.queue\n\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.RecyclerView\n\nclass SimpleItemTouchHelperCallback internal constructor(private val mAdapter: ItemTouchHelperAdapter) : ItemTouchHelper.Callback() {\n\n    override fun isLongPressDragEnabled(): Boolean {\n        return false\n    }\n\n    override fun isItemViewSwipeEnabled(): Boolean {\n        return true\n    }\n\n    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {\n        val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN\n        val swipeFlags = ItemTouchHelper.START or ItemTouchHelper.END\n        return makeMovementFlags(dragFlags, swipeFlags)\n    }\n\n    override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {\n        mAdapter.onItemMove(viewHolder.adapterPosition, target.adapterPosition)\n        return true\n    }\n\n    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {\n        mAdapter.onItemDismiss(viewHolder.adapterPosition)\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/random/RandomActivity.kt",
    "content": "package knf.kuma.random\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.widget.Toolbar\nimport androidx.core.content.ContextCompat\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.swiperefreshlayout.widget.SwipeRefreshLayout\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.customview.customView\nimport com.github.stephenvinouze.materialnumberpickercore.MaterialNumberPicker\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.custom.BannerContainerView\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\n\nclass RandomActivity : GenericActivity(), SwipeRefreshLayout.OnRefreshListener {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    private val refreshLayout: SwipeRefreshLayout by bind(R.id.refresh)\n    val recyclerView: RecyclerView by bind(R.id.recycler)\n    private var adapter: RandomAdapter? = null\n    private var counter = 0\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_refresh\n        } else {\n            R.layout.recycler_refresh_grid\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(layout)\n        toolbar.title = \"Random\"\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        toolbar.setNavigationOnClickListener { finish() }\n        refreshLayout.setOnRefreshListener(this)\n        adapter = RandomAdapter(this)\n        recyclerView.verifyManager()\n        recyclerView.adapter = adapter\n        refreshLayout.isRefreshing = true\n        refreshLayout.setColorSchemeResources(EAHelper.getThemeColor(), EAHelper.getThemeColorLight(), R.color.colorPrimary)\n        refreshList()\n        lifecycleScope.launch(Dispatchers.IO) {\n            delay(1000)\n            find<BannerContainerView>(R.id.adContainer).implBanner(AdsType.RANDOM_BANNER, true)\n        }\n    }\n\n    private fun refreshList() {\n        counter++\n        if (counter >= 15)\n            AchievementManager.unlock(listOf(32))\n        doAsync {\n            val list = CacheDB.INSTANCE.animeDAO().getRandom(PrefsUtil.randomLimit)\n            doOnUI {\n                refreshLayout.isRefreshing = false\n                adapter?.update(list)\n                recyclerView.scheduleLayoutAnimation()\n            }\n        }\n    }\n\n    override fun onRefresh() {\n        refreshList()\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_random, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        val picker = MaterialNumberPicker(\n                this, 5, 100,\n                PrefsUtil.randomLimit,\n                ContextCompat.getColor(this, R.color.colorAccent),\n                ContextCompat.getColor(this, R.color.textPrimary),\n                resources.getDimensionPixelSize(R.dimen.num_picker))\n        MaterialDialog(this@RandomActivity).safeShow {\n            title(text = \"Numero de resultados\")\n            customView(view = picker, scrollable = false)\n            positiveButton(text = \"OK\") {\n                PrefsUtil.randomLimit = picker.value\n                refreshLayout.post { refreshLayout.isRefreshing = true }\n                refreshList()\n            }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, RandomActivity::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/random/RandomActivityMaterial.kt",
    "content": "package knf.kuma.random\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.app.AlertDialog\nimport androidx.appcompat.widget.Toolbar\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.swiperefreshlayout.widget.SwipeRefreshLayout\nimport biz.kasual.materialnumberpicker.MaterialNumberPicker\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.inflate\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.custom.BannerContainerView\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\nclass RandomActivityMaterial : GenericActivity(), SwipeRefreshLayout.OnRefreshListener {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    private val refreshLayout: SwipeRefreshLayout by bind(R.id.refresh)\n    val recyclerView: RecyclerView by bind(R.id.recycler)\n    private var adapter: RandomAdapterMaterial? = null\n    private var counter = 0\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_refresh_material\n        } else {\n            R.layout.recycler_refresh_grid_material\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(layout)\n        toolbar.title = \"Random\"\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        toolbar.setNavigationOnClickListener { finish() }\n        refreshLayout.setOnRefreshListener(this)\n        adapter = RandomAdapterMaterial(this)\n        recyclerView.verifyManager()\n        recyclerView.adapter = adapter\n        refreshLayout.isRefreshing = true\n        refreshLayout.setColorSchemeResources(EAHelper.getThemeColor(), EAHelper.getThemeColorLight(), R.color.colorPrimary)\n        refreshList()\n        lifecycleScope.launch(Dispatchers.IO) {\n            delay(1000)\n            findViewById<BannerContainerView>(R.id.adContainer).implBanner(AdsType.RANDOM_BANNER, true)\n        }\n    }\n\n    private fun refreshList() {\n        counter++\n        if (counter >= 15)\n            AchievementManager.unlock(listOf(32))\n        lifecycleScope.launch(Dispatchers.IO) {\n            val list = CacheDB.INSTANCE.animeDAO().getRandom(PrefsUtil.randomLimit)\n            doOnUI {\n                refreshLayout.isRefreshing = false\n                adapter?.update(list)\n                recyclerView.scheduleLayoutAnimation()\n            }\n        }\n    }\n\n    override fun onRefresh() {\n        refreshList()\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_random, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        AlertDialog.Builder(this).apply {\n            setTitle(\"Numero de resultados\")\n            val view = inflate(this@RandomActivityMaterial, R.layout.dialog_random_picker)\n            val picker = view.findViewById<MaterialNumberPicker>(R.id.picker)\n            picker.value = PrefsUtil.randomLimit\n            setView(view)\n            setPositiveButton(\"OK\") { _, _ ->\n                PrefsUtil.randomLimit = picker.value\n                refreshLayout.post { refreshLayout.isRefreshing = true }\n                refreshList()\n            }\n        }.show()\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, RandomActivityMaterial::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/random/RandomAdapter.kt",
    "content": "package knf.kuma.random\n\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.commons.notSameContent\n\ninternal class RandomAdapter(private val activity: Activity) : RecyclerView.Adapter<RandomAdapter.RandomItem>() {\n    private var list: List<RandomObject> = ArrayList()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_fav\n        } else {\n            R.layout.item_fav_grid\n        }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RandomItem {\n        return RandomItem(LayoutInflater.from(activity).inflate(layout, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: RandomItem, position: Int) {\n        val animeObject = list[position]\n        holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n        holder.title.text = animeObject.name\n        holder.type.text = animeObject.type\n        holder.cardView.setOnClickListener { ActivityAnime.open(activity, animeObject, holder.imageView, false, true) }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(list: List<RandomObject>) {\n        if (this.list notSameContent list) {\n            this.list = list\n            notifyDataSetChanged()\n        }\n    }\n\n    internal class RandomItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val type: TextView by itemView.bind(R.id.type)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/random/RandomAdapterMaterial.kt",
    "content": "package knf.kuma.random\n\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.commons.notSameContent\n\ninternal class RandomAdapterMaterial(private val activity: Activity) : RecyclerView.Adapter<RandomAdapterMaterial.RandomItem>() {\n    private var list: List<RandomObject> = ArrayList()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_fav_material\n        } else {\n            R.layout.item_fav_grid_material\n        }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RandomItem {\n        return RandomItem(LayoutInflater.from(activity).inflate(layout, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: RandomItem, position: Int) {\n        val animeObject = list[position]\n        holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n        holder.title.text = animeObject.name\n        holder.type.text = animeObject.type\n        holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(activity, animeObject, holder.imageView, false, true) }\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    fun update(list: List<RandomObject>) {\n        if (this.list notSameContent list) {\n            this.list = list\n            notifyDataSetChanged()\n        }\n    }\n\n    internal class RandomItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val type: TextView by itemView.bind(R.id.type)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/random/RandomObject.kt",
    "content": "package knf.kuma.random\r\n\r\nimport knf.kuma.search.SearchObject\r\n\r\nclass RandomObject : SearchObject() {\r\n    var type = \"\"\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentFragment.kt",
    "content": "package knf.kuma.recents\n\nimport android.content.pm.ActivityInfo\nimport android.os.Bundle\nimport android.util.Log\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.fragment.app.viewModels\nimport androidx.swiperefreshlayout.widget.SwipeRefreshLayout\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.custom.BannerContainerView\nimport knf.kuma.home.HomeFragment\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.recents.viewholders.RecyclerRefreshHolder\nimport knf.kuma.videoservers.FileActions\nimport knf.kuma.videoservers.ServersFactory\nimport org.jetbrains.anko.support.v4.find\n\nclass RecentFragment : BottomFragment(), SwipeRefreshLayout.OnRefreshListener {\n    private val viewModel: RecentsViewModel by viewModels()\n    private var holder: RecyclerRefreshHolder? = null\n    private var adapter: RecentsAdapter? = null\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        viewModel.dbLiveData.observe(viewLifecycleOwner) { objects ->\n            holder?.setError(objects.isEmpty())\n            holder?.setRefreshing(false)\n            adapter?.updateList(objects) { holder?.recyclerView?.scheduleLayoutAnimation() }\n            scrollByKey(objects)\n        }\n        updateList()\n        if (!PrefsUtil.isNativeAdsEnabled)\n            find<BannerContainerView>(R.id.adContainer).implBanner(AdsType.RECENT_BANNER)\n    }\n\n    private fun scrollByKey(list: List<RecentObject>) {\n        if (list.isEmpty()) return\n        val initial = arguments?.getInt(\"initial\", -1) ?: -1\n        if (initial == -1) return\n        val find = list.find { it.key == initial } ?: return\n        holder?.scrollTo(list.indexOf(find))\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(R.layout.recycler_refresh_fragment, container, false)\n        holder = RecyclerRefreshHolder(view).also {\n            it.refreshLayout.setOnRefreshListener(this@RecentFragment)\n            adapter = RecentsAdapter(this@RecentFragment, it.recyclerView)\n            it.recyclerView.adapter = adapter\n            it.setRefreshing(true)\n        }\n        EAHelper.enter1(\"R\")\n        return view\n    }\n\n    override fun onRefresh() {\n        updateList()\n    }\n\n    private fun updateList() {\n        if (!Network.isConnected) {\n            holder?.setRefreshing(false)\n        } else {\n            viewModel.reload()\n        }\n    }\n\n    override fun onReselect() {\n        EAHelper.enter1(\"R\")\n        holder?.scrollToTop()\n    }\n\n\n    override fun onDestroyView() {\n        super.onDestroyView()\n        ServersFactory.clear()\n        FileActions.reset()\n        (activity as? AppCompatActivity)?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n    }\n\n    companion object {\n        fun get(initialKey: Int): BottomFragment {\n            val fragment = RecentFragment()\n            val bundle = Bundle()\n            bundle.putInt(\"initial\", initialKey.also { Log.e(\"Recent\", \"Add argument key: $it\") })\n            fragment.arguments = bundle\n            return fragment\n        }\n\n        fun get(): BottomFragment {\n            return if (PrefsUtil.useHome)\n                HomeFragment()\n            else\n                RecentFragment()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentModel.kt",
    "content": "package knf.kuma.recents\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.net.Uri\r\nimport androidx.core.text.isDigitsOnly\r\nimport androidx.recyclerview.widget.DiffUtil\r\nimport androidx.room.Entity\r\nimport androidx.room.Ignore\r\nimport androidx.room.PrimaryKey\r\nimport com.google.errorprone.annotations.Keep\r\nimport knf.kuma.R\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.commons.DesignUtils\r\nimport knf.kuma.commons.FileWrapper\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.PatternUtil.getAnimeUrl\r\nimport knf.kuma.commons.PatternUtil.getFileName\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.PrefsUtil.saveWithName\r\nimport knf.kuma.commons.distinct\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.database.CacheDBWrap\r\nimport knf.kuma.database.dao.SeenDAO\r\nimport knf.kuma.pojos.DownloadObject\r\nimport knf.kuma.pojos.SeenObject\r\nimport kotlinx.coroutines.CoroutineScope\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport org.jsoup.Jsoup\r\nimport org.jsoup.nodes.Element\r\nimport pl.droidsonroids.jspoon.ElementConverter\r\nimport pl.droidsonroids.jspoon.annotation.Selector\r\nimport kotlin.math.abs\r\n\r\n@Entity\r\n@Keep\r\nopen class RecentModel {\r\n\r\n    @JvmField\r\n    @PrimaryKey\r\n    var key: Int = -1\r\n\r\n    @JvmField\r\n    @Selector(value = \"img[src]\", attr = \"src\", format = \"/(\\\\d+)\\\\.\\\\w+\")\r\n    var aid: String = \"0\"\r\n\r\n    @JvmField\r\n    @Selector(value = \".Title\")\r\n    var name: String = \"\"\r\n\r\n    @JvmField\r\n    @Selector(\".Capi\")\r\n    var chapter: String = \"\"\r\n\r\n    @JvmField\r\n    @Selector(value = \"a\", converter = AFixer::class)\r\n    var chapterUrl: String = \"\"\r\n\r\n    @JvmField\r\n    @Selector(value = \"img[src]\", converter = ImageFixer::class)\r\n    var img: String = \"\"\r\n\r\n    @Ignore\r\n    lateinit var extras: RecentExtras\r\n\r\n    @Ignore\r\n    lateinit var state: RecentState\r\n\r\n    fun generate(element: Element) {\r\n        aid = element.select(\"img[src]\").attr(\"src\").let {\r\n            Regex(\"/(\\\\d+)\\\\.\\\\w+\").find(it)?.groupValues?.get(1) ?: \"0\"\r\n        }\r\n        name = element.select(\".Title\").text()\r\n        chapter = element.select(\".Capi\").text()\r\n        chapterUrl = element.select(\"a\").attr(\"href\")\r\n        img = element.select(\"img[src]\").attr(\"src\")\r\n    }\r\n\r\n    fun prepare() {\r\n        if (!aid.isDigitsOnly())\r\n            aid = \"0\"\r\n        if (!::extras.isInitialized)\r\n            extras = RecentExtras(this)\r\n        if (!::state.isInitialized)\r\n            state = RecentState(this)\r\n    }\r\n\r\n    val isNew: Boolean get() = chapter.matches(\"^.* [10]$\".toRegex())\r\n\r\n    override fun equals(other: Any?): Boolean = other is RecentModel && other.chapter == chapter && other.name == name && other.aid == aid && other.key == key\r\n    override fun hashCode(): Int = name.hashCode() + chapter.hashCode()\r\n\r\n    companion object {\r\n        val DIFF = object : DiffUtil.ItemCallback<RecentModel>() {\r\n            override fun areItemsTheSame(oldItem: RecentModel, newItem: RecentModel): Boolean =\r\n                    oldItem::class == newItem::class &&\r\n                            if (oldItem is RecentModelAd)\r\n                                oldItem.id == (newItem as RecentModelAd).id\r\n                            else\r\n                                oldItem.extras.eid == newItem.extras.eid\r\n\r\n            override fun areContentsTheSame(oldItem: RecentModel, newItem: RecentModel): Boolean =\r\n                    if (oldItem !is RecentModelAd) oldItem == newItem else true\r\n        }\r\n    }\r\n}\r\n\r\nclass RecentExtras(model: RecentModel) {\r\n    val eid: String by lazy { abs(\"${model.aid}${model.chapter}\".hashCode()).toString() }\r\n    val isNewChapter: Boolean by lazy { model.chapter.matches(\"^.* [10]$\".toRegex()) }\r\n    val animeUrl: String by lazy { getAnimeUrl(model.chapterUrl, model.aid) }\r\n    val filePath: String by lazy {\r\n        if (saveWithName) \"$\" + getFileName(model.chapterUrl) else \"$\" + model.aid + \"-\" + model.chapter.substring(model.chapter.lastIndexOf(\" \") + 1) + \".mp4\"\r\n    }\r\n    val fileName: String by lazy { eid + filePath }\r\n    val chapterTitle: String by lazy { model.name + model.chapter.substring(model.chapter.lastIndexOf(\" \")) }\r\n    val fileWrapper: FileWrapper<*> by lazy { FileWrapper.create(filePath) }\r\n}\r\n\r\nclass RecentState(val model: RecentModel) {\r\n    var isFavorite = CacheDB.INSTANCE.favsDAO().isFav(model.aid.toInt())\r\n    val favoriteLive = CacheDB.INSTANCE.favsDAO().isFavLive(model.aid.toInt()).distinct\r\n    var isSeen = CacheDB.INSTANCE.seenDAO().chapterIsSeen(model.aid, model.chapter)\r\n    val seenLive = CacheDB.INSTANCE.seenDAO().chapterIsSeenLive(model.aid, model.chapter).distinct\r\n    var downloadObject: DownloadObject? = CacheDBWrap.INSTANCE.downloadsDAO().getByEid(model.extras.eid)\r\n    var isDeleting = false\r\n    val downloadLive = CacheDB.INSTANCE.downloadsDAO().getLiveByEid(model.extras.eid)\r\n    var isDownloaded: Boolean\r\n        get() = model.extras.fileWrapper.exist\r\n        set(value) {\r\n            model.extras.fileWrapper.exist = value\r\n        }\r\n    val checkIsDownloaded: Boolean get() = model.extras.fileWrapper.existForced()\r\n    val canPlay: Boolean get() = downloadObject?.isDownloadingOrPaused == false && checkIsDownloaded\r\n}\r\n\r\n@Keep\r\nclass RecentsPage {\r\n    @Selector(\"ul.ListEpisodios li:not(article), ul.List-Episodes li:not(article)\")\r\n    var list: List<RecentModel> = emptyList()\r\n\r\n    fun create(html: String): RecentsPage {\r\n        val doc = Jsoup.parse(html, \"https://www3.animeflv.net\")\r\n        val episodes = doc.select(\"ul.ListEpisodios li:not(article), ul.List-Episodes li:not(article)\")\r\n        list = episodes.map {\r\n            RecentModel().apply {\r\n                generate(it)\r\n            }\r\n        }\r\n        return this\r\n    }\r\n}\r\n\r\nclass AFixer : ElementConverter<String> {\r\n    override fun convert(node: Element, selector: Selector): String {\r\n        return \"https://www3.animeflv.net${node.attr(\"href\")}\"\r\n    }\r\n}\r\n\r\nclass ImageFixer : ElementConverter<String> {\r\n    override fun convert(node: Element, selector: Selector): String {\r\n        return \"https://www3.animeflv.net${node.attr(\"src\")}\"\r\n    }\r\n}\r\n\r\nfun RecentModel.toggleSeen(scope: CoroutineScope, seenDAO: SeenDAO) {\r\n    scope.launch(Dispatchers.IO) {\r\n        if (!state.isSeen)\r\n            seenDAO.addChapter(SeenObject.fromRecentModel(this@toggleSeen))\r\n        else\r\n            seenDAO.deleteChapter(aid, chapter)\r\n        syncData { seen() }\r\n    }\r\n}\r\n\r\nval RecentModel.menuHideList: List<Int>\r\n    get() = mutableListOf<Int>().apply {\r\n        if (PrefsUtil.recentActionType == \"0\")\r\n            add(R.id.streaming)\r\n        if (PrefsUtil.recentActionType == \"1\" || state.downloadObject?.isDownloadingOrPaused == true || state.canPlay)\r\n            add(R.id.download)\r\n        if (state.isDeleting || !state.canPlay)\r\n            add(R.id.delete)\r\n    }\r\n\r\nfun RecentModel.openInfo(context: Context) {\r\n    context.startActivity(Intent(context, DesignUtils.infoClass).apply {\r\n        data = Uri.parse(this@openInfo.extras.animeUrl)\r\n        putExtra(\"title\", name)\r\n        putExtra(\"img\", PatternUtil.getCover(aid))\r\n    })\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentModelAd.kt",
    "content": "package knf.kuma.recents\r\n\r\n//import com.google.android.gms.ads.nativead.NativeAd\r\n\r\ndata class RecentModelAd(val id: Int/*, val unifiedNativeAd: NativeAd*/) : RecentModel()"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentModelCh.kt",
    "content": "package knf.kuma.recents\r\n\r\ndata class RecentModelCh(\r\n    val name: String,\r\n    val chapter: String,\r\n    val url: String,\r\n    val aid: String,\r\n    val eid: String\r\n)"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentModelsAdapter.kt",
    "content": "package knf.kuma.recents\r\n\r\n//import com.google.android.gms.ads.nativead.NativeAdView\r\nimport android.annotation.SuppressLint\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport android.widget.ImageView\r\nimport android.widget.TextView\r\nimport androidx.core.view.isVisible\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.lifecycle.LifecycleOwner\r\nimport androidx.lifecycle.Observer\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.recyclerview.widget.ListAdapter\r\nimport androidx.recyclerview.widget.RecyclerView.ViewHolder\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\r\nimport com.google.android.material.chip.Chip\r\nimport com.google.android.material.imageview.ShapeableImageView\r\nimport com.google.android.material.progressindicator.CircularProgressIndicator\r\nimport knf.kuma.R\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.cast.CastMedia\r\nimport knf.kuma.commons.CastUtil\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.inflate\r\nimport knf.kuma.commons.isFullMode\r\nimport knf.kuma.commons.isVisibleAnimate\r\nimport knf.kuma.commons.load\r\nimport knf.kuma.commons.onClickMenu\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.download.DownloadManagerCentral\r\nimport knf.kuma.download.FileAccessHelper\r\nimport knf.kuma.pojos.DownloadObject\r\nimport knf.kuma.pojos.RecordObject\r\nimport knf.kuma.pojos.SeenObject\r\nimport knf.kuma.queue.QueueManager\r\nimport knf.kuma.videoservers.FileActions\r\nimport kotlinx.coroutines.CoroutineScope\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.Job\r\nimport kotlinx.coroutines.isActive\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport org.jetbrains.anko.find\r\nimport org.jetbrains.anko.sdk27.coroutines.onClick\r\nimport java.util.Locale\r\n\r\nclass RecentModelsAdapter(private val fragment: Fragment) : ListAdapter<RecentModel, ViewHolder>(RecentModel.DIFF) {\r\n\r\n    private val lifecycleScope = fragment.lifecycleScope\r\n    private val chaptersDAO by lazy { CacheDB.INSTANCE.seenDAO() }\r\n    private val recordsDAO by lazy { CacheDB.INSTANCE.recordsDAO() }\r\n    private var adsList = emptyList<RecentModelAd>()\r\n\r\n    override fun getItemId(position: Int): Long = getItem(position).let {\r\n        if (it is RecentModelAd)\r\n            it.id.toLong()\r\n        else\r\n            it.hashCode().toLong()\r\n    }\r\n\r\n    override fun getItemViewType(position: Int): Int = getItem(position).let {\r\n        if (it is RecentModelAd)\r\n            0\r\n        else\r\n            1\r\n    }\r\n\r\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =\r\n            if (viewType == 0)\r\n                AdsViewHolder(fragment.lifecycleScope, parent.inflate(R.layout.item_ad_recents_material))\r\n            else\r\n                ModelsViewHolder(fragment.viewLifecycleOwner, parent.inflate(R.layout.item_recents_material))\r\n\r\n    override fun onBindViewHolder(holder: ViewHolder, position: Int) {\r\n        val item = getItem(position)\r\n        if (holder is ModelsViewHolder) {\r\n            holder.apply {\r\n                image.load(PatternUtil.getCover(item.aid))\r\n                chapter.text = item.chapter\r\n                name.text = item.name\r\n                newIndicator.isVisible = item.extras.isNewChapter && !item.state.isFavorite\r\n                seenIndicator.isVisible = item.state.isSeen\r\n                favIndicator.isVisible = item.state.isFavorite\r\n                setUp(item)\r\n                if (isFullMode)\r\n                    actionMenu.onClickMenu(R.menu.menu_download_info, true, { item.menuHideList }) {\r\n                        when (it.itemId) {\r\n                            R.id.download -> {\r\n                                FileActions.download(\r\n                                    fragment.requireContext(),\r\n                                    fragment.viewLifecycleOwner,\r\n                                    item,\r\n                                    fragment.view\r\n                                ) { state, _ ->\r\n                                    if (state == FileActions.CallbackState.START_DOWNLOAD)\r\n                                        item.state.isDownloaded = true\r\n                                }\r\n                            }\r\n                            R.id.streaming -> {\r\n                                FileActions.stream(\r\n                                    fragment.requireContext(),\r\n                                    fragment.viewLifecycleOwner,\r\n                                    item,\r\n                                    fragment.view\r\n                                ) { state, extra ->\r\n                                    when (state) {\r\n                                        FileActions.CallbackState.START_STREAM -> {\r\n                                            setAsSeen(item)\r\n                                        }\r\n                                        FileActions.CallbackState.START_CAST -> {\r\n                                            CastUtil.get().play(fragment.requireView(), CastMedia.create(item, extra as? String))\r\n                                            setAsSeen(item)\r\n                                        }\r\n                                        else -> {\r\n                                        }\r\n                                    }\r\n                                }\r\n                            }\r\n                            R.id.delete -> {\r\n                                MaterialDialog(fragment.requireContext()).safeShow {\r\n                                    lifecycleOwner(fragment.viewLifecycleOwner)\r\n                                    message(text = \"¿Eliminar el ${item.chapter.lowercase(Locale.ENGLISH)} de ${item.name}?\")\r\n                                    positiveButton(text = \"CONFIRMAR\") {\r\n                                        GlobalScope.launch(Dispatchers.IO) {\r\n                                            fragment.lifecycleScope.launch(Dispatchers.Main) {\r\n                                                item.state.isDownloaded = false\r\n                                                this@apply.downloadedChip.isVisibleAnimate = false\r\n                                            }\r\n                                            item.state.isDeleting = true\r\n                                            FileAccessHelper.deletePath(item.extras.filePath, false)\r\n                                            item.state.isDeleting = false\r\n                                            item.state.checkIsDownloaded\r\n                                            DownloadManagerCentral.cancel(item.extras.eid)\r\n                                            QueueManager.remove(item.extras.eid)\r\n                                        }\r\n                                    }\r\n                                    negativeButton(text = \"CANCELAR\")\r\n                                }\r\n                            }\r\n                            R.id.info -> {\r\n                                item.openInfo(fragment.requireContext())\r\n                            }\r\n                        }\r\n                    }\r\n                else\r\n                    actionMenu.isVisible = false\r\n                root.setOnClickListener {\r\n                    if (!isFullMode) {\r\n                        item.openInfo(fragment.requireContext())\r\n                        return@setOnClickListener\r\n                    }\r\n                    if (item.state.isDownloaded) {\r\n                        if (CastUtil.get().connected())\r\n                            CastUtil.get().play(fragment.requireView(), CastMedia.create(item))\r\n                        else\r\n                            FileActions.startPlay(\r\n                                fragment.requireContext(),\r\n                                item.extras.chapterTitle,\r\n                                item.extras.fileWrapper.name()\r\n                            )\r\n                        setAsSeen(item)\r\n                    } else {\r\n                        val callback: (FileActions.CallbackState, Any?) -> Unit = { state, extra ->\r\n                            when (state) {\r\n                                FileActions.CallbackState.START_STREAM -> {\r\n                                    setAsSeen(item)\r\n                                }\r\n                                FileActions.CallbackState.START_CAST -> {\r\n                                    CastUtil.get().play(fragment.requireView(), CastMedia.create(item, extra as? String))\r\n                                    setAsSeen(item)\r\n                                }\r\n                                FileActions.CallbackState.START_DOWNLOAD -> {\r\n                                    item.state.isDownloaded = true\r\n                                }\r\n                                else -> {\r\n                                }\r\n                            }\r\n                        }\r\n                        if (PrefsUtil.recentActionType == \"0\")\r\n                            FileActions.stream(fragment.requireContext(), fragment.viewLifecycleOwner, item, fragment.view, callback)\r\n                        else\r\n                            FileActions.download(fragment.requireContext(), fragment.viewLifecycleOwner, item, fragment.view, callback)\r\n                    }\r\n                }\r\n                root.setOnLongClickListener {\r\n                    item.toggleSeen(lifecycleScope, chaptersDAO)\r\n                    true\r\n                }\r\n            }\r\n        } else if (holder is AdsViewHolder) {\r\n            holder.setAd(item as RecentModelAd)\r\n        }\r\n    }\r\n\r\n    private fun setAsSeen(item: RecentModel) {\r\n        fragment.lifecycleScope.launch(Dispatchers.IO) {\r\n            chaptersDAO.addChapter(SeenObject.fromRecentModel(item))\r\n            recordsDAO.add(RecordObject.fromRecentModel(item))\r\n            syncData {\r\n                history()\r\n                seen()\r\n            }\r\n        }\r\n    }\r\n\r\n    override fun onViewRecycled(holder: ViewHolder) {\r\n        super.onViewRecycled(holder)\r\n        if (holder is ModelsViewHolder)\r\n            holder.recycle()\r\n    }\r\n\r\n    fun updateList(list: List<RecentModel>, aList: List<RecentModelAd> = adsList, callback: () -> Unit = {}) {\r\n        fragment.lifecycleScope.launch(Dispatchers.IO) {\r\n            list.forEach { if (it !is RecentModelAd) it.prepare() }\r\n            val fList = list.toMutableList()\r\n            if (list.isNotEmpty() && aList.isNotEmpty()) {\r\n                adsList = aList\r\n                fList.add(0, adsList[0])\r\n                if (adsList.size >= 2)\r\n                    fList.add(8, adsList[1])\r\n                if (adsList.size >= 3)\r\n                    fList.add(16, adsList[2])\r\n            }\r\n            launch(Dispatchers.Main) {\r\n                submitList(fList)\r\n                callback()\r\n            }\r\n        }\r\n    }\r\n\r\n    fun hasAds(): Boolean = adsList.isNotEmpty()\r\n\r\n    class ModelsViewHolder(private val lifecycleOwner: LifecycleOwner, view: View) : ViewHolder(view) {\r\n        val root: View = itemView.find(R.id.root)\r\n        val image: ImageView = itemView.find(R.id.image)\r\n        val chapter: TextView = itemView.find(R.id.chapter)\r\n        val name: TextView = itemView.find(R.id.name)\r\n        val newIndicator: ImageView = itemView.find(R.id.newIndicator)\r\n        val seenIndicator: View = itemView.find(R.id.seenIndicator)\r\n        val favIndicator: ImageView = itemView.find(R.id.favIndicator)\r\n        val actionMenu: View = itemView.find(R.id.actionMenu)\r\n        val downloadedChip: Chip = itemView.find(R.id.downloadedChip)\r\n        private val layDownloading: View = itemView.find(R.id.layDownloading)\r\n        private val progressIndicator: CircularProgressIndicator = itemView.find(R.id.progressIndicator)\r\n        private val actionCancel: View = itemView.find(R.id.actionCancel)\r\n\r\n        private lateinit var state: RecentState\r\n        private var checkJob: Job? = null\r\n        private val favoriteObserver = Observer<Boolean> {\r\n            if (state.isFavorite == it) return@Observer\r\n            state.isFavorite = it\r\n            favIndicator.isVisibleAnimate = it\r\n            newIndicator.isVisible = !it && state.isFavorite\r\n        }\r\n        private val seenObserver = Observer<Int> {\r\n            if (state.isSeen == it > 0) return@Observer\r\n            state.isSeen = it > 0\r\n            seenIndicator.isVisibleAnimate = it > 0\r\n        }\r\n        private val downloadObserver = Observer<DownloadObject?> {\r\n            if (state.downloadObject == it) return@Observer\r\n            state.downloadObject = it\r\n            if (it != null && it.isDownloadingOrPaused) {\r\n                if (!layDownloading.isVisible)\r\n                    layDownloading.isVisibleAnimate = true\r\n                when (it.state) {\r\n                    DownloadObject.DOWNLOADING, DownloadObject.PAUSED -> {\r\n                        progressIndicator.isVisible = false\r\n                        progressIndicator.isIndeterminate = false\r\n                        progressIndicator.isVisible = true\r\n                        if (it.getEta() == -2L || PrefsUtil.downloaderType == 0) {\r\n                            var progress = it.progress\r\n                            if (it.getEta() == -2L && PrefsUtil.downloaderType != 0) {\r\n                                progressIndicator.max = 200\r\n                                progress += 100\r\n                            } else {\r\n                                progressIndicator.max = 100\r\n                            }\r\n                            progressIndicator.setProgressCompat(progress, true)\r\n                        } else {\r\n                            progressIndicator.max = 200\r\n                            progressIndicator.setProgressCompat(it.progress, true)\r\n                        }\r\n                    }\r\n                    DownloadObject.PENDING -> {\r\n                        progressIndicator.isVisible = false\r\n                        progressIndicator.isIndeterminate = true\r\n                        progressIndicator.isVisible = true\r\n                    }\r\n                }\r\n            } else {\r\n                lifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {\r\n                    if (layDownloading.isVisible)\r\n                        layDownloading.isVisibleAnimate = false\r\n                    state.checkIsDownloaded\r\n                    if (withContext(Dispatchers.IO) { state.canPlay }) {\r\n                        if (!downloadedChip.isVisible)\r\n                            downloadedChip.isVisibleAnimate = true\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        fun setUp(item: RecentModel) {\r\n            this.state = item.state\r\n            state.favoriteLive.observe(lifecycleOwner, favoriteObserver)\r\n            state.seenLive.observe(lifecycleOwner, seenObserver)\r\n            state.downloadLive.observe(lifecycleOwner, downloadObserver)\r\n            setUpDownloadIndicators(item)\r\n        }\r\n\r\n        private fun setUpDownloadIndicators(item: RecentModel) {\r\n            checkJob = GlobalScope.launch(Dispatchers.Main) {\r\n                layDownloading.isVisible = false\r\n                downloadedChip.isVisible = false\r\n                when {\r\n                    state.downloadObject?.isDownloadingOrPaused == true -> {\r\n                        if (!isActive) return@launch\r\n                        layDownloading.isVisible = true\r\n                        downloadedChip.isVisible = false\r\n                        state.downloadObject?.let {\r\n                            when (it.state) {\r\n                                DownloadObject.DOWNLOADING, DownloadObject.PAUSED -> {\r\n                                    progressIndicator.isVisible = false\r\n                                    progressIndicator.isIndeterminate = false\r\n                                    progressIndicator.isVisible = true\r\n                                    if (it.getEta() == -2L || PrefsUtil.downloaderType == 0) {\r\n                                        var progress = it.progress\r\n                                        if (it.getEta() == -2L && PrefsUtil.downloaderType != 0) {\r\n                                            progressIndicator.max = 200\r\n                                            progress += 100\r\n                                        } else {\r\n                                            progressIndicator.max = 100\r\n                                        }\r\n                                        progressIndicator.setProgressCompat(progress, true)\r\n                                    } else {\r\n                                        progressIndicator.max = 200\r\n                                        progressIndicator.setProgressCompat(it.progress, true)\r\n                                    }\r\n                                }\r\n                                DownloadObject.PENDING -> {\r\n                                    progressIndicator.isVisible = false\r\n                                    progressIndicator.isIndeterminate = true\r\n                                    progressIndicator.isVisible = true\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                    withContext(Dispatchers.IO) { state.isDownloaded } -> {\r\n                        if (!isActive) return@launch\r\n                        layDownloading.isVisible = false\r\n                        downloadedChip.isVisible = true\r\n                    }\r\n                    else -> {\r\n                        if (!isActive) return@launch\r\n                        layDownloading.isVisible = false\r\n                        downloadedChip.isVisible = false\r\n                    }\r\n                }\r\n            }\r\n            actionCancel.onClick {\r\n                MaterialDialog(itemView.context).safeShow {\r\n                    lifecycleOwner(lifecycleOwner)\r\n                    message(text = \"¿Deseas cancelar esta descarga?\")\r\n                    positiveButton(text = \"confirmar\") {\r\n                        item.state.isDownloaded = false\r\n                        lifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {\r\n                            item.state.isDownloaded = false\r\n                            FileAccessHelper.deletePath(item.extras.filePath, true)\r\n                            DownloadManagerCentral.cancel(item.extras.eid)\r\n                            QueueManager.remove(item.extras.eid)\r\n                        }\r\n                    }\r\n                    negativeButton(text = \"abortar\")\r\n                }\r\n            }\r\n        }\r\n\r\n        fun recycle() {\r\n            checkJob?.cancel()\r\n            if (!::state.isInitialized) return\r\n            state.favoriteLive.removeObserver(favoriteObserver)\r\n            state.seenLive.removeObserver(seenObserver)\r\n            state.downloadLive.removeObserver(downloadObserver)\r\n        }\r\n    }\r\n\r\n    class AdsDealsViewHolder(private val scope: CoroutineScope, view: View): ViewHolder(view)\r\n\r\n    class AdsViewHolder(private val scope: CoroutineScope, view: View) : ViewHolder(view) {\r\n        //private val nativeAdView: NativeAdView = itemView.find(R.id.nativeAdView)\r\n        private val iconV: ShapeableImageView = itemView.find(R.id.icon)\r\n        /*private val primary: TextView = itemView.find(R.id.primary)\r\n        private val secondary: TextView = itemView.find(R.id.secondary)\r\n        private val cta: Chip = itemView.find(R.id.cta)*/\r\n\r\n        /*init {\r\n            nativeAdView.apply {\r\n                iconView = iconV\r\n                headlineView = primary\r\n                bodyView = secondary\r\n                callToActionView = cta\r\n            }\r\n        }*/\r\n\r\n        @SuppressLint(\"DefaultLocale\")\r\n        fun setAd(modelAd: RecentModelAd) {\r\n            /*modelAd.unifiedNativeAd.apply {\r\n                scope.launch(Dispatchers.Main) {\r\n                    if (icon == null)\r\n                        iconV.setImageDrawable(\r\n                            ColorDrawable(\r\n                                ContextCompat.getColor(\r\n                                    App.context,\r\n                                    EAHelper.getThemeColorLight()\r\n                                )\r\n                            )\r\n                        )\r\n                    else {\r\n                        iconV.setImageDrawable(icon!!.drawable)\r\n                    }\r\n                    primary.text = headline\r\n                    secondary.text = body\r\n                    if (callToAction != null) {\r\n                        cta.text = callToAction!!.lowercase(Locale.getDefault())\r\n                            .replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }\r\n                    }\r\n                    nativeAdView.setNativeAd(modelAd.unifiedNativeAd)\r\n                }\r\n            }*/\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentModelsFragment.kt",
    "content": "package knf.kuma.recents\n\nimport android.content.pm.ActivityInfo\nimport android.os.Bundle\nimport android.util.Log\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.fragment.app.viewModels\nimport androidx.lifecycle.lifecycleScope\nimport androidx.swiperefreshlayout.widget.SwipeRefreshLayout\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.AdsUtils\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.noCrash\nimport knf.kuma.custom.BannerContainerView\nimport knf.kuma.home.HomeFragmentMaterial\nimport knf.kuma.recents.viewholders.RecyclerRefreshHolder\nimport knf.kuma.videoservers.FileActions\nimport knf.kuma.videoservers.ServersFactory\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.support.v4.find\n\nclass RecentModelsFragment : BottomFragment(), SwipeRefreshLayout.OnRefreshListener {\n    private val viewModel: RecentModelsViewModel by viewModels()\n    private val holder: RecyclerRefreshHolder by lazy {\n        RecyclerRefreshHolder(requireView()).also {\n            it.refreshLayout.setOnRefreshListener(this@RecentModelsFragment)\n            it.recyclerView.adapter = adapter\n        }\n    }\n    private val adapter: RecentModelsAdapter by lazy { RecentModelsAdapter(this) }\n    private var isFirstLoad = true\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        lifecycleScope.launch(Dispatchers.Main) {\n            viewModel.dbLiveData.collectLatest { objects ->\n                holder.setError(objects.isEmpty())\n                holder.setRefreshing(false)\n                if (adapter.itemCount == 0 || objects.isNotEmpty() && objects[0].hashCode().toLong() != adapter.getItemId(0)) {\n                    adapter.updateList(objects) {\n                        loadAds(objects)\n                        if (isFirstLoad) {\n                            holder.recyclerView.scheduleLayoutAnimation()\n                            isFirstLoad = false\n                        } else {\n                            holder.scrollToTop()\n                        }\n                    }\n                    scrollByKey(objects)\n                }\n            }\n        }\n        updateList()\n    }\n\n    private fun scrollByKey(list: List<RecentModel>) {\n        if (list.isEmpty()) return\n        val initial = arguments?.getInt(\"initial\", -1) ?: -1\n        if (initial == -1) {\n            noCrash { holder.scrollToTop() }\n            return\n        }\n        val find = list.find { it.key == initial } ?: return\n        holder.scrollTo(list.indexOf(find))\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(R.layout.fragment_recent_material, container, false)\n        EAHelper.enter1(\"R\")\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        holder.setRefreshing(true)\n    }\n\n    private fun loadAds(list: List<RecentModel>) {\n        if (PrefsUtil.isAdsEnabled) {\n            val adContainer = find<BannerContainerView>(R.id.adContainer)\n            if (AdsUtils.isAdmobEnabled && PrefsUtil.isNativeAdsEnabled) {\n                if (adapter.hasAds()) return\n                /*lifecycleScope.launch(Dispatchers.Main) {\n                    NativeManager.take(this, 3) {\n                        if (it.isEmpty())\n                            adContainer.implBanner(AdsType.RECENT_BANNER, true)\n                        else {\n                            adapter.updateList(list, it.mapIndexed { index, unifiedNativeAd -> RecentModelAd(index, unifiedNativeAd) }) {\n                                holder.scrollToTop()\n                            }\n                        }\n                    }\n                }*/\n            } else\n                adContainer.implBanner(AdsType.RECENT_BANNER, true)\n        }\n    }\n\n    override fun onRefresh() {\n        updateList()\n    }\n\n    private fun updateList() {\n        if (!Network.isConnected) {\n            holder.setRefreshing(false)\n        } else {\n            viewModel.reload()\n        }\n    }\n\n    override fun onReselect() {\n        EAHelper.enter1(\"R\")\n        noCrash { holder.scrollToTop() }\n    }\n\n\n    override fun onDestroyView() {\n        super.onDestroyView()\n        ServersFactory.clear()\n        FileActions.reset()\n        (activity as? AppCompatActivity)?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n    }\n\n    companion object {\n        fun get(initialKey: Int): BottomFragment {\n            val fragment = RecentModelsFragment()\n            val bundle = Bundle()\n            bundle.putInt(\"initial\", initialKey.also { Log.e(\"Recent\", \"Add argument key: $it\") })\n            fragment.arguments = bundle\n            return fragment\n        }\n\n        fun get(): BottomFragment {\n            return if (PrefsUtil.useHome)\n                HomeFragmentMaterial()\n            else\n                RecentModelsFragment()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentModelsViewModel.kt",
    "content": "package knf.kuma.recents\n\nimport androidx.lifecycle.ViewModel\nimport knf.kuma.database.CacheDB\nimport knf.kuma.retrofit.Repository\nimport kotlinx.coroutines.flow.Flow\n\nclass RecentModelsViewModel : ViewModel() {\n    private val repository = Repository()\n\n    val dbLiveData: Flow<List<RecentModel>> = CacheDB.INSTANCE.recentModelsDAO().allFlow\n    /*.onEach { list ->\n        withContext(Dispatchers.IO){\n            list.forEach {\n                it.prepare()\n                it.extras.fileWrapper.exist\n            }\n        }\n    }*/\n\n    fun reload() {\n        repository.reloadRecentsAlt()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentsActivity.kt",
    "content": "package knf.kuma.recents\r\n\r\nimport androidx.fragment.app.Fragment\r\nimport knf.kuma.custom.SingleFragmentActivity\r\n\r\nclass RecentsActivity : SingleFragmentActivity() {\r\n    override fun createFragment(): Fragment = RecentFragment.get(intent.getIntExtra(\"initial\", -1))\r\n    override fun getActivityTitle(): String = \"Recientes\"\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentsAdapter.kt",
    "content": "package knf.kuma.recents\n\nimport android.content.Context\nimport android.content.pm.ActivityInfo\nimport android.os.Build\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.Button\nimport android.widget.ImageView\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.annotation.UiThread\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.fragment.app.Fragment\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.Observer\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.ads.AdCallback\nimport knf.kuma.ads.AdCardItemHolder\nimport knf.kuma.ads.AdRecentObject\nimport knf.kuma.ads.AdsUtilsMob\nimport knf.kuma.ads.implAdsRecent\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.cast.CastMedia\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.FileWrapper\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.distinct\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.load\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.noCrashLet\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.SeenAnimeOverlay\nimport knf.kuma.database.CacheDB\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeenObject\nimport knf.kuma.queue.QueueManager\nimport knf.kuma.videoservers.ServersFactory\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster.toast\nimport java.util.Locale\n\nclass RecentsAdapter internal constructor(private val fragment: Fragment, private val view: View) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {\n\n    private val context: Context? = fragment.context\n    private var list: MutableList<RecentObject> = ArrayList()\n    private val dao = CacheDB.INSTANCE.favsDAO()\n    private val animeDAO = CacheDB.INSTANCE.animeDAO()\n    private val chaptersDAO = CacheDB.INSTANCE.seenDAO()\n    private val recordsDAO = CacheDB.INSTANCE.recordsDAO()\n    private val downloadsDAO = CacheDB.INSTANCE.downloadsDAO()\n    private var isNetworkAvailable: Boolean = Network.isConnected\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {\n        if (viewType == 1)\n            return AdCardItemHolder(parent).also {\n                it.loadAd(fragment.lifecycleScope, object : AdCallback {\n                    override fun getID(): String = AdsUtilsMob.RECENT_BANNER\n                }, 500)\n            }\n        return ItemHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_recents, parent, false))\n    }\n\n    override fun getItemViewType(position: Int): Int {\n        return noCrashLet { if (list[position] is AdRecentObject) 1 else 0 } ?: 1\n    }\n\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\n        noCrash {\n            if (context == null || list.isEmpty()) return@noCrash\n            if (holder is ItemHolder) {\n                holder.unsetObservers()\n                val recentObject = noCrashLet { list[position] } ?: return@noCrash\n                holder.imageView.load(PatternUtil.getCover(recentObject.aid))\n                holder.setNew(recentObject.isNew)\n                holder.setFav(recentObject.isFav)\n                holder.setSeen(recentObject.isSeen)\n                dao.favObserver(Integer.parseInt(recentObject.aid)).distinct.observe(fragment) { object1 -> holder.setFav((object1 != null).also { recentObject.isFav = it }) }\n                holder.setChapterObserver(chaptersDAO.chapterSeen(recentObject.aid, recentObject.chapter).distinct, fragment, Observer { chapter -> holder.setSeen(chapter != null) })\n                holder.setState(isNetworkAvailable, recentObject.isDownloading)\n                holder.apply {\n                    fileWrapperJob?.cancel()\n                    fileWrapperJob = fragment.lifecycleScope.launch(Dispatchers.Main) {\n                        withContext(Dispatchers.IO) {\n                            recentObject.fileWrapper()\n                        }\n                        if (!isActive)\n                            return@launch\n                        holder.setState(isNetworkAvailable, recentObject.fileWrapper().exist || recentObject.isDownloading)\n                        holder.setDownloadObserver(downloadsDAO.getLiveByEid(recentObject.eid).distinct, fragment, Observer { downloadObject ->\n                            fragment.lifecycleScope.launch(Dispatchers.Main) {\n                                holder.setDownloadState(downloadObject)\n                                if (downloadObject == null) {\n                                    recentObject.downloadState = -8\n                                    recentObject.isDownloading = false\n                                } else {\n                                    recentObject.isDownloading = downloadObject.state == DownloadObject.DOWNLOADING || downloadObject.state == DownloadObject.PENDING || downloadObject.state == DownloadObject.PAUSED\n                                    recentObject.downloadState = downloadObject.state\n                                    if (downloadObject.state == DownloadObject.DOWNLOADING || downloadObject.state == DownloadObject.PENDING)\n                                        holder.downIcon.setImageResource(R.drawable.ic_download)\n                                    else if (downloadObject.state == DownloadObject.PAUSED)\n                                        holder.downIcon.setImageResource(R.drawable.ic_pause_normal)\n                                    withContext(Dispatchers.IO) { recentObject.fileWrapper().reset() }\n                                }\n                                holder.setState(isNetworkAvailable, recentObject.fileWrapper().exist || recentObject.isDownloading)\n                            }\n                        })\n                        holder.setCastingObserver(fragment, Observer { s ->\n                            if (recentObject.eid == s) {\n                                holder.setCasting(true, recentObject.fileWrapper())\n                                holder.streaming.setOnClickListener { CastUtil.get().openControls() }\n                            } else {\n                                holder.setCasting(false, recentObject.fileWrapper())\n                                holder.streaming.setOnClickListener {\n                                    if (recentObject.fileWrapper().exist || recentObject.isDownloading) {\n                                        MaterialDialog(context).safeShow {\n                                            message(text = \"¿Eliminar el ${recentObject.chapter.lowercase(\n                                                Locale.ENGLISH\n                                            )} de ${recentObject.name}?\")\n                                            positiveButton(text = \"CONFIRMAR\") {\n                                                FileAccessHelper.deletePath(recentObject.filePath, true)\n                                                DownloadManagerCentral.cancel(recentObject.eid)\n                                                QueueManager.remove(recentObject.eid)\n                                                recentObject.fileWrapper().exist = false\n                                                holder.setState(isNetworkAvailable, false)\n                                            }\n                                            negativeButton(text = \"CANCELAR\")\n                                        }\n                                    } else {\n                                        holder.setLocked(true)\n                                        ServersFactory.start(context, recentObject.url, DownloadObject.fromRecent(recentObject), true, object : ServersFactory.ServersInterface {\n                                            override fun onFinish(started: Boolean, success: Boolean) {\n                                                if (!started && success) {\n                                                    doAsync {\n                                                        chaptersDAO.addChapter(SeenObject.fromRecent(recentObject))\n                                                        recordsDAO.add(RecordObject.fromRecent(recentObject))\n                                                        syncData {\n                                                            history()\n                                                            seen()\n                                                        }\n                                                    }\n                                                    recentObject.isSeen = true\n                                                }\n                                                holder.setLocked(false)\n                                            }\n\n                                            override fun onCast(url: String?) {\n                                                CastUtil.get().play(view, CastMedia.create(recentObject, url))\n                                                doAsync {\n                                                    chaptersDAO.addChapter(SeenObject.fromRecent(recentObject))\n                                                    recordsDAO.add(RecordObject.fromRecent(recentObject))\n                                                    syncData {\n                                                        history()\n                                                        seen()\n                                                    }\n                                                }\n                                                recentObject.isSeen = true\n                                                holder.setSeen(true)\n                                                holder.setLocked(false)\n                                            }\n\n                                            override fun onProgressIndicator(boolean: Boolean) {\n                                                fragment.doOnUI {\n                                                    if (boolean) {\n                                                        holder.progressBar.isIndeterminate = true\n                                                        holder.progressBarRoot.visibility = View.VISIBLE\n                                                    } else\n                                                        holder.progressBarRoot.visibility = View.GONE\n                                                }\n                                            }\n\n                                            override fun getView(): View {\n                                                return view\n                                            }\n                                        })\n                                    }\n                                }\n                            }\n                        })\n                    }\n                }\n                holder.title.text = recentObject.name\n                holder.chapter.text = recentObject.chapter\n                if (!isFullMode) holder.layButtons.visibility = View.INVISIBLE\n                holder.cardView.setOnClickListener {\n                    if (recentObject.animeObject != null) {\n                        ActivityAnime.open(fragment, recentObject.animeObject, holder.imageView)\n                    } else {\n                        if (!isFullMode && PrefsUtil.isDirectoryFinished) {\n                            toast(\"Anime deshabilitado para esta version\")\n                        } else if (PrefsUtil.isFamilyFriendly && PrefsUtil.isDirectoryFinished) {\n                            toast(\"Anime no familiar\")\n                        } else {\n                            fragment.lifecycleScope.launch(Dispatchers.Main) {\n                                val animeObject =\n                                    withContext(Dispatchers.IO) { animeDAO.getByAid(recentObject.aid) }\n                                if (animeObject != null) {\n                                    ActivityAnime.open(fragment, animeObject, holder.imageView)\n                                } else {\n                                    ActivityAnime.open(fragment, recentObject, holder.imageView)\n                                }\n                            }\n                        }\n                    }\n                }\n                holder.cardView.setOnLongClickListener {\n                    if (!recentObject.isSeen) {\n                        doAsync {\n                            chaptersDAO.addChapter(SeenObject.fromRecent(recentObject))\n                        }\n                        recentObject.isSeen = true\n                        holder.animeOverlay.setSeen(seen = true, animate = true)\n                    } else {\n                        doAsync {\n                            chaptersDAO.deleteChapter(recentObject.aid, recentObject.chapter)\n                        }\n                        recentObject.isSeen = false\n                        holder.animeOverlay.setSeen(seen = false, animate = true)\n                    }\n                    syncData { seen() }\n                    true\n                }\n                holder.download.setOnClickListener {\n                    fragment.lifecycleScope.launch(Dispatchers.Main){\n                        val obj = withContext(Dispatchers.IO) { downloadsDAO.getByEid(recentObject.eid) }\n                        if (FileAccessHelper.canDownload(fragment) &&\n                                !recentObject.fileWrapper().exist &&\n                                !recentObject.isDownloading &&\n                                recentObject.downloadState != DownloadObject.PENDING) {\n                            holder.setLocked(true)\n                            ServersFactory.start(context, recentObject.url, AnimeObject.WebInfo.AnimeChapter.fromRecent(recentObject), isStream = false, addQueue = false, serversInterface = object : ServersFactory.ServersInterface {\n                                override fun onFinish(started: Boolean, success: Boolean) {\n                                    if (started) {\n                                        recentObject.fileWrapper().exist = true\n                                        holder.setState(isNetworkAvailable, true)\n                                    }\n                                    holder.setLocked(false)\n                                }\n\n                                override fun onCast(url: String?) {\n\n                                }\n\n                                override fun onProgressIndicator(boolean: Boolean) {\n                                    fragment.doOnUI {\n                                        if (boolean) {\n                                            holder.progressBar.isIndeterminate = true\n                                            holder.progressBarRoot.visibility = View.VISIBLE\n                                        } else\n                                            holder.progressBarRoot.visibility = View.GONE\n                                    }\n                                }\n\n                                override fun getView(): View {\n                                    return view\n                                }\n                            })\n                        } else if (recentObject.fileWrapper().exist && (obj == null || obj.state == DownloadObject.DOWNLOADING || obj.state == DownloadObject.COMPLETED)) {\n                            doAsync {\n                                chaptersDAO.addChapter(SeenObject.fromRecent(recentObject))\n                                recordsDAO.add(RecordObject.fromRecent(recentObject))\n                                syncData {\n                                    history()\n                                    seen()\n                                }\n                            }\n                            recentObject.isSeen = true\n                            holder.setSeen(true)\n                            ServersFactory.startPlay(context, recentObject.epTitle, recentObject.fileWrapper().name())\n                        } else {\n                            toast(\"Aun no se está descargando\")\n                        }\n                    }\n                }\n                holder.download.setOnLongClickListener {\n                    fragment.lifecycleScope.launch(Dispatchers.Main){\n                        val obj = withContext(Dispatchers.IO) { downloadsDAO.getByEid(recentObject.eid) }\n                        if (CastUtil.get().connected() &&\n                                recentObject.fileWrapper().exist && (obj == null || obj.state == DownloadObject.COMPLETED)) {\n                            doAsync {\n                                chaptersDAO.addChapter(SeenObject.fromRecent(recentObject))\n                                syncData { seen() }\n                            }\n                            recentObject.isSeen = true\n                            CastUtil.get().play(view, CastMedia.create(recentObject))\n                        }\n                    }\n                    true\n                }\n            }\n        }\n    }\n\n    private fun setOrientation(block: Boolean) {\n        noCrash {\n            if (block)\n                (fragment.activity as? AppCompatActivity)?.requestedOrientation = when {\n                    context?.resources?.getBoolean(R.bool.isLandscape) == true -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE\n                    else -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT\n                }\n            else (fragment.activity as? AppCompatActivity)?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED\n        }\n    }\n\n    override fun onViewRecycled(holder: RecyclerView.ViewHolder) {\n        if (holder is ItemHolder)\n            holder.unsetObservers()\n        super.onViewRecycled(holder)\n    }\n\n    internal fun updateList(list: MutableList<RecentObject>, updateListener: UpdateListener) {\n        this.isNetworkAvailable = Network.isConnected\n        val wasEmpty = this.list.isEmpty()\n        fragment.lifecycleScope.launch(Dispatchers.IO) {\n            this@RecentsAdapter.list = list.distinctBy { it.eid } as MutableList<RecentObject>\n            if (PrefsUtil.isNativeAdsEnabled)\n                this@RecentsAdapter.list.implAdsRecent()\n            if (this@RecentsAdapter.list.isNotEmpty())\n                withContext(Dispatchers.Main) {\n                    notifyDataSetChanged()\n                    if (wasEmpty)\n                        updateListener.invoke()\n                }\n        }\n    }\n\n    /*override fun getItemId(position: Int): Long {\n        return noCrashLet { list[position].key.toLong() } ?: 0\n    }*/\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    inner class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView = itemView.find(R.id.card)\n        val imageView: ImageView = itemView.find(R.id.img)\n        val title: TextView = itemView.find(R.id.title)\n        val chapter: TextView = itemView.find(R.id.chapter)\n        val streaming: Button = itemView.find(R.id.streaming)\n        val download: Button = itemView.find(R.id.download)\n        val animeOverlay: SeenAnimeOverlay = itemView.find(R.id.seenOverlay)\n        val downIcon: ImageView = itemView.find(R.id.down_icon)\n        private val newIcon: ImageView = itemView.find(R.id.new_icon)\n        private val favIcon: ImageView = itemView.find(R.id.fav_icon)\n        val progressBar: ProgressBar = itemView.find(R.id.progress)\n        val progressBarRoot: View = itemView.find(R.id.progress_root)\n        val layButtons: View = itemView.find(R.id.lay_buttons)\n        var fileWrapperJob: Job? = null\n\n        private var chapterLiveData: LiveData<SeenObject> = MutableLiveData()\n        private var downloadLiveData: LiveData<DownloadObject> = MutableLiveData()\n\n        private var chapterObserver: Observer<SeenObject?>? = null\n        private var downloadObserver: Observer<DownloadObject>? = null\n        private var castingObserver: Observer<String>? = null\n\n        fun setChapterObserver(chapterLiveData: LiveData<SeenObject>, owner: LifecycleOwner, observer: Observer<SeenObject?>) {\n            this.chapterLiveData = chapterLiveData\n            this.chapterObserver = observer\n            this.chapterLiveData.observe(owner, observer)\n        }\n\n        private fun unsetChapterObserver() {\n            chapterObserver?.let {\n                chapterLiveData.removeObserver(it)\n                chapterObserver = null\n            }\n        }\n\n        fun setDownloadObserver(downloadLiveData: LiveData<DownloadObject>, owner: LifecycleOwner, observer: Observer<DownloadObject>) {\n            this.downloadLiveData = downloadLiveData\n            this.downloadObserver = observer\n            this.downloadLiveData.observe(owner, observer)\n        }\n\n        private fun unsetDownloadObserver() {\n            downloadObserver?.let {\n                downloadLiveData.removeObserver(it)\n                downloadObserver = null\n            }\n        }\n\n        fun setCastingObserver(owner: LifecycleOwner, observer: Observer<String>) {\n            this.castingObserver = observer\n            CastUtil.get().casting.observe(owner, observer)\n        }\n\n        private fun unsetCastingObserver() {\n            castingObserver?.let {\n                CastUtil.get().casting.removeObserver(it)\n                castingObserver = null\n            }\n        }\n\n        fun unsetObservers() {\n            unsetChapterObserver()\n            unsetDownloadObserver()\n            unsetCastingObserver()\n        }\n\n        fun setNew(isNew: Boolean) {\n            newIcon.post { newIcon.visibility = if (isNew) View.VISIBLE else View.GONE }\n        }\n\n        fun setFav(isFav: Boolean) {\n            favIcon.post { favIcon.visibility = if (isFav) View.VISIBLE else View.GONE }\n        }\n\n        private fun setDownloaded(isDownloaded: Boolean) {\n            downIcon.post { downIcon.visibility = if (isDownloaded) View.VISIBLE else View.GONE }\n        }\n\n        fun setSeen(seen: Boolean) {\n            animeOverlay.setSeen(seen, false)\n        }\n\n        fun setLocked(locked: Boolean) {\n            streaming.post { streaming.isEnabled = !locked }\n            download.post { download.isEnabled = !locked }\n            setOrientation(locked)\n        }\n\n        fun setCasting(casting: Boolean, fileWrapper: FileWrapper<*>) {\n            streaming.post { streaming.text = if (casting) \"CAST\" else if (fileWrapper.exist) \"ELIMINAR\" else \"STREAMING\" }\n        }\n\n        @UiThread\n        fun setState(isNetworkAvailable: Boolean, existFile: Boolean) {\n            setDownloaded(existFile)\n            streaming.post {\n                streaming.text = if (existFile) \"ELIMINAR\" else \"STREAMING\"\n                if (!existFile)\n                    streaming.isEnabled = isNetworkAvailable\n                else\n                    streaming.isEnabled = true\n            }\n            download.post {\n                download.isEnabled = isNetworkAvailable || existFile\n                download.text = if (existFile) \"REPRODUCIR\" else \"DESCARGA\"\n            }\n        }\n\n        fun setDownloadState(downloadObject: DownloadObject?) {\n            progressBar.post {\n                if (downloadObject != null && PrefsUtil.showProgress())\n                    when (downloadObject.state) {\n                        DownloadObject.PENDING -> {\n                            progressBarRoot.visibility = View.VISIBLE\n                            progressBar.isIndeterminate = true\n                        }\n                        DownloadObject.DOWNLOADING -> {\n                            progressBarRoot.visibility = View.VISIBLE\n                            progressBar.isIndeterminate = false\n                            if (downloadObject.getEta() == -2L || PrefsUtil.downloaderType == 0) {\n                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)\n                                    progressBar.setProgress(downloadObject.progress, true)\n                                else\n                                    progressBar.progress = downloadObject.progress\n                                if (downloadObject.getEta() == -2L && PrefsUtil.downloaderType != 0)\n                                    progressBar.secondaryProgress = 100\n                            } else {\n                                progressBar.progress = 0\n                                progressBar.secondaryProgress = downloadObject.progress\n                            }\n                        }\n                        DownloadObject.PAUSED -> {\n                            progressBarRoot.visibility = View.VISIBLE\n                            progressBar.isIndeterminate = false\n                        }\n                        else -> progressBarRoot.visibility = View.GONE\n                    }\n                else\n                    progressBarRoot.visibility = View.GONE\n            }\n        }\n    }\n}\n\ntypealias UpdateListener = () -> Unit\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentsModelActivity.kt",
    "content": "package knf.kuma.recents\r\n\r\nimport androidx.fragment.app.Fragment\r\nimport knf.kuma.custom.SingleFragmentMaterialActivity\r\n\r\nclass RecentsModelActivity : SingleFragmentMaterialActivity() {\r\n    override fun createFragment(): Fragment = RecentModelsFragment.get(intent.getIntExtra(\"initial\", -1))\r\n    override fun getActivityTitle(): String = \"Recientes\"\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentsNotReceiver.kt",
    "content": "package knf.kuma.recents\n\nimport android.app.NotificationManager\nimport android.content.BroadcastReceiver\nimport android.content.Context\nimport android.content.Intent\nimport knf.kuma.database.CacheDB\nimport knf.kuma.jobscheduler.RecentsWork\nimport knf.kuma.pojos.NotificationObj\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.notificationManager\n\nclass RecentsNotReceiver : BroadcastReceiver() {\n\n    override fun onReceive(context: Context, intent: Intent) {\n        val notificationDAO = CacheDB.INSTANCE.notificationDAO()\n        if (intent.getIntExtra(\"mode\", 0) == 1)\n            removeAll(context)\n        else {\n            doAsync {\n                notificationDAO.delete(NotificationObj.fromIntent(intent))\n                if (notificationDAO.getByType(NotificationObj.RECENT).isEmpty())\n                    context.notificationManager.cancel(RecentsWork.KEY_SUMMARY)\n            }\n        }\n    }\n\n    companion object {\n        fun removeAll(context: Context) {\n            doAsync {\n                val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager\n                val notificationDAO = CacheDB.INSTANCE.notificationDAO()\n                for (obj in notificationDAO.all)\n                    manager.cancel(obj.key)\n                notificationDAO.clear()\n                manager.cancel(RecentsWork.KEY_SUMMARY)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/RecentsViewModel.kt",
    "content": "package knf.kuma.recents\n\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.ViewModel\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.retrofit.Repository\nimport kotlinx.coroutines.flow.Flow\n\nclass RecentsViewModel : ViewModel() {\n    private val repository = Repository()\n\n    val dbLiveData: LiveData<MutableList<RecentObject>>\n        get() = CacheDB.INSTANCE.recentsDAO().objects\n\n    val dbFlow: Flow<List<RecentObject>>\n        get() = CacheDB.INSTANCE.recentsDAO().objectsFlow\n\n    fun reload() {\n        repository.reloadAllRecents()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recents/viewholders/RecyclerRefreshHolder.kt",
    "content": "package knf.kuma.recents.viewholders\n\nimport android.view.View\nimport android.view.animation.AnimationUtils\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport androidx.swiperefreshlayout.widget.SwipeRefreshLayout\nimport knf.kuma.R\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport org.jetbrains.anko.find\n\nclass RecyclerRefreshHolder(view: View) {\n    val recyclerView: RecyclerView = view.find(R.id.recycler)\n    val refreshLayout: SwipeRefreshLayout = view.find(R.id.refresh)\n    val error: View = view.find(R.id.error)\n    private val layoutManager: LinearLayoutManager = VariantLinearLayoutManager(view.context)\n\n    init {\n        recyclerView.layoutManager = layoutManager\n        recyclerView.layoutAnimation = AnimationUtils.loadLayoutAnimation(view.context, R.anim.layout_fall_down)\n        refreshLayout.setColorSchemeResources(EAHelper.getThemeColor(), EAHelper.getThemeColorLight(), R.color.colorPrimary)\n    }\n\n    fun scrollToTop() {\n        layoutManager.smoothScrollToPosition(recyclerView, null, 0)\n    }\n\n    fun scrollTo(position: Int) {\n        layoutManager.smoothScrollToPosition(recyclerView, null, position)\n    }\n\n    fun setRefreshing(refreshing: Boolean) {\n        refreshLayout.post { refreshLayout.isRefreshing = refreshing }\n    }\n\n    fun setError(visible: Boolean) {\n        error.post { error.visibility = if (visible) View.VISIBLE else View.GONE }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/AnimeShortObject.kt",
    "content": "package knf.kuma.recommended\r\n\r\nclass AnimeShortObject {\r\n    var key = 0\r\n    var aid = \"\"\r\n    var img = \"\"\r\n    var link = \"\"\r\n    var name = \"\"\r\n    var type = \"\"\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/BlacklistDialog.kt",
    "content": "package knf.kuma.recommended\n\nimport android.app.Dialog\nimport android.os.Bundle\nimport androidx.fragment.app.DialogFragment\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\nimport com.afollestad.materialdialogs.list.listItemsMultiChoice\nimport knf.kuma.commons.transform\nimport java.util.Arrays\n\nclass BlacklistDialog : DialogFragment() {\n\n    private val genres = getGenres()\n    private var selected: MutableList<String> = mutableListOf()\n    private var listener: MultiChoiceListener? = null\n\n    private val statesIndex: IntArray\n        get() {\n            val states = IntArray(selected.size)\n            selected.forEachIndexed { index, genre ->\n                states[index] = genres.indexOf(genre)\n            }\n            return states\n        }\n\n    fun init(selected: MutableList<String>, listener: MultiChoiceListener) {\n        this.selected = selected\n        this.listener = listener\n    }\n\n    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {\n        return activity?.let {\n            MaterialDialog(it).apply {\n                lifecycleOwner()\n                title(text = \"Lista negra\")\n                listItemsMultiChoice(items = genres, initialSelection = statesIndex, allowEmptySelection = true) { _, _, items ->\n                    selected = mutableListOf<String>().apply {\n                        addAll(items.transform())\n                        sort()\n                    }\n                    listener?.onOkay(selected)\n                }\n                positiveButton(text = \"SELECCIONAR\")\n                negativeButton(text = \"CERRAR\")\n            }\n        } ?: super.onCreateDialog(savedInstanceState)\n    }\n\n    interface MultiChoiceListener {\n        fun onOkay(selected: MutableList<String>)\n    }\n\n    companion object {\n\n        fun getGenres(): MutableList<String> {\n            return Arrays.asList(\n                    \"Acción\",\n                    \"Artes Marciales\",\n                    \"Aventuras\",\n                    \"Carreras\",\n                    \"Comedia\",\n                    \"Demencia\",\n                    \"Demonios\",\n                    \"Deportes\",\n                    \"Drama\",\n                    \"Ecchi\",\n                    \"Escolares\",\n                    \"Espacial\",\n                    \"Fantasía\",\n                    \"Ciencia Ficción\",\n                    \"Harem\",\n                    \"Historico\",\n                    \"Infantil\",\n                    \"Josei\",\n                    \"Juegos\",\n                    \"Magia\",\n                    \"Mecha\",\n                    \"Militar\",\n                    \"Misterio\",\n                    \"Musica\",\n                    \"Parodia\",\n                    \"Policía\",\n                    \"Psicológico\",\n                    \"Recuentos de la vida\",\n                    \"Romance\",\n                    \"Samurai\",\n                    \"Seinen\",\n                    \"Shoujo\",\n                    \"Shounen\",\n                    \"Sin Generos\",\n                    \"Sobrenatural\",\n                    \"Superpoderes\",\n                    \"Suspenso\",\n                    \"Terror\",\n                    \"Vampiros\",\n                    \"Yaoi\",\n                    \"Yuri\")\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RHHolder.kt",
    "content": "package knf.kuma.recommended\n\nimport android.view.View\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport org.jetbrains.anko.find\n\n/**\n * Created by jordy on 26/03/2018.\n */\n\nclass RHHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n    val title: TextView = itemView.find(R.id.title)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RIHolder.kt",
    "content": "package knf.kuma.recommended\n\nimport android.view.View\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.commons.bind\n\n/**\n * Created by jordy on 26/03/2018.\n */\n\nclass RIHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n    val cardView: View by itemView.bind(R.id.card)\n    val img: ImageView by itemView.bind(R.id.img)\n    val title: TextView by itemView.bind(R.id.title)\n    val type: TextView by itemView.bind(R.id.type)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RankType.kt",
    "content": "package knf.kuma.recommended\n\n/**\n * Created by jordy on 26/03/2018.\n */\n\nenum class RankType {\n    FAV, UNFAV, FOLLOW, UNFOLLOW, CHECK, SEARCH\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RankingActivity.kt",
    "content": "package knf.kuma.recommended\n\nimport android.app.Activity\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport androidx.lifecycle.lifecycleScope\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.R\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.RecyclerRankingBinding\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\n\nclass RankingActivity : GenericActivity() {\n\n    private val binding by lazy { RecyclerRankingBinding.inflate(layoutInflater) }\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(binding.root)\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.apply {\n            setDisplayHomeAsUpEnabled(true)\n            setDisplayShowHomeEnabled(false)\n            title = \"Ranking\"\n        }\n        with(binding.toolbar) {\n            setNavigationIcon(R.drawable.ic_close)\n            setNavigationOnClickListener { finish() }\n        }\n        with(binding.recycler) {\n            layoutManager = VariantLinearLayoutManager(this@RankingActivity)\n            lifecycleScope.launch(Dispatchers.Main){\n                adapter = RankingAdapterMaterial(withContext(Dispatchers.IO) { CacheDB.INSTANCE.genresDAO().ranking })\n            }\n        }\n        setResult(1234)\n        showRandomInterstitial(this, PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_rating, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.clear ->\n                MaterialDialog(this@RankingActivity).safeShow {\n                    message(text = \"¿Deseas reiniciar la puntuación de todos los géneros?\")\n                    positiveButton(text = \"continuar\") {\n                        setResult(4321)\n                        doAsync {\n                            CacheDB.INSTANCE.genresDAO().reset()\n                            syncData { genres() }\n                        }\n                        finish()\n                    }\n                    negativeButton(text = \"cancelar\")\n                }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        fun open(activity: Activity) {\n            activity.startActivityForResult(Intent(activity, RankingActivity::class.java), 46897)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RankingActivityMaterial.kt",
    "content": "package knf.kuma.recommended\n\nimport android.app.Activity\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport androidx.lifecycle.lifecycleScope\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.R\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.RecyclerRankingMaterialBinding\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\n\nclass RankingActivityMaterial : GenericActivity() {\n\n    private val binding by lazy { RecyclerRankingMaterialBinding.inflate(layoutInflater) }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(binding.root)\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.apply {\n            setDisplayHomeAsUpEnabled(true)\n            setDisplayShowHomeEnabled(false)\n            title = \"Ranking\"\n        }\n        with(binding.toolbar) {\n            setNavigationIcon(R.drawable.ic_close)\n            setNavigationOnClickListener { finish() }\n        }\n        with(binding.recycler) {\n            layoutManager = VariantLinearLayoutManager(this@RankingActivityMaterial)\n            lifecycleScope.launch(Dispatchers.Main){\n                adapter = RankingAdapterMaterial(withContext(Dispatchers.IO) { CacheDB.INSTANCE.genresDAO().ranking })\n            }\n        }\n        setResult(1234)\n        showRandomInterstitial(this, PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_rating, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.clear ->\n                MaterialDialog(this@RankingActivityMaterial).safeShow {\n                    message(text = \"¿Deseas reiniciar la puntuación de todos los géneros?\")\n                    positiveButton(text = \"continuar\") {\n                        setResult(4321)\n                        doAsync {\n                            CacheDB.INSTANCE.genresDAO().reset()\n                            syncData { genres() }\n                        }\n                        finish()\n                    }\n                    negativeButton(text = \"cancelar\")\n                }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        fun open(activity: Activity) {\n            activity.startActivityForResult(Intent(activity, RankingActivityMaterial::class.java), 46897)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RankingAdapter.kt",
    "content": "package knf.kuma.recommended\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.pojos.GenreStatusObject\nimport org.jetbrains.anko.find\n\nclass RankingAdapter(val list: List<GenreStatusObject>) : RecyclerView.Adapter<RankingAdapter.RankHolder>() {\n\n    private var total = 0\n\n    init {\n        if (list.isNotEmpty())\n            total = list[0].count\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RankHolder {\n        return RankHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_ranking, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: RankHolder, position: Int) {\n        val statusObject = list[position]\n        holder.title.text = statusObject.name\n        holder.count.text = statusObject.count.toString()\n        holder.ranking.max = total\n        holder.ranking.progress = statusObject.count\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    class RankHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val title: TextView = itemView.find(R.id.title)\n        val count: TextView = itemView.find(R.id.count)\n        val ranking: ProgressBar = itemView.find(R.id.ranking)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RankingAdapterMaterial.kt",
    "content": "package knf.kuma.recommended\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.pojos.GenreStatusObject\nimport org.jetbrains.anko.find\n\nclass RankingAdapterMaterial(val list: List<GenreStatusObject>) : RecyclerView.Adapter<RankingAdapterMaterial.RankHolder>() {\n    private var total = 0\n\n    init {\n        if (list.isNotEmpty())\n            total = list[0].count\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RankHolder {\n        return RankHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_ranking_material, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: RankHolder, position: Int) {\n        val statusObject = list[position]\n        holder.title.text = statusObject.name\n        holder.count.text = statusObject.count.toString()\n        holder.ranking.max = total\n        holder.ranking.progress = statusObject.count\n    }\n\n    override fun getItemCount(): Int {\n        return list.size\n    }\n\n    class RankHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val title: TextView = itemView.find(R.id.title)\n        val count: TextView = itemView.find(R.id.count)\n        val ranking: ProgressBar = itemView.find(R.id.ranking)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RecommendActivity.kt",
    "content": "package knf.kuma.recommended\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.widget.Toolbar\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.gridColumns\nimport knf.kuma.commons.removeAll\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.custom.VariantGridLayoutManager\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.GenreStatusObject\nimport knf.kuma.recommended.sections.MultipleSection\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster\n\n/**\n * Created by jordy on 26/03/2018.\n */\n\nclass RecommendActivity : GenericActivity() {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    val recyclerView: RecyclerView by bind(R.id.recycler)\n    val error: LinearLayout by bind(R.id.error)\n    val loading: LinearLayout by bind(R.id.loading)\n    val state: TextView by bind(R.id.state)\n    private val dao = CacheDB.INSTANCE.animeDAO()\n\n    private val defaultGridColumns = gridColumns()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (isGrid) {\n            R.layout.recycler_recommends\n        } else {\n            R.layout.recycler_recommends_grid\n        }\n\n    private val isGrid: Boolean\n        get() = PrefsUtil.layType != \"0\"\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(layout)\n        toolbar.title = \"Sugeridos\"\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        toolbar.setNavigationOnClickListener { finish() }\n        find<FrameLayout>(R.id.adContainer).implBanner(AdsType.RECOMMEND_BANNER, true)\n        setAdapter()\n    }\n\n    private fun setAdapter() {\n        doAsync {\n            try {\n                val excludeList = LinkedHashSet<String>().apply {\n                    addAll(CacheDB.INSTANCE.favsDAO().allAids)\n                    addAll(CacheDB.INSTANCE.seeingDAO().allAids)\n                }.toList()\n                val status = CacheDB.INSTANCE.genresDAO().top\n                setState(\"Revisando generos\")\n                if (status.size == 3) {\n                    setState(\"Buscando sugerencias\")\n                    val sectionedAdapter = SectionedRecyclerViewAdapter()\n                    val abc = getList(status[0], status[1], status[2])\n                    val ab = getList(status[0], status[1])\n                    ab.removeAll(abc)\n                    val ac = getList(status[0], status[2])\n                    ac.removeAll(abc, ab)\n                    val bc = getList(status[1], status[2])\n                    bc.removeAll(abc, ab, ac)\n                    val a = getList(status[0])\n                    a.removeAll(abc, ab, ac, bc)\n                    val b = getList(status[1])\n                    b.removeAll(abc, ab, ac, bc, a)\n                    val c = getList(status[2])\n                    c.removeAll(abc, ab, ac, bc, a, b)\n                    setState(\"Filtrando lista\")\n                    removeFavs(excludeList, abc, ab, ac, bc, a, b, c)\n                    if (abc.size > 0)\n                        sectionedAdapter.addSection(MultipleSection(this@RecommendActivity, getStringTitle(status[0], status[1], status[2]), getAnimeList(abc), isGrid))\n                    if (ab.size > 0)\n                        sectionedAdapter.addSection(MultipleSection(this@RecommendActivity, getStringTitle(status[0], status[1]), getAnimeList(ab), isGrid))\n                    if (ac.size > 0)\n                        sectionedAdapter.addSection(MultipleSection(this@RecommendActivity, getStringTitle(status[0], status[2]), getAnimeList(ac), isGrid))\n                    if (bc.size > 0)\n                        sectionedAdapter.addSection(MultipleSection(this@RecommendActivity, getStringTitle(status[1], status[2]), getAnimeList(bc), isGrid))\n                    if (a.size > 0)\n                        sectionedAdapter.addSection(MultipleSection(this@RecommendActivity, getStringTitle(status[0]), getAnimeList(a), isGrid))\n                    if (b.size > 0)\n                        sectionedAdapter.addSection(MultipleSection(this@RecommendActivity, getStringTitle(status[1]), getAnimeList(b), isGrid))\n                    if (c.size > 0)\n                        sectionedAdapter.addSection(MultipleSection(this@RecommendActivity, getStringTitle(status[2]), getAnimeList(c), isGrid))\n                    val layoutManager: RecyclerView.LayoutManager\n                    if (isGrid) {\n                        val grid = VariantGridLayoutManager(this@RecommendActivity, defaultGridColumns)\n                        grid.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {\n                            override fun getSpanSize(position: Int): Int {\n                                return try {\n                                    when (sectionedAdapter.getSectionItemViewType(position)) {\n                                        SectionedRecyclerViewAdapter.VIEW_TYPE_HEADER -> defaultGridColumns\n                                        else -> 1\n                                    }\n                                } catch (e: Exception) {\n                                    e.printStackTrace()\n                                    defaultGridColumns\n                                }\n\n                            }\n                        }\n                        layoutManager = grid\n                    } else {\n                        layoutManager = VariantLinearLayoutManager(this@RecommendActivity)\n                    }\n                    runOnUiThread {\n                        loading.visibility = View.GONE\n                        recyclerView.layoutManager = layoutManager\n                        recyclerView.adapter = sectionedAdapter\n                    }\n                } else\n                    runOnUiThread {\n                        loading.visibility = View.GONE\n                        error.visibility = View.VISIBLE\n                    }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                FirebaseCrashlytics.getInstance().recordException(e)\n                Toaster.toast(\"Error al cargar recomendados\")\n                runOnUiThread {\n                    loading.visibility = View.GONE\n                }\n            }\n        }\n    }\n\n    @SafeVarargs\n    private fun removeFavs(excludeList: List<String>, vararg lists: MutableList<String>) {\n        lists.forEach { list ->\n            list.removeAll(list.filter { excludeList.contains(it) })\n        }\n    }\n\n    private fun getList(vararg status: GenreStatusObject): MutableList<String> {\n        return dao.getAidsByGenres(getString(*status))\n    }\n\n    private fun getAnimeList(list: List<String>): MutableList<AnimeShortObject> {\n        val chunk = list.chunked(900)\n        val animes = mutableListOf<AnimeShortObject>()\n        chunk.forEach {\n            animes.addAll(CacheDB.INSTANCE.animeDAO().getAnimesByAids(it))\n        }\n        return animes\n    }\n\n    private fun getString(vararg status: GenreStatusObject): String {\n        val builder = StringBuilder(\"%\")\n        for (s in status) {\n            builder.append(s.name)\n                    .append(\"%\")\n        }\n        return builder.toString()\n    }\n\n    private fun getStringTitle(vararg status: GenreStatusObject): String {\n        val builder = StringBuilder()\n        for (s in status) {\n            builder.append(s.name)\n                    .append(\", \")\n        }\n        return builder.toString().substring(0, builder.length - 2)\n    }\n\n    private fun setState(stateString: String) {\n        runOnUiThread {\n            state.text = stateString\n        }\n    }\n\n    private fun showBlacklist() {\n        lifecycleScope.launch(Dispatchers.Main) {\n            val blacklist = withContext(Dispatchers.IO) { GenreStatusObject.names(CacheDB.INSTANCE.genresDAO().blacklist) }\n            val dialog = BlacklistDialog()\n            dialog.init(blacklist, object : BlacklistDialog.MultiChoiceListener {\n                override fun onOkay(selected: MutableList<String>) {\n                    setBlacklist(selected)\n                }\n            })\n            dialog.show(supportFragmentManager, \"Blacklist\")\n        }\n    }\n\n    private fun setBlacklist(selected: MutableList<String>) {\n        doAsync {\n            for (s in selected)\n                RecommendHelper.block(s)\n            for (statusObject in CacheDB.INSTANCE.genresDAO().all)\n                if (statusObject.isBlocked && !selected.contains(statusObject.name))\n                    RecommendHelper.reset(statusObject.name)\n            resetSuggestions()\n        }\n    }\n\n    private fun resetSuggestions() {\n        setState(\"Iniciando búsqueda\")\n        runOnUiThread {\n            val adapter = recyclerView.adapter as SectionedRecyclerViewAdapter?\n            if (adapter != null) {\n                adapter.removeAllSections()\n                recyclerView.adapter = adapter\n                loading.visibility = View.VISIBLE\n                error.visibility = View.GONE\n                setAdapter()\n            }\n        }\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_suggestions, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.blacklist -> showBlacklist()\n            R.id.rating -> RankingActivity.open(this)\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        if (resultCode == 4321)\n            resetSuggestions()\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, RecommendActivity::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RecommendActivityMaterial.kt",
    "content": "package knf.kuma.recommended\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.FrameLayout\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.widget.Toolbar\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.GridLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter\nimport knf.kuma.R\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.gridColumns\nimport knf.kuma.commons.removeAll\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.custom.VariantGridLayoutManager\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.GenreStatusObject\nimport knf.kuma.recommended.sections.MultipleSectionMaterial\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\nimport xdroid.toaster.Toaster\n\n/**\n * Created by jordy on 26/03/2018.\n */\n\nclass RecommendActivityMaterial : GenericActivity() {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    val recyclerView: RecyclerView by bind(R.id.recycler)\n    val error: LinearLayout by bind(R.id.error)\n    val loading: LinearLayout by bind(R.id.loading)\n    val state: TextView by bind(R.id.state)\n    private val dao = CacheDB.INSTANCE.animeDAO()\n\n    private val defaultGridColumns = gridColumns()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (isGrid) {\n            R.layout.recycler_recommends_material\n        } else {\n            R.layout.recycler_recommends_grid_material\n        }\n\n    private val isGrid: Boolean\n        get() = PrefsUtil.layType != \"0\"\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(layout)\n        toolbar.title = \"Sugeridos\"\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        toolbar.setNavigationOnClickListener { finish() }\n        find<FrameLayout>(R.id.adContainer).implBanner(AdsType.RECOMMEND_BANNER, true)\n        setAdapter()\n    }\n\n    private fun setAdapter() {\n        doAsync {\n            try {\n                val excludeList = LinkedHashSet<String>().apply {\n                    addAll(CacheDB.INSTANCE.favsDAO().allAids)\n                    addAll(CacheDB.INSTANCE.seeingDAO().allAids)\n                }.toList()\n                val status = CacheDB.INSTANCE.genresDAO().top\n                setState(\"Revisando generos\")\n                if (status.size == 3) {\n                    setState(\"Buscando sugerencias\")\n                    val sectionedAdapter = SectionedRecyclerViewAdapter()\n                    val abc = getList(status[0], status[1], status[2])\n                    val ab = getList(status[0], status[1])\n                    ab.removeAll(abc)\n                    val ac = getList(status[0], status[2])\n                    ac.removeAll(abc, ab)\n                    val bc = getList(status[1], status[2])\n                    bc.removeAll(abc, ab, ac)\n                    val a = getList(status[0])\n                    a.removeAll(abc, ab, ac, bc)\n                    val b = getList(status[1])\n                    b.removeAll(abc, ab, ac, bc, a)\n                    val c = getList(status[2])\n                    c.removeAll(abc, ab, ac, bc, a, b)\n                    setState(\"Filtrando lista\")\n                    removeFavs(excludeList, abc, ab, ac, bc, a, b, c)\n                    if (abc.size > 0)\n                        sectionedAdapter.addSection(MultipleSectionMaterial(this@RecommendActivityMaterial, getStringTitle(status[0], status[1], status[2]), getAnimeList(abc), isGrid))\n                    if (ab.size > 0)\n                        sectionedAdapter.addSection(MultipleSectionMaterial(this@RecommendActivityMaterial, getStringTitle(status[0], status[1]), getAnimeList(ab), isGrid))\n                    if (ac.size > 0)\n                        sectionedAdapter.addSection(MultipleSectionMaterial(this@RecommendActivityMaterial, getStringTitle(status[0], status[2]), getAnimeList(ac), isGrid))\n                    if (bc.size > 0)\n                        sectionedAdapter.addSection(MultipleSectionMaterial(this@RecommendActivityMaterial, getStringTitle(status[1], status[2]), getAnimeList(bc), isGrid))\n                    if (a.size > 0)\n                        sectionedAdapter.addSection(MultipleSectionMaterial(this@RecommendActivityMaterial, getStringTitle(status[0]), getAnimeList(a), isGrid))\n                    if (b.size > 0)\n                        sectionedAdapter.addSection(MultipleSectionMaterial(this@RecommendActivityMaterial, getStringTitle(status[1]), getAnimeList(b), isGrid))\n                    if (c.size > 0)\n                        sectionedAdapter.addSection(MultipleSectionMaterial(this@RecommendActivityMaterial, getStringTitle(status[2]), getAnimeList(c), isGrid))\n                    val layoutManager: RecyclerView.LayoutManager\n                    if (isGrid) {\n                        val grid = VariantGridLayoutManager(this@RecommendActivityMaterial, defaultGridColumns)\n                        grid.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {\n                            override fun getSpanSize(position: Int): Int {\n                                return try {\n                                    when (sectionedAdapter.getSectionItemViewType(position)) {\n                                        SectionedRecyclerViewAdapter.VIEW_TYPE_HEADER -> defaultGridColumns\n                                        else -> 1\n                                    }\n                                } catch (e: Exception) {\n                                    e.printStackTrace()\n                                    defaultGridColumns\n                                }\n\n                            }\n                        }\n                        layoutManager = grid\n                    } else {\n                        layoutManager = VariantLinearLayoutManager(this@RecommendActivityMaterial)\n                    }\n                    runOnUiThread {\n                        loading.visibility = View.GONE\n                        recyclerView.layoutManager = layoutManager\n                        recyclerView.adapter = sectionedAdapter\n                    }\n                } else\n                    runOnUiThread {\n                        loading.visibility = View.GONE\n                        error.visibility = View.VISIBLE\n                    }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                FirebaseCrashlytics.getInstance().recordException(e)\n                Toaster.toast(\"Error al cargar recomendados\")\n                runOnUiThread {\n                    loading.visibility = View.GONE\n                }\n            }\n        }\n    }\n\n    @SafeVarargs\n    private fun removeFavs(excludeList: List<String>, vararg lists: MutableList<String>) {\n        lists.forEach { list ->\n            list.removeAll(list.filter { excludeList.contains(it) })\n        }\n    }\n\n    private fun getList(vararg status: GenreStatusObject): MutableList<String> {\n        return dao.getAidsByGenres(getString(*status))\n    }\n\n    private fun getAnimeList(list: List<String>): MutableList<AnimeShortObject> {\n        val chunk = list.chunked(900)\n        val animes = mutableListOf<AnimeShortObject>()\n        chunk.forEach {\n            animes.addAll(CacheDB.INSTANCE.animeDAO().getAnimesByAids(it))\n        }\n        return animes\n    }\n\n    private fun getString(vararg status: GenreStatusObject): String {\n        val builder = StringBuilder(\"%\")\n        for (s in status) {\n            builder.append(s.name)\n                    .append(\"%\")\n        }\n        return builder.toString()\n    }\n\n    private fun getStringTitle(vararg status: GenreStatusObject): String {\n        val builder = StringBuilder()\n        for (s in status) {\n            builder.append(s.name)\n                    .append(\", \")\n        }\n        return builder.toString().substring(0, builder.length - 2)\n    }\n\n    private fun setState(stateString: String) {\n        runOnUiThread {\n            state.text = stateString\n        }\n    }\n\n    private fun showBlacklist() {\n        lifecycleScope.launch(Dispatchers.Main) {\n            val blacklist = withContext(Dispatchers.IO) { GenreStatusObject.names(CacheDB.INSTANCE.genresDAO().blacklist) }\n            val dialog = BlacklistDialog()\n            dialog.init(blacklist, object : BlacklistDialog.MultiChoiceListener {\n                override fun onOkay(selected: MutableList<String>) {\n                    setBlacklist(selected)\n                }\n            })\n            dialog.show(supportFragmentManager, \"Blacklist\")\n        }\n    }\n\n    private fun setBlacklist(selected: MutableList<String>) {\n        doAsync {\n            for (s in selected)\n                RecommendHelper.block(s)\n            for (statusObject in CacheDB.INSTANCE.genresDAO().all)\n                if (statusObject.isBlocked && !selected.contains(statusObject.name))\n                    RecommendHelper.reset(statusObject.name)\n            resetSuggestions()\n        }\n    }\n\n    private fun resetSuggestions() {\n        setState(\"Iniciando búsqueda\")\n        runOnUiThread {\n            val adapter = recyclerView.adapter as SectionedRecyclerViewAdapter?\n            if (adapter != null) {\n                adapter.removeAllSections()\n                recyclerView.adapter = adapter\n                loading.visibility = View.VISIBLE\n                error.visibility = View.GONE\n                setAdapter()\n            }\n        }\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_suggestions, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.blacklist -> showBlacklist()\n            R.id.rating -> RankingActivityMaterial.open(this)\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        if (resultCode == 4321)\n            resetSuggestions()\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, RecommendActivityMaterial::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/RecommendHelper.kt",
    "content": "package knf.kuma.recommended\n\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.removeAll\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.GenreStatusObject\nimport org.jetbrains.anko.doAsync\n\n/**\n * Created by jordy on 26/03/2018.\n */\n\nobject RecommendHelper {\n    fun registerAll(list: MutableList<String>, type: RankType) {\n        doAsync {\n            for (genre in list)\n                register(genre, type)\n            syncData { genres() }\n        }\n    }\n\n    private fun register(name: String, type: RankType) {\n        doAsync {\n            val status = getStatus(name)\n            if (!status.isBlocked) {\n                when (type) {\n                    RankType.FAV -> status.add(3)\n                    RankType.UNFAV -> status.sub(3)\n                    RankType.FOLLOW -> status.add(2)\n                    RankType.UNFOLLOW -> status.sub(2)\n                    RankType.CHECK -> status.add(1)\n                    RankType.SEARCH -> status.add(1)\n                }\n                CacheDB.INSTANCE.genresDAO().insertStatus(status)\n            }\n        }\n    }\n\n    fun block(name: String) {\n        doAsync {\n            val status = getStatus(name)\n            status.block()\n            CacheDB.INSTANCE.genresDAO().insertStatus(status)\n            syncData { genres() }\n        }\n    }\n\n    fun reset(name: String) {\n        doAsync {\n            val status = getStatus(name)\n            status.reset()\n            CacheDB.INSTANCE.genresDAO().insertStatus(status)\n            syncData { genres() }\n        }\n    }\n\n    private fun getStatus(name: String): GenreStatusObject {\n        var status: GenreStatusObject? = CacheDB.INSTANCE.genresDAO().getStatus(name)\n        if (status == null) status = GenreStatusObject(name)\n        return status\n    }\n\n    fun createRecommended(onCreate: (list: List<AnimeShortObject>) -> Unit) {\n        doAsync {\n            val status = CacheDB.INSTANCE.genresDAO().top\n            if (status.size <= 2) {\n                onCreate(emptyList())\n                return@doAsync\n            }\n            val excludeList = LinkedHashSet<String>().apply {\n                addAll(CacheDB.INSTANCE.favsDAO().allAids)\n                addAll(CacheDB.INSTANCE.seeingDAO().allAids)\n            }.toList()\n            val abc = getList(status[0], status[1], status[2])\n            val ab = getList(status[0], status[1])\n            ab.removeAll(abc)\n            val ac = getList(status[0], status[2])\n            ac.removeAll(abc, ab)\n            val bc = getList(status[1], status[2])\n            bc.removeAll(abc, ab, ac)\n            val a = getList(status[0])\n            a.removeAll(abc, ab, ac, bc)\n            val b = getList(status[1])\n            b.removeAll(abc, ab, ac, bc, a)\n            val c = getList(status[2])\n            c.removeAll(abc, ab, ac, bc, a, b)\n            removeFavs(excludeList, abc, ab, ac, bc, a, b, c)\n            val list = mutableListOf<AnimeShortObject>().apply {\n                addAll(getAnimeList(abc))\n                addAll(getAnimeList(ab))\n                addAll(getAnimeList(ac))\n                addAll(getAnimeList(bc))\n                addAll(getAnimeList(a))\n                addAll(getAnimeList(b))\n                addAll(getAnimeList(c))\n            }\n            onCreate(list)\n        }\n    }\n\n    @SafeVarargs\n    private fun removeFavs(excludeList: List<String>, vararg lists: MutableList<String>) {\n        lists.forEach { list ->\n            list.removeAll(list.filter { excludeList.contains(it) })\n        }\n    }\n\n    private fun getList(vararg status: GenreStatusObject): MutableList<String> {\n        return CacheDB.INSTANCE.animeDAO().getAidsByGenresLimited(getString(*status))\n    }\n\n    private fun getAnimeList(list: List<String>): MutableList<AnimeShortObject> {\n        val chunk = list.chunked(900)\n        val animes = mutableListOf<AnimeShortObject>()\n        chunk.forEach {\n            animes.addAll(CacheDB.INSTANCE.animeDAO().getAnimesByAids(it))\n        }\n        return animes\n    }\n\n    private fun getString(vararg status: GenreStatusObject): String {\n        val builder = StringBuilder(\"%\")\n        for (s in status) {\n            builder.append(s.name)\n                    .append(\"%\")\n        }\n        return builder.toString()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/sections/MultipleSection.kt",
    "content": "package knf.kuma.recommended.sections\n\nimport android.app.Activity\nimport android.view.View\nimport androidx.recyclerview.widget.RecyclerView\nimport io.github.luizgrp.sectionedrecyclerviewadapter.SectionParameters\nimport io.github.luizgrp.sectionedrecyclerviewadapter.StatelessSection\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.load\nimport knf.kuma.recommended.AnimeShortObject\nimport knf.kuma.recommended.RHHolder\nimport knf.kuma.recommended.RIHolder\n\n/**\n * Created by jordy on 26/03/2018.\n */\n\nclass MultipleSection(private val activity: Activity, private val name: String, list: MutableList<AnimeShortObject>, isGrid: Boolean) : StatelessSection(SectionParameters.builder()\n        .itemResourceId(if (isGrid) R.layout.item_fav_grid else R.layout.item_fav)\n        .headerResourceId(R.layout.item_recommend_header)\n        .build()) {\n    private val animeObjects = list\n\n    override fun getContentItemsTotal(): Int {\n        return animeObjects.size\n    }\n\n    override fun getItemViewHolder(view: View): RecyclerView.ViewHolder {\n        return RIHolder(view)\n    }\n\n    override fun onBindItemViewHolder(h: RecyclerView.ViewHolder, position: Int) {\n        val holder = h as RIHolder\n        val animeObject = animeObjects[position]\n        holder.img.load(PatternUtil.getCover(animeObject.aid))\n        holder.title.text = animeObject.name\n        holder.type.text = animeObject.type\n        holder.cardView.setOnClickListener { ActivityAnime.open(activity, animeObject, holder.img, true, true) }\n    }\n\n    override fun getHeaderViewHolder(view: View): RecyclerView.ViewHolder {\n        return RHHolder(view)\n    }\n\n    override fun onBindHeaderViewHolder(h: RecyclerView.ViewHolder?) {\n        val holder = h as RHHolder?\n        holder?.title?.text = name\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/recommended/sections/MultipleSectionMaterial.kt",
    "content": "package knf.kuma.recommended.sections\n\nimport android.app.Activity\nimport android.view.View\nimport androidx.recyclerview.widget.RecyclerView\nimport io.github.luizgrp.sectionedrecyclerviewadapter.SectionParameters\nimport io.github.luizgrp.sectionedrecyclerviewadapter.StatelessSection\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.load\nimport knf.kuma.recommended.AnimeShortObject\nimport knf.kuma.recommended.RHHolder\nimport knf.kuma.recommended.RIHolder\n\n/**\n * Created by jordy on 26/03/2018.\n */\n\nclass MultipleSectionMaterial(private val activity: Activity, private val name: String, list: MutableList<AnimeShortObject>, isGrid: Boolean) : StatelessSection(SectionParameters.builder()\n        .itemResourceId(if (isGrid) R.layout.item_fav_grid_material else R.layout.item_fav_material)\n        .headerResourceId(R.layout.item_recommend_header)\n        .build()) {\n    private val animeObjects = list\n\n    override fun getContentItemsTotal(): Int {\n        return animeObjects.size\n    }\n\n    override fun getItemViewHolder(view: View): RecyclerView.ViewHolder {\n        return RIHolder(view)\n    }\n\n    override fun onBindItemViewHolder(h: RecyclerView.ViewHolder, position: Int) {\n        val holder = h as RIHolder\n        val animeObject = animeObjects[position]\n        holder.img.load(PatternUtil.getCover(animeObject.aid))\n        holder.title.text = animeObject.name\n        holder.type.text = animeObject.type\n        holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(activity, animeObject, holder.img, true, true) }\n    }\n\n    override fun getHeaderViewHolder(view: View): RecyclerView.ViewHolder {\n        return RHHolder(view)\n    }\n\n    override fun onBindHeaderViewHolder(h: RecyclerView.ViewHolder?) {\n        val holder = h as RHHolder?\n        holder?.title?.text = name\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/record/RecordActivity.kt",
    "content": "package knf.kuma.record\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.FrameLayout\nimport android.widget.ProgressBar\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.widget.Toolbar\nimport androidx.lifecycle.Observer\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.commons.toast\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\n\nclass RecordActivity : GenericActivity() {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    val recyclerView: RecyclerView by bind(R.id.recycler)\n    val progressBar: ProgressBar by bind(R.id.progress)\n    val error: View by bind(R.id.error)\n    private var adapter: RecordsAdapter? = null\n    private var isFirst = true\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_records\n        } else {\n            R.layout.recycler_records_grid\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(layout)\n        toolbar.title = \"Historial\"\n        setSupportActionBar(toolbar)\n        find<FrameLayout>(R.id.adContainer).implBanner(AdsType.RECORD_BANNER, true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        toolbar.setNavigationOnClickListener { finish() }\n        adapter = RecordsAdapter(this)\n        recyclerView.verifyManager()\n        recyclerView.adapter = adapter\n        val touchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.RIGHT, ItemTouchHelper.RIGHT) {\n            override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {\n                return false\n            }\n\n            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {\n                adapter?.remove(viewHolder.adapterPosition)\n                recyclerView.showSnackbar(\"Elemento eliminado\")\n            }\n        })\n        touchHelper.attachToRecyclerView(recyclerView)\n        CacheDB.INSTANCE.recordsDAO().allLive.observe(this, Observer { recordObjects ->\n            adapter?.update(recordObjects)\n            if (isFirst) {\n                isFirst = false\n                recyclerView.scheduleLayoutAnimation()\n            } else\n                syncData { history() }\n            if (recordObjects.isEmpty())\n                error.visibility = View.VISIBLE\n            else\n                error.visibility = View.GONE\n            progressBar.visibility = View.GONE\n        })\n        showRandomInterstitial(this,PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_records, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_clear ->\n                MaterialDialog(this@RecordActivity).safeShow {\n                    message(text = \"¿Limpiar el historial?\")\n                    positiveButton(text = \"Continuar\") { doAsync { CacheDB.INSTANCE.recordsDAO().clear() } }\n                    negativeButton(text = \"cancelar\")\n                }\n            R.id.action_status -> doAsync {\n                val count = CacheDB.INSTANCE.seenDAO().count\n                doOnUI { \"$count episodios vistos\".toast() }\n            }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, RecordActivity::class.java))\n            AchievementManager.onRecordsOpened()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/record/RecordActivityMaterial.kt",
    "content": "package knf.kuma.record\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport android.view.View\nimport android.widget.FrameLayout\nimport android.widget.ProgressBar\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.widget.Toolbar\nimport androidx.lifecycle.Observer\nimport androidx.recyclerview.widget.ItemTouchHelper\nimport androidx.recyclerview.widget.RecyclerView\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.R\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.ads.AdsType\nimport knf.kuma.ads.implBanner\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.commons.toast\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.database.CacheDB\nimport org.jetbrains.anko.doAsync\nimport org.jetbrains.anko.find\n\nclass RecordActivityMaterial : GenericActivity() {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    val recyclerView: RecyclerView by bind(R.id.recycler)\n    val progressBar: ProgressBar by bind(R.id.progress)\n    val error: View by bind(R.id.error)\n    private var adapter: RecordsAdapterMaterial? = null\n    private var isFirst = true\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.recycler_records_material\n        } else {\n            R.layout.recycler_records_grid_material\n        }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(layout)\n        toolbar.title = \"Historial\"\n        setSupportActionBar(toolbar)\n        find<FrameLayout>(R.id.adContainer).implBanner(AdsType.RECORD_BANNER, true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        toolbar.setNavigationOnClickListener { finish() }\n        adapter = RecordsAdapterMaterial(this)\n        recyclerView.verifyManager()\n        recyclerView.adapter = adapter\n        val touchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.RIGHT, ItemTouchHelper.RIGHT) {\n            override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {\n                return false\n            }\n\n            override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {\n                adapter?.remove(viewHolder.adapterPosition)\n                recyclerView.showSnackbar(\"Elemento eliminado\")\n            }\n        })\n        touchHelper.attachToRecyclerView(recyclerView)\n        CacheDB.INSTANCE.recordsDAO().allLive.observe(this, Observer { recordObjects ->\n            adapter?.update(recordObjects)\n            if (isFirst) {\n                isFirst = false\n                recyclerView.scheduleLayoutAnimation()\n            } else\n                syncData { history() }\n            if (recordObjects.isEmpty())\n                error.visibility = View.VISIBLE\n            else\n                error.visibility = View.GONE\n            progressBar.visibility = View.GONE\n        })\n        showRandomInterstitial(this,PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_records, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.action_clear ->\n                MaterialDialog(this@RecordActivityMaterial).safeShow {\n                    message(text = \"¿Limpiar el historial?\")\n                    positiveButton(text = \"Continuar\") { doAsync { CacheDB.INSTANCE.recordsDAO().clear() } }\n                    negativeButton(text = \"cancelar\")\n                }\n            R.id.action_status -> doAsync {\n                val count = CacheDB.INSTANCE.seenDAO().count\n                doOnUI { \"$count episodios vistos\".toast() }\n            }\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, RecordActivityMaterial::class.java))\n            AchievementManager.onRecordsOpened()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/record/RecordsAdapter.kt",
    "content": "package knf.kuma.record\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.RecordObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport xdroid.toaster.Toaster\n\nclass RecordsAdapter(private val activity: AppCompatActivity) : RecyclerView.Adapter<RecordsAdapter.RecordItem>() {\n    private var items: MutableList<RecordObject> = ArrayList()\n\n    private val dao = CacheDB.INSTANCE.recordsDAO()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_record\n        } else {\n            R.layout.item_record_grid\n        }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecordItem {\n        return RecordItem(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: RecordItem, position: Int) {\n        val item = items[position]\n        val animeObject = item.animeObject\n        animeObject?.let { holder.imageView.load(PatternUtil.getCover(animeObject.aid)) }\n        holder.title.text = item.name\n        holder.chapter.text = getCardText(item)\n        holder.cardView.setOnClickListener {\n            if (item.animeObject != null)\n                ActivityAnime.open(activity, item, holder.imageView)\n            else\n                Toaster.toast(\"Error al abrir\")\n        }\n    }\n\n    private fun getCardText(recordObject: RecordObject): String {\n        return if (!recordObject.chapter.startsWith(\"Episodio \"))\n            \"Episodio ${recordObject.chapter}\"\n        else\n            recordObject.chapter\n    }\n\n    override fun getItemCount(): Int {\n        return items.size\n    }\n\n    fun remove(position: Int) {\n        activity.lifecycleScope.launch(Dispatchers.IO){\n            dao.delete(items[position])\n            items.removeAt(position)\n            launch(Dispatchers.Main) {\n                notifyItemRemoved(position)\n            }\n        }\n    }\n\n    fun update(items: MutableList<RecordObject>) {\n        if (this.items notSameContent items) {\n            this.items = items\n            notifyDataSetChanged()\n        }\n    }\n\n    class RecordItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val chapter: TextView by itemView.bind(R.id.chapter)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/record/RecordsAdapterMaterial.kt",
    "content": "package knf.kuma.record\n\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.annotation.LayoutRes\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.commons.notSameContent\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.RecordObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport xdroid.toaster.Toaster\n\nclass RecordsAdapterMaterial(private val activity: AppCompatActivity) : RecyclerView.Adapter<RecordsAdapterMaterial.RecordItem>() {\n    private var items: MutableList<RecordObject> = ArrayList()\n\n    private val dao = CacheDB.INSTANCE.recordsDAO()\n\n    private val layout: Int\n        @LayoutRes\n        get() = if (PrefsUtil.layType == \"0\") {\n            R.layout.item_record_material\n        } else {\n            R.layout.item_record_grid_material\n        }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecordItem {\n        return RecordItem(LayoutInflater.from(parent.context).inflate(layout, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: RecordItem, position: Int) {\n        val item = items[position]\n        val animeObject = item.animeObject\n        animeObject?.let { holder.imageView.load(PatternUtil.getCover(animeObject.aid)) }\n        holder.title.text = item.name\n        holder.chapter.text = getCardText(item)\n        holder.cardView.setOnClickListener {\n            if (item.animeObject != null)\n                ActivityAnimeMaterial.open(activity, item, holder.imageView)\n            else\n                Toaster.toast(\"Error al abrir\")\n        }\n    }\n\n    private fun getCardText(recordObject: RecordObject): String {\n        return if (!recordObject.chapter.startsWith(\"Episodio \"))\n            \"Episodio ${recordObject.chapter}\"\n        else\n            recordObject.chapter\n    }\n\n    override fun getItemCount(): Int {\n        return items.size\n    }\n\n    fun remove(position: Int) {\n        activity.lifecycleScope.launch(Dispatchers.IO){\n            dao.delete(items[position])\n            items.removeAt(position)\n            launch(Dispatchers.Main) {\n                notifyItemRemoved(position)\n            }\n        }\n    }\n\n    fun update(items: MutableList<RecordObject>) {\n        if (this.items notSameContent items) {\n            this.items = items\n            notifyDataSetChanged()\n        }\n    }\n\n    class RecordItem(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val title: TextView by itemView.bind(R.id.title)\n        val chapter: TextView by itemView.bind(R.id.chapter)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/retrofit/Repository.kt",
    "content": "package knf.kuma.retrofit\n\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport androidx.paging.DataSource\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.PagingData\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.commons.jsoupCookiesAdapter\nimport knf.kuma.database.CacheDB\nimport knf.kuma.directory.DirObject\nimport knf.kuma.directory.DirObjectCompact\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.pojos.Recents\nimport knf.kuma.recents.RecentsPage\nimport knf.kuma.search.SearchCompactDataSource\nimport knf.kuma.search.SearchObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport pl.droidsonroids.jspoon.Jspoon\nimport java.util.Locale\nimport javax.inject.Singleton\n\n@Singleton\nclass Repository {\n\n    val search: Flow<PagingData<SearchObject>>\n        get() = getSearch(\"\")\n\n    fun reloadAllRecents() {\n        reloadRecents()\n        reloadRecentsAlt()\n    }\n\n    fun reloadRecents() {\n        if (Network.isConnected) {\n            GlobalScope.launch(Dispatchers.IO) {\n                try {\n                    val recents = Jspoon.create().adapter(Recents::class.java).fromHtml(jsoupCookies(\"https://www3.animeflv.net/\").get().outerHtml())\n                    val objects = RecentObject.create(recents.list)\n                    for ((i, recentObject) in objects.withIndex()) {\n                        recentObject.key = i\n                        recentObject.fileWrapper()\n                    }\n                    CacheDB.INSTANCE.recentsDAO().setCache(objects)\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n            }\n        }\n    }\n\n    fun reloadRecentsAlt() {\n        if (Network.isConnected) {\n            GlobalScope.launch(Dispatchers.IO) {\n                try {\n                    val page = Jspoon.create().adapter(RecentsPage::class.java).fromHtml(jsoupCookies(\"https://animeflv.net/\").get().outerHtml())\n                    val list = page.list.apply {\n                        forEachIndexed { index, model ->\n                            model.key = index\n                        }\n                    }\n                    withContext(Dispatchers.IO) {\n                        CacheDB.INSTANCE.recentModelsDAO().setCache(list)\n                    }\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n            }\n        }\n    }\n\n    fun getAnime(\n        link: String,\n        persist: Boolean,\n        data: MutableLiveData<AnimeObject?> = MutableLiveData<AnimeObject?>()\n    ): LiveData<AnimeObject?> {\n        doAsync {\n            var cacheUsed = false\n            try {\n                val dao = CacheDB.INSTANCE.animeDAO()\n                val dbLink = \"%/${link.substringAfterLast(\"/\")}\"\n                dao.getAnimeRaw(dbLink)?.let {\n                    cacheUsed = true\n                    doOnUIGlobal {\n                        data.value = it\n                    }\n                }\n                if (Network.isConnected) {\n                    val animeObject = AnimeObject(link, jsoupCookiesAdapter(link, AnimeObject.WebInfo::class.java))\n                    if (persist)\n                        dao.insert(animeObject)\n                    doOnUIGlobal { data.value = animeObject }\n                } else if (!cacheUsed)\n                    doOnUIGlobal { data.value = null }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                if (!cacheUsed)\n                    doOnUIGlobal { data.value = null }\n            }\n        }\n        return data\n    }\n\n    fun getAnimeDir(): Flow<PagingData<DirObject>> {\n        return Pager(\n            PagingConfig(25), 0,\n            when (PrefsUtil.dirOrder) {\n                1 -> CacheDB.INSTANCE.animeDAO().animeDirVotes\n                2 -> CacheDB.INSTANCE.animeDAO().animeDirID\n                3 -> CacheDB.INSTANCE.animeDAO().animeDirAdded\n                4 -> CacheDB.INSTANCE.animeDAO().animeDirFollowers\n                else -> CacheDB.INSTANCE.animeDAO().animeDir\n            }.asPagingSourceFactory(Dispatchers.IO)\n        ).flow\n    }\n\n    fun getOvaDir(): Flow<PagingData<DirObject>> {\n        return Pager(\n            PagingConfig(25), 0,\n            when (PrefsUtil.dirOrder) {\n                1 -> CacheDB.INSTANCE.animeDAO().ovaDirVotes\n                2 -> CacheDB.INSTANCE.animeDAO().ovaDirID\n                3 -> CacheDB.INSTANCE.animeDAO().ovaDirAdded\n                4 -> CacheDB.INSTANCE.animeDAO().ovaDirFollowers\n                else -> CacheDB.INSTANCE.animeDAO().ovaDir\n            }.asPagingSourceFactory(Dispatchers.IO)\n        ).flow\n    }\n\n    fun getMovieDir(): Flow<PagingData<DirObject>> {\n        return Pager(\n            PagingConfig(25), 0,\n            when (PrefsUtil.dirOrder) {\n                1 -> CacheDB.INSTANCE.animeDAO().movieDirVotes\n                2 -> CacheDB.INSTANCE.animeDAO().movieDirID\n                3 -> CacheDB.INSTANCE.animeDAO().movieDirAdded\n                4 -> CacheDB.INSTANCE.animeDAO().movieDirFollowers\n                else -> CacheDB.INSTANCE.animeDAO().movieDir\n            }.asPagingSourceFactory(Dispatchers.IO)\n        ).flow\n    }\n\n    fun getSearch(query: String): Flow<PagingData<SearchObject>> {\n        return Pager(\n            PagingConfig(25), 0,\n            when {\n                query == \"\" -> CacheDB.INSTANCE.animeDAO().allSearch\n                query.trim().matches(\"^#\\\\d+$\".toRegex()) -> CacheDB.INSTANCE.animeDAO()\n                    .getSearchID(query.replace(\"#\", \"\"))\n                PatternUtil.isCustomSearch(query) -> getFiltered(query, null)\n                else -> CacheDB.INSTANCE.animeDAO().getSearch(\"%$query%\")\n            }.asPagingSourceFactory(Dispatchers.IO)\n        ).flow\n    }\n\n    private fun getFiltered(query: String, genres: String?): DataSource.Factory<Int, SearchObject> {\n        var tQuery = PatternUtil.getCustomSearch(query).trim { it <= ' ' }\n        var fQuery = tQuery\n        fQuery = if (fQuery != \"\") \"%$fQuery%\" else \"%\"\n        when (PatternUtil.getCustomAttr(query).lowercase(Locale.getDefault())) {\n            \"emision\" -> return if (genres == null)\n                CacheDB.INSTANCE.animeDAO().getSearchS(fQuery, \"En emisión\")\n            else\n                CacheDB.INSTANCE.animeDAO().getSearchSG(fQuery, \"En emisión\", genres)\n            \"finalizado\" -> return if (genres == null)\n                CacheDB.INSTANCE.animeDAO().getSearchS(fQuery, \"Finalizado\")\n            else\n                CacheDB.INSTANCE.animeDAO().getSearchSG(fQuery, \"Finalizado\", genres)\n            \"anime\" -> return if (genres == null)\n                CacheDB.INSTANCE.animeDAO().getSearchTY(fQuery, \"Anime\")\n            else\n                CacheDB.INSTANCE.animeDAO().getSearchTYG(fQuery, \"Anime\", genres)\n            \"ova\" -> return if (genres == null)\n                CacheDB.INSTANCE.animeDAO().getSearchTY(fQuery, \"OVA\")\n            else\n                CacheDB.INSTANCE.animeDAO().getSearchTYG(fQuery, \"OVA\", genres)\n            \"pelicula\" -> return if (genres == null)\n                CacheDB.INSTANCE.animeDAO().getSearchTY(fQuery, \"Película\")\n            else\n                CacheDB.INSTANCE.animeDAO().getSearchTYG(fQuery, \"Película\", genres)\n            \"personalizado\" -> {\n                if (tQuery == \"\")\n                    tQuery = \"%\"\n                return if (genres == null)\n                    CacheDB.INSTANCE.animeDAO().getSearch(tQuery)\n                else\n                    CacheDB.INSTANCE.animeDAO().getSearchTG(tQuery, genres)\n            }\n            else -> return if (genres == null)\n                CacheDB.INSTANCE.animeDAO().getSearch(fQuery)\n            else\n                CacheDB.INSTANCE.animeDAO().getSearchTG(fQuery, genres)\n        }\n    }\n\n    fun getSearch(query: String, genres: String): Flow<PagingData<SearchObject>> {\n        return Pager(\n            PagingConfig(25), 0,\n            when {\n                query == \"\" -> CacheDB.INSTANCE.animeDAO().getSearchG(genres)\n                PatternUtil.isCustomSearch(query) -> getFiltered(query, genres)\n                else -> CacheDB.INSTANCE.animeDAO().getSearchTG(\"%$query%\", genres)\n            }.asPagingSourceFactory(Dispatchers.IO)\n        ).flow\n    }\n\n    fun getSearchCompact(\n        query: String,\n        onInit: (isEmpty: Boolean) -> Unit\n    ): Flow<PagingData<DirObjectCompact>> {\n        return Pager(\n            config = PagingConfig(24),\n            pagingSourceFactory = {\n                SearchCompactDataSource(\n                    query,\n                    onInit\n                )\n            }\n        ).flow\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/FiltersSuggestion.kt",
    "content": "package knf.kuma.search\n\nimport android.content.Context\nimport knf.kuma.R\nimport org.cryse.widget.persistentsearch.SearchItem\nimport org.cryse.widget.persistentsearch.SearchSuggestionsBuilder\n\nclass FiltersSuggestion(private val context: Context) : SearchSuggestionsBuilder {\n\n    override fun buildEmptySearchSuggestion(maxCount: Int): Collection<SearchItem> {\n        return ArrayList()\n    }\n\n    override fun buildSearchSuggestion(maxCount: Int, query: String): Collection<SearchItem> {\n        val items = ArrayList<SearchItem>()\n        if (query == \":\") {\n            val drawable = context.getDrawable(R.drawable.ic_hash)\n            items.add(SearchItem(\"En emisión\", \":emision:\", SearchItem.TYPE_SEARCH_ITEM_CUSTOM, drawable))\n            items.add(SearchItem(\"Finalizados\", \":finalizado:\", SearchItem.TYPE_SEARCH_ITEM_CUSTOM, drawable))\n            items.add(SearchItem(\"Animes\", \":anime:\", SearchItem.TYPE_SEARCH_ITEM_CUSTOM, drawable))\n            items.add(SearchItem(\"Ovas\", \":ova:\", SearchItem.TYPE_SEARCH_ITEM_CUSTOM, drawable))\n            items.add(SearchItem(\"Películas\", \":pelicula:\", SearchItem.TYPE_SEARCH_ITEM_CUSTOM, drawable))\n            items.add(SearchItem(\"Personalizado\", \":personalizado:\", SearchItem.TYPE_SEARCH_ITEM_CUSTOM, drawable))\n        }\n        return items\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/GenreActivity.kt",
    "content": "package knf.kuma.search\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.View\nimport android.view.animation.AnimationUtils\nimport androidx.lifecycle.lifecycleScope\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport knf.kuma.R\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.RecyclerGenreBinding\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.launch\n\nclass GenreActivity : GenericActivity() {\n    private var adapter: GenreAdapter? = null\n    private var isFirst = true\n    private val binding by lazy { RecyclerGenreBinding.inflate(layoutInflater) }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(binding.root)\n        binding.toolbar.title = intent.getStringExtra(\"name\")\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        binding.toolbar.setNavigationOnClickListener { finish() }\n        binding.recycler.layoutManager = VariantLinearLayoutManager(this)\n        binding.recycler.layoutAnimation = AnimationUtils.loadLayoutAnimation(this, R.anim.layout_fall_down)\n        adapter = GenreAdapter(this)\n        binding.recycler.adapter = adapter\n        lifecycleScope.launch {\n            Pager(\n                config = PagingConfig(25), 0,\n                CacheDB.INSTANCE.animeDAO().getAllGenre(\"%\" + intent.getStringExtra(\"name\") + \"%\").asPagingSourceFactory()\n            ).flow.collectLatest {\n                adapter?.submitData(it)\n                binding.progress.visibility = View.GONE\n                if (isFirst) {\n                    isFirst = false\n                    binding.recycler.scheduleLayoutAnimation()\n                }\n            }\n        }\n    }\n\n    companion object {\n\n        fun open(context: Context, name: String) {\n            val intent = Intent(context, GenreActivity::class.java)\n            intent.putExtra(\"name\", name)\n            context.startActivity(intent)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/GenreActivityMaterial.kt",
    "content": "package knf.kuma.search\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.View\nimport android.view.animation.AnimationUtils\nimport androidx.lifecycle.lifecycleScope\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport knf.kuma.R\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.custom.VariantLinearLayoutManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.databinding.RecyclerGenreMaterialBinding\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.launch\n\nclass GenreActivityMaterial : GenericActivity() {\n    private val adapter: GenreAdapterMaterial by lazy { GenreAdapterMaterial(this) }\n    private var isFirst = true\n    private val binding by lazy { RecyclerGenreMaterialBinding.inflate(layoutInflater) }\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(binding.root)\n        binding.toolbar.title = intent.getStringExtra(\"name\")\n        setSupportActionBar(binding.toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        binding.toolbar.setNavigationOnClickListener { finish() }\n        binding.recycler.layoutManager = VariantLinearLayoutManager(this)\n        binding.recycler.layoutAnimation = AnimationUtils.loadLayoutAnimation(this, R.anim.layout_fall_down)\n        binding.recycler.adapter = adapter\n        lifecycleScope.launch {\n            Pager(\n                config = PagingConfig(25), 0,\n                CacheDB.INSTANCE.animeDAO().getAllGenre(\"%\" + intent.getStringExtra(\"name\") + \"%\").asPagingSourceFactory()\n            ).flow.collectLatest {\n                adapter.submitData(it)\n                binding.progress.visibility = View.GONE\n                if (isFirst) {\n                    isFirst = false\n                    binding.recycler.scheduleLayoutAnimation()\n                }\n            }\n        }\n    }\n\n    companion object {\n\n        fun open(context: Context, name: String) {\n            val intent = Intent(context, GenreActivityMaterial::class.java)\n            intent.putExtra(\"name\", name)\n            context.startActivity(intent)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/GenreAdapter.kt",
    "content": "package knf.kuma.search\n\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.load\nimport org.jetbrains.anko.find\n\ninternal class GenreAdapter(private val activity: Activity) : PagingDataAdapter<SearchObject, GenreAdapter.ItemHolder>(DIFF_CALLBACK) {\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {\n        return ItemHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_dir, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\n        val animeObject = getItem(position)\n        animeObject?.let {\n            holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n            holder.textView.text = animeObject.name\n            holder.cardView.setOnClickListener { ActivityAnime.open(activity, animeObject, holder.imageView, false, true) }\n        }\n    }\n\n    internal class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView = itemView.find(R.id.card)\n        val imageView: ImageView = itemView.find(R.id.img)\n        val textView: TextView = itemView.find(R.id.title)\n    }\n\n    companion object {\n\n        val DIFF_CALLBACK = object : DiffUtil.ItemCallback<SearchObject>() {\n            override fun areItemsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean {\n                return oldItem.key == newItem.key\n            }\n\n            override fun areContentsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean {\n                return oldItem.name == newItem.name\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/GenreAdapterMaterial.kt",
    "content": "package knf.kuma.search\n\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.TextView\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.load\nimport org.jetbrains.anko.find\n\ninternal class GenreAdapterMaterial(private val activity: Activity) : PagingDataAdapter<SearchObject, GenreAdapterMaterial.ItemHolder>(DIFF_CALLBACK) {\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {\n        return ItemHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_dir_material, parent, false))\n    }\n\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\n        val animeObject = getItem(position)\n        animeObject?.let {\n            holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n            holder.textView.text = animeObject.name\n            holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(activity, animeObject, holder.imageView, false, true) }\n        }\n    }\n\n    internal class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View = itemView.find(R.id.card)\n        val imageView: ImageView = itemView.find(R.id.img)\n        val textView: TextView = itemView.find(R.id.title)\n    }\n\n    companion object {\n\n        val DIFF_CALLBACK = object : DiffUtil.ItemCallback<SearchObject>() {\n            override fun areItemsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean {\n                return oldItem.key == newItem.key\n            }\n\n            override fun areContentsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean {\n                return oldItem.name == newItem.name\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/GenresDialog.kt",
    "content": "package knf.kuma.search\n\nimport android.app.Dialog\nimport android.os.Bundle\nimport androidx.fragment.app.DialogFragment\nimport androidx.fragment.app.FragmentManager\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\nimport com.afollestad.materialdialogs.list.listItemsMultiChoice\nimport knf.kuma.commons.transform\n\nclass GenresDialog : DialogFragment() {\n\n    private var genres: MutableList<String> = ArrayList()\n    private var selected: MutableList<String> = ArrayList()\n    private var listener: MultiChoiceListener? = null\n\n    private val states: BooleanArray\n        get() {\n            val states = BooleanArray(genres.size)\n            var index = 0\n            for (genre in genres) {\n                states[index++] = selected.contains(genre)\n            }\n            return states\n        }\n\n    private val selectedStates: IntArray\n        get() {\n            val states = IntArray(selected.size)\n            for ((index, item) in selected.withIndex())\n                states[index] = genres.indexOf(item)\n            return states\n        }\n\n    fun init(genres: MutableList<String>, selected: MutableList<String>, listener: MultiChoiceListener) {\n        this.genres = genres\n        this.selected = selected\n        this.listener = listener\n    }\n\n    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {\n        return activity?.let {\n            MaterialDialog(it).apply {\n                lifecycleOwner()\n                title(text = \"Géneros\")\n                listItemsMultiChoice(items = genres, initialSelection = selectedStates, allowEmptySelection = true) { _: MaterialDialog, _: IntArray, items: List<CharSequence> ->\n                    selected.apply {\n                        clear()\n                        addAll(items.transform())\n                        sort()\n                    }\n                    listener?.onOkay(selected)\n                }\n                positiveButton(text = \"BUSCAR\")\n                negativeButton(text = \"CERRAR\")\n            }\n            /*AlertDialog.Builder(it)\n                    .setTitle(\"Generos\")\n                    .setMultiChoiceItems(genres.toTypedArray(), states) { _, index, isSelected ->\n                        if (isSelected)\n                            selected.add(genres[index])\n                        else\n                            selected.remove(genres[index])\n                    }.setPositiveButton(\"BUSCAR\") { _, _ ->\n                        selected.sort()\n                        listener?.onOkay(selected)\n                    }.setNegativeButton(\"CERRAR\") { dialogInterface, _ -> dialogInterface.dismiss() }\n                    .create()*/\n        } ?: super.onCreateDialog(savedInstanceState)\n    }\n\n    override fun show(manager: FragmentManager, tag: String?) {\n        try {\n            super.show(manager, tag)\n        } catch (e: Exception) {\n            //\n        }\n    }\n\n    override fun dismiss() {\n        try {\n            super.dismiss()\n        } catch (e: Exception) {\n            //\n        }\n    }\n\n    interface MultiChoiceListener {\n        fun onOkay(selected: MutableList<String>)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchActivity.kt",
    "content": "package knf.kuma.search\r\n\r\nimport androidx.activity.addCallback\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport androidx.activity.viewModels\r\nimport androidx.core.app.ActivityOptionsCompat\r\nimport androidx.core.widget.addTextChangedListener\r\nimport knf.kuma.R\r\nimport knf.kuma.achievements.AchievementManager\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.setSurfaceBars\r\nimport knf.kuma.custom.GenericActivity\r\nimport knf.kuma.databinding.ActivitySearchBinding\r\n\r\nclass SearchActivity : GenericActivity() {\r\n\r\n    private val model by viewModels<SearchViewModel>()\r\n    private val binding by lazy { ActivitySearchBinding.inflate(layoutInflater) }\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        setTheme(EAHelper.getTheme())\r\n        super.onCreate(savedInstanceState)\r\n        setSurfaceBars()\r\n        setContentView(binding.root)\r\n        setSupportActionBar(binding.toolbar)\r\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\r\n        binding.etSearch.setText(model.queryListener.value)\r\n        binding.etSearch.requestFocus()\r\n        binding.etSearch.addTextChangedListener(afterTextChanged = {\r\n            EAHelper.checkStart(it.toString())\r\n            AchievementManager.onSearch(it.toString())\r\n            model.sendQuery(it?.toString())\r\n        })\r\n        onBackPressedDispatcher.addCallback(this) {\r\n            finish()\r\n            overridePendingTransition(R.anim.fade_in, R.anim.fade_out)\r\n        }\r\n    }\r\n\r\n    override fun onSupportNavigateUp(): Boolean {\r\n        onBackPressedDispatcher.onBackPressed()\r\n        return super.onSupportNavigateUp()\r\n    }\r\n\r\n    companion object {\r\n        fun open(context: Context) {\r\n            context.startActivity(Intent(context, SearchActivity::class.java), ActivityOptionsCompat.makeCustomAnimation(context, R.anim.fade_in, R.anim.fade_out).toBundle())\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchAdapter.kt",
    "content": "package knf.kuma.search\n\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.fragment.app.Fragment\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\n\nclass SearchAdapter internal constructor(private val fragment: Fragment) :\n    PagingDataAdapter<SearchObject, SearchAdapter.ItemHolder>(DIFF_CALLBACK) {\n\n    private val layType = PrefsUtil.layType\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {\n        return ItemHolder(\n            LayoutInflater.from(parent.context).inflate(\n                if (layType == \"0\")\n                    R.layout.item_dir\n                else\n                    R.layout.item_dir_grid, parent, false\n            )\n        )\n    }\n\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\n        if (fragment.context == null) return\n        val animeObject = getItem(position)\n        if (animeObject != null) {\n            holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n            holder.progressView.visibility = View.GONE\n            holder.textView.text = animeObject.name\n            holder.cardView.setOnClickListener { ActivityAnime.open(fragment, animeObject, holder.imageView, false, true) }\n        } else {\n            holder.progressView.visibility = View.VISIBLE\n            holder.textView.text = null\n        }\n    }\n\n    class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val progressView: ProgressBar by itemView.bind(R.id.progress)\n        val textView: TextView by itemView.bind(R.id.title)\n    }\n\n    companion object {\n\n        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<SearchObject>() {\n            override fun areItemsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean {\n                return oldItem.key == newItem.key\n            }\n\n            override fun areContentsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean {\n                return oldItem.name == newItem.name && oldItem.aid == newItem.aid\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchAdapterCompact.kt",
    "content": "package knf.kuma.search\n\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.fragment.app.Fragment\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.directory.DirObjectCompact\n\nclass SearchAdapterCompact internal constructor(private val fragment: Fragment) :\n    PagingDataAdapter<DirObjectCompact, SearchAdapterCompact.ItemHolder>(DIFF_CALLBACK) {\n\n    private val layType = PrefsUtil.layType\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {\n        return ItemHolder(\n            LayoutInflater.from(parent.context).inflate(\n                if (layType == \"0\")\n                    R.layout.item_dir\n                else\n                    R.layout.item_dir_grid, parent, false\n            )\n        )\n    }\n\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\n        if (fragment.context == null) return\n        val animeObject = getItem(position)\n        if (animeObject != null) {\n            holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n            holder.progressView.visibility = View.GONE\n            holder.textView.text = animeObject.name\n            holder.cardView.setOnClickListener { ActivityAnime.open(fragment, animeObject, holder.imageView, persist = true, animate = true) }\n        } else {\n            holder.progressView.visibility = View.VISIBLE\n            holder.textView.text = null\n        }\n    }\n\n    class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val progressView: ProgressBar by itemView.bind(R.id.progress)\n        val textView: TextView by itemView.bind(R.id.title)\n    }\n\n    companion object {\n\n        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<DirObjectCompact>() {\n            override fun areItemsTheSame(oldItem: DirObjectCompact, newItem: DirObjectCompact): Boolean {\n                return oldItem.aid == newItem.aid\n            }\n\n            override fun areContentsTheSame(oldItem: DirObjectCompact, newItem: DirObjectCompact): Boolean {\n                return oldItem.name == newItem.name && oldItem.aid == newItem.aid\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchAdapterCompactMaterial.kt",
    "content": "package knf.kuma.search\n\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.fragment.app.Fragment\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\nimport knf.kuma.directory.DirObjectCompact\n\nclass SearchAdapterCompactMaterial internal constructor(private val fragment: Fragment) :\n    PagingDataAdapter<DirObjectCompact, SearchAdapterCompactMaterial.ItemHolder>(DIFF_CALLBACK) {\n\n    private val layType = PrefsUtil.layType\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {\n        return ItemHolder(\n            LayoutInflater.from(parent.context).inflate(\n                if (layType == \"0\")\n                    R.layout.item_dir_material\n                else\n                    R.layout.item_dir_grid_material, parent, false\n            )\n        )\n    }\n\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\n        if (fragment.context == null) return\n        val animeObject = getItem(position)\n        if (animeObject != null) {\n            holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n            holder.progressView.visibility = View.GONE\n            holder.textView.text = animeObject.name\n            holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(fragment, animeObject, holder.imageView, persist = true, animate = true) }\n        } else {\n            holder.progressView.visibility = View.VISIBLE\n            holder.textView.text = null\n        }\n    }\n\n    class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val progressView: ProgressBar by itemView.bind(R.id.progress)\n        val textView: TextView by itemView.bind(R.id.title)\n    }\n\n    companion object {\n\n        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<DirObjectCompact>() {\n            override fun areItemsTheSame(oldItem: DirObjectCompact, newItem: DirObjectCompact): Boolean {\n                return oldItem.aid == newItem.aid\n            }\n\n            override fun areContentsTheSame(oldItem: DirObjectCompact, newItem: DirObjectCompact): Boolean {\n                return oldItem.name == newItem.name && oldItem.aid == newItem.aid\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchAdapterMaterial.kt",
    "content": "package knf.kuma.search\n\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.fragment.app.Fragment\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.load\n\nclass SearchAdapterMaterial internal constructor(private val fragment: Fragment) :\n    PagingDataAdapter<SearchObject, SearchAdapterMaterial.ItemHolder>(DIFF_CALLBACK) {\n\n    private val layType = PrefsUtil.layType\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemHolder {\n        return ItemHolder(\n            LayoutInflater.from(parent.context).inflate(\n                if (layType == \"0\")\n                    R.layout.item_dir_material\n                else\n                    R.layout.item_dir_grid_material, parent, false\n            )\n        )\n    }\n\n    override fun onBindViewHolder(holder: ItemHolder, position: Int) {\n        if (fragment.context == null) return\n        val animeObject = getItem(position)\n        if (animeObject != null) {\n            holder.imageView.load(PatternUtil.getCover(animeObject.aid))\n            holder.progressView.visibility = View.GONE\n            holder.textView.text = animeObject.name\n            holder.cardView.setOnClickListener { ActivityAnimeMaterial.open(fragment, animeObject, holder.imageView, false, true) }\n        } else {\n            holder.progressView.visibility = View.VISIBLE\n            holder.textView.text = null\n        }\n    }\n\n    class ItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val progressView: ProgressBar by itemView.bind(R.id.progress)\n        val textView: TextView by itemView.bind(R.id.title)\n    }\n\n    companion object {\n\n        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<SearchObject>() {\n            override fun areItemsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean {\n                return oldItem.key == newItem.key\n            }\n\n            override fun areContentsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean {\n                return oldItem.name == newItem.name && oldItem.aid == newItem.aid\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchAdvObject.kt",
    "content": "package knf.kuma.search\r\n\r\nimport com.google.gson.annotations.SerializedName\r\n\r\nclass SearchAdvObject : SearchObject() {\r\n    @SerializedName(\"adv_img\")\r\n    var img = \"\"\r\n    @SerializedName(\"adv_type\")\r\n    var type = \"\"\r\n\r\n    override fun equals(other: Any?): Boolean {\r\n        return other is SearchAdvObject &&\r\n                key == other.key &&\r\n                aid == other.aid &&\r\n                name == other.name &&\r\n                link == other.link &&\r\n                img == other.img &&\r\n                type == other.type\r\n    }\r\n\r\n    override fun hashCode(): Int {\r\n        return \"$key$aid$name$link$img$type\".hashCode()\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchCompactDataSource.kt",
    "content": "package knf.kuma.search\r\n\r\nimport androidx.paging.PagingSource\r\nimport androidx.paging.PagingState\r\nimport knf.kuma.commons.jsoupCookiesAdapter\r\nimport knf.kuma.directory.DirObjectCompact\r\nimport knf.kuma.directory.DirectoryPageCompact\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.withContext\r\nimport java.net.URLEncoder\r\n\r\nclass SearchCompactDataSource(\r\n    val query: String,\r\n    val onInit: (isEmpty: Boolean) -> Unit\r\n) : PagingSource<Int, DirObjectCompact>() {\r\n\r\n    override fun getRefreshKey(state: PagingState<Int, DirObjectCompact>): Int? =\r\n        state.anchorPosition\r\n\r\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, DirObjectCompact> {\r\n        val page = params.key ?: 1\r\n        try {\r\n            val dir = withContext(Dispatchers.IO) {\r\n                jsoupCookiesAdapter(\"https://www3.animeflv.net/browse?order=title&q=${URLEncoder.encode(query, \"utf-8\")}&page=$page\", DirectoryPageCompact::class.java)\r\n            }\r\n            if (page == 1)\r\n                onInit(dir.list.isEmpty())\r\n            return LoadResult.Page(dir.list, null, if (dir.hasNext) page + 1 else null)\r\n        }catch (e:Exception){\r\n            e.printStackTrace()\r\n            if (page == 1)\r\n                onInit(true)\r\n            return LoadResult.Page(emptyList(), null, null)\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchFragment.kt",
    "content": "package knf.kuma.search\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport androidx.annotation.DrawableRes\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updateLayoutParams\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.lifecycleScope\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton\nimport com.google.android.material.snackbar.Snackbar\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.recommended.RankType\nimport knf.kuma.recommended.RecommendHelper\nimport knf.kuma.retrofit.Repository\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.find\n\nclass SearchFragment : BottomFragment() {\n    lateinit var recyclerView: RecyclerView\n    lateinit var fab: ExtendedFloatingActionButton\n    lateinit var progressBar: ProgressBar\n    private lateinit var errorView: View\n\n    private val model: SearchViewModel by activityViewModels()\n    private var searchAdapter: SearchAdapter? = null\n    private var searchAdapterCompact: SearchAdapterCompact? = null\n    private var manager: RecyclerView.LayoutManager? = null\n\n    private var isFirst = true\n    private var waitingScroll = false\n\n    private var query: String = \"\"\n\n    private var selected: MutableList<String> = ArrayList()\n\n    private val needOnlineSearch: Boolean by lazy { !PrefsUtil.isDirectoryFinished && Network.isConnected && isFullMode && !PrefsUtil.isFamilyFriendly }\n\n    private val genresString: String\n        get() {\n            return if (selected.size == 0) {\n                \"\"\n            } else {\n                RecommendHelper.registerAll(selected, RankType.SEARCH)\n                val builder = StringBuilder(\"%\")\n                for (genre in selected) {\n                    builder.append(genre)\n                            .append(\"%\")\n                }\n                builder.toString()\n            }\n        }\n\n    private val fabIcon: Int\n        @DrawableRes\n        get() {\n            return when (selected.size) {\n                0 -> R.drawable.ic_genres_0\n                1 -> R.drawable.ic_genres_1\n                2 -> R.drawable.ic_genres_2\n                3 -> R.drawable.ic_genres_3\n                4 -> R.drawable.ic_genres_4\n                5 -> R.drawable.ic_genres_5\n                6 -> R.drawable.ic_genres_6\n                7 -> R.drawable.ic_genres_7\n                8 -> R.drawable.ic_genres_8\n                9 -> R.drawable.ic_genres_9\n                else -> R.drawable.ic_genres_more\n            }\n        }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        noCrash {\n            if (!needOnlineSearch)\n                model.setSearch(query, \"\") { animeObjects ->\n                    searchAdapter?.submitData(animeObjects)\n                    if (isFirst) {\n                        progressBar.visibility = View.GONE\n                        isFirst = false\n                        recyclerView.scheduleLayoutAnimation()\n                    }\n                }\n            searchAdapter?.addLoadStateListener {\n                if (it.append.endOfPaginationReached) {\n                    errorView.visibility =\n                        if (searchAdapter?.itemCount == 0) View.VISIBLE else View.GONE\n                }\n            }\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(\n                if (PrefsUtil.layType == \"0\")\n                    R.layout.fragment_search\n                else\n                    R.layout.fragment_search_grid, container, false)\n        recyclerView = view.find(R.id.recycler)\n        fab = view.find(R.id.fab)\n        progressBar = view.find(R.id.progress)\n        errorView = view.find(R.id.error)\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(view) { _, insets ->\n            fab.updateLayoutParams<ViewGroup.MarginLayoutParams> {\n                bottomMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom * 2\n            }\n            WindowInsetsCompat.CONSUMED\n        }\n        recyclerView.verifyManager()\n        recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {\n            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {\n                if (dy > 0)\n                    fab.shrink()\n                else if (dy < 0)\n                    fab.extend()\n            }\n        })\n        manager = recyclerView.layoutManager\n        if (needOnlineSearch) {\n            searchAdapterCompact = SearchAdapterCompact(this)\n            lifecycleScope.launch {\n                Repository().getSearchCompact(\"\") {\n                    if (it) {\n                        errorView.visibility = if (it) View.VISIBLE else View.GONE\n                    }\n                    if (isFirst) {\n                        progressBar.visibility = View.GONE\n                        isFirst = false\n                        recyclerView.scheduleLayoutAnimation()\n                    }\n                }.collect {\n                    searchAdapterCompact?.submitData(it)\n                }\n            }\n            searchAdapterCompact?.registerAdapterDataObserver(object :\n                RecyclerView.AdapterDataObserver() {\n                override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {\n                    super.onItemRangeMoved(fromPosition, toPosition, itemCount)\n                    if (toPosition == 0 && waitingScroll) {\n                        manager?.smoothScrollToPosition(recyclerView, null, 0)\n                        waitingScroll = false\n                    }\n                }\n            })\n            recyclerView.adapter = searchAdapterCompact\n        } else {\n            searchAdapter = SearchAdapter(this)\n            searchAdapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {\n                override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {\n                    super.onItemRangeMoved(fromPosition, toPosition, itemCount)\n                    if (toPosition == 0 && waitingScroll) {\n                        manager?.smoothScrollToPosition(recyclerView, null, 0)\n                        fab.extend()\n                        waitingScroll = false\n                    }\n                }\n\n                override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {\n                    super.onItemRangeInserted(positionStart, itemCount)\n                    if (positionStart == 0 && waitingScroll) {\n                        manager?.smoothScrollToPosition(recyclerView, null, 0)\n                        fab.extend()\n                        waitingScroll = false\n                    }\n                }\n            })\n            recyclerView.adapter = searchAdapter\n        }\n        fab.setOnClickListener {\n            if (needOnlineSearch){\n                recyclerView.showSnackbar(\"Se necesita el directorio completo para busquedas por genero\", Snackbar.LENGTH_LONG, Snackbar.ANIMATION_MODE_SLIDE)\n            }else{\n                val dialog = GenresDialog()\n                dialog.init(genres, selected, object : GenresDialog.MultiChoiceListener {\n                    override fun onOkay(selected: MutableList<String>) {\n                        this@SearchFragment.selected = selected\n                        setFabIcon()\n                        setSearchNormal(query)\n                    }\n                })\n                dialog.show(childFragmentManager, \"genres\")\n            }\n        }\n    }\n\n    fun setSearch(q: String) = if (needOnlineSearch) setSearchCompact(q) else setSearchNormal(q)\n\n    private fun setSearchCompact(q: String) {\n        waitingScroll = true\n        this.query = q.trim()\n        lifecycleScope.launch {\n            Repository().getSearchCompact(q) {\n                errorView.visibility = if (it) View.VISIBLE else View.GONE\n                if (isFirst) {\n                    progressBar.visibility = View.GONE\n                    isFirst = false\n                    recyclerView.scheduleLayoutAnimation()\n                }\n            }.collect {\n                searchAdapterCompact?.submitData(it)\n            }\n        }\n    }\n\n    private fun setSearchNormal(q: String) {\n        waitingScroll = true\n        this.query = q.trim()\n        model.setSearch(q.trim(), genresString) { animeObjects ->\n            searchAdapter?.submitData(animeObjects)\n            //errorView.visibility = if (animeObjects.isEmpty()) View.VISIBLE else View.GONE\n            if (isFirst) {\n                progressBar.visibility = View.GONE\n                isFirst = false\n                recyclerView.scheduleLayoutAnimation()\n            }\n        }\n    }\n\n    private fun setFabIcon() {\n        fab.post { fab.setIconResource(fabIcon) }\n    }\n\n    override fun onReselect() {\n\n    }\n\n    companion object {\n\n        @JvmOverloads\n        operator fun get(query: String = \"\"): SearchFragment {\n            val fragment = SearchFragment()\n            fragment.query = query\n            return fragment\n        }\n\n        val genres: MutableList<String>\n            get() = mutableListOf(\n                    \"Acción\",\n                    \"Artes Marciales\",\n                    \"Aventuras\",\n                    \"Carreras\",\n                    \"Ciencia Ficción\",\n                    \"Comedia\",\n                    \"Demencia\",\n                    \"Demonios\",\n                    \"Deportes\",\n                    \"Drama\",\n                    \"Ecchi\",\n                    \"Escolares\",\n                    \"Espacial\",\n                    \"Fantasía\",\n                    \"Harem\",\n                    \"Historico\",\n                    \"Infantil\",\n                    \"Josei\",\n                    \"Juegos\",\n                    \"Magia\",\n                    \"Mecha\",\n                    \"Militar\",\n                    \"Misterio\",\n                    \"Música\",\n                    \"Parodia\",\n                    \"Policía\",\n                    \"Psicológico\",\n                    \"Recuentos de la vida\",\n                    \"Romance\",\n                    \"Samurai\",\n                    \"Seinen\",\n                    \"Shoujo\",\n                    \"Shounen\",\n                    \"Sin Generos\",\n                    \"Sobrenatural\",\n                    \"Superpoderes\",\n                    \"Suspenso\",\n                    \"Terror\",\n                    \"Vampiros\",\n                    \"Yaoi\",\n                    \"Yuri\")\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchFragmentMaterial.kt",
    "content": "package knf.kuma.search\n\nimport android.os.Bundle\nimport android.util.Log\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ProgressBar\nimport androidx.annotation.DrawableRes\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.updateLayoutParams\nimport androidx.fragment.app.activityViewModels\nimport androidx.lifecycle.lifecycleScope\nimport androidx.paging.LoadState\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton\nimport com.google.android.material.snackbar.Snackbar\nimport knf.kuma.BottomFragment\nimport knf.kuma.R\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.isFullMode\nimport knf.kuma.commons.noCrash\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.commons.verifyManager\nimport knf.kuma.recommended.RankType\nimport knf.kuma.recommended.RecommendHelper\nimport knf.kuma.retrofit.Repository\nimport kotlinx.coroutines.launch\nimport org.jetbrains.anko.find\n\nclass SearchFragmentMaterial : BottomFragment() {\n    lateinit var recyclerView: RecyclerView\n    lateinit var fab: ExtendedFloatingActionButton\n    lateinit var progressBar: ProgressBar\n    private lateinit var errorView: View\n\n    private val model: SearchViewModel by activityViewModels()\n    private var searchAdapter: SearchAdapterMaterial? = null\n    private var searchAdapterCompact: SearchAdapterCompactMaterial? = null\n    private var manager: RecyclerView.LayoutManager? = null\n\n    private var isFirst = true\n    private var waitingScroll = false\n\n    private var query: String = \"\"\n\n    private var selected: MutableList<String> = ArrayList()\n\n    private val needOnlineSearch: Boolean by lazy { !PrefsUtil.isDirectoryFinished && Network.isConnected && isFullMode && !PrefsUtil.isFamilyFriendly }\n\n    private val genresString: String\n        get() {\n            return if (selected.size == 0) {\n                \"\"\n            } else {\n                RecommendHelper.registerAll(selected, RankType.SEARCH)\n                val builder = StringBuilder(\"%\")\n                for (genre in selected) {\n                    builder.append(genre)\n                            .append(\"%\")\n                }\n                builder.toString()\n            }\n        }\n\n    private val fabIcon: Int\n        @DrawableRes\n        get() {\n            return when (selected.size) {\n                0 -> R.drawable.ic_genres_0\n                1 -> R.drawable.ic_genres_1\n                2 -> R.drawable.ic_genres_2\n                3 -> R.drawable.ic_genres_3\n                4 -> R.drawable.ic_genres_4\n                5 -> R.drawable.ic_genres_5\n                6 -> R.drawable.ic_genres_6\n                7 -> R.drawable.ic_genres_7\n                8 -> R.drawable.ic_genres_8\n                9 -> R.drawable.ic_genres_9\n                else -> R.drawable.ic_genres_more\n            }\n        }\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        noCrash {\n            if (!needOnlineSearch)\n                model.setSearch(query, \"\") { animeObjects ->\n                    searchAdapter?.submitData(animeObjects)\n                    if (isFirst) {\n                        progressBar.visibility = View.GONE\n                        isFirst = false\n                        recyclerView.scheduleLayoutAnimation()\n                    }\n                }\n            model.queryListener.observe(viewLifecycleOwner, {\n                setSearch(it?.trim() ?: \"\")\n            })\n            searchAdapter?.addLoadStateListener {\n                if (it.append != LoadState.Loading) {\n                    progressBar.visibility = View.GONE\n                }\n                if (it.append.endOfPaginationReached) {\n                    errorView.visibility =\n                        if (searchAdapter?.itemCount == 0) View.VISIBLE else View.GONE\n                }\n            }\n        }\n    }\n\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\n        val view = inflater.inflate(\n                if (PrefsUtil.layType == \"0\")\n                    R.layout.fragment_search\n                else\n                    R.layout.fragment_search_grid, container, false)\n        recyclerView = view.find(R.id.recycler)\n        fab = view.find(R.id.fab)\n        progressBar = view.find(R.id.progress)\n        errorView = view.find(R.id.error)\n        return view\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        ViewCompat.setOnApplyWindowInsetsListener(view) { _, insets ->\n            fab.updateLayoutParams<ViewGroup.MarginLayoutParams> {\n                bottomMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom * 2\n            }\n            WindowInsetsCompat.CONSUMED\n        }\n        recyclerView.verifyManager()\n        recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {\n            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {\n                if (dy > 0)\n                    fab.shrink()\n                else if (dy < 0)\n                    fab.extend()\n            }\n        })\n        manager = recyclerView.layoutManager\n        if (needOnlineSearch) {\n            searchAdapterCompact = SearchAdapterCompactMaterial(this)\n            lifecycleScope.launch {\n                Repository().getSearchCompact(\"\") {\n                    if (it) {\n                        errorView.visibility = if (it) View.VISIBLE else View.GONE\n                    }\n                    if (isFirst) {\n                        progressBar.visibility = View.GONE\n                        isFirst = false\n                        recyclerView.scheduleLayoutAnimation()\n                    }\n                }.collect {\n                    searchAdapterCompact?.submitData(it)\n                }\n            }\n            searchAdapterCompact?.registerAdapterDataObserver(object :\n                RecyclerView.AdapterDataObserver() {\n                override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {\n                    super.onItemRangeMoved(fromPosition, toPosition, itemCount)\n                    if (toPosition == 0 && waitingScroll) {\n                        manager?.smoothScrollToPosition(recyclerView, null, 0)\n                        waitingScroll = false\n                    }\n                }\n            })\n            recyclerView.adapter = searchAdapterCompact\n        } else {\n            searchAdapter = SearchAdapterMaterial(this)\n            searchAdapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {\n                override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {\n                    super.onItemRangeMoved(fromPosition, toPosition, itemCount)\n                    if (toPosition == 0 && waitingScroll) {\n                        manager?.smoothScrollToPosition(recyclerView, null, 0)\n                        fab.extend()\n                        waitingScroll = false\n                    }\n                }\n\n                override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {\n                    super.onItemRangeInserted(positionStart, itemCount)\n                    if (positionStart == 0 && waitingScroll) {\n                        manager?.smoothScrollToPosition(recyclerView, null, 0)\n                        fab.extend()\n                        waitingScroll = false\n                    }\n                }\n            })\n            recyclerView.adapter = searchAdapter\n        }\n        fab.setOnClickListener {\n            if (needOnlineSearch){\n                recyclerView.showSnackbar(\"Se necesita el directorio completo para busquedas por genero\", Snackbar.LENGTH_LONG,Snackbar.ANIMATION_MODE_SLIDE)\n            }else{\n                val dialog = GenresDialog()\n                dialog.init(SearchFragment.genres, selected, object : GenresDialog.MultiChoiceListener {\n                    override fun onOkay(selected: MutableList<String>) {\n                        this@SearchFragmentMaterial.selected = selected\n                        setFabIcon()\n                        setSearchNormal(query)\n                    }\n                })\n                dialog.show(childFragmentManager, \"genres\")\n            }\n        }\n    }\n\n    private fun setSearch(q: String) = if (needOnlineSearch) setSearchCompact(q) else setSearchNormal(q)\n\n    private fun setSearchCompact(q: String) {\n        waitingScroll = true\n        this.query = q.trim()\n        lifecycleScope.launch {\n            Repository().getSearchCompact(q) {\n                errorView.visibility = if (it) View.VISIBLE else View.GONE\n                if (isFirst) {\n                    progressBar.visibility = View.GONE\n                    isFirst = false\n                    recyclerView.scheduleLayoutAnimation()\n                }\n            }.collect {\n                searchAdapterCompact?.submitData(it)\n            }\n        }\n    }\n\n    private fun setSearchNormal(q: String) {\n        Log.e(\"Search\", \"On search: \")\n        waitingScroll = true\n        this.query = q.trim()\n        model.setSearch(q.trim(), genresString) { animeObjects ->\n            searchAdapter?.submitData(animeObjects)\n            //errorView.visibility = if (animeObjects.isEmpty()) View.VISIBLE else View.GONE\n            if (isFirst) {\n                progressBar.visibility = View.GONE\n                isFirst = false\n                recyclerView.scheduleLayoutAnimation()\n            }\n        }\n    }\n\n    private fun setFabIcon() {\n        fab.post { fab.setIconResource(fabIcon) }\n    }\n\n    override fun onReselect() {\n\n    }\n\n    companion object {\n\n        @JvmOverloads\n        operator fun get(query: String = \"\"): SearchFragmentMaterial {\n            val fragment = SearchFragmentMaterial()\n            fragment.query = query\n            return fragment\n        }\n\n        val genres: MutableList<String>\n            get() = mutableListOf(\n                    \"Acción\",\n                    \"Artes Marciales\",\n                    \"Aventuras\",\n                    \"Carreras\",\n                    \"Ciencia Ficción\",\n                    \"Comedia\",\n                    \"Demencia\",\n                    \"Demonios\",\n                    \"Deportes\",\n                    \"Drama\",\n                    \"Ecchi\",\n                    \"Escolares\",\n                    \"Espacial\",\n                    \"Fantasía\",\n                    \"Harem\",\n                    \"Historico\",\n                    \"Infantil\",\n                    \"Josei\",\n                    \"Juegos\",\n                    \"Magia\",\n                    \"Mecha\",\n                    \"Militar\",\n                    \"Misterio\",\n                    \"Música\",\n                    \"Parodia\",\n                    \"Policía\",\n                    \"Psicológico\",\n                    \"Recuentos de la vida\",\n                    \"Romance\",\n                    \"Samurai\",\n                    \"Seinen\",\n                    \"Shoujo\",\n                    \"Shounen\",\n                    \"Sin Generos\",\n                    \"Sobrenatural\",\n                    \"Superpoderes\",\n                    \"Suspenso\",\n                    \"Terror\",\n                    \"Vampiros\",\n                    \"Yaoi\",\n                    \"Yuri\")\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchObject.kt",
    "content": "package knf.kuma.search\r\n\r\nimport androidx.recyclerview.widget.DiffUtil\r\nimport com.google.gson.annotations.SerializedName\r\n\r\nopen class SearchObject {\r\n    @SerializedName(\"adv_key\")\r\n    var key = 0\r\n    @SerializedName(\"adv_aid\")\r\n    var aid = \"\"\r\n    @SerializedName(\"adv_name\")\r\n    var name = \"\"\r\n    @SerializedName(\"adv_link\")\r\n    var link = \"\"\r\n\r\n    override fun equals(other: Any?): Boolean {\r\n        return other is SearchObject &&\r\n                key == other.key &&\r\n                aid == other.aid &&\r\n                name == other.name &&\r\n                link == other.link\r\n    }\r\n\r\n    override fun hashCode(): Int {\r\n        return \"$key$aid$name$link\".hashCode()\r\n    }\r\n\r\n    companion object{\r\n        val DIFF = object : DiffUtil.ItemCallback<SearchObject>(){\r\n            override fun areItemsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean =\r\n                    oldItem.key == newItem.key\r\n\r\n            override fun areContentsTheSame(oldItem: SearchObject, newItem: SearchObject): Boolean =\r\n                    oldItem == newItem\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchObjectFav.kt",
    "content": "package knf.kuma.search\r\n\r\nimport androidx.recyclerview.widget.DiffUtil\r\nimport knf.kuma.database.CacheDB\r\n\r\nopen class SearchObjectFav(val key: Int, val aid: String, val name: String, val link: String) {\r\n\r\n    var isFav = CacheDB.INSTANCE.favsDAO().isFav(aid.toInt())\r\n\r\n    override fun equals(other: Any?): Boolean {\r\n        return other is SearchObjectFav &&\r\n                key == other.key &&\r\n                aid == other.aid &&\r\n                name == other.name &&\r\n                link == other.link\r\n    }\r\n\r\n    override fun hashCode(): Int {\r\n        return \"$key$aid$name$link\".hashCode()\r\n    }\r\n\r\n    companion object {\r\n        val DIFF = object : DiffUtil.ItemCallback<SearchObjectFav>() {\r\n            override fun areItemsTheSame(oldItem: SearchObjectFav, newItem: SearchObjectFav): Boolean =\r\n                    oldItem.key == newItem.key\r\n\r\n            override fun areContentsTheSame(oldItem: SearchObjectFav, newItem: SearchObjectFav): Boolean =\r\n                    oldItem == newItem\r\n        }\r\n    }\r\n}\r\n\r\nfun SearchObject.forFav(): SearchObjectFav = SearchObjectFav(key, aid, name, link)"
  },
  {
    "path": "app/src/main/java/knf/kuma/search/SearchViewModel.kt",
    "content": "package knf.kuma.search\n\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.MutableLiveData\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.PagingData\nimport knf.kuma.retrofit.Repository\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.launch\n\nclass SearchViewModel : ViewModel() {\n    private val repository = Repository()\n\n    private var searchJob: Job? = null\n\n    private var queryLive = MutableLiveData<String?>(null)\n\n    fun sendQuery(query: String?) {\n        queryLive.value = query\n    }\n\n    val queryListener: LiveData<String?> get() = queryLive\n\n    fun setSearch(\n        query: String,\n        genres: String,\n        callback: suspend (PagingData<SearchObject>) -> Unit\n    ) {\n        searchJob?.cancel()\n        searchJob = viewModelScope.launch {\n            (if (query == \"\" && genres == \"\")\n                repository.search\n            else if (genres == \"\")\n                repository.getSearch(query)\n            else\n                repository.getSearch(query, genres)).collectLatest {\n                callback(it)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/seeing/FavToSeeing.kt",
    "content": "package knf.kuma.seeing\r\n\r\nimport android.content.Context\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.WhichButton\r\nimport com.afollestad.materialdialogs.actions.getActionButton\r\nimport com.afollestad.materialdialogs.checkbox.checkBoxPrompt\r\nimport com.afollestad.materialdialogs.checkbox.isCheckPromptChecked\r\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.commons.doOnUIGlobal\r\nimport knf.kuma.commons.noCrash\r\nimport knf.kuma.commons.noCrashLet\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.AnimeObject\r\nimport knf.kuma.pojos.FavoriteObject\r\nimport knf.kuma.pojos.SeeingObject\r\nimport knf.kuma.pojos.SeenObject\r\nimport org.jetbrains.anko.doAsync\r\n\r\nobject FavToSeeing {\r\n\r\n    fun onConfirmation(context: Context) {\r\n        MaterialDialog(context).safeShow {\r\n            title(text = \"Convertir favoritos\")\r\n            message(text = \"Se marcarán todos los animes FINALIZADOS en favoritos como COMPLETADOS, continuar?\")\r\n            checkBoxPrompt(text = \"Marcar todos los episodios como vistos\") {}\r\n            positiveButton(text = \"Continuar\") {\r\n                start(context, it.isCheckPromptChecked())\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun start(context: Context, withChapters: Boolean) {\r\n        doAsync {\r\n            noCrash {\r\n                val favList = CacheDB.INSTANCE.favsDAO().allRaw\r\n                var count = 0\r\n                doOnUIGlobal {\r\n                    val dialog = MaterialDialog(context).apply {\r\n                        lifecycleOwner()\r\n                        message(text = \"Procesando favoritos... ($count/${favList.size})\")\r\n                        cancelable(false)\r\n                        positiveButton(text = \"Aceptar\") {\r\n                            it.dismiss()\r\n                        }\r\n                    }\r\n                    dialog.getActionButton(WhichButton.POSITIVE).isEnabled = false\r\n                    dialog.safeShow()\r\n                    doAsync {\r\n                        var needSeeingUpdate = false\r\n                        var needSeenUpdate = false\r\n                        favList.forEach { favoriteObject ->\r\n                            if (favoriteObject.isCompleted) {\r\n                                if (!favoriteObject.isSeeing) {\r\n                                    CacheDB.INSTANCE.seeingDAO().add(SeeingObject.fromAnime(favoriteObject).apply { state = SeeingObject.STATE_COMPLETED })\r\n                                    needSeeingUpdate = true\r\n                                }\r\n                                if (withChapters) {\r\n                                    CacheDB.INSTANCE.seenDAO().addAll(favoriteObject.chapters.map { SeenObject.fromChapter(it) })\r\n                                    needSeenUpdate = true\r\n                                }\r\n                            }\r\n                            count++\r\n                            doOnUIGlobal { dialog.message(text = \"Procesando favoritos... ($count/${favList.size})\") }\r\n                        }\r\n                        syncData {\r\n                            if (needSeeingUpdate)\r\n                                seeing()\r\n                            if (needSeenUpdate)\r\n                                seen()\r\n                        }\r\n                        doOnUIGlobal { dialog.getActionButton(WhichButton.POSITIVE).isEnabled = true }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    fun getLast(list: List<SeenObject>): SeenObject? =\r\n        list.maxByOrNull {\r\n            noCrashLet(-1.0) {\r\n                \"(\\\\d+\\\\.?\\\\d?)\".toRegex().findAll(it.number).last().destructured.component1()\r\n                    .toDouble()\r\n            }\r\n        }\r\n\r\n    private val FavoriteObject.isCompleted: Boolean get() = CacheDB.INSTANCE.animeDAO().isCompleted(aid)\r\n    private val FavoriteObject.isSeeing: Boolean get() = CacheDB.INSTANCE.seeingDAO().isSeeingAll(aid)\r\n    private val FavoriteObject.chapters: List<AnimeObject.WebInfo.AnimeChapter>\r\n        get() = CacheDB.INSTANCE.animeDAO().getFullByAid(aid)?.chapters ?: listOf()\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/seeing/SeeingActivity.kt",
    "content": "package knf.kuma.seeing\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport androidx.appcompat.widget.Toolbar\nimport androidx.viewpager.widget.ViewPager\nimport com.google.android.material.tabs.TabLayout\nimport knf.kuma.R\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.custom.GenericActivity\n\nclass SeeingActivity : GenericActivity() {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    val tabs: TabLayout by bind(R.id.tabs)\n    val pager: ViewPager by bind(R.id.pager)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_seening)\n        toolbar.title = \"Siguiendo\"\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        toolbar.setNavigationOnClickListener { finish() }\n        pager.adapter = SeeingPagerAdapter(supportFragmentManager)\n        pager.offscreenPageLimit = 5\n        tabs.setupWithViewPager(pager)\n        tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {\n            override fun onTabReselected(tab: TabLayout.Tab?) {\n                ((pager.adapter as? SeeingPagerAdapter)?.fragmentList)?.let { it[pager.currentItem].onSelected() }\n            }\n\n            override fun onTabUnselected(p0: TabLayout.Tab?) {\n\n            }\n\n            override fun onTabSelected(p0: TabLayout.Tab?) {\n\n            }\n        })\n        pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {\n            override fun onPageScrollStateChanged(state: Int) {\n\n            }\n\n            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {\n\n            }\n\n            override fun onPageSelected(position: Int) {\n                ((pager.adapter as? SeeingPagerAdapter)?.fragmentList)?.let { it[position].clickCount = 0 }\n            }\n        })\n        showRandomInterstitial(this, PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_seeing_auto, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.auto -> FavToSeeing.onConfirmation(this)\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, SeeingActivity::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/seeing/SeeingActivityMaterial.kt",
    "content": "package knf.kuma.seeing\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.Menu\nimport android.view.MenuItem\nimport androidx.appcompat.widget.Toolbar\nimport androidx.viewpager.widget.ViewPager\nimport com.google.android.material.tabs.TabLayout\nimport knf.kuma.R\nimport knf.kuma.ads.showRandomInterstitial\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.setSurfaceBars\nimport knf.kuma.custom.GenericActivity\n\nclass SeeingActivityMaterial : GenericActivity() {\n    val toolbar: Toolbar by bind(R.id.toolbar)\n    val tabs: TabLayout by bind(R.id.tabs)\n    val pager: ViewPager by bind(R.id.pager)\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getTheme())\n        super.onCreate(savedInstanceState)\n        setSurfaceBars()\n        setContentView(R.layout.activity_seening_material)\n        toolbar.title = \"Siguiendo\"\n        setSupportActionBar(toolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        supportActionBar?.setDisplayShowHomeEnabled(false)\n        toolbar.setNavigationOnClickListener { finish() }\n        pager.adapter = SeeingPagerAdapterMaterial(supportFragmentManager)\n        pager.offscreenPageLimit = 5\n        tabs.setupWithViewPager(pager)\n        tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {\n            override fun onTabReselected(tab: TabLayout.Tab?) {\n                ((pager.adapter as? SeeingPagerAdapterMaterial)?.fragmentList)?.let { it[pager.currentItem].onSelected() }\n            }\n\n            override fun onTabUnselected(p0: TabLayout.Tab?) {\n\n            }\n\n            override fun onTabSelected(p0: TabLayout.Tab?) {\n\n            }\n        })\n        pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {\n            override fun onPageScrollStateChanged(state: Int) {\n\n            }\n\n            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {\n\n            }\n\n            override fun onPageSelected(position: Int) {\n                ((pager.adapter as? SeeingPagerAdapter)?.fragmentList)?.let { it[position].clickCount = 0 }\n            }\n        })\n        showRandomInterstitial(this, PrefsUtil.fullAdsExtraProbability)\n    }\n\n    override fun onCreateOptionsMenu(menu: Menu): Boolean {\n        menuInflater.inflate(R.menu.menu_seeing_auto, menu)\n        return super.onCreateOptionsMenu(menu)\n    }\n\n    override fun onOptionsItemSelected(item: MenuItem): Boolean {\n        when (item.itemId) {\n            R.id.auto -> FavToSeeing.onConfirmation(this)\n        }\n        return super.onOptionsItemSelected(item)\n    }\n\n    companion object {\n\n        fun open(context: Context) {\n            context.startActivity(Intent(context, SeeingActivityMaterial::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/seeing/SeeingAdapter.kt",
    "content": "package knf.kuma.seeing\n\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.PopupMenu\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.card.MaterialCardView\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.load\nimport knf.kuma.commons.optionalBind\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.SeeingObject\nimport org.jetbrains.anko.doAsync\n\ninternal class SeeingAdapter(private val activity: Activity, private val isFullList: Boolean) : PagingDataAdapter<SeeingObject, RecyclerView.ViewHolder>(SeeingObject.diffCallback), FastScrollRecyclerView.SectionedAdapter {\n\n    private val seeingDAO = CacheDB.INSTANCE.seeingDAO()\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {\n        return when (viewType) {\n            0 -> SeeingItem(LayoutInflater.from(parent.context).inflate(R.layout.item_record_grid, parent, false))\n            else -> SeeingItemNormal(LayoutInflater.from(parent.context).inflate(R.layout.item_dir_grid, parent, false))\n        }\n    }\n\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>) {\n        val item = getItem(position)\n        if (payloads.isEmpty() || item == null)\n            super.onBindViewHolder(holder, position, payloads)\n        else if (holder is SeeingItem) {\n            holder.chapter.text = getCardText(item)\n        }\n    }\n\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\n        val seeingObject = getItem(position) ?: return\n        if (holder is SeeingItem)\n            holder.chapter.text = getCardText(seeingObject)\n        (holder as? SeeingItemNormal)?.apply {\n            imageView.load(PatternUtil.getCover(seeingObject.aid))\n            title.text = seeingObject.title\n            progressView?.visibility = View.GONE\n            cardView.setOnClickListener { ActivityAnime.open(activity, seeingObject) }\n            cardView.setOnLongClickListener { view ->\n                val popupMenu = PopupMenu(activity, view)\n                popupMenu.inflate(R.menu.menu_seeing)\n                when (seeingObject.state) {\n                    SeeingObject.STATE_WATCHING -> popupMenu.menu.findItem(R.id.watching).isVisible = false\n                    SeeingObject.STATE_CONSIDERING -> popupMenu.menu.findItem(R.id.considering).isVisible = false\n                    SeeingObject.STATE_COMPLETED -> popupMenu.menu.findItem(R.id.completed).isVisible = false\n                    SeeingObject.STATE_DROPPED -> popupMenu.menu.findItem(R.id.droped).isVisible = false\n                }\n                popupMenu.setOnMenuItemClickListener { menuItem ->\n                    doAsync {\n                        when (menuItem.itemId) {\n                            R.id.watching -> seeingDAO.update(seeingObject.also { it.state = 1 })\n                            R.id.considering -> seeingDAO.update(seeingObject.also { it.state = 2 })\n                            R.id.completed -> seeingDAO.update(seeingObject.also { it.state = 3 })\n                            R.id.droped -> seeingDAO.update(seeingObject.also { it.state = 4 })\n                            R.id.paused -> seeingDAO.update(seeingObject.also { it.state = 5 })\n                        }\n                        syncData { seeing() }\n                        if (isFullList)\n                            doOnUIGlobal {\n                                (holder as? SeeingItem)?.chapter?.text = getCardText(seeingObject)\n                            }\n                    }\n                    true\n                }\n                popupMenu.show()\n                true\n            }\n        }\n    }\n\n    override fun getSectionName(position: Int): String {\n        return getItem(position)?.title?.substring(0, 1) ?: \"\"\n    }\n\n    private fun getCardText(seeingObject: SeeingObject): String {\n        return if (isFullList) {\n            getStateText(seeingObject.state)\n        } else {\n            val lastChapter = seeingObject.lastChapter\n            val number = lastChapter?.number\n            if (number == null)\n                \"No empezado\"\n            else if (!lastChapter.number.startsWith(\"Episodio \"))\n                \"Episodio ${lastChapter.number}\"\n            else\n                lastChapter.number\n        }\n    }\n\n    private fun getStateText(state: Int): String {\n        return when (state) {\n            1 -> \"Viendo\"\n            2 -> \"Considerando\"\n            3 -> \"Completado\"\n            4 -> \"Dropeado\"\n            else -> \"Pausado\"\n        }\n    }\n\n    override fun getItemViewType(position: Int): Int {\n        val seeingObject = getItem(position) ?: return 0\n        return when {\n            isFullList || seeingObject.state in 0..1 -> 0\n            else -> 1\n        }\n    }\n\n    internal class SeeingItem(itemView: View) : SeeingItemNormal(itemView) {\n        val chapter: TextView by itemView.bind(R.id.chapter)\n    }\n\n    internal open class SeeingItemNormal(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: MaterialCardView by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val progressView: ProgressBar? by itemView.optionalBind(R.id.progress)\n        val title: TextView by itemView.bind(R.id.title)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/seeing/SeeingAdapterMaterial.kt",
    "content": "package knf.kuma.seeing\n\nimport android.app.Activity\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.widget.ImageView\nimport android.widget.PopupMenu\nimport android.widget.ProgressBar\nimport android.widget.TextView\nimport androidx.paging.PagingDataAdapter\nimport androidx.recyclerview.widget.RecyclerView\nimport com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.bind\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.load\nimport knf.kuma.commons.optionalBind\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.SeeingObject\nimport org.jetbrains.anko.doAsync\n\ninternal class SeeingAdapterMaterial(private val activity: Activity, private val isFullList: Boolean) : PagingDataAdapter<SeeingObject, RecyclerView.ViewHolder>(SeeingObject.diffCallback), FastScrollRecyclerView.SectionedAdapter {\n\n    private val seeingDAO = CacheDB.INSTANCE.seeingDAO()\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {\n        return when (viewType) {\n            0 -> SeeingItem(LayoutInflater.from(parent.context).inflate(R.layout.item_record_grid_material, parent, false))\n            else -> SeeingItemNormal(LayoutInflater.from(parent.context).inflate(R.layout.item_dir_grid_material, parent, false))\n        }\n    }\n\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList<Any>) {\n        val item = getItem(position)\n        if (payloads.isEmpty() || item == null)\n            super.onBindViewHolder(holder, position, payloads)\n        else if (holder is SeeingItem) {\n            holder.chapter.text = getCardText(item)\n        }\n    }\n\n    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {\n        val seeingObject = getItem(position) ?: return\n        if (holder is SeeingItem)\n            holder.chapter.text = getCardText(seeingObject)\n        (holder as? SeeingItemNormal)?.apply {\n            imageView.load(PatternUtil.getCover(seeingObject.aid))\n            title.text = seeingObject.title\n            progressView?.visibility = View.GONE\n            cardView.setOnClickListener { ActivityAnimeMaterial.open(activity, seeingObject) }\n            cardView.setOnLongClickListener { view ->\n                val popupMenu = PopupMenu(activity, view)\n                popupMenu.inflate(R.menu.menu_seeing)\n                when (seeingObject.state) {\n                    SeeingObject.STATE_WATCHING -> popupMenu.menu.findItem(R.id.watching).isVisible = false\n                    SeeingObject.STATE_CONSIDERING -> popupMenu.menu.findItem(R.id.considering).isVisible = false\n                    SeeingObject.STATE_COMPLETED -> popupMenu.menu.findItem(R.id.completed).isVisible = false\n                    SeeingObject.STATE_DROPPED -> popupMenu.menu.findItem(R.id.droped).isVisible = false\n                }\n                popupMenu.setOnMenuItemClickListener { menuItem ->\n                    doAsync {\n                        when (menuItem.itemId) {\n                            R.id.watching -> seeingDAO.update(seeingObject.also { it.state = 1 })\n                            R.id.considering -> seeingDAO.update(seeingObject.also { it.state = 2 })\n                            R.id.completed -> seeingDAO.update(seeingObject.also { it.state = 3 })\n                            R.id.droped -> seeingDAO.update(seeingObject.also { it.state = 4 })\n                            R.id.paused -> seeingDAO.update(seeingObject.also { it.state = 5 })\n                        }\n                        syncData { seeing() }\n                        if (isFullList)\n                            doOnUIGlobal {\n                                (holder as? SeeingItem)?.chapter?.text = getCardText(seeingObject)\n                            }\n                    }\n                    true\n                }\n                popupMenu.show()\n                true\n            }\n        }\n    }\n\n    override fun getSectionName(position: Int): String {\n        return getItem(position)?.title?.substring(0, 1) ?: \"\"\n    }\n\n    private fun getCardText(seeingObject: SeeingObject): String {\n        return if (isFullList) {\n            getStateText(seeingObject.state)\n        } else {\n            val lastChapter = seeingObject.lastChapter\n            val number = lastChapter?.number\n            if (number == null)\n                \"No empezado\"\n            else if (!lastChapter.number.startsWith(\"Episodio \"))\n                \"Episodio ${lastChapter.number}\"\n            else\n                lastChapter.number\n        }\n    }\n\n    private fun getStateText(state: Int): String {\n        return when (state) {\n            1 -> \"Viendo\"\n            2 -> \"Considerando\"\n            3 -> \"Completado\"\n            4 -> \"Dropeado\"\n            else -> \"Pausado\"\n        }\n    }\n\n    override fun getItemViewType(position: Int): Int {\n        val seeingObject = getItem(position) ?: return 0\n        return when {\n            isFullList || seeingObject.state in 0..1 -> 0\n            else -> 1\n        }\n    }\n\n    internal class SeeingItem(itemView: View) : SeeingItemNormal(itemView) {\n        val chapter: TextView by itemView.bind(R.id.chapter)\n    }\n\n    internal open class SeeingItemNormal(itemView: View) : RecyclerView.ViewHolder(itemView) {\n        val cardView: View by itemView.bind(R.id.card)\n        val imageView: ImageView by itemView.bind(R.id.img)\n        val progressView: ProgressBar? by itemView.optionalBind(R.id.progress)\n        val title: TextView by itemView.bind(R.id.title)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/seeing/SeeingFragment.kt",
    "content": "package knf.kuma.seeing\r\n\r\nimport android.annotation.SuppressLint\r\nimport android.os.Bundle\r\nimport android.view.LayoutInflater\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport androidx.core.view.isVisible\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.paging.Pager\r\nimport androidx.paging.PagingConfig\r\nimport androidx.paging.PagingData\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsType\r\nimport knf.kuma.ads.implBanner\r\nimport knf.kuma.commons.verifyManager\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.databinding.FragmentSeeingBinding\r\nimport knf.kuma.pojos.SeeingObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.flow.Flow\r\nimport kotlinx.coroutines.flow.collectLatest\r\nimport kotlinx.coroutines.launch\r\nimport xdroid.toaster.Toaster\r\n\r\nclass SeeingFragment : Fragment() {\r\n\r\n    var clickCount = 0\r\n\r\n    private lateinit var binding: FragmentSeeingBinding\r\n    private val adapter: SeeingAdapter? by lazy { activity?.let { SeeingAdapter(it, arguments?.getInt(\"state\", 0) == 0) } }\r\n\r\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\r\n        super.onActivityCreated(savedInstanceState)\r\n        lifecycleScope.launch {\r\n            liveData.collectLatest {\r\n                binding.progress.visibility = View.GONE\r\n                adapter?.submitData(it)\r\n            }\r\n        }\r\n        adapter?.addLoadStateListener {\r\n            binding.error.isVisible = it.append.endOfPaginationReached && adapter?.itemCount == 0\r\n        }\r\n    }\r\n\r\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\r\n        return inflater.inflate(R.layout.fragment_seeing, container, false).also {\r\n            binding = FragmentSeeingBinding.bind(it)\r\n        }\r\n    }\r\n\r\n    @SuppressLint(\"SetTextI18n\")\r\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\r\n        super.onViewCreated(view, savedInstanceState)\r\n        lifecycleScope.launch(Dispatchers.IO) {\r\n            delay(1000)\r\n            binding.adContainer.implBanner(AdsType.SEEING_BANNER, true)\r\n        }\r\n        when (arguments?.getInt(\"state\", 0)) {\r\n            1 -> {\r\n                binding.errorText.text = \"No estas viendo ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_watching)\r\n            }\r\n            2 -> {\r\n                binding.errorText.text = \"No consideras ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_considering)\r\n            }\r\n            3 -> {\r\n                binding.errorText.text = \"No has terminado ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_completed)\r\n            }\r\n            4 -> {\r\n                binding.errorText.text = \"No has dropeado ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_droped)\r\n            }\r\n            5 -> {\r\n                binding.errorText.text = \"No tienes pausado ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_paused)\r\n            }\r\n            else -> binding.errorText.text = \"No has marcado ningún anime\"\r\n        }\r\n        binding.recycler.verifyManager()\r\n        binding.recycler.adapter = adapter\r\n    }\r\n\r\n    val liveData: Flow<PagingData<SeeingObject>>\r\n        get() {\r\n            return Pager(\r\n                PagingConfig(15, enablePlaceholders = false), 0,\r\n                (if (arguments?.getInt(\"state\", 0) ?: 0 == 0)\r\n                    CacheDB.INSTANCE.seeingDAO().allPaging\r\n                else\r\n                    CacheDB.INSTANCE.seeingDAO().getLiveByStatePaging(\r\n                        arguments?.getInt(\"state\", 0) ?: 0\r\n                    )).asPagingSourceFactory()\r\n            ).flow\r\n        }\r\n\r\n    val title: String\r\n        get() {\r\n            return when (arguments?.getInt(\"state\", 0)) {\r\n                1 -> \"Viendo\"\r\n                2 -> \"Considerando\"\r\n                3 -> \"Completado\"\r\n                4 -> \"Dropeado\"\r\n                5 -> \"Pausado\"\r\n                else -> \"Todos\"\r\n            }\r\n        }\r\n\r\n    fun onSelected() {\r\n        clickCount++\r\n        if (clickCount == 3) {\r\n            lifecycleScope.launch(Dispatchers.Main) {\r\n                val state = arguments?.getInt(\"state\", -1) ?: -1\r\n                if (state == -1) return@launch\r\n                val num = if (state == 0)\r\n                    CacheDB.INSTANCE.seeingDAO().countAll\r\n                else\r\n                    CacheDB.INSTANCE.seeingDAO().countByState(state)\r\n                if (num > 0)\r\n                    Toaster.toast(\"$num anime\" + adapter?.let { if (num > 1) \"s\" else \"\" })\r\n            }\r\n            clickCount = 0\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        operator fun get(state: Int): SeeingFragment {\r\n            val emissionFragment = SeeingFragment()\r\n            val bundle = Bundle()\r\n            bundle.putInt(\"state\", state)\r\n            emissionFragment.arguments = bundle\r\n            return emissionFragment\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/seeing/SeeingFragmentMaterial.kt",
    "content": "package knf.kuma.seeing\r\n\r\nimport android.annotation.SuppressLint\r\nimport android.os.Bundle\r\nimport android.view.LayoutInflater\r\nimport android.view.View\r\nimport android.view.ViewGroup\r\nimport androidx.core.view.isVisible\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.paging.Pager\r\nimport androidx.paging.PagingConfig\r\nimport androidx.paging.PagingData\r\nimport knf.kuma.R\r\nimport knf.kuma.ads.AdsType\r\nimport knf.kuma.ads.implBanner\r\nimport knf.kuma.commons.verifyManager\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.databinding.FragmentSeeingBinding\r\nimport knf.kuma.pojos.SeeingObject\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.flow.Flow\r\nimport kotlinx.coroutines.flow.collectLatest\r\nimport kotlinx.coroutines.launch\r\nimport kotlinx.coroutines.withContext\r\nimport xdroid.toaster.Toaster\r\n\r\nclass SeeingFragmentMaterial : Fragment() {\r\n\r\n    private var clickCount = 0\r\n\r\n    private lateinit var binding: FragmentSeeingBinding\r\n    private val adapter: SeeingAdapterMaterial? by lazy { activity?.let { SeeingAdapterMaterial(it, arguments?.getInt(\"state\", 0) == 0) } }\r\n\r\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\r\n        super.onActivityCreated(savedInstanceState)\r\n        lifecycleScope.launch {\r\n            liveData.collectLatest {\r\n                binding.progress.visibility = View.GONE\r\n                adapter?.submitData(it)\r\n            }\r\n        }\r\n        adapter?.addLoadStateListener {\r\n            binding.error.isVisible = it.append.endOfPaginationReached && adapter?.itemCount == 0\r\n        }\r\n    }\r\n\r\n    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {\r\n        return inflater.inflate(R.layout.fragment_seeing, container, false).also {\r\n            binding = FragmentSeeingBinding.bind(it)\r\n        }\r\n    }\r\n\r\n    @SuppressLint(\"SetTextI18n\")\r\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\r\n        super.onViewCreated(view, savedInstanceState)\r\n        lifecycleScope.launch(Dispatchers.IO) {\r\n            delay(1000)\r\n            binding.adContainer.implBanner(AdsType.SEEING_BANNER, true)\r\n        }\r\n        when (arguments?.getInt(\"state\", 0)) {\r\n            1 -> {\r\n                binding.errorText.text = \"No estas viendo ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_watching)\r\n            }\r\n            2 -> {\r\n                binding.errorText.text = \"No consideras ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_considering)\r\n            }\r\n            3 -> {\r\n                binding.errorText.text = \"No has terminado ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_completed)\r\n            }\r\n            4 -> {\r\n                binding.errorText.text = \"No has dropeado ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_droped)\r\n            }\r\n            5 -> {\r\n                binding.errorText.text = \"No tienes pausado ningún anime\"\r\n                binding.errorImg.setImageResource(R.drawable.ic_paused)\r\n            }\r\n            else -> binding.errorText.text = \"No has marcado ningún anime\"\r\n        }\r\n        binding.recycler.verifyManager()\r\n        binding.recycler.adapter = adapter\r\n    }\r\n\r\n    val liveData: Flow<PagingData<SeeingObject>>\r\n        get() {\r\n            return Pager(\r\n                PagingConfig(15, enablePlaceholders = false), 0,\r\n                (if (arguments?.getInt(\"state\", 0) ?: 0 == 0)\r\n                    CacheDB.INSTANCE.seeingDAO().allPaging\r\n                else\r\n                    CacheDB.INSTANCE.seeingDAO().getLiveByStatePaging(\r\n                        arguments?.getInt(\"state\", 0) ?: 0\r\n                    )).asPagingSourceFactory()\r\n            ).flow\r\n        }\r\n\r\n    val title: String\r\n        get() {\r\n            return when (arguments?.getInt(\"state\", 0)) {\r\n                1 -> \"Viendo\"\r\n                2 -> \"Considerando\"\r\n                3 -> \"Completado\"\r\n                4 -> \"Dropeado\"\r\n                5 -> \"Pausado\"\r\n                else -> \"Todos\"\r\n            }\r\n        }\r\n\r\n    fun onSelected() {\r\n        clickCount++\r\n        if (clickCount == 3) {\r\n            lifecycleScope.launch(Dispatchers.Main) {\r\n                val state = arguments?.getInt(\"state\", -1) ?: -1\r\n                if (state == -1) return@launch\r\n                val num = withContext(Dispatchers.IO) {\r\n                    if (state == 0)\r\n                        CacheDB.INSTANCE.seeingDAO().countAll\r\n                    else\r\n                        CacheDB.INSTANCE.seeingDAO().countByState(state)\r\n                }\r\n                if (num > 0)\r\n                    Toaster.toast(\"$num anime\" + adapter?.let { if (num > 1) \"s\" else \"\" })\r\n            }\r\n            clickCount = 0\r\n        }\r\n    }\r\n\r\n    companion object {\r\n        operator fun get(state: Int): SeeingFragmentMaterial {\r\n            val emissionFragment = SeeingFragmentMaterial()\r\n            val bundle = Bundle()\r\n            bundle.putInt(\"state\", state)\r\n            emissionFragment.arguments = bundle\r\n            return emissionFragment\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/seeing/SeeingPagerAdapter.kt",
    "content": "package knf.kuma.seeing\r\n\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.fragment.app.FragmentManager\r\nimport androidx.fragment.app.FragmentPagerAdapter\r\n\r\nclass SeeingPagerAdapter(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager) {\r\n\r\n    val fragmentList: MutableList<SeeingFragment> = mutableListOf()\r\n\r\n    init {\r\n        for (i in 0..5) {\r\n            fragmentList.add(SeeingFragment[i])\r\n        }\r\n    }\r\n\r\n    override fun getItem(position: Int): Fragment {\r\n        return fragmentList[position]\r\n    }\r\n\r\n    override fun getCount(): Int {\r\n        return fragmentList.size\r\n    }\r\n\r\n    override fun getPageTitle(position: Int): CharSequence {\r\n        return fragmentList[position].title\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/seeing/SeeingPagerAdapterMaterial.kt",
    "content": "package knf.kuma.seeing\r\n\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.fragment.app.FragmentManager\r\nimport androidx.fragment.app.FragmentPagerAdapter\r\n\r\nclass SeeingPagerAdapterMaterial(fragmentManager: FragmentManager) : FragmentPagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {\r\n\r\n    val fragmentList: MutableList<SeeingFragmentMaterial> = mutableListOf()\r\n\r\n    init {\r\n        for (i in 0..5) {\r\n            fragmentList.add(SeeingFragmentMaterial[i])\r\n        }\r\n    }\r\n\r\n    override fun getItem(position: Int): Fragment {\r\n        return fragmentList[position]\r\n    }\r\n\r\n    override fun getCount(): Int {\r\n        return fragmentList.size\r\n    }\r\n\r\n    override fun getPageTitle(position: Int): CharSequence {\r\n        return fragmentList[position].title\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/shortcuts/DummyActivity.kt",
    "content": "package knf.kuma.shortcuts\r\n\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.core.app.ActivityOptionsCompat\r\n\r\nabstract class DummyActivity : AppCompatActivity() {\r\n\r\n    abstract val intentClass: Class<*>\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        finish()\r\n        startActivity(Intent(this, intentClass).apply {\r\n            data = intent.data\r\n            putExtras(intent)\r\n        }, ActivityOptionsCompat.makeCustomAnimation(this, android.R.anim.fade_in, android.R.anim.fade_out).toBundle())\r\n    }\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/shortcuts/DummyEmissionActivity.kt",
    "content": "package knf.kuma.shortcuts\r\n\r\nimport knf.kuma.commons.DesignUtils\r\n\r\nclass DummyEmissionActivity : DummyActivity() {\r\n    override val intentClass: Class<*> = DesignUtils.emissionClass\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/shortcuts/DummyExplorerActivity.kt",
    "content": "package knf.kuma.shortcuts\r\n\r\nimport knf.kuma.commons.DesignUtils\r\n\r\nclass DummyExplorerActivity : DummyActivity() {\r\n    override val intentClass: Class<*> = DesignUtils.explorerClass\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/shortcuts/DummyMainActivity.kt",
    "content": "package knf.kuma.shortcuts\r\n\r\nimport knf.kuma.commons.DesignUtils\r\n\r\nclass DummyMainActivity : DummyActivity() {\r\n    override val intentClass: Class<*> = DesignUtils.mainClass\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/slices/AnimeSliceObject.kt",
    "content": "package knf.kuma.slices\r\n\r\nimport androidx.core.graphics.drawable.IconCompat\r\nimport androidx.room.Ignore\r\nimport androidx.room.TypeConverters\r\nimport knf.kuma.pojos.AnimeObject\r\nimport knf.kuma.search.SearchObject\r\n\r\n@TypeConverters(AnimeObject.Converter::class)\r\nclass AnimeSliceObject : SearchObject() {\r\n    var genres = listOf<String>()\r\n    @Ignore\r\n    lateinit var icon: IconCompat\r\n\r\n    val genresString: String\r\n        get() {\r\n            if (genres.isEmpty())\r\n                return \"Sin generos\"\r\n            val builder = StringBuilder()\r\n            for (genre in genres) {\r\n                builder.append(genre)\r\n                        .append(\", \")\r\n            }\r\n            val g = builder.toString()\r\n            return g.substring(0, g.lastIndexOf(\",\"))\r\n        }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/AnimeRow.kt",
    "content": "package knf.kuma.tv\n\nimport androidx.leanback.widget.ArrayObjectAdapter\n\nclass AnimeRow {\n\n    internal var page: Int = 0\n    internal var id: Int = 0\n    internal var adapter: ArrayObjectAdapter? = null\n    internal var title: String? = null\n\n    fun getPage(): Int {\n        return page\n    }\n\n    fun setPage(page: Int): AnimeRow {\n        this.page = page\n        return this\n    }\n\n    fun getId(): Int {\n        return id\n    }\n\n    fun setId(id: Int): AnimeRow {\n        this.id = id\n        return this\n    }\n\n    fun getAdapter(): ArrayObjectAdapter? {\n        return adapter\n    }\n\n    fun setAdapter(adapter: ArrayObjectAdapter): AnimeRow {\n        this.adapter = adapter\n        return this\n    }\n\n    fun getTitle(): String? {\n        return title\n    }\n\n    fun setTitle(title: String): AnimeRow {\n        this.title = title\n        return this\n    }\n\n    fun setList(list: List<Any>) {\n        adapter?.apply {\n            clear()\n            addAll(0, list)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/BindableCardView.kt",
    "content": "package knf.kuma.tv\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.view.LayoutInflater\nimport android.widget.ImageView\n\nimport androidx.annotation.LayoutRes\nimport androidx.leanback.widget.BaseCardView\n\nabstract class BindableCardView<T> : BaseCardView {\n\n    abstract val imageView: ImageView\n\n    @get:LayoutRes\n    abstract val layoutResource: Int\n\n    constructor(context: Context) : super(context) {\n        initLayout()\n    }\n\n    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {\n        initLayout()\n    }\n\n    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {\n        initLayout()\n    }\n\n    private fun initLayout() {\n        isFocusable = true\n        isFocusableInTouchMode = true\n        val inflater = LayoutInflater.from(context)\n        inflater.inflate(layoutResource, this)\n    }\n\n    abstract fun bind(data: T)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/ChannelUtils.kt",
    "content": "package knf.kuma.tv\r\n\r\nimport android.content.Context\r\nimport android.graphics.BitmapFactory\r\nimport android.net.Uri\r\nimport androidx.tvprovider.media.tv.PreviewChannel\r\nimport androidx.tvprovider.media.tv.PreviewChannelHelper\r\nimport androidx.tvprovider.media.tv.PreviewProgram\r\nimport androidx.tvprovider.media.tv.TvContractCompat\r\nimport knf.kuma.R\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.urlFixed\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.pojos.RecentObject\r\nimport knf.kuma.retrofit.Repository\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.GlobalScope\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.launch\r\n\r\nobject ChannelUtils {\r\n    fun createIfNeeded(context: Context) {\r\n        if (!context.resources.getBoolean(R.bool.isTv)) return\r\n        if (!PrefsUtil.tvRecentsChannelCreated) {\r\n            GlobalScope.launch(Dispatchers.IO) {\r\n                try {\r\n                    val channelBuilder = PreviewChannel.Builder()\r\n                        .setDisplayName(\"Episodios recientes\")\r\n                        .setAppLinkIntentUri(Uri.parse(\"ukiku://tv/home\"))\r\n                        .setLogo(\r\n                            BitmapFactory.decodeResource(\r\n                                context.resources,\r\n                                R.drawable.ukiku_logo_plain\r\n                            )\r\n                        )\r\n                    val channelId =\r\n                        PreviewChannelHelper(context).publishDefaultChannel(channelBuilder.build())\r\n                    PrefsUtil.tvRecentsChannelCreated = true\r\n                    PrefsUtil.tvRecentsChannelId = channelId\r\n                } catch (e: Exception) {\r\n                    e.printStackTrace()\r\n                }\r\n            }\r\n        }\r\n        initChannelIfNeeded(context)\r\n    }\r\n\r\n    fun initChannelIfNeeded(context: Context) {\r\n        if (!context.resources.getBoolean(R.bool.isTv) || !PrefsUtil.tvRecentsChannelCreated) return\r\n        if (!PrefsUtil.tvRecentsPreFilled)\r\n            GlobalScope.launch(Dispatchers.IO) {\r\n                delay(5000)\r\n                val recents = CacheDB.INSTANCE.recentsDAO().allSimple\r\n                if (recents.isNotEmpty()) {\r\n                    PrefsUtil.tvRecentsPreFilled = true\r\n                    val programIds = mutableSetOf<String>()\r\n                    recents.forEach {\r\n                        val chapUri = Uri.Builder().scheme(\"ukiku\")\r\n                            .authority(\"tv\")\r\n                            .appendPath(\"chapter\")\r\n                            .appendQueryParameter(\"aid\", it.aid)\r\n                            .appendQueryParameter(\"chapter\", it.chapter)\r\n                            .appendQueryParameter(\"eid\", it.eid)\r\n                            .appendQueryParameter(\"url\", it.url.urlFixed)\r\n                            .appendQueryParameter(\"name\", it.name)\r\n                            .build()\r\n                        val program = PreviewProgram.Builder()\r\n                            .setChannelId(PrefsUtil.tvRecentsChannelId)\r\n                            .setType(TvContractCompat.PreviewPrograms.TYPE_TV_EPISODE)\r\n                            .setTitle(it.name)\r\n                            .setEpisodeNumber(it.chapter.substringAfterLast(\" \").toInt())\r\n                            .setIntentUri(chapUri)\r\n                            .setPosterArtAspectRatio(TvContractCompat.PreviewPrograms.ASPECT_RATIO_3_2)\r\n                            .setPosterArtUri(Uri.parse(PatternUtil.getThumb(it.aid)))\r\n                        programIds.add(\r\n                            PreviewChannelHelper(context).publishPreviewProgram(program.build())\r\n                                .toString()\r\n                        )\r\n                    }\r\n                    PrefsUtil.tvRecentsChannelLastEid = recents.first().eid\r\n                    PrefsUtil.tvRecentsChannelIds = programIds\r\n                } else\r\n                    Repository().reloadAllRecents()\r\n            }\r\n    }\r\n\r\n    fun addProgram(context: Context, recentObject: RecentObject): Long {\r\n        val chapUri = Uri.Builder().scheme(\"ukiku\")\r\n            .authority(\"tv\")\r\n            .appendPath(\"chapter\")\r\n            .appendQueryParameter(\"aid\", recentObject.aid)\r\n            .appendQueryParameter(\"chapter\", recentObject.chapter)\r\n            .appendQueryParameter(\"eid\", recentObject.eid)\r\n            .appendQueryParameter(\"url\", recentObject.url.urlFixed)\r\n            .appendQueryParameter(\"name\", recentObject.name)\r\n            .build()\r\n        val program = PreviewProgram.Builder()\r\n            .setContentId(recentObject.eid)\r\n            .setChannelId(PrefsUtil.tvRecentsChannelId)\r\n            .setType(TvContractCompat.PreviewPrograms.TYPE_TV_EPISODE)\r\n            .setTitle(recentObject.name)\r\n            .setEpisodeNumber(recentObject.chapter.substringAfterLast(\" \").toInt())\r\n            .setIntentUri(chapUri)\r\n            .setPosterArtAspectRatio(TvContractCompat.PreviewPrograms.ASPECT_RATIO_3_2)\r\n            .setPosterArtUri(Uri.parse(PatternUtil.getThumb(recentObject.aid)))\r\n            .setWeight(999)\r\n        return PreviewChannelHelper(context).publishPreviewProgram(program.build())\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/GlideBackgroundManager.kt",
    "content": "package knf.kuma.tv\n\nimport android.app.Activity\nimport android.graphics.drawable.BitmapDrawable\nimport android.graphics.drawable.ColorDrawable\nimport android.graphics.drawable.Drawable\nimport androidx.leanback.app.BackgroundManager\nimport androidx.palette.graphics.Palette\nimport com.bumptech.glide.Glide\nimport com.bumptech.glide.request.target.SimpleTarget\nimport com.bumptech.glide.request.transition.Transition\nimport knf.kuma.App\nimport knf.kuma.commons.doOnUIGlobal\nimport java.lang.ref.WeakReference\nimport java.util.Timer\nimport java.util.TimerTask\n\nclass GlideBackgroundManager(activity: Activity) {\n    private val mActivityWeakReference: WeakReference<Activity> = WeakReference(activity)\n    private val mBackgroundManager: BackgroundManager? = BackgroundManager.getInstance(activity)\n    private var mBackgroundURI: String? = null\n    private var mBackgroundTimer: Timer? = null\n    private val mGlideDrawableSimpleTarget = object : SimpleTarget<Drawable>() {\n        override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {\n            Palette.from((resource as BitmapDrawable).bitmap).generate { palette ->\n                val textSwatch = palette?.darkMutedSwatch\n                if (textSwatch != null)\n                    setBackground(ColorDrawable(textSwatch.rgb))\n            }\n        }\n    }\n\n    init {\n        if (mBackgroundManager?.isAttached == false)\n            mBackgroundManager.attach(activity.window)\n    }\n\n    fun loadImage(imageUrl: String) {\n        mBackgroundURI = imageUrl\n        startBackgroundTimer()\n    }\n\n    fun setBackground(drawable: Drawable) {\n        if (mBackgroundManager != null) {\n            if (!mBackgroundManager.isAttached) {\n                mBackgroundManager.attach(mActivityWeakReference.get()?.window)\n            }\n            mBackgroundManager.drawable = drawable\n        }\n    }\n\n    /**\n     * Cancels an ongoing background change\n     */\n    fun cancelBackgroundChange() {\n        mBackgroundURI = null\n        cancelTimer()\n    }\n\n    /**\n     * Stops the timer\n     */\n    private fun cancelTimer() {\n        mBackgroundTimer?.cancel()\n    }\n\n    /**\n     * Starts the background change timer\n     */\n    private fun startBackgroundTimer() {\n        cancelTimer()\n        mBackgroundTimer = Timer()\n        /* set delay time to reduce too much background image loading process */\n        mBackgroundTimer?.schedule(UpdateBackgroundTask(), BACKGROUND_UPDATE_DELAY.toLong())\n    }\n\n    /**\n     * Updates the background with the last known URI\n     */\n    fun updateBackground() {\n        Glide.with(App.context)\n                .load(mBackgroundURI)\n                .into<SimpleTarget<Drawable>>(mGlideDrawableSimpleTarget)\n    }\n\n    private inner class UpdateBackgroundTask : TimerTask() {\n        override fun run() {\n            doOnUIGlobal {\n                if (mBackgroundURI != null) {\n                    updateBackground()\n                }\n            }\n        }\n    }\n\n    companion object {\n\n        private val TAG = GlideBackgroundManager::class.java.simpleName\n        private const val BACKGROUND_UPDATE_DELAY = 200\n        var instance: GlideBackgroundManager? = null\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/TVBaseActivity.kt",
    "content": "package knf.kuma.tv\n\n\nimport android.os.Bundle\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.FragmentActivity\nimport knf.kuma.R\nimport knf.kuma.backup.firestore.FirestoreManager\nimport knf.kuma.commons.SSLSkipper\n\n\nopen class TVBaseActivity : FragmentActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.tv_activity_main)\n        SSLSkipper.skip()\n        FirestoreManager.start()\n    }\n\n    fun addFragment(fragment: Fragment) {\n        val fragmentTransaction = supportFragmentManager.beginTransaction()\n        fragmentTransaction.replace(R.id.tv_frame_content, fragment)\n        fragmentTransaction.commit()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/TVServersFactory.kt",
    "content": "package knf.kuma.tv\n\nimport android.app.Activity\nimport android.content.Intent\nimport android.net.Uri\nimport android.util.Log\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.App\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.iterator\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.database.CacheDB\nimport knf.kuma.player.openWebPlayer\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.pojos.SeenObject\nimport knf.kuma.tv.exoplayer.TVPlayer\nimport knf.kuma.tv.streaming.TVMultiSelection\nimport knf.kuma.tv.streaming.TVServerSelection\nimport knf.kuma.tv.streaming.TVServerSelectionFragment\nimport knf.kuma.videoservers.Option\nimport knf.kuma.videoservers.Server\nimport knf.kuma.videoservers.VideoServer\nimport knf.kuma.videoservers.WebServer\nimport org.jetbrains.anko.doAsync\nimport org.json.JSONArray\nimport org.json.JSONObject\nimport xdroid.toaster.Toaster\nimport java.util.Locale\n\n\nclass TVServersFactory private constructor(\n    private val activity: Activity,\n    private val url: String,\n    private val chapter: AnimeObject.WebInfo.AnimeChapter,\n    val viewHolder: Presenter.ViewHolder?,\n    private val serversInterface: ServersInterface\n) {\n    private val downloadObject: DownloadObject = DownloadObject.fromChapter(chapter, false)\n\n    private var jsonObject: JSONObject? = null\n    private var servers: MutableList<Server> = ArrayList()\n\n    private var current: VideoServer? = null\n\n    fun showServerList() {\n        doOnUIGlobal {\n            try {\n                if (servers.isEmpty()) {\n                    Toaster.toast(\"Sin servidores disponibles\")\n                    serversInterface.onFinish(false, false)\n                } else {\n                    activity.startActivityForResult(\n                        Intent(activity, TVServerSelection::class.java)\n                            .putExtra(TVServerSelectionFragment.SERVERS_DATA, Server.getNames(servers) as ArrayList),\n                        REQUEST_CODE_LIST\n                    )\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n\n    }\n\n    fun analyzeMulti(position: Int) {\n        doAsync {\n            val main = jsoupCookies(url).get()\n            val downloads = main.select(\"table.RTbl.Dwnl tr:contains(${if (position == 0) \"SUB\" else \"LAT\"}) a.Button.Sm.fa-download\")\n            for (e in downloads) {\n                var z = e.attr(\"href\")\n                z = z.substring(z.lastIndexOf(\"http\"))\n                val server = Server.check(activity, z)\n                if (server != null)\n                    servers.add(server)\n            }\n            val jsonArray = jsonObject?.getJSONArray(if (position == 0) \"SUB\" else \"LAT\")\n                ?: JSONArray()\n            for (baseLink in jsonArray) {\n                val server = Server.check(activity, baseLink.optString(\"code\"))\n                if (server != null)\n                    try {\n                        var skip = false\n                        servers.forEach {\n                            if (it.name == server.name) {\n                                skip = true\n                                return@forEach\n                            }\n                        }\n                        if (!skip)\n                            servers.add(server)\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                    }\n            }\n            servers.sort()\n            showServerList()\n        }\n    }\n\n    fun analyzeServer(position: Int) {\n        doAsync {\n            try {\n                val text = servers[position].name\n                val server = servers[position].verified\n                if (server == null && servers.size == 1) {\n                    Toaster.toast(\"Error en servidor, intente mas tarde\")\n                    serversInterface.onFinish(false, false)\n                } else if (server == null) {\n                    Toaster.toast(\"Error en servidor\")\n                    showServerList()\n                } else if (server.options.size == 0) {\n                    Toaster.toast(\"Error en servidor\")\n                    showServerList()\n                } else if (server.haveOptions()) {\n                    showOptions(server)\n                } else if (servers[position] is WebServer) {\n                    try {\n                        openWebPlayer(activity, server.option.url!!)\n                        doAsync {\n                            CacheDB.INSTANCE.seenDAO().addChapter(SeenObject.fromChapter(chapter))\n                            CacheDB.INSTANCE.recordsDAO().add(RecordObject.fromChapter(chapter))\n                            syncData {\n                                history()\n                                seen()\n                            }\n                        }\n                        serversInterface.onFinish(false, true)\n                    } catch (_: Exception) {\n                        Toaster.toast(\"Error al abrir explorador web\")\n                        showServerList()\n                    }\n\n                } else {\n                    when (text.lowercase(Locale.getDefault())) {\n                        \"mega\" -> {\n                            Toaster.toast(\"No se puede usar Mega en TV\")\n                            showServerList()\n                        }\n\n                        else -> startStreaming(server.option)\n                    }\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n    }\n\n    fun analyzeOption(position: Int) {\n        current?.let { startStreaming(it.options[position]) }\n    }\n\n    private fun showOptions(server: VideoServer) {\n        this.current = server\n        activity.startActivityForResult(\n            Intent(activity, TVServerSelection::class.java)\n                .putExtra(\"name\", server.name)\n                .putExtra(\n                    TVServerSelectionFragment.VIDEO_DATA, (Option.getNames(server.options) as? ArrayList)\n                        ?: arrayListOf<String>()\n                ),\n            REQUEST_CODE_OPTION\n        )\n    }\n\n    private fun startStreaming(option: Option) {\n        doAsync {\n            CacheDB.INSTANCE.seenDAO().addChapter(SeenObject.fromChapter(chapter))\n            CacheDB.INSTANCE.recordsDAO().add(RecordObject.fromChapter(chapter))\n            syncData {\n                history()\n                seen()\n            }\n        }\n        activity.startActivity(Intent(activity, TVPlayer::class.java).apply {\n            setDataAndType(Uri.parse(option.url), \"video/*\")\n            putExtra(\"title\", downloadObject.name)\n            putExtra(\"chapter\", downloadObject.chapter)\n            putStringArrayListExtra(\"headers\", ArrayList(option.headers?.createHeadersList()?: emptyList()))\n        })\n        serversInterface.onFinish(false, true)\n    }\n\n    fun get() {\n        try {\n            Log.e(\"Url\", url)\n            val main = jsoupCookies(url).get()\n            val servers = ArrayList<Server>()\n            val sScript = main.select(\"script\")\n            var j = \"\"\n            for (element in sScript) {\n                val sEl = element.outerHtml()\n                if (\"\\\\{\\\"[SUBLAT]+\\\":\\\\[.*\\\\]\\\\}\".toRegex().containsMatchIn(sEl)) {\n                    j = sEl\n                    break\n                }\n            }\n            jsonObject = JSONObject(\"\\\\{\\\"[SUBLAT]+\\\":\\\\[.*\\\\]\\\\}\".toRegex().find(j)?.value)\n            if (jsonObject?.length() ?: 0 > 1) {\n                this.servers = servers\n                activity.startActivityForResult(\n                    Intent(activity, TVMultiSelection::class.java),\n                    REQUEST_CODE_MULTI\n                )\n            } else {\n                val downloads = main.select(\"table.RTbl.Dwnl tr:contains(SUB) a.Button.Sm.fa-download\")\n                for (e in downloads) {\n                    var z = e.attr(\"href\")\n                    z = z.substring(z.lastIndexOf(\"http\"))\n                    val server = Server.check(activity, z)\n                    if (server != null)\n                        servers.add(server)\n                }\n                val jsonArray = jsonObject?.getJSONArray(\"SUB\") ?: JSONArray()\n                for (baseLink in jsonArray) {\n                    val server = Server.check(activity, baseLink.optString(\"code\"))\n                    if (server != null)\n                        servers.add(server)\n                    else if (!baseLink.optString(\"code\").contains(\"linkinpork\"))\n                        servers.add(WebServer(App.context, baseLink.optString(\"code\"), baseLink.optString(\"title\")))\n                }\n                servers.sort()\n                this.servers = servers.filter { it is WebServer || it.canStream }.distinctBy { it.baseLink.dropLastWhile { it == '/' }.substringAfterLast(\"/\") }.toMutableList()\n                showServerList()\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            this.servers = ArrayList()\n            serversInterface.onFinish(false, false)\n        }\n\n    }\n\n    interface ServersInterface {\n        fun onReady(serversFactory: TVServersFactory)\n\n        fun onFinish(started: Boolean, success: Boolean)\n    }\n\n    companion object {\n        var REQUEST_CODE_LIST = 4456\n        var REQUEST_CODE_OPTION = 6157\n        var REQUEST_CODE_MULTI = 6497\n\n        fun start(activity: Activity, url: String, chapter: AnimeObject.WebInfo.AnimeChapter, serversInterface: ServersInterface) {\n            start(activity, url, chapter, null, serversInterface)\n        }\n\n        fun start(activity: Activity, url: String, chapter: AnimeObject.WebInfo.AnimeChapter, viewHolder: Presenter.ViewHolder?, serversInterface: ServersInterface?) {\n            doAsync {\n                serversInterface?.let {\n                    val factory = TVServersFactory(activity, url, chapter, viewHolder, it)\n                    serversInterface.onReady(factory)\n                    factory.get()\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/anime/AnimePresenter.kt",
    "content": "package knf.kuma.tv.anime\n\nimport android.view.ViewGroup\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.tv.cards.AnimeCardView\nimport knf.kuma.tv.search.BasicAnimeObject\n\nclass AnimePresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(AnimeCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as AnimeCardView).bind(item as BasicAnimeObject)\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/anime/ChapterPresenter.kt",
    "content": "package knf.kuma.tv.anime\n\nimport android.view.ViewGroup\n\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.tv.cards.ChapterCardView\n\nclass ChapterPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(ChapterCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as ChapterCardView).bind(item as AnimeObject.WebInfo.AnimeChapter)\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/anime/EmissionPresenter.kt",
    "content": "package knf.kuma.tv.anime\n\nimport android.view.ViewGroup\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.search.SearchObject\nimport knf.kuma.tv.cards.EmissionCardView\n\nclass EmissionPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(EmissionCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as EmissionCardView).bind(item as SearchObject)\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/anime/FavPresenter.kt",
    "content": "package knf.kuma.tv.anime\n\nimport android.view.ViewGroup\n\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.pojos.FavoriteObject\nimport knf.kuma.tv.cards.FavCardView\n\nclass FavPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(FavCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as FavCardView).bind(item as FavoriteObject)\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/anime/RecentsPresenter.kt",
    "content": "package knf.kuma.tv.anime\n\nimport android.view.ViewGroup\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.tv.cards.RecentsCardView\nimport knf.kuma.tv.details.TVAnimesDetails\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass RecentsPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(RecentsCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as RecentsCardView).bind(item as RecentObject)\n        viewHolder.view.setOnLongClickListener { v ->\n            GlobalScope.launch(Dispatchers.Main){\n                val animeObject = withContext(Dispatchers.IO) { CacheDB.INSTANCE.animeDAO().getByAid(item.aid) }\n                animeObject?.let { TVAnimesDetails.start(v.context, it.link) }\n            }\n            true\n        }\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/anime/RecordPresenter.kt",
    "content": "package knf.kuma.tv.anime\n\nimport android.view.ViewGroup\n\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.tv.cards.RecordCardView\n\nclass RecordPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(RecordCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as RecordCardView).bind(item as RecordObject)\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/anime/RelatedPresenter.kt",
    "content": "package knf.kuma.tv.anime\n\nimport android.view.ViewGroup\n\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.tv.cards.RelatedCardView\n\nclass RelatedPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(RelatedCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as RelatedCardView).bind(item as AnimeObject.WebInfo.AnimeRelated)\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/anime/SectionPresenter.kt",
    "content": "package knf.kuma.tv.anime\n\nimport android.view.ViewGroup\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.tv.cards.SectionCardView\nimport knf.kuma.tv.sections.SectionObject\n\nclass SectionPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(SectionCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        (item as? SectionObject)?.let {\n            (viewHolder.view as? SectionCardView)?.bind(it)\n        }\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/anime/SyncPresenter.kt",
    "content": "package knf.kuma.tv.anime\n\nimport android.view.ViewGroup\n\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.tv.cards.SyncCardView\nimport knf.kuma.tv.sync.SyncObject\n\nclass SyncPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(SyncCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        (item as? SyncObject)?.let {\n            (viewHolder.view as? SyncCardView)?.bind(it)\n        }\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/AnimeCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.loadGlide\nimport knf.kuma.tv.BindableCardView\nimport knf.kuma.tv.search.BasicAnimeObject\nimport org.jetbrains.anko.find\n\nclass AnimeCardView(context: Context) : BindableCardView<BasicAnimeObject>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card\n\n    override fun bind(data: BasicAnimeObject) {\n        imageView.loadGlide(PatternUtil.getCover(data.aid))\n        find<TextView>(R.id.title).text = data.name\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/ChapterCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.view.View\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.loadGlide\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.tv.BindableCardView\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.find\n\nclass ChapterCardView(context: Context) : BindableCardView<AnimeObject.WebInfo.AnimeChapter>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card_chapter_preview\n\n    override fun bind(data: AnimeObject.WebInfo.AnimeChapter) {\n        imageView.loadGlide(data.img)\n        GlobalScope.launch(Dispatchers.Main) {\n            find<View>(R.id.indicator).visibility = if (withContext(Dispatchers.IO) { CacheDB.INSTANCE.seenDAO().chapterIsSeen(data.aid, data.number) }) VISIBLE else GONE\n        }\n        find<TextView>(R.id.chapter).text = data.number\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/DirAdvCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.loadGlide\nimport knf.kuma.directory.DirObject\nimport knf.kuma.tv.BindableCardView\nimport org.jetbrains.anko.find\n\nclass DirAdvCardView(context: Context) : BindableCardView<DirObject>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card_adv\n\n    override fun bind(data: DirObject) {\n        imageView.loadGlide(PatternUtil.getCover(data.aid))\n        find<TextView>(R.id.title).text = data.name\n        find<TextView>(R.id.rating).text = \"\\u2605${data.rate_stars ?: \"?.?\"}\"\n        find<TextView>(R.id.type).text = data.type\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/DirCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.loadGlide\nimport knf.kuma.directory.DirObject\nimport knf.kuma.tv.BindableCardView\nimport org.jetbrains.anko.find\n\nclass DirCardView(context: Context) : BindableCardView<DirObject>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card_rate\n\n    override fun bind(data: DirObject) {\n        imageView.loadGlide(PatternUtil.getCover(data.aid))\n        find<TextView>(R.id.title).text = data.name\n        find<TextView>(R.id.rating).text = \"\\u2605${data.rate_stars ?: \"?.?\"}\"\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/EmissionCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.loadGlide\nimport knf.kuma.search.SearchObject\nimport knf.kuma.tv.BindableCardView\nimport org.jetbrains.anko.find\n\nclass EmissionCardView(context: Context) : BindableCardView<SearchObject>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card\n\n    override fun bind(data: SearchObject) {\n        imageView.loadGlide(PatternUtil.getCover(data.aid))\n        find<TextView>(R.id.title).text = data.name\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/FavCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.loadGlide\nimport knf.kuma.pojos.FavoriteObject\nimport knf.kuma.tv.BindableCardView\nimport org.jetbrains.anko.find\n\nclass FavCardView(context: Context) : BindableCardView<FavoriteObject>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card\n\n    override fun bind(data: FavoriteObject) {\n        imageView.loadGlide(PatternUtil.getCover(data.aid))\n        find<TextView>(R.id.title).text = data.name\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/RecentsCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.loadGlide\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.tv.BindableCardView\nimport org.jetbrains.anko.find\n\nclass RecentsCardView(context: Context) : BindableCardView<RecentObject>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card_chapter\n\n    override fun bind(data: RecentObject) {\n        imageView.loadGlide(PatternUtil.getCover(data.aid))\n        find<TextView>(R.id.title).text = data.name\n        find<TextView>(R.id.chapter).text = data.chapter\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/RecordCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.loadGlide\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.tv.BindableCardView\nimport org.jetbrains.anko.find\n\nclass RecordCardView(context: Context) : BindableCardView<RecordObject>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card_chapter\n\n    override fun bind(data: RecordObject) {\n        imageView.loadGlide(PatternUtil.getCover(data.aid))\n        find<TextView>(R.id.title).text = data.name\n        find<TextView>(R.id.chapter).text = data.chapter\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/RelatedCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.loadGlide\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.tv.BindableCardView\nimport org.jetbrains.anko.find\n\nclass RelatedCardView(context: Context) : BindableCardView<AnimeObject.WebInfo.AnimeRelated>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card_chapter\n\n    override fun bind(data: AnimeObject.WebInfo.AnimeRelated) {\n        imageView.loadGlide(PatternUtil.getCover(data.aid))\n        find<TextView>(R.id.title).text = data.name\n        find<TextView>(R.id.chapter).text = data.relation\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/SectionCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.tv.BindableCardView\nimport knf.kuma.tv.sections.SectionObject\nimport org.jetbrains.anko.find\n\nclass SectionCardView(context: Context) : BindableCardView<SectionObject>(context) {\n\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card_section\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n\n    override fun bind(data: SectionObject) {\n        doOnUIGlobal { imageView.setImageResource(data.image) }\n        find<TextView>(R.id.title).text = data.title\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/SyncCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.tv.BindableCardView\nimport knf.kuma.tv.sync.SyncObject\nimport org.jetbrains.anko.find\n\nclass SyncCardView(context: Context) : BindableCardView<SyncObject>(context) {\n\n    override val layoutResource: Int\n        get() = R.layout.item_tv_card_sync\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n\n    override fun bind(data: SyncObject) {\n        imageView.setImageResource(data.image)\n        find<TextView>(R.id.title).text = data.title\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/cards/TagCardView.kt",
    "content": "package knf.kuma.tv.cards\n\nimport android.content.Context\nimport android.widget.ImageView\nimport android.widget.TextView\nimport knf.kuma.R\nimport knf.kuma.tv.BindableCardView\nimport org.jetbrains.anko.find\n\nclass TagCardView(context: Context) : BindableCardView<String>(context) {\n\n    override val imageView: ImageView\n        get() = find(R.id.img)\n    override val layoutResource: Int\n        get() = R.layout.item_tv_tag\n\n    override fun bind(data: String) {\n        find<TextView>(R.id.title).text = data\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/details/ChaptersListPresenter.kt",
    "content": "package knf.kuma.tv.details\n\nimport androidx.leanback.widget.ListRowPresenter\nimport androidx.leanback.widget.RowPresenter\n\nclass ChaptersListPresenter(val position: Int) : ListRowPresenter() {\n\n    override fun onBindRowViewHolder(holder: RowPresenter.ViewHolder, item: Any) {\n        super.onBindRowViewHolder(holder, item)\n        val vh = holder as ViewHolder\n        vh.gridView.selectedPosition = position\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/details/ChaptersListRow.kt",
    "content": "package knf.kuma.tv.details\n\nimport androidx.leanback.widget.HeaderItem\nimport androidx.leanback.widget.ListRow\nimport androidx.leanback.widget.ObjectAdapter\n\nclass ChaptersListRow : ListRow {\n    constructor(header: HeaderItem, adapter: ObjectAdapter) : super(header, adapter)\n\n    constructor(id: Long, header: HeaderItem, adapter: ObjectAdapter) : super(id, header, adapter)\n\n    constructor(adapter: ObjectAdapter) : super(adapter)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/details/CustomFullWidthDetailsOverviewRowPresenter.kt",
    "content": "package knf.kuma.tv.details\n\nimport android.view.ViewGroup\nimport androidx.leanback.widget.FullWidthDetailsOverviewRowPresenter\nimport androidx.leanback.widget.Presenter\n\nclass CustomFullWidthDetailsOverviewRowPresenter internal constructor(detailsPresenter: Presenter) : FullWidthDetailsOverviewRowPresenter(detailsPresenter) {\n\n    private var mPreviousState = STATE_FULL\n\n    init {\n        initialState = STATE_FULL\n    }\n\n    override fun onLayoutLogo(viewHolder: ViewHolder, oldState: Int, logoChanged: Boolean) {\n        val v = viewHolder.logoViewHolder.view\n        val lp = v.layoutParams as ViewGroup.MarginLayoutParams\n\n        lp.marginStart = v.resources.getDimensionPixelSize(\n                androidx.leanback.R.dimen.lb_details_v2_logo_margin_start)\n        lp.topMargin = v.resources.getDimensionPixelSize(androidx.leanback.R.dimen.lb_details_v2_blank_height) - lp.height / 2\n\n        val offset = (v.resources.getDimensionPixelSize(androidx.leanback.R.dimen.lb_details_v2_actions_height) + v\n                .resources.getDimensionPixelSize(androidx.leanback.R.dimen.lb_details_v2_description_margin_top) + lp.height / 2).toFloat()\n\n        when (viewHolder.state) {\n            STATE_FULL -> if (mPreviousState == STATE_HALF) {\n                v.animate().translationYBy(-offset)\n            }\n            STATE_HALF -> if (mPreviousState == STATE_FULL) {\n                v.animate().translationYBy(offset)\n            }\n            else -> if (mPreviousState == STATE_HALF) {\n                v.animate().translationYBy(-offset)\n            }\n        }\n        mPreviousState = viewHolder.state\n        v.layoutParams = lp\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/details/DetailsDescriptionPresenter.kt",
    "content": "package knf.kuma.tv.details\n\nimport androidx.annotation.ColorInt\nimport androidx.leanback.widget.AbstractDetailsDescriptionPresenter\nimport knf.kuma.pojos.AnimeObject\n\nclass DetailsDescriptionPresenter : AbstractDetailsDescriptionPresenter {\n    @ColorInt\n    private var titleColor: Int = 0\n    @ColorInt\n    private var bodyColor: Int = 0\n\n    internal constructor(titleColor: Int, bodyColor: Int) {\n        this.titleColor = titleColor\n        this.bodyColor = bodyColor\n    }\n\n    internal constructor() {\n        this.titleColor = 0\n        this.bodyColor = 0\n    }\n\n    override fun onBindDescription(viewHolder: ViewHolder, itemData: Any) {\n        val animeObject = itemData as AnimeObject\n        viewHolder.title.text = animeObject.name\n        viewHolder.subtitle.text = animeObject.genresString\n        viewHolder.body.text = animeObject.description\n        if (titleColor != 0)\n            viewHolder.title.setTextColor(titleColor)\n        if (bodyColor != 0) {\n            viewHolder.subtitle.setTextColor(bodyColor)\n            viewHolder.body.setTextColor(bodyColor)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/details/TVAnimesDetails.kt",
    "content": "package knf.kuma.tv.details\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport android.view.View\nimport knf.kuma.R\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.tv.TVBaseActivity\nimport knf.kuma.tv.TVServersFactory\n\n\nclass TVAnimesDetails : TVBaseActivity(), TVServersFactory.ServersInterface {\n    private var fragment: TVAnimesDetailsFragment? = null\n    private var serversFactory: TVServersFactory? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        fragment = TVAnimesDetailsFragment[intent.getStringExtra(keyUrl) ?: \"\"]\n        addFragment(fragment as TVAnimesDetailsFragment)\n    }\n\n    override fun onReady(serversFactory: TVServersFactory) {\n        this.serversFactory = serversFactory\n    }\n\n    override fun onFinish(started: Boolean, success: Boolean) {\n        if (fragment != null && success) {\n            fragment?.onStartStreaming()\n            doOnUI {\n                serversFactory?.viewHolder?.view?.apply {\n                    findViewById<View>(R.id.indicator).visibility = View.VISIBLE\n                    invalidate()\n                }\n            }\n        }\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        if (resultCode == RESULT_OK) {\n            val bundle = data?.extras\n            if (requestCode == TVServersFactory.REQUEST_CODE_MULTI)\n                serversFactory?.analyzeMulti(bundle?.getInt(keyPosition, 0) ?: 0)\n            else {\n                if (bundle?.getBoolean(keyIsVideoServer, false) == true)\n                    serversFactory?.analyzeOption(bundle.getInt(keyPosition, 0))\n                else\n                    serversFactory?.analyzeServer(bundle?.getInt(keyPosition, 0) ?: 0)\n            }\n        } else if (resultCode == RESULT_CANCELED && data?.extras?.getBoolean(keyIsVideoServer, false) == true)\n            serversFactory?.showServerList()\n    }\n\n    companion object {\n\n        private const val keyPosition = \"position\"\n        private const val keyUrl = \"url\"\n        private const val keyIsVideoServer = \"is_video_server\"\n\n        fun start(context: Context, url: String?) {\n            url ?: return\n            context.startActivity(Intent(context, TVAnimesDetails::class.java).putExtra(keyUrl, url))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/details/TVAnimesDetailsFragment.kt",
    "content": "package knf.kuma.tv.details\n\nimport android.graphics.Bitmap\nimport android.graphics.Color\nimport android.os.Bundle\nimport androidx.core.content.ContextCompat\nimport androidx.leanback.app.DetailsSupportFragment\nimport androidx.leanback.widget.Action\nimport androidx.leanback.widget.ArrayObjectAdapter\nimport androidx.leanback.widget.ClassPresenterSelector\nimport androidx.leanback.widget.DetailsOverviewRow\nimport androidx.leanback.widget.HeaderItem\nimport androidx.leanback.widget.ListRow\nimport androidx.leanback.widget.ListRowPresenter\nimport androidx.leanback.widget.OnActionClickedListener\nimport androidx.leanback.widget.OnItemViewClickedListener\nimport androidx.leanback.widget.Presenter\nimport androidx.leanback.widget.Row\nimport androidx.leanback.widget.RowPresenter\nimport androidx.leanback.widget.SparseArrayObjectAdapter\nimport androidx.lifecycle.lifecycleScope\nimport androidx.palette.graphics.Palette\nimport com.bumptech.glide.Glide\nimport com.bumptech.glide.request.target.SimpleTarget\nimport com.bumptech.glide.request.transition.Transition\nimport knf.kuma.App\nimport knf.kuma.R\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.noCrash\nimport knf.kuma.database.CacheDB\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.FavoriteObject\nimport knf.kuma.retrofit.Repository\nimport knf.kuma.tv.TVServersFactory\nimport knf.kuma.tv.anime.ChapterPresenter\nimport knf.kuma.tv.anime.RelatedPresenter\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass TVAnimesDetailsFragment : DetailsSupportFragment(), OnItemViewClickedListener, OnActionClickedListener {\n\n    private var mRowsAdapter: ArrayObjectAdapter? = null\n    private var favoriteObject: FavoriteObject? = null\n    private var currentChapter: AnimeObject.WebInfo.AnimeChapter? = null\n    private var chapters: MutableList<AnimeObject.WebInfo.AnimeChapter>? = ArrayList()\n    private var actionAdapter: SparseArrayObjectAdapter? = null\n    private var listRowAdapter: ArrayObjectAdapter? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        buildDetails()\n        onItemViewClickedListener = this\n    }\n\n    private suspend fun getLastSeen(chapters: MutableList<AnimeObject.WebInfo.AnimeChapter>?): Int {\n        if (chapters?.isNotEmpty() == true) {\n            val eids =\n                chapters.sortedBy { it.number.substringAfterLast(\" \").toFloat() }.map { it.eid }\n            eids.chunked(50).forEach { list ->\n                val chapter =\n                    withContext(Dispatchers.IO) { CacheDB.INSTANCE.seenDAO().getLast(list) }\n                if (chapter != null) {\n                    val position = chapters.indexOf(chapters.find { it.eid == chapter.eid })\n                    if (position >= 0)\n                        return position\n                }\n            }\n        }\n        return 0\n    }\n\n    private fun buildDetails() {\n        val activity = activity ?: return\n        Repository().getAnime(\n            arguments?.getString(\"url\")\n                ?: \"\", true\n        ).observe(activity) { animeObject ->\n            if (animeObject != null) {\n                Glide.with(App.context).asBitmap().load(PatternUtil.getCoverGlide(animeObject.aid))\n                    .into(object : SimpleTarget<Bitmap>() {\n                        override fun onResourceReady(\n                            resource: Bitmap,\n                            transition: Transition<in Bitmap>?\n                        ) {\n                            Palette.from(resource).generate { palette ->\n                                val swatch = palette?.darkMutedSwatch\n                                favoriteObject = FavoriteObject(animeObject)\n                                chapters = animeObject.chapters\n                                chapters?.reversed()\n                                val selector = ClassPresenterSelector()\n                                val rowPresenter = CustomFullWidthDetailsOverviewRowPresenter(\n                                    if (swatch == null)\n                                        DetailsDescriptionPresenter()\n                                    else\n                                        DetailsDescriptionPresenter(\n                                            swatch.titleTextColor,\n                                            swatch.bodyTextColor\n                                        )\n                                )\n                                if (swatch != null) {\n                                    rowPresenter.backgroundColor = swatch.rgb\n                                    val hsv = FloatArray(3)\n                                    val color = swatch.rgb\n                                    Color.colorToHSV(color, hsv)\n                                    hsv[2] *= 0.8f\n                                    rowPresenter.actionsBackgroundColor = Color.HSVToColor(hsv)\n                                }\n                                selector.addClassPresenter(\n                                    DetailsOverviewRow::class.java,\n                                    rowPresenter\n                                )\n                                lifecycleScope.launch {\n                                    selector.addClassPresenter(\n                                        ChaptersListRow::class.java,\n                                        ChaptersListPresenter(getLastSeen(chapters))\n                                    )\n                                    selector.addClassPresenter(\n                                        ListRow::class.java,\n                                        ListRowPresenter()\n                                    )\n                                    mRowsAdapter = ArrayObjectAdapter(selector)\n                                    val detailsOverview = DetailsOverviewRow(animeObject)\n\n                                    // Add images and action buttons to the details view\n                                    detailsOverview.setImageBitmap(activity, resource)\n                                    detailsOverview.isImageScaleUpAllowed = true\n                                    actionAdapter = SparseArrayObjectAdapter()\n                                    if (withContext(Dispatchers.IO) {\n                                            CacheDB.INSTANCE.favsDAO().isFav(animeObject.key)\n                                        }) {\n                                        actionAdapter?.set(\n                                            1,\n                                            Action(\n                                                1,\n                                                \"Quitar favorito\",\n                                                null,\n                                                ContextCompat.getDrawable(\n                                                    App.context,\n                                                    R.drawable.heart_full\n                                                )\n                                            )\n                                        )\n                                    } else {\n                                        actionAdapter?.set(\n                                            1,\n                                            Action(\n                                                1,\n                                                \"Añadir favorito\",\n                                                null,\n                                                ContextCompat.getDrawable(\n                                                    App.context,\n                                                    R.drawable.heart_empty\n                                                )\n                                            )\n                                        )\n                                    }\n                                    actionAdapter?.apply {\n                                        set(\n                                            2,\n                                            Action(\n                                                2,\n                                                \"${animeObject.rate_stars}/5.0 (${animeObject.rate_count})\",\n                                                null,\n                                                ContextCompat.getDrawable(\n                                                    App.context,\n                                                    R.drawable.ic_seeing\n                                                )\n                                            )\n                                        )\n                                        detailsOverview.actionsAdapter = this\n                                    }\n                                    rowPresenter.onActionClickedListener =\n                                        this@TVAnimesDetailsFragment\n                                    mRowsAdapter?.add(detailsOverview)\n                                    // Add a Chapters items row\n                                    if (chapters?.isNotEmpty() == true) {\n                                        chapters?.let {\n                                            listRowAdapter = ArrayObjectAdapter(\n                                                ChapterPresenter()\n                                            )\n                                            for (chapter in it)\n                                                listRowAdapter?.add(chapter)\n                                            val header = HeaderItem(0, \"Episodios\")\n                                            mRowsAdapter?.add(\n                                                ChaptersListRow(\n                                                    header, listRowAdapter\n                                                        ?: ArrayObjectAdapter()\n                                                )\n                                            )\n                                        }\n                                    }\n\n                                    // Add a Related items row\n                                    if (animeObject.related?.isNotEmpty() == true) {\n                                        val listRowAdapter = ArrayObjectAdapter(\n                                            RelatedPresenter()\n                                        )\n                                        for (related in animeObject.related ?: listOf())\n                                            listRowAdapter.add(related)\n                                        val header = HeaderItem(0, \"Relacionados\")\n                                        mRowsAdapter?.add(ListRow(header, listRowAdapter))\n                                    }\n\n                                    noCrash { adapter = mRowsAdapter }\n                                }\n                            }\n                        }\n                    })\n            }\n        }\n    }\n\n    override fun onItemClicked(itemViewHolder: Presenter.ViewHolder, item: Any, rowViewHolder: RowPresenter.ViewHolder, row: Row) {\n        val activity = activity ?: return\n        if (item is AnimeObject.WebInfo.AnimeRelated) {\n            TVAnimesDetails.start(activity, \"https://www3.animeflv.net\" + item.link)\n        } else if (item is AnimeObject.WebInfo.AnimeChapter) {\n            currentChapter = item\n            TVServersFactory.start(activity, item.link, item, itemViewHolder, activity as? TVServersFactory.ServersInterface)\n        }\n    }\n\n    fun onStartStreaming() {\n        currentChapter?.let { listRowAdapter?.notifyArrayItemRangeChanged(chapters?.indexOf(it)?:0, 1) }\n    }\n\n    override fun onActionClicked(action: Action) {\n        if (action.id == 1L) {\n            actionAdapter?.clear()\n            favoriteObject?.let {\n                lifecycleScope.launch(Dispatchers.IO) {\n                    if (CacheDB.INSTANCE.favsDAO().isFav(it.key)) {\n                        CacheDB.INSTANCE.favsDAO().deleteFav(it)\n                        launch(Dispatchers.Main){\n                            action.label1 = \"Añadir favorito\"\n                            action.icon = ContextCompat.getDrawable(App.context, R.drawable.heart_empty)\n                        }\n                    } else {\n                        CacheDB.INSTANCE.favsDAO().addFav(it)\n                        launch(Dispatchers.Main){\n                            action.label1 = \"Quitar favorito\"\n                            action.icon = ContextCompat.getDrawable(App.context, R.drawable.heart_full)\n                        }\n                    }\n                    syncData { favs() }\n                }\n            }\n            actionAdapter?.set(1, action)\n        }\n    }\n\n    companion object {\n\n        operator fun get(url: String): TVAnimesDetailsFragment {\n            val fragment = TVAnimesDetailsFragment()\n            val bundle = Bundle()\n            bundle.putString(\"url\", url)\n            fragment.arguments = bundle\n            return fragment\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/directory/DirAdvPresenter.kt",
    "content": "package knf.kuma.tv.directory\n\nimport android.view.ViewGroup\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.directory.DirObject\nimport knf.kuma.tv.cards.DirAdvCardView\n\nclass DirAdvPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(DirAdvCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as DirAdvCardView).bind(item as DirObject)\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/directory/DirPresenter.kt",
    "content": "package knf.kuma.tv.directory\n\nimport android.view.ViewGroup\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.directory.DirObject\nimport knf.kuma.tv.cards.DirCardView\n\nclass DirPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(DirCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as DirCardView).bind(item as DirObject)\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/directory/TVDir.kt",
    "content": "package knf.kuma.tv.directory\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport knf.kuma.tv.TVBaseActivity\n\nclass TVDir : TVBaseActivity() {\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        addFragment(TVDirFragment())\n    }\n\n    companion object {\n        fun start(context: Context?) {\n            context?.startActivity(Intent(context, TVDir::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/directory/TVDirFragment.kt",
    "content": "package knf.kuma.tv.directory\r\n\r\nimport android.os.Bundle\r\nimport androidx.leanback.app.VerticalGridSupportFragment\r\nimport androidx.leanback.widget.ArrayObjectAdapter\r\nimport androidx.leanback.widget.OnItemViewClickedListener\r\nimport androidx.leanback.widget.Presenter\r\nimport androidx.leanback.widget.Row\r\nimport androidx.leanback.widget.RowPresenter\r\nimport androidx.leanback.widget.VerticalGridPresenter\r\nimport androidx.lifecycle.Observer\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.directory.DirObject\r\nimport knf.kuma.tv.details.TVAnimesDetails\r\nimport org.jetbrains.anko.doAsync\r\n\r\nclass TVDirFragment : VerticalGridSupportFragment(), OnItemViewClickedListener {\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        title = \"Directorio\"\r\n        setGridPresenter(\r\n            VerticalGridPresenter().apply {\r\n                numberOfColumns = 4\r\n            }\r\n        )\r\n        onItemViewClickedListener = this\r\n        CacheDB.INSTANCE.animeDAO().allLive.observe(this, Observer {\r\n            if (!it.isNullOrEmpty()) {\r\n                doAsync {\r\n                    val arrayAdapter = ArrayObjectAdapter(DirAdvPresenter()).apply {\r\n                        addAll(0, it)\r\n                    }\r\n                    doOnUI { adapter = arrayAdapter }\r\n                }\r\n            }\r\n        })\r\n    }\r\n\r\n    override fun onItemClicked(itemViewHolder: Presenter.ViewHolder?, item: Any?, rowViewHolder: RowPresenter.ViewHolder?, row: Row?) {\r\n        if (item is DirObject)\r\n            context?.let { TVAnimesDetails.start(it, item.link) }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/emission/TVEmission.kt",
    "content": "package knf.kuma.tv.emission\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport knf.kuma.tv.TVBaseActivity\n\nclass TVEmission : TVBaseActivity() {\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        addFragment(TVEmissionFragment())\n    }\n\n    companion object {\n        fun start(context: Context?) {\n            context?.startActivity(Intent(context, TVEmission::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/emission/TVEmissionFragment.kt",
    "content": "package knf.kuma.tv.emission\r\n\r\nimport android.graphics.Color\r\nimport android.os.Bundle\r\nimport android.util.Log\r\nimport android.util.SparseArray\r\nimport androidx.leanback.app.BrowseSupportFragment\r\nimport androidx.leanback.widget.ArrayObjectAdapter\r\nimport androidx.leanback.widget.HeaderItem\r\nimport androidx.leanback.widget.ListRow\r\nimport androidx.leanback.widget.ListRowPresenter\r\nimport androidx.leanback.widget.OnItemViewClickedListener\r\nimport androidx.leanback.widget.Presenter\r\nimport androidx.leanback.widget.Row\r\nimport androidx.leanback.widget.RowPresenter\r\nimport androidx.lifecycle.Observer\r\nimport knf.kuma.commons.distinct\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.directory.DirObject\r\nimport knf.kuma.pojos.AnimeObject\r\nimport knf.kuma.tv.AnimeRow\r\nimport knf.kuma.tv.details.TVAnimesDetails\r\nimport knf.kuma.tv.directory.DirPresenter\r\n\r\nclass TVEmissionFragment : BrowseSupportFragment(), OnItemViewClickedListener {\r\n    private val mRows: SparseArray<AnimeRow> = SparseArray()\r\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\r\n        super.onActivityCreated(savedInstanceState)\r\n        headersState = HEADERS_ENABLED\r\n        isHeadersTransitionOnBackEnabled = true\r\n        title = \"Emisión\"\r\n        brandColor = Color.parseColor(\"#424242\")\r\n        createDataRows()\r\n        prepareEntranceTransition()\r\n        fetchData()\r\n    }\r\n\r\n    private fun createDataRows() {\r\n        mRows.put(AnimeObject.Day.MONDAY.value, AnimeRow()\r\n                .setId(AnimeObject.Day.MONDAY.value)\r\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\r\n                .setTitle(\"Lunes\")\r\n                .setPage(1))\r\n        mRows.put(AnimeObject.Day.TUESDAY.value, AnimeRow()\r\n                .setId(AnimeObject.Day.TUESDAY.value)\r\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\r\n                .setTitle(\"Martes\")\r\n                .setPage(1))\r\n        mRows.put(AnimeObject.Day.WEDNESDAY.value, AnimeRow()\r\n                .setId(AnimeObject.Day.WEDNESDAY.value)\r\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\r\n                .setTitle(\"Miercoles\")\r\n                .setPage(1))\r\n        mRows.put(AnimeObject.Day.THURSDAY.value, AnimeRow()\r\n                .setId(AnimeObject.Day.THURSDAY.value)\r\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\r\n                .setTitle(\"Jueves\")\r\n                .setPage(1))\r\n        mRows.put(AnimeObject.Day.FRIDAY.value, AnimeRow()\r\n                .setId(AnimeObject.Day.FRIDAY.value)\r\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\r\n                .setTitle(\"Viernes\")\r\n                .setPage(1))\r\n        mRows.put(AnimeObject.Day.SATURDAY.value, AnimeRow()\r\n                .setId(AnimeObject.Day.SATURDAY.value)\r\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\r\n                .setTitle(\"Sabado\")\r\n                .setPage(1))\r\n        mRows.put(AnimeObject.Day.SUNDAY.value, AnimeRow()\r\n                .setId(AnimeObject.Day.SUNDAY.value)\r\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\r\n                .setTitle(\"Domingo\")\r\n                .setPage(1))\r\n        createRows()\r\n    }\r\n\r\n    private fun createRows() {\r\n        val rowsAdapter = ArrayObjectAdapter(ListRowPresenter())\r\n        for (i in AnimeObject.Day.values()) {\r\n            Log.e(\"Emission\", \"Key: ${i.value}\")\r\n            val row = mRows.get(i.value) ?: continue\r\n            rowsAdapter.add(ListRow(HeaderItem(row.id.toLong(), row.title), row.adapter))\r\n        }\r\n        adapter = rowsAdapter\r\n        onItemViewClickedListener = this\r\n    }\r\n\r\n    private fun fetchData() {\r\n        CacheDB.INSTANCE.animeDAO().getByDayDir(AnimeObject.Day.MONDAY.value).distinct.observe(viewLifecycleOwner, Observer {\r\n            mRows.get(AnimeObject.Day.MONDAY.value)?.apply {\r\n                page = page.plus(1)\r\n                setList(it)\r\n            }\r\n            startEntranceTransition()\r\n        })\r\n        CacheDB.INSTANCE.animeDAO().getByDayDir(AnimeObject.Day.TUESDAY.value).distinct.observe(viewLifecycleOwner, Observer {\r\n            mRows.get(AnimeObject.Day.TUESDAY.value)?.apply {\r\n                page = page.plus(1)\r\n                setList(it)\r\n            }\r\n            startEntranceTransition()\r\n        })\r\n        CacheDB.INSTANCE.animeDAO().getByDayDir(AnimeObject.Day.WEDNESDAY.value).distinct.observe(viewLifecycleOwner, Observer {\r\n            mRows.get(AnimeObject.Day.WEDNESDAY.value)?.apply {\r\n                page = page.plus(1)\r\n                setList(it)\r\n            }\r\n            startEntranceTransition()\r\n        })\r\n        CacheDB.INSTANCE.animeDAO().getByDayDir(AnimeObject.Day.THURSDAY.value).distinct.observe(viewLifecycleOwner, Observer {\r\n            mRows.get(AnimeObject.Day.THURSDAY.value)?.apply {\r\n                page = page.plus(1)\r\n                setList(it)\r\n            }\r\n            startEntranceTransition()\r\n        })\r\n        CacheDB.INSTANCE.animeDAO().getByDayDir(AnimeObject.Day.FRIDAY.value).distinct.observe(viewLifecycleOwner, Observer {\r\n            mRows.get(AnimeObject.Day.FRIDAY.value)?.apply {\r\n                page = page.plus(1)\r\n                setList(it)\r\n            }\r\n            startEntranceTransition()\r\n        })\r\n        CacheDB.INSTANCE.animeDAO().getByDayDir(AnimeObject.Day.SATURDAY.value).distinct.observe(viewLifecycleOwner, Observer {\r\n            mRows.get(AnimeObject.Day.SATURDAY.value)?.apply {\r\n                page = page.plus(1)\r\n                setList(it)\r\n            }\r\n            startEntranceTransition()\r\n        })\r\n        CacheDB.INSTANCE.animeDAO().getByDayDir(AnimeObject.Day.SUNDAY.value).distinct.observe(viewLifecycleOwner, Observer {\r\n            mRows.get(AnimeObject.Day.SUNDAY.value)?.apply {\r\n                page = page.plus(1)\r\n                setList(it)\r\n            }\r\n            startEntranceTransition()\r\n        })\r\n    }\r\n\r\n    override fun onItemClicked(itemViewHolder: Presenter.ViewHolder?, item: Any?, rowViewHolder: RowPresenter.ViewHolder?, row: Row?) {\r\n        if (item is DirObject) {\r\n            context?.let { TVAnimesDetails.start(it, item.link) }\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/exoplayer/LeanbackPlayerAdapter.kt",
    "content": "package knf.kuma.tv.exoplayer\n\nimport android.content.Context\nimport android.os.Handler\nimport android.os.Looper\nimport android.view.Surface\nimport android.view.SurfaceHolder\nimport androidx.leanback.media.PlaybackGlueHost\nimport androidx.leanback.media.PlayerAdapter\nimport androidx.leanback.media.SurfaceHolderGlueHost\nimport com.google.android.exoplayer2.C\nimport com.google.android.exoplayer2.ExoPlaybackException\nimport com.google.android.exoplayer2.ExoPlayer\nimport com.google.android.exoplayer2.ExoPlayerLibraryInfo\nimport com.google.android.exoplayer2.PlaybackException\nimport com.google.android.exoplayer2.Player\nimport com.google.android.exoplayer2.SimpleExoPlayer\nimport com.google.android.exoplayer2.Timeline\nimport com.google.android.exoplayer2.util.ErrorMessageProvider\nimport com.google.android.exoplayer2.video.VideoSize\nimport knf.kuma.commons.findActivity\nimport xdroid.toaster.Toaster\n\n/**\n * Leanback `PlayerAdapter` implementation for [SimpleExoPlayer].\n */\nclass LeanbackPlayerAdapter\n/**\n * Builds an instance. Note that the `PlayerAdapter` does not manage the lifecycle of the\n * [SimpleExoPlayer] instance. The caller remains responsible for releasing the exoPlayer when\n * it's no longer required.\n *\n * @param context        The current context (activity).\n * @param player         Instance of your exoplayer that needs to be configured.\n * @param updatePeriodMs The delay between exoPlayer control updates, in milliseconds.\n */\n    (private val context: Context, private val player: ExoPlayer, updatePeriodMs: Int) :\n    PlayerAdapter() {\n    private val handler: Handler = Handler(Looper.getMainLooper())\n    private val componentListener: ComponentListener\n    private val updateProgressRunnable: Runnable\n\n    //private var controlDispatcher: ControlDispatcher? = null\n    private var errorMessageProvider: ErrorMessageProvider<in ExoPlaybackException>? = null\n    private var surfaceHolderGlueHost: SurfaceHolderGlueHost? = null\n    private var hasSurface: Boolean = false\n    private var lastNotifiedPreparedState: Boolean = false\n\n    init {\n        componentListener = ComponentListener()\n        //controlDispatcher = DefaultControlDispatcher()\n        updateProgressRunnable = object : Runnable {\n            override fun run() {\n                callback?.apply {\n                    onCurrentPositionChanged(this@LeanbackPlayerAdapter)\n                    onBufferedPositionChanged(this@LeanbackPlayerAdapter)\n                }\n                handler.postDelayed(this, updatePeriodMs.toLong())\n            }\n        }\n    }\n\n    // PlayerAdapter implementation.\n\n    override fun onAttachedToHost(host: PlaybackGlueHost) {\n        if (host is SurfaceHolderGlueHost) {\n            surfaceHolderGlueHost = host\n            surfaceHolderGlueHost?.setSurfaceHolderCallback(componentListener)\n        }\n        notifyStateChanged()\n        player.addListener(componentListener)\n    }\n\n    override fun onDetachedFromHost() {\n        player.removeListener(componentListener)\n        surfaceHolderGlueHost?.setSurfaceHolderCallback(null)\n        surfaceHolderGlueHost = null\n        hasSurface = false\n        val callback = callback\n        callback?.apply {\n            onBufferingStateChanged(this@LeanbackPlayerAdapter, false)\n            onPlayStateChanged(this@LeanbackPlayerAdapter)\n            maybeNotifyPreparedStateChanged(callback)\n        }\n    }\n\n    override fun setProgressUpdatingEnabled(enabled: Boolean) {\n        handler.removeCallbacks(updateProgressRunnable)\n        if (enabled) {\n            handler.post(updateProgressRunnable)\n        }\n    }\n\n    override fun isPlaying(): Boolean {\n        val playbackState = player.playbackState\n        return (playbackState != Player.STATE_IDLE && playbackState != Player.STATE_ENDED\n                && player.playWhenReady)\n    }\n\n    override fun getDuration(): Long {\n        val durationMs = player.duration\n        return if (durationMs == C.TIME_UNSET) -1 else durationMs\n    }\n\n    override fun getCurrentPosition(): Long {\n        return if (player.playbackState == Player.STATE_IDLE) -1 else player.currentPosition\n    }\n\n    override fun play() {\n        if (player.playbackState == Player.STATE_ENDED) {\n            player.seekTo(player.currentMediaItemIndex, C.TIME_UNSET)\n            //controlDispatcher?.dispatchSeekTo(player, player.currentWindowIndex, C.TIME_UNSET)\n        }\n        player.play()\n        /*if (player.playWhenReady) {\n            callback.onPlayStateChanged(this)\n        }*/\n    }\n\n    override fun pause() {\n        player.pause()\n        /*if (controlDispatcher?.dispatchSetPlayWhenReady(player, false) == true) {\n            callback.onPlayStateChanged(this)\n        }*/\n    }\n\n    override fun seekTo(positionMs: Long) {\n        //controlDispatcher?.dispatchSeekTo(player, player.currentWindowIndex, positionMs)\n        player.seekTo(player.currentMediaItemIndex, positionMs)\n    }\n\n    override fun getBufferedPosition(): Long {\n        return player.bufferedPosition\n    }\n\n    override fun isPrepared(): Boolean {\n        return player.playbackState != Player.STATE_IDLE && (surfaceHolderGlueHost == null || hasSurface)\n    }\n\n    // Internal methods.\n\n    /* package */ internal fun setVideoSurface(surface: Surface?) {\n        hasSurface = surface != null\n        player.setVideoSurface(surface)\n        maybeNotifyPreparedStateChanged(callback)\n    }\n\n    /* package */ internal fun notifyStateChanged() {\n        val playbackState = player.playbackState\n        val callback = callback\n        maybeNotifyPreparedStateChanged(callback)\n        callback?.apply {\n            onPlayStateChanged(this@LeanbackPlayerAdapter)\n            onBufferingStateChanged(this@LeanbackPlayerAdapter, playbackState == Player.STATE_BUFFERING)\n            if (playbackState == Player.STATE_ENDED) {\n                onPlayCompleted(this@LeanbackPlayerAdapter)\n            }\n        }\n    }\n\n    private fun maybeNotifyPreparedStateChanged(callback: Callback?) {\n        val isPrepared = isPrepared\n        if (lastNotifiedPreparedState != isPrepared) {\n            lastNotifiedPreparedState = isPrepared\n            callback?.onPreparedStateChanged(this)\n        }\n    }\n\n    private inner class ComponentListener : Player.Listener, SurfaceHolder.Callback {\n\n        // SurfaceHolder.Callback implementation.\n\n        override fun surfaceCreated(surfaceHolder: SurfaceHolder) {\n            setVideoSurface(surfaceHolder.surface)\n        }\n\n        override fun surfaceChanged(\n            surfaceHolder: SurfaceHolder,\n            format: Int,\n            width: Int,\n            height: Int\n        ) {\n            // Do nothing.\n        }\n\n        override fun surfaceDestroyed(surfaceHolder: SurfaceHolder) {\n            setVideoSurface(null)\n        }\n\n        // Player.EventListener implementation.\n\n        override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {\n            callback?.onPlayStateChanged(this@LeanbackPlayerAdapter)\n            notifyStateChanged()\n        }\n\n        override fun onPlayerError(error: PlaybackException) {\n            context.findActivity()?.finish()\n            Toaster.toast(\"Error al reproducir\")\n            callback?.onError(this@LeanbackPlayerAdapter, error.errorCode, error.message)\n        }\n\n        override fun onTimelineChanged(timeline: Timeline, reason: Int) {\n            callback?.apply {\n                onDurationChanged(this@LeanbackPlayerAdapter)\n                onCurrentPositionChanged(this@LeanbackPlayerAdapter)\n                onBufferedPositionChanged(this@LeanbackPlayerAdapter)\n            }\n        }\n\n        override fun onPositionDiscontinuity(oldPosition: Player.PositionInfo, newPosition: Player.PositionInfo, reason: Int) {\n            callback?.apply {\n                onCurrentPositionChanged(this@LeanbackPlayerAdapter)\n                onBufferedPositionChanged(this@LeanbackPlayerAdapter)\n            }\n        }\n\n        // SimpleExoplayerView.Callback implementation.\n\n        override fun onVideoSizeChanged(videoSize: VideoSize) {\n            if (videoSize.width > 0 && videoSize.height > 0) {\n                callback?.onVideoSizeChanged(\n                    this@LeanbackPlayerAdapter,\n                    videoSize.width,\n                    videoSize.height\n                )\n            }\n        }\n\n        override fun onRenderedFirstFrame() {\n            // Do nothing.\n        }\n\n    }\n\n    companion object {\n\n        init {\n            ExoPlayerLibraryInfo.registerModule(\"goog.exo.leanback\")\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/exoplayer/PlaybackFragment.kt",
    "content": "package knf.kuma.tv.exoplayer\n\nimport android.annotation.TargetApi\nimport android.content.Context\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport android.webkit.MimeTypeMap\nimport androidx.leanback.app.VideoSupportFragment\nimport androidx.leanback.app.VideoSupportFragmentGlueHost\nimport androidx.lifecycle.lifecycleScope\nimport com.google.android.exoplayer2.DefaultRenderersFactory\nimport com.google.android.exoplayer2.ExoPlayer\nimport com.google.android.exoplayer2.MediaItem\nimport com.google.android.exoplayer2.source.ProgressiveMediaSource\nimport com.google.android.exoplayer2.source.hls.HlsMediaSource\nimport com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection\nimport com.google.android.exoplayer2.trackselection.DefaultTrackSelector\nimport com.google.android.exoplayer2.trackselection.TrackSelector\nimport com.google.android.exoplayer2.upstream.DefaultHttpDataSource\nimport com.google.android.exoplayer2.util.Util\nimport knf.kuma.database.CacheDB\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass PlaybackFragment : VideoSupportFragment() {\n    private var mPlayerGlue: VideoPlayerGlue? = null\n    private var mPlayerAdapter: LeanbackPlayerAdapter? = null\n    private var mPlayer: ExoPlayer? = null\n    private var mTrackSelector: TrackSelector? = null\n    private var mVideo: Video? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        activity?.intent?.let {\n            mVideo = Video(it)\n        }\n    }\n\n    override fun onStart() {\n        super.onStart()\n        if (Util.SDK_INT > 23) {\n            initializePlayer()\n        }\n    }\n\n    override fun onResume() {\n        super.onResume()\n        if (Util.SDK_INT <= 23 || mPlayer ==\n                null) {\n            initializePlayer()\n        }\n    }\n\n    /**\n     * Pauses the exoPlayer.\n     */\n    @TargetApi(Build.VERSION_CODES.N)\n    override fun onPause() {\n        super.onPause()\n        mPlayerGlue?.save(mVideo)\n        if (mPlayerGlue?.isPlaying == true)\n            mPlayerGlue?.pause()\n        if (Util.SDK_INT <= 23) {\n            releasePlayer()\n        }\n    }\n\n    override fun onStop() {\n        super.onStop()\n        if (Util.SDK_INT > 23) {\n            releasePlayer()\n        }\n    }\n\n    private fun initializePlayer() {\n        val videoTrackSelectionFactory = AdaptiveTrackSelection.Factory()\n        mTrackSelector = DefaultTrackSelector(requireContext(), videoTrackSelectionFactory)\n        mPlayer =\n            ExoPlayer.Builder(requireContext(), DefaultRenderersFactory(requireContext())).build()\n        mPlayerAdapter =\n            LeanbackPlayerAdapter(activity as Context, mPlayer as ExoPlayer, UPDATE_DELAY)\n        mPlayerGlue = VideoPlayerGlue(activity as Context, mPlayerAdapter as LeanbackPlayerAdapter)\n        mPlayerGlue?.host = VideoSupportFragmentGlueHost(this)\n        mPlayerGlue?.playWhenPrepared()\n\n        play(mVideo)\n    }\n\n    private fun releasePlayer() {\n        mPlayer?.release()\n        mPlayer = null\n        mTrackSelector = null\n        mPlayerGlue = null\n        mPlayerAdapter = null\n    }\n\n    private fun play(video: Video?) {\n        lifecycleScope.launch {\n            mPlayerGlue?.title = video?.title\n            mPlayerGlue?.subtitle = video?.chapter\n            prepareMediaForPlaying(video?.uri ?: Uri.EMPTY, video?.headers)\n            val state = withContext(Dispatchers.IO) { CacheDB.INSTANCE.playerStateDAO().find(\"${video?.title}: ${video?.chapter}\") }\n            if (state != null) {\n                mPlayerGlue?.seekTo(state.position)\n            }\n            mPlayerGlue?.play()\n        }\n    }\n\n    private fun prepareMediaForPlaying(mediaSourceUri: Uri, headers: Map<String, String>?) {\n        activity?.let {\n            val httpFactory = DefaultHttpDataSource.Factory().apply {\n                if (headers?.containsKey(\"User-Agent\") != true) {\n                    setUserAgent(Util.getUserAgent(it, \"UKIKU\"))\n                } else {\n                    setUserAgent(headers[\"User-Agent\"])\n                }\n                setDefaultRequestProperties(headers ?: emptyMap())\n            }\n            val mediaSource = when(MimeTypeMap.getFileExtensionFromUrl(mediaSourceUri.toString())) {\n                \"m3u8\" -> HlsMediaSource.Factory(httpFactory)\n                else -> ProgressiveMediaSource.Factory(httpFactory)\n            }.createMediaSource(MediaItem.fromUri(mediaSourceUri))\n            mPlayer?.setMediaSource(mediaSource)\n            mPlayer?.prepare()\n        }\n    }\n\n    fun skipToNext() {\n        mPlayerGlue?.next()\n    }\n\n    fun skipToPrevious() {\n        mPlayerGlue?.previous()\n    }\n\n    fun rewind() {\n        mPlayerGlue?.rewind()\n    }\n\n    fun fastForward() {\n        mPlayerGlue?.fastForward()\n    }\n\n    companion object {\n\n        private const val UPDATE_DELAY = 16\n\n        operator fun get(bundle: Bundle?): PlaybackFragment {\n            val fragment = PlaybackFragment()\n            fragment.arguments = bundle\n            return fragment\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/exoplayer/TVPlayer.kt",
    "content": "package knf.kuma.tv.exoplayer\n\nimport android.os.Bundle\nimport android.view.WindowManager\nimport knf.kuma.tv.TVBaseActivity\n\nclass TVPlayer : TVBaseActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)\n        addFragment(PlaybackFragment[intent.extras])\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/exoplayer/Video.kt",
    "content": "package knf.kuma.tv.exoplayer\n\nimport android.content.Intent\nimport android.net.Uri\n\nclass Video(intent: Intent) {\n    internal var uri: Uri = Uri.parse(intent.dataString)\n    internal var title: String? = null\n    internal var chapter: String? = null\n    internal var headers: Map<String, String>? = null\n\n    init {\n        this.title = intent.getStringExtra(\"title\")\n        this.chapter = intent.getStringExtra(\"chapter\")\n        this.headers = intent.getStringArrayListExtra(\"headers\")?.chunked(2)?.associate { Pair(it[0], it[1]) }?.ifEmpty { null }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/exoplayer/VideoPlayerGlue.kt",
    "content": "package knf.kuma.tv.exoplayer\n\nimport android.content.Context\nimport androidx.leanback.media.PlaybackTransportControlGlue\nimport androidx.leanback.widget.Action\nimport androidx.leanback.widget.ArrayObjectAdapter\nimport androidx.leanback.widget.PlaybackControlsRow\nimport knf.kuma.database.CacheDB\nimport knf.kuma.player.PlayerState\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport java.util.concurrent.TimeUnit\n\n/**\n * Manages customizing the actions in the [PlaybackControlsRow]. Adds and manages the\n * following actions to the primary and secondary controls:\n *\n *\n *  * [androidx.leanback.widget.PlaybackControlsRow.RepeatAction]\n *  * [androidx.leanback.widget.PlaybackControlsRow.ThumbsDownAction]\n *  * [androidx.leanback.widget.PlaybackControlsRow.ThumbsUpAction]\n *  * [androidx.leanback.widget.PlaybackControlsRow.SkipPreviousAction]\n *  * [androidx.leanback.widget.PlaybackControlsRow.SkipNextAction]\n *  * [androidx.leanback.widget.PlaybackControlsRow.FastForwardAction]\n *  * [androidx.leanback.widget.PlaybackControlsRow.RewindAction]\n *\n *\n *\n * Note that the superclass, [PlaybackTransportControlGlue], manages the playback controls\n * row.\n */\nclass VideoPlayerGlue(\n        context: Context,\n        playerAdapter: LeanbackPlayerAdapter) : PlaybackTransportControlGlue<LeanbackPlayerAdapter>(context, playerAdapter) {\n    private val mRepeatAction: PlaybackControlsRow.RepeatAction\n    private val mThumbsUpAction: PlaybackControlsRow.ThumbsUpAction = PlaybackControlsRow.ThumbsUpAction(context)\n    private val mThumbsDownAction: PlaybackControlsRow.ThumbsDownAction\n    private val mSkipPreviousAction: PlaybackControlsRow.SkipPreviousAction = PlaybackControlsRow.SkipPreviousAction(context)\n    private val mSkipNextAction: PlaybackControlsRow.SkipNextAction = PlaybackControlsRow.SkipNextAction(context)\n    private val mFastForwardAction: PlaybackControlsRow.FastForwardAction = PlaybackControlsRow.FastForwardAction(context)\n    private val mRewindAction: PlaybackControlsRow.RewindAction = PlaybackControlsRow.RewindAction(context)\n\n    init {\n        mThumbsUpAction.index = PlaybackControlsRow.ThumbsUpAction.INDEX_OUTLINE\n        mThumbsDownAction = PlaybackControlsRow.ThumbsDownAction(context)\n        mThumbsDownAction.index = PlaybackControlsRow.ThumbsDownAction.INDEX_OUTLINE\n        mRepeatAction = PlaybackControlsRow.RepeatAction(context)\n    }\n\n    override fun onCreatePrimaryActions(adapter: ArrayObjectAdapter) {\n        // Order matters, super.onCreatePrimaryActions() will create the play / pause action.\n        // Will display as follows:\n        // play/pause, previous, rewind, fast forward, next\n        //   > /||      |<        <<        >>         >|\n        //adapter.add(mSkipPreviousAction);\n        adapter.add(mRewindAction)\n        super.onCreatePrimaryActions(adapter)\n        adapter.add(mFastForwardAction)\n        //adapter.add(mSkipNextAction);\n    }\n\n    override fun onActionClicked(action: Action) {\n        if (shouldDispatchAction(action)) {\n            dispatchAction(action)\n            return\n        }\n        // Super class handles play/pause and delegates to abstract methods next()/previous().\n        super.onActionClicked(action)\n    }\n\n    // Should dispatch actions that the super class does not supply callbacks for.\n    private fun shouldDispatchAction(action: Action): Boolean {\n        return (action === mRewindAction\n                || action === mFastForwardAction\n                || action === mThumbsDownAction\n                || action === mThumbsUpAction\n                || action === mRepeatAction)\n    }\n\n    private fun dispatchAction(action: Action) {\n        // Primary actions are handled manually.\n        when {\n            action === mRewindAction -> rewind()\n            action === mFastForwardAction -> fastForward()\n            action is PlaybackControlsRow.MultiAction -> {\n                action.nextIndex()\n                // Notify adapter of action changes to handle secondary actions, such as, thumbs up/down\n                // and repeat.\n                controlsRow?.secondaryActionsAdapter?.apply {\n                    notifyActionChanged(action, this as ArrayObjectAdapter)\n                }\n            }\n        }\n    }\n\n    fun save(video: Video?) {\n        if (video != null) {\n            val pos = currentPosition\n            GlobalScope.launch(Dispatchers.IO) {\n                CacheDB.INSTANCE.playerStateDAO().set(PlayerState(\"${video.title}: ${video.chapter}\", pos))\n            }\n        }\n    }\n\n    private fun notifyActionChanged(\n            action: PlaybackControlsRow.MultiAction, adapter: ArrayObjectAdapter?) {\n        if (adapter != null) {\n            val index = adapter.indexOf(action)\n            if (index >= 0) {\n                adapter.notifyArrayItemRangeChanged(index, 1)\n            }\n        }\n    }\n\n    override fun next() {}\n\n    override fun previous() {}\n\n    /**\n     * Skips backwards 10 seconds.\n     */\n    fun rewind() {\n        var newPosition = currentPosition - TEN_SECONDS\n        newPosition = if (newPosition < 0) 0 else newPosition\n        playerAdapter.seekTo(newPosition)\n    }\n\n    /**\n     * Skips forward 10 seconds.\n     */\n    fun fastForward() {\n        if (duration > -1) {\n            var newPosition = currentPosition + TEN_SECONDS\n            newPosition = if (newPosition > duration) duration else newPosition\n            playerAdapter.seekTo(newPosition)\n        }\n    }\n\n\n    /**\n     * Listens for when skip to next and previous actions have been dispatched.\n     */\n    interface OnActionClickedListener {\n\n        /**\n         * Skip to the previous item in the queue.\n         */\n        fun onPrevious()\n\n        /**\n         * Skip to the next item in the queue.\n         */\n        fun onNext()\n    }\n\n    companion object {\n\n        private val TEN_SECONDS = TimeUnit.SECONDS.toMillis(30)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/search/BasicAnimeObject.kt",
    "content": "package knf.kuma.tv.search\r\n\r\ndata class BasicAnimeObject(\r\n        var key: Int = 0,\r\n        var aid: String = \"\",\r\n        var name: String = \"\",\r\n        var link: String = \"\"\r\n)"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/search/TVSearch.kt",
    "content": "package knf.kuma.tv.search\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport knf.kuma.tv.TVBaseActivity\n\nclass TVSearch : TVBaseActivity() {\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        addFragment(TVSearchFragment())\n    }\n\n    companion object {\n        fun start(context: Context) {\n            context.startActivity(Intent(context, TVSearch::class.java))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/search/TVSearchFragment.kt",
    "content": "package knf.kuma.tv.search\n\nimport android.os.Bundle\nimport androidx.leanback.app.SearchSupportFragment\nimport androidx.leanback.widget.ArrayObjectAdapter\nimport androidx.leanback.widget.HeaderItem\nimport androidx.leanback.widget.ListRow\nimport androidx.leanback.widget.ListRowPresenter\nimport androidx.leanback.widget.ObjectAdapter\nimport androidx.leanback.widget.OnItemViewClickedListener\nimport androidx.leanback.widget.Presenter\nimport androidx.leanback.widget.Row\nimport androidx.leanback.widget.RowPresenter\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.Observer\nimport knf.kuma.database.CacheDB\nimport knf.kuma.search.SearchFragment\nimport knf.kuma.tv.anime.AnimePresenter\nimport knf.kuma.tv.details.TVAnimesDetails\n\nclass TVSearchFragment : SearchSupportFragment(), SearchSupportFragment.SearchResultProvider, OnItemViewClickedListener {\n    private var arrayObjectAdapter: ArrayObjectAdapter? = null\n    private lateinit var liveData: LiveData<MutableList<BasicAnimeObject>>\n    private lateinit var observer: Observer<MutableList<BasicAnimeObject>>\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        arrayObjectAdapter = ArrayObjectAdapter(ListRowPresenter())\n        setSearchResultProvider(this)\n        setOnItemViewClickedListener(this)\n        val headerItem = HeaderItem(\"Géneros\")\n        val objectAdapter = ArrayObjectAdapter(TagPresenter()).also {\n            it.addAll(0, SearchFragment.genres)\n        }\n        arrayObjectAdapter?.clear()\n        arrayObjectAdapter?.add(ListRow(headerItem, objectAdapter))\n        setResult(\"\")\n    }\n\n    override fun getResultsAdapter(): ObjectAdapter? {\n        return arrayObjectAdapter\n    }\n\n    override fun onQueryTextChange(newQuery: String): Boolean {\n        setResult(newQuery.trim())\n        return true\n    }\n\n    override fun onQueryTextSubmit(query: String): Boolean {\n        setResult(query.trim())\n        return true\n    }\n\n    private fun setResult(query: String) {\n        if (::liveData.isInitialized && ::observer.isInitialized)\n            liveData.removeObserver(observer)\n        activity?.let {\n            liveData = CacheDB.INSTANCE.animeDAO().getSearchList(\"%$query%\")\n            observer = Observer { animeObjects ->\n                liveData.removeObservers(it)\n                if ((arrayObjectAdapter?.size() ?: 0) > 1)\n                    arrayObjectAdapter?.removeItems(1, 1)\n                val objectAdapter = ArrayObjectAdapter(AnimePresenter())\n                for (animeObject in animeObjects)\n                    objectAdapter.add(animeObject)\n                val headerItem = HeaderItem(\n                        when {\n                            query.isEmpty() -> \"Todos los animes\"\n                            animeObjects.isNotEmpty() -> \"Resultados para '$query'\"\n                            else -> \"Sin resultados\"\n                        }\n                )\n                arrayObjectAdapter?.add(ListRow(headerItem, objectAdapter))\n            }\n            liveData.observe(it, observer)\n        }\n    }\n\n    override fun onItemClicked(itemViewHolder: Presenter.ViewHolder, item: Any, rowViewHolder: RowPresenter.ViewHolder, row: Row) {\n        when (item) {\n            is BasicAnimeObject -> context?.let { TVAnimesDetails.start(it, item.link) }\n            is String -> context?.let { TVTag.start(it, item) }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/search/TVTag.kt",
    "content": "package knf.kuma.tv.search\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport knf.kuma.tv.TVBaseActivity\n\nclass TVTag : TVBaseActivity() {\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        addFragment(TVTagFragment().apply { arguments = Bundle().apply { putString(keyGenre, intent.getStringExtra(keyGenre)) } })\n    }\n\n    companion object {\n\n        private const val keyGenre = \"genre\"\n\n        fun start(context: Context, genre: String) {\n            context.startActivity(Intent(context, TVTag::class.java).putExtra(keyGenre, genre))\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/search/TVTagFragment.kt",
    "content": "package knf.kuma.tv.search\r\n\r\nimport android.os.Bundle\r\nimport androidx.leanback.app.VerticalGridSupportFragment\r\nimport androidx.leanback.widget.ArrayObjectAdapter\r\nimport androidx.leanback.widget.OnItemViewClickedListener\r\nimport androidx.leanback.widget.Presenter\r\nimport androidx.leanback.widget.Row\r\nimport androidx.leanback.widget.RowPresenter\r\nimport androidx.leanback.widget.VerticalGridPresenter\r\nimport androidx.lifecycle.Observer\r\nimport knf.kuma.commons.doOnUI\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.tv.anime.AnimePresenter\r\nimport knf.kuma.tv.details.TVAnimesDetails\r\nimport org.jetbrains.anko.doAsync\r\n\r\nclass TVTagFragment : VerticalGridSupportFragment(), OnItemViewClickedListener {\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        title = arguments?.getString(\"genre\")\r\n        setGridPresenter(\r\n            VerticalGridPresenter().apply {\r\n                numberOfColumns = 4\r\n            }\r\n        )\r\n        onItemViewClickedListener = this\r\n        CacheDB.INSTANCE.animeDAO().getAllGenreLive(\"%\" + arguments?.getString(\"genre\") + \"%\").observe(this, Observer {\r\n            if (!it.isNullOrEmpty()) {\r\n                doAsync {\r\n                    val arrayAdapter = ArrayObjectAdapter(AnimePresenter()).apply {\r\n                        addAll(0, it)\r\n                    }\r\n                    doOnUI { adapter = arrayAdapter }\r\n                }\r\n            }\r\n        })\r\n    }\r\n\r\n    override fun onItemClicked(itemViewHolder: Presenter.ViewHolder?, item: Any?, rowViewHolder: RowPresenter.ViewHolder?, row: Row?) {\r\n        val anime = item as? BasicAnimeObject\r\n        if (anime != null)\r\n            context?.let { TVAnimesDetails.start(it, anime.link) }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/search/TagPresenter.kt",
    "content": "package knf.kuma.tv.search\n\nimport android.view.ViewGroup\nimport androidx.leanback.widget.Presenter\nimport knf.kuma.tv.cards.TagCardView\n\nclass TagPresenter : Presenter() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {\n        return ViewHolder(TagCardView(parent.context))\n    }\n\n    override fun onBindViewHolder(viewHolder: ViewHolder, item: Any?) {\n        if (item == null) return\n        (viewHolder.view as TagCardView).bind(item as String)\n    }\n\n    override fun onUnbindViewHolder(viewHolder: ViewHolder) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/sections/DirSection.kt",
    "content": "package knf.kuma.tv.sections\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport knf.kuma.R\r\nimport knf.kuma.tv.directory.TVDir\r\n\r\nclass DirSection : SectionObject() {\r\n    override val image: Int\r\n        get() = R.drawable.ic_directory_not\r\n\r\n    override val title: String\r\n        get() = \"Directorio\"\r\n\r\n    override fun open(context: Context?) {\r\n        context?.startActivity(Intent(context, TVDir::class.java))\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/sections/EmissionSection.kt",
    "content": "package knf.kuma.tv.sections\r\n\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport knf.kuma.R\r\nimport knf.kuma.tv.emission.TVEmission\r\n\r\nclass EmissionSection : SectionObject() {\r\n    override val image: Int\r\n        get() = R.drawable.ic_emision_not\r\n\r\n    override val title: String\r\n        get() = \"Emisión\"\r\n\r\n    override fun open(context: Context?) {\r\n        context?.startActivity(Intent(context, TVEmission::class.java))\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/sections/SectionObject.kt",
    "content": "package knf.kuma.tv.sections\n\nimport android.content.Context\n\nabstract class SectionObject {\n\n    abstract val image: Int\n\n    abstract val title: String\n\n    abstract fun open(context: Context?)\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/streaming/StreamTvActivity.kt",
    "content": "package knf.kuma.tv.streaming\n\nimport android.content.Intent\nimport android.graphics.Color\nimport android.graphics.drawable.ColorDrawable\nimport android.os.Bundle\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.tv.TVBaseActivity\nimport knf.kuma.tv.TVServersFactory\nimport org.jetbrains.anko.doAsync\n\nclass StreamTvActivity : TVBaseActivity() {\n\n    private lateinit var downloadObject: DownloadObject\n    private var serversFactory: TVServersFactory? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        setTheme(EAHelper.getThemeDialog())\n        super.onCreate(savedInstanceState)\n        title = \" \"\n        window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))\n        setFinishOnTouchOutside(false)\n\n        doAsync {\n            try {\n                val data = intent.data\n                if (data != null) {\n                    val chapter = AnimeObject.WebInfo.AnimeChapter\n                        .fromData(\n                            data.getQueryParameter(\"aid\"),\n                            data.getQueryParameter(\"chapter\"),\n                            data.getQueryParameter(\"eid\"),\n                            data.getQueryParameter(\"url\"),\n                            data.getQueryParameter(\"name\")\n                        )\n                    downloadObject = DownloadObject.fromChapter(chapter, false)\n                    doOnUI {\n                        try {\n                            TVServersFactory.start(\n                                this@StreamTvActivity,\n                                chapter.link,\n                                chapter,\n                                object : TVServersFactory.ServersInterface {\n                                    override fun onReady(serversFactory: TVServersFactory) {\n                                        this@StreamTvActivity.serversFactory = serversFactory\n                                    }\n\n                                    override fun onFinish(started: Boolean, success: Boolean) {\n                                        finish()\n                                    }\n                                })\n                        } catch (e: Exception) {\n                            e.printStackTrace()\n                            finish()\n                        }\n                    }\n                } else {\n                    finish()\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                finish()\n            }\n        }\n\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        try {\n            if (data != null)\n                if (resultCode == RESULT_OK) {\n                    val bundle = data.extras\n                    if (requestCode == TVServersFactory.REQUEST_CODE_MULTI)\n                        serversFactory?.analyzeMulti(bundle?.getInt(\"position\", 0) ?: 0)\n                    else {\n                        if (bundle?.getBoolean(\"is_video_server\", false) == true)\n                            serversFactory?.analyzeOption(bundle.getInt(\"position\", 0))\n                        else\n                            serversFactory?.analyzeServer(bundle?.getInt(\"position\", 0) ?: 0)\n                    }\n                } else if (resultCode == RESULT_CANCELED && data.extras?.getBoolean(\n                        \"is_video_server\",\n                        false\n                    ) == true\n                )\n                    serversFactory?.showServerList()\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/streaming/TVMultiSelection.kt",
    "content": "package knf.kuma.tv.streaming\r\n\r\nimport android.os.Bundle\r\nimport androidx.fragment.app.FragmentActivity\r\nimport androidx.leanback.app.GuidedStepSupportFragment\r\n\r\nclass TVMultiSelection : FragmentActivity() {\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        if (savedInstanceState == null)\r\n            GuidedStepSupportFragment.addAsRoot(this,TVMultiSelectionFragment(),android.R.id.content)\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/streaming/TVMultiSelectionFragment.kt",
    "content": "package knf.kuma.tv.streaming\r\n\r\nimport android.app.Activity\r\nimport android.content.Intent\r\nimport android.os.Bundle\r\nimport androidx.leanback.app.GuidedStepSupportFragment\r\nimport androidx.leanback.widget.GuidanceStylist\r\nimport androidx.leanback.widget.GuidedAction\r\n\r\nclass TVMultiSelectionFragment : GuidedStepSupportFragment(){\r\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\r\n        super.onActivityCreated(savedInstanceState)\r\n        activity?.setResult(Activity.RESULT_CANCELED, Intent())\r\n    }\r\n\r\n    override fun onCreateGuidance(savedInstanceState: Bundle?): GuidanceStylist.Guidance {\r\n        return GuidanceStylist.Guidance(\"Selecciona idioma\",\"\",\"\",null)\r\n    }\r\n\r\n    override fun onCreateActions(actions: MutableList<GuidedAction>, savedInstanceState: Bundle?) {\r\n        actions.apply {\r\n            add(GuidedAction.Builder(context).id(0).title(\"Subtitulado\").build())\r\n            add(GuidedAction.Builder(context).id(1).title(\"Latino\").build())\r\n        }\r\n    }\r\n\r\n    override fun onGuidedActionClicked(action: GuidedAction) {\r\n        super.onGuidedActionClicked(action)\r\n        activity?.setResult(Activity.RESULT_OK, Intent()\r\n            .putExtra(\"position\", action.id.toInt())\r\n        )\r\n        activity?.finish()\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/streaming/TVServerSelection.kt",
    "content": "package knf.kuma.tv.streaming\n\nimport android.os.Bundle\nimport androidx.fragment.app.FragmentActivity\nimport androidx.leanback.app.GuidedStepSupportFragment\n\nclass TVServerSelection : FragmentActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        if (savedInstanceState == null)\n            if (intent.hasExtra(TVServerSelectionFragment.SERVERS_DATA))\n                GuidedStepSupportFragment.addAsRoot(this, TVServerSelectionFragment[intent.getStringArrayListExtra(TVServerSelectionFragment.SERVERS_DATA)\n                        ?: ArrayList(), intent.getStringExtra(\"name\"), false], android.R.id.content)\n            else if (intent.hasExtra(TVServerSelectionFragment.VIDEO_DATA))\n                GuidedStepSupportFragment.addAsRoot(this, TVServerSelectionFragment[intent.getStringArrayListExtra(TVServerSelectionFragment.VIDEO_DATA)\n                        ?: ArrayList(), intent.getStringExtra(\"name\"), true], android.R.id.content)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/streaming/TVServerSelectionFragment.kt",
    "content": "package knf.kuma.tv.streaming\n\nimport android.app.Activity\nimport android.content.Intent\nimport android.os.Bundle\nimport androidx.leanback.app.GuidedStepSupportFragment\nimport androidx.leanback.widget.GuidanceStylist\nimport androidx.leanback.widget.GuidedAction\n\nclass TVServerSelectionFragment : GuidedStepSupportFragment() {\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        activity?.setResult(Activity.RESULT_CANCELED, Intent()\n                .putExtra(keyIsVideoServer, arguments?.getBoolean(IS_SERVER_DATA, false)))\n    }\n\n    override fun onCreateGuidance(savedInstanceState: Bundle?): GuidanceStylist.Guidance {\n        return if (arguments?.getBoolean(IS_SERVER_DATA, false) == true)\n            GuidanceStylist.Guidance(arguments?.getString(keyServerName)\n                    ?: \"\", \"Selecciona calidad\", \"\", null)\n        else\n            GuidanceStylist.Guidance(\"Selecciona servidor\", \"\", \"\", null)\n    }\n\n    override fun onCreateActions(actions: MutableList<GuidedAction>, savedInstanceState: Bundle?) {\n        val list = arguments?.getStringArrayList(SERVERS_DATA) ?: arrayListOf()\n        for ((id, name) in list.withIndex()) {\n            if (!name.contains(\"mega\", true))\n                actions.add(GuidedAction.Builder(context)\n                        .id(id.toLong())\n                        .title(name)\n                        .build())\n        }\n    }\n\n    override fun onGuidedActionClicked(action: GuidedAction) {\n        super.onGuidedActionClicked(action)\n        activity?.setResult(Activity.RESULT_OK, Intent()\n                .putExtra(keyIsVideoServer, arguments?.getBoolean(IS_SERVER_DATA, false))\n            .putExtra(keyPosition, action.id.toInt())\n        )\n        activity?.finish()\n    }\n\n    companion object {\n        const val keyIsVideoServer = \"is_video_server\"\n        const val keyPosition = \"position\"\n        const val keyServerName = \"server_name\"\n\n        const val VIDEO_DATA = \"option_data\"\n        const val SERVERS_DATA = \"list_data\"\n        const val IS_SERVER_DATA = \"is_server\"\n\n        operator fun get(servers: ArrayList<String>, name: String?, isServerData: Boolean): TVServerSelectionFragment {\n            val fragment = TVServerSelectionFragment()\n            val bundle = Bundle()\n            bundle.putStringArrayList(SERVERS_DATA, servers)\n            bundle.putBoolean(IS_SERVER_DATA, isServerData)\n            if (name != null)\n                bundle.putString(keyServerName, name)\n            fragment.arguments = bundle\n            return fragment\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/sync/BypassObject.kt",
    "content": "package knf.kuma.tv.sync\n\nimport knf.kuma.R\n\nclass BypassObject : SyncObject() {\n\n    override val image: Int\n        get() = R.drawable.banner_cloudflare\n\n    override val title: String\n        get() = \"Recrear bypass\"\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/sync/LogOutObject.kt",
    "content": "package knf.kuma.tv.sync\n\nimport knf.kuma.R\n\nclass LogOutObject : SyncObject() {\n\n    override val image: Int\n        get() = R.drawable.banner_signout\n\n    override val title: String\n        get() = \"Cerrar sesión\"\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/sync/SyncObject.kt",
    "content": "package knf.kuma.tv.sync\n\nimport androidx.annotation.DrawableRes\nimport knf.kuma.R\nimport knf.kuma.backup.Backups\n\nopen class SyncObject {\n    var type = Backups.Type.NONE\n\n    open val image: Int\n        @DrawableRes\n        get() = when (type) {\n            Backups.Type.DROPBOX -> R.drawable.banner_dropbox\n            Backups.Type.FIRESTORE -> R.drawable.banner_firestore\n            else -> R.drawable.banner_drive\n        }\n\n    open val title: String\n        get() = when (type) {\n            Backups.Type.DROPBOX -> \"Dropbox\"\n            Backups.Type.FIRESTORE -> \"Firestore\"\n            else -> \"Google Drive\"\n        }\n\n    internal constructor()\n\n    constructor(type: Backups.Type) {\n        this.type = type\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/ui/TVMain.kt",
    "content": "package knf.kuma.tv.ui\n\nimport android.content.Intent\nimport android.os.Bundle\nimport androidx.lifecycle.lifecycleScope\nimport com.google.android.gms.common.GooglePlayServicesNotAvailableException\nimport com.google.android.gms.common.GooglePlayServicesRepairableException\nimport com.google.android.gms.security.ProviderInstaller\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\nimport knf.kuma.commons.BypassUtil\nimport knf.kuma.commons.DesignUtils\nimport knf.kuma.commons.PicassoSingle\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUI\nimport knf.kuma.commons.isTV\nimport knf.kuma.commons.toast\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.directory.DirManager\nimport knf.kuma.directory.DirectoryService\nimport knf.kuma.jobscheduler.DirUpdateWork\nimport knf.kuma.jobscheduler.RecentsWork\nimport knf.kuma.recents.RecentsNotReceiver\nimport knf.kuma.retrofit.Repository\nimport knf.kuma.tv.ChannelUtils\nimport knf.kuma.tv.TVBaseActivity\nimport knf.kuma.tv.TVServersFactory\nimport knf.kuma.uagen.randomUA\nimport knf.kuma.updater.UpdateActivity\nimport knf.kuma.updater.UpdateChecker\nimport knf.tools.bypass.startBypass\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\nclass TVMain : TVBaseActivity(), TVServersFactory.ServersInterface, UpdateChecker.CheckListener {\n\n    private var fragment: TVMainFragment? = null\n    private var serversFactory: TVServersFactory? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        //SSLManager.disable()\n        if (!isTV) {\n            finish()\n            startActivity(Intent(this, DesignUtils.mainClass))\n            return\n        }\n        if (savedInstanceState == null) {\n            fragment = TVMainFragment.get().also {\n                addFragment(it)\n            }\n            DirUpdateWork.schedule(this)\n            RecentsNotReceiver.removeAll(this)\n            UpdateChecker.check(this, this)\n            RecentsWork.schedule(this@TVMain)\n            lifecycleScope.launch(Dispatchers.IO) {\n                DirManager.checkPreDir()\n                DirectoryService.run(this@TVMain)\n                installSecurityProvider()\n            }\n            ChannelUtils.createIfNeeded(this)\n        }\n    }\n\n    private suspend fun installSecurityProvider() {\n        withContext(Dispatchers.IO) {\n            try {\n                ProviderInstaller.installIfNeeded(this@TVMain)\n                PrefsUtil.isSecurityUpdated = true\n                PrefsUtil.spErrorType = null\n            } catch (e: GooglePlayServicesRepairableException) {\n                PrefsUtil.isSecurityUpdated = false\n                PrefsUtil.spErrorType = \"Gplay services deshabilitado o desactualizado\"\n                e.printStackTrace()\n            } catch (e: GooglePlayServicesNotAvailableException) {\n                PrefsUtil.isSecurityUpdated = false\n                PrefsUtil.spErrorType = \"GPlay services no esta disponible\"\n                e.printStackTrace()\n            } catch (e: Throwable) {\n                PrefsUtil.isSecurityUpdated = false\n                //Toaster.toastLong(\"SProvider: Unknown error, ${e.message}\")\n                PrefsUtil.spErrorType = \"Error desconocido: ${e.message}\"\n                e.printStackTrace()\n            }\n            if (!PrefsUtil.isSecurityUpdated && FirebaseCrashlytics.getInstance().didCrashOnPreviousExecution()) {\n                PrefsUtil.spProtectionEnabled = true\n                //Toaster.toastLong(\"Proteccion de SP reactivada\")\n\n            }\n        }\n    }\n\n    private fun doBlockTests(): Boolean {\n        var blockCount = 0\n        repeat(3) {\n            if (BypassUtil.isCloudflareActiveRandom())\n                blockCount++\n            if (blockCount >= 2)\n                return true\n        }\n        return false\n    }\n\n    override fun onNeedUpdate(o_code: String, n_code: String) {\n        runOnUiThread {\n            UpdateActivity.start(this@TVMain, true, n_code)\n        }\n    }\n\n    override fun onUpdateNotRequired() {\n        lifecycleScope.launch(Dispatchers.Main) {\n            if (PrefsUtil.mayUseRandomUA)\n                PrefsUtil.alwaysGenerateUA = !withContext(Dispatchers.IO) { doBlockTests() }\n            else\n                PrefsUtil.alwaysGenerateUA = false\n            if (withContext(Dispatchers.IO) { BypassUtil.isNeeded() }) {\n                startBypass(\n                    7425,\n                    BypassUtil.createRequest()\n                )\n                //startBypass(this@TVMain, 7425, \"https://www3.animeflv.net\", true)\n            }\n        }\n    }\n\n    override fun onReady(serversFactory: TVServersFactory) {\n        this.serversFactory = serversFactory\n    }\n\n    override fun onFinish(started: Boolean, success: Boolean) {\n\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        if (requestCode == 7425) {\n            val cookiesUpdated = data?.let {\n                PrefsUtil.useDefaultUserAgent = false\n                PrefsUtil.userAgent = it.getStringExtra(\"user_agent\") ?: randomUA()\n                BypassUtil.saveCookies(this, it.getStringExtra(\"cookies\") ?: \"null\")\n            } ?: false\n            GenericActivity.bypassLive.postValue(Pair(first = cookiesUpdated, second = false))\n            Repository().reloadAllRecents()\n            BypassUtil.isLoading = false\n            PicassoSingle.clear()\n            RecentsWork.run()\n            doOnUI {\n                \"Bypass actualizado\".toast()\n            }\n            ChannelUtils.initChannelIfNeeded(this)\n            if (!PrefsUtil.isDirectoryFinished) {\n                lifecycleScope.launch(Dispatchers.IO) {\n                    DirManager.checkPreDir()\n                    DirectoryService.run(this@TVMain)\n                }\n            }\n        } else\n            try {\n                if (data != null)\n                    if (resultCode == RESULT_OK) {\n                        val bundle = data.extras\n                        if (requestCode == TVServersFactory.REQUEST_CODE_MULTI)\n                            serversFactory?.analyzeMulti(bundle?.getInt(\"position\", 0) ?: 0)\n                        else {\n                            if (bundle?.getBoolean(\"is_video_server\", false) == true)\n                                serversFactory?.analyzeOption(bundle.getInt(\"position\", 0))\n                            else\n                                serversFactory?.analyzeServer(bundle?.getInt(\"position\", 0) ?: 0)\n                        }\n                    } else if (resultCode == RESULT_CANCELED && data.extras?.getBoolean(\n                            \"is_video_server\",\n                            false\n                        ) == true\n                    )\n                        serversFactory?.showServerList()\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/tv/ui/TVMainFragment.kt",
    "content": "package knf.kuma.tv.ui\n\nimport android.app.Activity\nimport android.content.Intent\nimport android.graphics.Color\nimport android.os.Bundle\nimport android.util.SparseArray\nimport android.view.View\nimport androidx.core.content.ContextCompat\nimport androidx.leanback.app.BrowseSupportFragment\nimport androidx.leanback.widget.ArrayObjectAdapter\nimport androidx.leanback.widget.HeaderItem\nimport androidx.leanback.widget.ListRow\nimport androidx.leanback.widget.ListRowPresenter\nimport androidx.leanback.widget.OnItemViewClickedListener\nimport androidx.leanback.widget.Presenter\nimport androidx.leanback.widget.Row\nimport androidx.leanback.widget.RowPresenter\nimport androidx.lifecycle.lifecycleScope\nimport com.dropbox.core.android.Auth\nimport knf.kuma.App\nimport knf.kuma.Diagnostic\nimport knf.kuma.R\nimport knf.kuma.backup.Backups\nimport knf.kuma.backup.firestore.FirestoreManager\nimport knf.kuma.backup.framework.BackupService\nimport knf.kuma.backup.framework.DropBoxService\nimport knf.kuma.commons.distinct\nimport knf.kuma.database.CacheDB\nimport knf.kuma.directory.DirObject\nimport knf.kuma.home.StaffRecommendations\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.FavoriteObject\nimport knf.kuma.pojos.RecentObject\nimport knf.kuma.pojos.RecordObject\nimport knf.kuma.retrofit.Repository\nimport knf.kuma.tv.AnimeRow\nimport knf.kuma.tv.GlideBackgroundManager\nimport knf.kuma.tv.TVServersFactory\nimport knf.kuma.tv.anime.FavPresenter\nimport knf.kuma.tv.anime.RecentsPresenter\nimport knf.kuma.tv.anime.RecordPresenter\nimport knf.kuma.tv.anime.SectionPresenter\nimport knf.kuma.tv.anime.SyncPresenter\nimport knf.kuma.tv.details.TVAnimesDetails\nimport knf.kuma.tv.directory.DirPresenter\nimport knf.kuma.tv.search.TVSearch\nimport knf.kuma.tv.sections.DirSection\nimport knf.kuma.tv.sections.EmissionSection\nimport knf.kuma.tv.sections.SectionObject\nimport knf.kuma.tv.sync.BypassObject\nimport knf.kuma.tv.sync.LogOutObject\nimport knf.kuma.tv.sync.SyncObject\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport xdroid.toaster.Toaster\n\nclass TVMainFragment : BrowseSupportFragment(), OnItemViewClickedListener, View.OnClickListener {\n    private var mRows: SparseArray<AnimeRow>? = null\n\n    private var backgroundManager: GlideBackgroundManager? = null\n    private var service: BackupService? = null\n    private var waitingLoginDropbox = false\n    private var waitingLoginFirestore = false\n\n    override fun onActivityCreated(savedInstanceState: Bundle?) {\n        super.onActivityCreated(savedInstanceState)\n        backgroundManager = GlideBackgroundManager(activity as Activity)\n        headersState = HEADERS_ENABLED\n        isHeadersTransitionOnBackEnabled = true\n        title = \"UKIKU\"\n        brandColor = Color.parseColor(\"#424242\")\n        searchAffordanceColor = ContextCompat.getColor(App.context, R.color.colorAccent)\n        setOnSearchClickedListener(this)\n        createDataRows()\n        createRows()\n        prepareEntranceTransition()\n        fetchData()\n        service = Backups.createService()\n        onLogin()\n    }\n\n    private fun createDataRows() {\n        mRows = SparseArray()\n        mRows?.put(RECENTS, AnimeRow()\n                .setId(RECENTS)\n                .setAdapter(ArrayObjectAdapter(RecentsPresenter()))\n                .setTitle(\"Recientes\")\n                .setPage(1))\n        mRows?.put(LAST_SEEN, AnimeRow()\n                .setId(LAST_SEEN)\n                .setAdapter(ArrayObjectAdapter(RecordPresenter()))\n                .setTitle(\"Ultimos vistos\")\n                .setPage(1))\n        mRows?.put(FAVORITES, AnimeRow()\n                .setId(FAVORITES)\n                .setAdapter(ArrayObjectAdapter(FavPresenter()))\n                .setTitle(\"Favoritos\")\n                .setPage(1))\n        mRows?.put(STAFF, AnimeRow()\n                .setId(STAFF)\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\n                .setTitle(\"Recomendados\")\n                .setPage(1))\n        mRows?.put(BEST, AnimeRow()\n                .setId(BEST)\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\n                .setTitle(\"Mejores en emisión\")\n                .setPage(1))\n        mRows?.put(BESTGLOBAL, AnimeRow()\n                .setId(BESTGLOBAL)\n                .setAdapter(ArrayObjectAdapter(DirPresenter()))\n                .setTitle(\"Mejores en general\")\n                .setPage(1))\n        mRows?.put(SECTIONS, AnimeRow()\n                .setId(SECTIONS)\n                .setAdapter(ArrayObjectAdapter(SectionPresenter()))\n                .setTitle(\"Secciones\")\n                .setPage(1))\n    }\n\n    private fun createRows() {\n        val rowsAdapter = ArrayObjectAdapter(ListRowPresenter())\n        for (i in 0 until (mRows?.size() ?: 0)) {\n            val row = mRows?.get(i)\n            val headerItem = HeaderItem(row?.id?.toLong() ?: 0, row?.title)\n            val listRow = ListRow(headerItem, row?.adapter)\n            rowsAdapter.add(listRow)\n        }\n        adapter = rowsAdapter\n        onItemViewClickedListener = this\n    }\n\n    private fun fetchData() {\n        Repository().reloadRecents()\n        activity?.let {\n            CacheDB.INSTANCE.recentsDAO().objects.distinct.observe(it) { recentObjects ->\n                mRows?.get(RECENTS)?.apply {\n                    page = page.plus(1)\n                    adapter?.apply {\n                        clear()\n                        addAll(0, recentObjects)\n                    }\n                }\n                startEntranceTransition()\n            }\n            CacheDB.INSTANCE.recordsDAO().allLive.distinct.observe(it) { recordObjects ->\n                mRows?.get(LAST_SEEN)?.apply {\n                    page = page.plus(1)\n                    adapter?.apply {\n                        clear()\n                        addAll(0, recordObjects)\n                    }\n                }\n                startEntranceTransition()\n            }\n            CacheDB.INSTANCE.favsDAO().all.distinct.observe(it) { favoriteObjects ->\n                mRows?.get(FAVORITES)?.apply {\n                    page = page.plus(1)\n                    adapter?.apply {\n                        clear()\n                        addAll(0, favoriteObjects)\n                    }\n                }\n                startEntranceTransition()\n            }\n            viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {\n                var recList = emptyList<DirObject>()\n                while (recList.size < 15) {\n                    delay(100)\n                    recList = CacheDB.INSTANCE.animeDAO()\n                        .animesDirWithIDRandomNL(StaffRecommendations.randomIds(15))\n                }\n                launch(Dispatchers.Main) {\n                    mRows?.get(STAFF)?.apply {\n                        page = page.plus(1)\n                        adapter?.apply {\n                            clear()\n                            addAll(0, recList)\n                        }\n                    }\n                    startEntranceTransition()\n                }\n            }\n            CacheDB.INSTANCE.animeDAO().emissionVotesLimited.distinct.observe(\n                it\n            ) { emissionObjects ->\n                mRows?.get(BEST)?.apply {\n                    page = page.plus(1)\n                    adapter?.apply {\n                        clear()\n                        addAll(0, emissionObjects)\n                    }\n                }\n                startEntranceTransition()\n            }\n            CacheDB.INSTANCE.animeDAO().allVotesLimited.distinct.observe(it) { emissionObjects ->\n                mRows?.get(BESTGLOBAL)?.apply {\n                    page = page.plus(1)\n                    adapter?.apply {\n                        clear()\n                        addAll(0, emissionObjects)\n                    }\n                }\n                startEntranceTransition()\n            }\n            arrayListOf(DirSection(), EmissionSection()).let { sections ->\n                mRows?.get(SECTIONS)?.apply {\n                    page = page.plus(1)\n                    adapter?.apply {\n                        clear()\n                        addAll(0, sections)\n                    }\n                }\n                startEntranceTransition()\n            }\n        }\n    }\n\n    override fun onClick(v: View) {\n        context?.let { TVSearch.start(it) }\n    }\n\n    override fun onItemClicked(itemViewHolder: Presenter.ViewHolder?, item: Any?, rowViewHolder: RowPresenter.ViewHolder?, row: Row?) {\n        if (item is RecentObject) {\n            TVServersFactory.start(activity as Activity, item.url, AnimeObject.WebInfo.AnimeChapter.fromRecent(item), activity as TVServersFactory.ServersInterface)\n        } else if (item is RecordObject) {\n            if (item.animeObject != null)\n                context?.let { TVAnimesDetails.start(it, item.animeObject.link) }\n            else\n                Toaster.toast(\"Anime no encontrado\")\n        } else if (item is FavoriteObject) {\n            context?.let { TVAnimesDetails.start(it, item.link) }\n        } else if (item is DirObject) {\n            context?.let { TVAnimesDetails.start(it, item.link) }\n        } else if (item is SectionObject) {\n            item.open(context)\n        } else if (item is SyncObject) {\n            when (item) {\n                is LogOutObject -> {\n                    service?.logOut()\n                    activity?.let { FirestoreManager.doSignOut(it) }\n                    Backups.type = Backups.Type.NONE\n                    onLogin()\n                }\n                is BypassObject -> startActivity(Intent(context, Diagnostic.FullBypass::class.java))\n                else -> {\n                    when (item.type) {\n                        Backups.Type.DROPBOX -> {\n                            waitingLoginDropbox = true\n                            if (item.type == Backups.Type.DROPBOX)\n                                service = DropBoxService().also { it.logIn() }\n                        }\n                        Backups.Type.FIRESTORE -> {\n                            waitingLoginFirestore = true\n                            activity?.let { FirestoreManager.doLogin(it) }\n                        }\n                        else -> {\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    override fun onResume() {\n        super.onResume()\n        if (waitingLoginDropbox) {\n            val token = Auth.getOAuth2Token()\n            if (service is DropBoxService && service?.logIn(token) == true) {\n                Backups.type = Backups.Type.DROPBOX\n            }\n            onLogin()\n        }\n        if (waitingLoginFirestore) {\n            onLogin()\n        }\n    }\n\n    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n        super.onActivityResult(requestCode, resultCode, data)\n        activity?.let { FirestoreManager.handleLogin(it, requestCode, resultCode, data) }\n    }\n\n    private fun onLogin() {\n        if (service?.isLoggedIn == false && waitingLoginDropbox) {\n            Toaster.toast(\"Error al iniciar sesión\")\n        } else {\n            val adapter = ArrayObjectAdapter(SyncPresenter())\n            val headerItem = HeaderItem(SYNC.toLong(), \"Sincronización\")\n            if (service?.isLoggedIn == true || FirestoreManager.isLoggedIn) {\n                adapter.add(LogOutObject())\n                Backups.restoreAll()\n            } else {\n                adapter.add(SyncObject(Backups.Type.DROPBOX))\n                adapter.add(SyncObject(Backups.Type.FIRESTORE))\n            }\n            adapter.add(BypassObject())\n            if (getAdapter().size() == 7)\n                (getAdapter() as ArrayObjectAdapter).add(SYNC, ListRow(headerItem, adapter))\n            else\n                (getAdapter() as ArrayObjectAdapter).replace(SYNC, ListRow(headerItem, adapter))\n        }\n        waitingLoginDropbox = false\n        waitingLoginFirestore = false\n    }\n\n    companion object {\n\n        private const val RECENTS = 0\n        private const val LAST_SEEN = 1\n        private const val FAVORITES = 2\n        private const val STAFF = 3\n        private const val BEST = 4\n        private const val BESTGLOBAL = 5\n        private const val SECTIONS = 6\n        private const val SYNC = 7\n\n        fun get(): TVMainFragment {\n            return TVMainFragment()\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/updater/UpdateActivity.kt",
    "content": "package knf.kuma.updater\n\nimport androidx.activity.addCallback\nimport android.annotation.SuppressLint\nimport android.content.Context\nimport android.content.Intent\nimport android.graphics.drawable.AnimationDrawable\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport android.view.View\nimport android.view.WindowManager\nimport android.view.animation.AnimationUtils\nimport androidx.activity.viewModels\nimport androidx.core.content.FileProvider\nimport androidx.lifecycle.Observer\nimport com.afollestad.materialdialogs.MaterialDialog\nimport knf.kuma.R\nimport knf.kuma.commons.getUpdateDir\nimport knf.kuma.commons.safeShow\nimport knf.kuma.custom.GenericActivity\nimport knf.kuma.databinding.ActivityUpdaterBinding\nimport knf.kuma.download.DownloadManagerCentral\nimport java.io.File\n\nclass UpdateActivity : GenericActivity() {\n\n    private val binding by lazy { ActivityUpdaterBinding.inflate(layoutInflater) }\n    private val updaterViewModel: UpdaterViewModel by viewModels()\n    private val update: File by lazy { File.createTempFile(\"update\", \".apk\", filesDir) }\n    private var isUpdateDownloaded = false\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(binding.root)\n        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS or WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)\n        binding.download.setOnClickListener { install() }\n        binding.retry.setOnClickListener {\n            prepareForStart()\n            start()\n        }\n        binding.progress.max = 100\n        val animationDrawable = binding.relBack.background as AnimationDrawable\n        if (!animationDrawable.isRunning) {\n            animationDrawable.setEnterFadeDuration(2500)\n            animationDrawable.setExitFadeDuration(2500)\n            animationDrawable.start()\n        }\n        onBackPressedDispatcher.addCallback(this) {\n            if (intent.getBooleanExtra(\"canExit\", true)) {\n                isEnabled = false\n                onBackPressedDispatcher.onBackPressed()\n                isEnabled = true\n            }\n        }\n        start()\n    }\n\n    private fun start() {\n        updaterViewModel.start(update, \"https://github.com/jordyamc/UKIKU/raw/master/app/$getUpdateDir/app-$getUpdateDir.apk\")\n            .observe(this, Observer {\n                when (it.first) {\n                    UpdaterType.TYPE_IDLE -> {\n                        binding.progress.isIndeterminate = true\n                    }\n\n                    UpdaterType.TYPE_PROGRESS -> {\n                        setDownProgress(it.second as Int)\n                    }\n\n                    UpdaterType.TYPE_ERROR -> {\n                        prepareForRetry()\n                        onShowAlternativeDownload()\n                    }\n\n                    UpdaterType.TYPE_COMPLETED -> {\n                        isUpdateDownloaded = true\n                        binding.progress.progress = 100\n                        binding.progressText.text = \"100%\"\n                        prepareForInstall()\n                    }\n                }\n            })\n    }\n\n    override fun onStart() {\n        super.onStart()\n        if (!intent.getBooleanExtra(\"canExit\", true)) {\n            MaterialDialog(this).safeShow {\n                message(text = \"Parece que la versión ${intent.getStringExtra(\"version\")} está disponible, es obligatoria\")\n                positiveButton(text = \"ok\")\n            }\n        }\n    }\n\n    private fun install() {\n        DownloadManagerCentral.pauseAll()\n        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {\n            val intent = Intent(Intent.ACTION_INSTALL_PACKAGE, FileProvider.getUriForFile(this, \"${applicationContext.packageName}.fileprovider\", update))\n                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)\n                .putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)\n                .putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, packageName)\n            startActivity(intent)\n        } else {\n            val intent = Intent(Intent.ACTION_VIEW)\n                    .setDataAndType(Uri.fromFile(update), \"application/vnd.android.package-archive\")\n                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)\n            startActivity(intent)\n        }\n    }\n\n    private fun setDownProgress(p: Int) {\n        try {\n            binding.progress.apply {\n                isIndeterminate = false\n                progress = p\n            }\n            binding.progressText.text = String.format(\"%d%%\", p)\n        } catch (e: Exception) {\n            e.printStackTrace()\n        }\n    }\n\n    private fun prepareForInstall() {\n        setDownProgress(100)\n        val fadein = AnimationUtils.loadAnimation(this, R.anim.fadein)\n        fadein.duration = 1000\n        val fadeout = AnimationUtils.loadAnimation(this, R.anim.fadeout)\n        fadeout.duration = 1000\n        binding.progressText.post {\n            with(binding.progressText) {\n                visibility = View.INVISIBLE\n                startAnimation(fadeout)\n            }\n        }\n        binding.download.post {\n            with(binding.download) {\n                visibility = View.VISIBLE\n                startAnimation(fadein)\n            }\n        }\n    }\n\n    private fun prepareForStart() {\n        setDownProgress(100)\n        val fadein = AnimationUtils.loadAnimation(this, R.anim.fadein)\n        fadein.duration = 1000\n        val fadeout = AnimationUtils.loadAnimation(this, R.anim.fadeout)\n        fadeout.duration = 1000\n        binding.retry.post {\n            with(binding.retry) {\n                visibility = View.INVISIBLE\n                startAnimation(fadeout)\n            }\n        }\n        binding.progressText.post {\n            with(binding.progressText) {\n                visibility = View.VISIBLE\n                startAnimation(fadein)\n            }\n        }\n    }\n\n    private fun prepareForRetry() {\n        setDownProgress(100)\n        val fadein = AnimationUtils.loadAnimation(this, R.anim.fadein)\n        fadein.duration = 1000\n        val fadeout = AnimationUtils.loadAnimation(this, R.anim.fadeout)\n        fadeout.duration = 1000\n        binding.progressText.post {\n            with(binding.progressText) {\n                visibility = View.INVISIBLE\n                startAnimation(fadeout)\n            }\n        }\n        binding.retry.post {\n            with(binding.retry) {\n                visibility = View.VISIBLE\n                startAnimation(fadein)\n            }\n        }\n    }\n\n    private fun onShowAlternativeDownload() {\n        MaterialDialog(this).safeShow {\n            title(text = \"¿Error al actualizar?\")\n            message(text = \"Puedes descargar la actualizacion desde la pagina web oficial!\")\n            positiveButton(text = \"Descargar\") {\n                startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(\"https://ukiku.app\")))\n            }\n        }\n    }\n\n    override fun onResume() {\n        super.onResume()\n        if (isUpdateDownloaded) {\n            onShowAlternativeDownload()\n        }\n    }\n\n    companion object {\n        fun start(context: Context, canExit: Boolean, version: String) {\n            context.startActivity(Intent(context, UpdateActivity::class.java).apply {\n                putExtra(\"canExit\", canExit)\n                putExtra(\"version\", version)\n            })\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/updater/UpdateChecker.kt",
    "content": "package knf.kuma.updater\n\nimport android.util.Log\nimport androidx.core.content.pm.PackageInfoCompat\nimport androidx.fragment.app.FragmentActivity\nimport androidx.lifecycle.lifecycleScope\nimport knf.kuma.commons.Network\nimport knf.kuma.commons.isFullMode\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\nimport org.jsoup.Jsoup\n\nobject UpdateChecker {\n    fun check(context: FragmentActivity, listener: CheckListener) {\n        if (Network.isConnected && isFullMode)\n            context.lifecycleScope.launch(Dispatchers.IO) {\n                try {\n                    val document =\n                        Jsoup.connect(\"https://raw.githubusercontent.com/jordyamc/UKIKU/master/version.num\")\n                            .get()\n                    val nCode = Integer.parseInt(document.select(\"body\").first().ownText().trim())\n                    val oCode = PackageInfoCompat.getLongVersionCode(\n                        context.packageManager.getPackageInfo(\n                            context.packageName,\n                            0\n                        )\n                    ).toInt()\n                    if (nCode > oCode) {\n                        delay(2000)\n                        listener.onNeedUpdate(oCode.toString(), nCode.toString())\n                    } else {\n                        context.filesDir.listFiles()\n                            ?.filter {\n                                !it.isDirectory && it.name.startsWith(\"update\") && it.name.endsWith(\n                                    \".apk\"\n                                )\n                            }\n                                ?.forEach {\n                                    it.delete()\n                                }\n                        Log.e(\"Version\", \"Up to date: $oCode\")\n                        listener.onUpdateNotRequired()\n                    }\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                    listener.onUpdateNotRequired()\n                }\n            }\n        else\n            listener.onUpdateNotRequired()\n    }\n\n    interface CheckListener {\n        fun onNeedUpdate(o_code: String, n_code: String)\n        fun onUpdateNotRequired()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/updater/UpdaterViewModel.kt",
    "content": "package knf.kuma.updater\r\n\r\nimport android.net.Uri\r\nimport android.util.Log\r\nimport androidx.core.net.toUri\r\nimport androidx.lifecycle.LiveData\r\nimport androidx.lifecycle.MutableLiveData\r\nimport androidx.lifecycle.ViewModel\r\nimport androidx.lifecycle.viewModelScope\r\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\r\nimport com.thin.downloadmanager.DefaultRetryPolicy\r\nimport com.thin.downloadmanager.DownloadRequest\r\nimport com.thin.downloadmanager.DownloadStatusListenerV1\r\nimport com.thin.downloadmanager.ThinDownloadManager\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.launch\r\nimport xdroid.toaster.Toaster\r\nimport java.io.File\r\n\r\nclass UpdaterViewModel : ViewModel() {\r\n    private val liveData = MutableLiveData<Pair<UpdaterType, Any?>>(UpdaterType.TYPE_IDLE to null)\r\n    private val manager = ThinDownloadManager()\r\n    private var isStarted = false\r\n\r\n    fun start(file: File, link: String): LiveData<Pair<UpdaterType, Any?>> {\r\n        if (isStarted) return liveData\r\n        isStarted = true\r\n        manager.add(\r\n            DownloadRequest(link.toUri())\r\n                .setDestinationURI(Uri.fromFile(file))\r\n                .setDownloadResumable(false)\r\n                .setRetryPolicy(DefaultRetryPolicy(5000, 3, 1f))\r\n                .setStatusListener(object : DownloadStatusListenerV1 {\r\n                    override fun onDownloadComplete(downloadRequest: DownloadRequest?) {\r\n                        viewModelScope.launch(Dispatchers.Main) {\r\n                            liveData.value = UpdaterType.TYPE_COMPLETED to null\r\n                        }\r\n                    }\r\n\r\n                    override fun onDownloadFailed(downloadRequest: DownloadRequest?, errorCode: Int, errorMessage: String?) {\r\n                        viewModelScope.launch(Dispatchers.Main) {\r\n                            liveData.value = UpdaterType.TYPE_ERROR to errorMessage\r\n                        }\r\n                        Log.e(\"Update Error\", \"Code: $errorCode Message: $errorMessage\")\r\n                        Toaster.toast(\"Error al actualizar: $errorMessage\")\r\n                        FirebaseCrashlytics.getInstance().recordException(IllegalStateException(\"Update failed\\nCode: $errorCode Message: $errorMessage\"))\r\n                    }\r\n\r\n                    override fun onProgress(downloadRequest: DownloadRequest?, totalBytes: Long, downloadedBytes: Long, progress: Int) {\r\n                        viewModelScope.launch(Dispatchers.Main) {\r\n                            liveData.value = UpdaterType.TYPE_PROGRESS to progress\r\n                        }\r\n                    }\r\n                }))\r\n        return liveData\r\n    }\r\n\r\n    override fun onCleared() {\r\n        super.onCleared()\r\n        manager.cancelAll()\r\n        isStarted = false\r\n        liveData.value = UpdaterType.TYPE_IDLE to null\r\n    }\r\n}\r\n\r\nenum class UpdaterType {\r\n    TYPE_ERROR, TYPE_PROGRESS, TYPE_COMPLETED, TYPE_IDLE\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/FembedServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.iterator\nimport knf.kuma.videoservers.VideoServer.Names.FEMBED\nimport org.json.JSONObject\nimport org.jsoup.Connection\nimport org.jsoup.Jsoup\n\nclass FembedServer internal constructor(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"fembed\") || baseLink.contains(\"embedsito.com\")\n\n    override val name: String\n        get() = FEMBED\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                val downLink = PatternUtil.extractLink(baseLink)\n                val fLink = if (downLink.contains(\"value=\"))\n                    \"https://embedsito.com/v/${downLink.substring(downLink.lastIndexOf(\"=\") + 1)}\"\n                else\n                    downLink\n                val json = JSONObject(Jsoup.connect(fLink.replace(\"/v/\", \"/api/source/\")).ignoreContentType(true).method(Connection.Method.POST).execute().body())\n                check(json.getBoolean(\"success\")) { \"Request was not succeeded\" }\n                val array = json.getJSONArray(\"data\")\n                val options = mutableListOf<Option>()\n                for (item in array) {\n                    options.add(Option(name, item.getString(\"label\"), item.getString(\"file\")))\n                }\n                VideoServer(name, options, true)\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/FenixServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.videoservers.VideoServer.Names.FENIX\nimport org.json.JSONObject\n\nclass FenixServer internal constructor(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"s=fenix\")\n\n    override val name: String\n        get() = FENIX\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                val downLink = PatternUtil.extractLink(baseLink)\n                val link = JSONObject(jsoupCookies(downLink.replace(\"embed\", \"check\")).get().body().text()).getString(\"file\")\n                VideoServer(FENIX, Option(name, null, link))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/FileActions.kt",
    "content": "package knf.kuma.videoservers\r\n\r\nimport android.content.ActivityNotFoundException\r\nimport android.content.Context\r\nimport android.content.Intent\r\nimport android.graphics.Color\r\nimport android.net.Uri\r\nimport android.os.Build\r\nimport android.util.Log\r\nimport android.view.View\r\nimport androidx.appcompat.app.AppCompatActivity\r\nimport androidx.browser.customtabs.CustomTabsIntent\r\nimport androidx.fragment.app.Fragment\r\nimport androidx.lifecycle.Lifecycle\r\nimport androidx.lifecycle.LifecycleOwner\r\nimport androidx.lifecycle.coroutineScope\r\nimport androidx.lifecycle.lifecycleScope\r\nimport androidx.preference.PreferenceManager\r\nimport com.afollestad.materialdialogs.MaterialDialog\r\nimport com.afollestad.materialdialogs.callbacks.onDismiss\r\nimport com.afollestad.materialdialogs.checkbox.checkBoxPrompt\r\nimport com.afollestad.materialdialogs.lifecycle.lifecycleOwner\r\nimport com.afollestad.materialdialogs.list.listItems\r\nimport com.afollestad.materialdialogs.list.listItemsSingleChoice\r\nimport com.google.firebase.crashlytics.FirebaseCrashlytics\r\nimport knf.kuma.App\r\nimport knf.kuma.BuildConfig\r\nimport knf.kuma.achievements.AchievementManager\r\nimport knf.kuma.animeinfo.ktx.fileName\r\nimport knf.kuma.backup.firestore.syncData\r\nimport knf.kuma.commons.CastUtil\r\nimport knf.kuma.commons.EAHelper\r\nimport knf.kuma.commons.Network\r\nimport knf.kuma.commons.PrefsUtil\r\nimport knf.kuma.commons.isNull\r\nimport knf.kuma.commons.iterator\r\nimport knf.kuma.commons.jsoupCookies\r\nimport knf.kuma.commons.safeShow\r\nimport knf.kuma.commons.showProgressSnackbar\r\nimport knf.kuma.commons.toArray\r\nimport knf.kuma.commons.urlDecode\r\nimport knf.kuma.custom.snackbar.SnackProgressBarManager\r\nimport knf.kuma.database.CacheDB\r\nimport knf.kuma.download.DownloadManagerCentral\r\nimport knf.kuma.download.DownloadService\r\nimport knf.kuma.download.FileAccessHelper\r\nimport knf.kuma.download.MultipleDownloadManager\r\nimport knf.kuma.download.service\r\nimport knf.kuma.player.openWebPlayer\r\nimport knf.kuma.pojos.AnimeObject\r\nimport knf.kuma.pojos.DownloadObject\r\nimport knf.kuma.pojos.QueueObject\r\nimport knf.kuma.queue.QueueManager\r\nimport knf.kuma.recents.RecentModel\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.delay\r\nimport kotlinx.coroutines.launch\r\nimport org.json.JSONObject\r\nimport xdroid.toaster.Toaster\r\nimport java.util.Locale\r\n\r\nobject FileActions {\r\n    private var isExecuting = false\r\n    private var snackBarManager: SnackProgressBarManager? = null\r\n    private var servers: MutableList<Server> = ArrayList()\r\n    private var selected = 0\r\n\r\n    fun stream(fragment: Fragment, item: Any, isQueued: Boolean = false, callback: ActionCallback) {\r\n        when (item) {\r\n            is RecentModel -> stream(fragment.requireContext(), fragment.viewLifecycleOwner, item, fragment.view, callback)\r\n            is AnimeObject.WebInfo.AnimeChapter -> {\r\n                if (isQueued)\r\n                    queuedStream(fragment.requireContext(), fragment.viewLifecycleOwner, item, fragment.view, callback)\r\n                else\r\n                    stream(fragment.requireContext(), fragment.viewLifecycleOwner, item, fragment.view, callback)\r\n            }\r\n        }\r\n    }\r\n\r\n    fun stream(activity: AppCompatActivity, item: Any, isQueued: Boolean = false, callback: ActionCallback) {\r\n        when (item) {\r\n            is RecentModel -> stream(activity, activity, item, activity.window.decorView, callback)\r\n            is AnimeObject.WebInfo.AnimeChapter -> {\r\n                if (isQueued)\r\n                    queuedStream(activity, activity, item, activity.window.decorView, callback)\r\n                else\r\n                    stream(activity, activity, item, activity.window.decorView, callback)\r\n            }\r\n        }\r\n    }\r\n\r\n    fun download(fragment: Fragment, item: Any, isQueued: Boolean = false, callback: ActionCallback) {\r\n        when (item) {\r\n            is RecentModel -> download(fragment.requireContext(), fragment.viewLifecycleOwner, item, fragment.view, callback)\r\n            is AnimeObject.WebInfo.AnimeChapter -> {\r\n                if (isQueued)\r\n                    queuedDownload(fragment.requireContext(), fragment.viewLifecycleOwner, item, fragment.view, callback)\r\n                else\r\n                    download(fragment.requireContext(), fragment.viewLifecycleOwner, item, fragment.view, callback)\r\n            }\r\n        }\r\n    }\r\n\r\n    fun download(activity: AppCompatActivity, item: Any, isQueued: Boolean = false, callback: ActionCallback) {\r\n        when (item) {\r\n            is RecentModel -> download(activity, activity, item, activity.window.decorView, callback)\r\n            is AnimeObject.WebInfo.AnimeChapter -> {\r\n                if (isQueued)\r\n                    queuedDownload(activity, activity, item, activity.window.decorView, callback)\r\n                else\r\n                    download(activity, activity, item, activity.window.decorView, callback)\r\n            }\r\n        }\r\n    }\r\n\r\n    fun stream(context: Context, owner: LifecycleOwner, item: RecentModel, anchorView: View? = null, callback: ActionCallback) {\r\n        execute(context, owner, if (CastUtil.get().connected()) Type.CAST else Type.STREAM, item.chapterUrl, item, DownloadObject.fromRecentModel(item), anchorView, callback)\r\n    }\r\n\r\n    fun stream(context: Context, owner: LifecycleOwner, item: AnimeObject.WebInfo.AnimeChapter, anchorView: View? = null, callback: ActionCallback) {\r\n        execute(context, owner, if (CastUtil.get().connected()) Type.CAST else Type.STREAM, item.link, item, DownloadObject.fromChapter(item, false), anchorView, callback)\r\n    }\r\n\r\n    fun download(context: Context, owner: LifecycleOwner, item: RecentModel, anchorView: View? = null, callback: ActionCallback) {\r\n        execute(context, owner, Type.DOWNLOAD, item.chapterUrl, item, DownloadObject.fromRecentModel(item), anchorView, callback)\r\n    }\r\n\r\n    fun download(context: Context, owner: LifecycleOwner, item: AnimeObject.WebInfo.AnimeChapter, anchorView: View? = null, callback: ActionCallback) {\r\n        execute(context, owner, Type.DOWNLOAD, item.link, item, DownloadObject.fromChapter(item, false), anchorView, callback)\r\n    }\r\n\r\n    fun queuedStream(context: Context, owner: LifecycleOwner, item: AnimeObject.WebInfo.AnimeChapter, anchorView: View? = null, callback: ActionCallback) {\r\n        execute(context, owner, Type.STREAM, item.link, item, DownloadObject.fromChapter(item, true), anchorView, callback)\r\n    }\r\n\r\n    fun queuedDownload(context: Context, owner: LifecycleOwner, item: AnimeObject.WebInfo.AnimeChapter, anchorView: View? = null, callback: ActionCallback) {\r\n        execute(context, owner, Type.DOWNLOAD, item.link, item, DownloadObject.fromChapter(item, true), anchorView, callback)\r\n    }\r\n\r\n    private fun execute(context: Context, owner: LifecycleOwner, type: Type, url: String, item: Any, downloadObject: DownloadObject, anchorView: View?, callback: ActionCallback) {\r\n        if (isExecuting) {\r\n            Toaster.toast(\"Solo una petición a la vez\")\r\n            callback.call(CallbackState.OPERATION_RUNNING)\r\n            return\r\n        }\r\n        if (!Network.isConnected) {\r\n            Toaster.toast(\"No hay internet\")\r\n            callback.call(CallbackState.UNEXPECTED_ERROR)\r\n            return\r\n        }\r\n        owner.lifecycleScope.launch(Dispatchers.Main) {\r\n            val result = checkPreconditions(context, type == Type.DOWNLOAD)\r\n            if (result != null) {\r\n                reset()\r\n                callback.call(result)\r\n                return@launch\r\n            }\r\n            val actionRequest = ActionRequest(context, owner, type, url, item, downloadObject, callback)\r\n            isExecuting = true\r\n            snackBarManager = getSnackManager(anchorView)\r\n            snackBarManager.showSnack(\"Obteniendo servidores...\")\r\n            launch(Dispatchers.IO) {\r\n                try {\r\n                    val main = jsoupCookies(url).get()\r\n                    val servers = ArrayList<Server>()\r\n                    val sScript = main.select(\"script\")\r\n                    var j = \"\"\r\n                    for (element in sScript) {\r\n                        val sEl = element.outerHtml()\r\n                        if (\"\\\\{\\\"[SUBLAT]+\\\":\\\\[.*\\\\]\\\\}\".toRegex().containsMatchIn(sEl)) {\r\n                            j = sEl\r\n                            break\r\n                        }\r\n                    }\r\n                    val jsonObject = JSONObject(\"\\\\{\\\"[SUBLAT]+\\\":\\\\[.*\\\\]\\\\}\".toRegex().find(j)?.value\r\n                            ?: throw IllegalStateException(\"Episodes json not found\"))\r\n                    if (jsonObject.length() > 1) {\r\n                        launch(Dispatchers.Main) {\r\n                            val langSelect: (Int) -> Unit = { index ->\r\n                                owner.lifecycle.coroutineScope.launch(Dispatchers.IO) {\r\n                                    val downloads = main.select(\"table.RTbl.Dwnl tr:contains(${if (index == 0) \"SUB\" else \"LAT\"}) a.Button.Sm.fa-download\")\r\n                                    for (e in downloads) {\r\n                                        var z = e.attr(\"href\")\r\n                                        z = z.substring(z.lastIndexOf(\"http\"))\r\n                                        val server = Server.check(context, z)\r\n                                        if (server != null)\r\n                                            servers.add(server)\r\n                                    }\r\n                                    val jsonArray =\r\n                                            when (index) {\r\n                                                1 -> jsonObject.getJSONArray(\"LAT\")\r\n                                                else -> jsonObject.getJSONArray(\"SUB\")\r\n                                            }\r\n                                    for (baseLink in jsonArray) {\r\n                                        val server = Server.check(context, baseLink.optString(\"code\"))\r\n                                        if (server != null) {\r\n                                            try {\r\n                                                var skip = false\r\n                                                servers.forEach {\r\n                                                    if (it.name == server.name) {\r\n                                                        skip = true\r\n                                                        return@forEach\r\n                                                    }\r\n                                                }\r\n                                                if (!skip)\r\n                                                    servers.add(server)\r\n                                            } catch (e: Exception) {\r\n                                                e.printStackTrace()\r\n                                            }\r\n                                        } else if (!baseLink.optString(\"code\").contains(\"linkinpork\")) {\r\n                                            servers.add(WebServer(context, baseLink.optString(\"code\"), baseLink.optString(\"title\")))\r\n                                        }\r\n                                    }\r\n                                    servers.sort()\r\n                                    this@FileActions.servers = servers.filter {\r\n                                        if (downloadObject.addQueue || type != Type.STREAM) {\r\n                                            it.canDownload\r\n                                        } else {\r\n                                            true\r\n                                        }\r\n                                    }.toMutableList()\r\n                                    showServerList(actionRequest)\r\n                                }\r\n                            }\r\n                            if (!MultipleDownloadManager.isLoading || MultipleDownloadManager.langSelected == -1)\r\n                                MaterialDialog(context).safeShow {\r\n                                    lifecycleOwner(actionRequest.owner)\r\n                                    listItems(items = listOf(\"Subtitulado\", \"Latino\")) { _, index, _ ->\r\n                                        langSelect(index)\r\n                                        if (MultipleDownloadManager.isLoading)\r\n                                            MultipleDownloadManager.langSelected = index\r\n                                    }\r\n                                    onDismiss {\r\n                                        if (isCancelling(actionRequest.owner)) {\r\n                                            reset()\r\n                                            actionRequest.callback.call(CallbackState.LIFECYCLE_EXPIRED)\r\n                                        }\r\n                                    }\r\n                                    setOnCancelListener {\r\n                                        reset()\r\n                                        callback.call(CallbackState.USER_CANCELLED)\r\n                                    }\r\n                                }\r\n                            else\r\n                                langSelect(MultipleDownloadManager.langSelected)\r\n                        }\r\n                    } else {\r\n                        val downloads = main.select(\"table.RTbl.Dwnl tr:contains(SUB) a.Button.Sm.fa-download\")\r\n                        for (e in downloads) {\r\n                            var z = e.attr(\"href\")\r\n                            z = urlDecode(z.substring(z.lastIndexOf(\"http\")))\r\n                            val server = Server.check(context, z)\r\n                            if (server != null)\r\n                                servers.add(server)\r\n                        }\r\n                        val jsonArray = jsonObject.getJSONArray(if (jsonObject.has(\"SUB\")) \"SUB\" else \"LAT\")\r\n                        for (baseLink in jsonArray) {\r\n                            val server = Server.check(context, baseLink.optString(\"code\"))\r\n                            if (server != null) {\r\n                                try {\r\n                                    var skip = false\r\n                                    servers.forEach {\r\n                                        if (it.name == server.name) {\r\n                                            skip = true\r\n                                            return@forEach\r\n                                        }\r\n                                    }\r\n                                    if (!skip)\r\n                                        servers.add(server)\r\n                                } catch (e: Exception) {\r\n                                    e.printStackTrace()\r\n                                }\r\n                            } else if (!baseLink.optString(\"code\").contains(\"linkinpork\")) {\r\n                                servers.add(WebServer(context, baseLink.optString(\"code\"), baseLink.optString(\"title\")))\r\n                            }\r\n                        }\r\n                        servers.sort()\r\n                        this@FileActions.servers = servers.filter {\r\n                            if (downloadObject.addQueue || type != Type.STREAM) {\r\n                                it.canDownload\r\n                            } else {\r\n                                true\r\n                            }\r\n                        }.toMutableList()\r\n                        showServerList(actionRequest)\r\n                    }\r\n                } catch (e: Exception) {\r\n                    e.printStackTrace()\r\n                    FirebaseCrashlytics.getInstance().recordException(e)\r\n                    owner.lifecycleScope.launch(Dispatchers.Main) {\r\n                        snackBarManager.dismissSnack()\r\n                        delay(1000)\r\n                        reset()\r\n                        callback.call(CallbackState.UNEXPECTED_ERROR)\r\n                        Toaster.toast(\"Error al obtener servidores: ${e.message}\")\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun showServerList(actionRequest: ActionRequest, useLast: Boolean = true) {\r\n        actionRequest.owner.lifecycleScope.launch(Dispatchers.Main) {\r\n            try {\r\n                if (servers.size == 0) {\r\n                    Toaster.toast(\"Sin servidores disponibles\")\r\n                    reset()\r\n                    actionRequest.callback.call(CallbackState.NO_SERVERS)\r\n                } else {\r\n                    snackBarManager.dismissSnack()\r\n                    val names = Server.getNames(servers)\r\n                    val lasServer = PrefsUtil.lastServer\r\n                    if (PrefsUtil.rememberServer && lasServer != null && names.contains(lasServer) && useLast)\r\n                        processSelectedServer(actionRequest, names.indexOf(lasServer), lasServer, true)\r\n                    else\r\n                        MaterialDialog(actionRequest.context).safeShow {\r\n                            lifecycleOwner(actionRequest.owner)\r\n                            title(text = \"Selecciona servidor\")\r\n                            listItemsSingleChoice(items = names, initialSelection = selected) { _, index, text ->\r\n                                processSelectedServer(actionRequest, index, text.toString())\r\n                            }\r\n                            checkBoxPrompt(text = \"Recordar selección\", isCheckedDefault = PrefsUtil.rememberServer) {\r\n                                PrefsUtil.rememberServer = it\r\n                                if (!it) PrefsUtil.lastServer = null\r\n                            }\r\n                            positiveButton(text =\r\n                            when {\r\n                                actionRequest.downloadObject.addQueue -> \"AÑADIR\"\r\n                                actionRequest.type == Type.CAST -> \"CAST\"\r\n                                else -> \"INICIAR\"\r\n                            })\r\n                            onDismiss {\r\n                                if (isCancelling(actionRequest.owner)) {\r\n                                    reset()\r\n                                    actionRequest.callback.call(CallbackState.LIFECYCLE_EXPIRED)\r\n                                }\r\n                            }\r\n                            negativeButton(text = \"CANCELAR\") {\r\n                                reset()\r\n                                actionRequest.callback.call(CallbackState.USER_CANCELLED)\r\n                                if (PrefsUtil.lastServer.isNull()) PrefsUtil.rememberServer = false\r\n                            }\r\n                            setOnCancelListener {\r\n                                reset()\r\n                                actionRequest.callback.call(CallbackState.USER_CANCELLED)\r\n                                if (PrefsUtil.lastServer.isNull()) PrefsUtil.rememberServer = false\r\n                            }\r\n                        }\r\n                }\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n                Toaster.toast(\"Error al mostrar lista de servidores\")\r\n                reset()\r\n                actionRequest.callback.call(CallbackState.UNEXPECTED_ERROR)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun processSelectedServer(actionRequest: ActionRequest, index: Int, text: String, showName: Boolean = false) {\r\n        selected = index\r\n        actionRequest.owner.lifecycleScope.launch(Dispatchers.IO) {\r\n            try {\r\n                snackBarManager.showSnack(\"Obteniendo link${if (showName) \" $text\" else \"\"}...\")\r\n                val server = servers[selected].verified\r\n                snackBarManager.dismissSnack()\r\n                if (server == null && servers.size == 1) {\r\n                    Toaster.toast(\"Error en servidor, intente mas tarde\")\r\n                    actionRequest.callback.call(CallbackState.SERVER_ERROR)\r\n                } else if (server == null) {\r\n                    servers.removeAt(selected)\r\n                    selected = 0\r\n                    Toaster.toast(\"Error en servidor\")\r\n                    showServerList(actionRequest)\r\n                } else if (server.options.size == 0) {\r\n                    servers.removeAt(selected)\r\n                    selected = 0\r\n                    Toaster.toast(\"Error en servidor\")\r\n                    showServerList(actionRequest)\r\n                } else if (server.haveOptions()) {\r\n                    showOptions(actionRequest, server)\r\n                } else {\r\n                    saveLastServer(text)\r\n                    when {\r\n                        text.lowercase(Locale.ENGLISH) in listOf(\"mega d\", \"mega s\") -> {\r\n                            if (actionRequest.downloadObject.addQueue) {\r\n                                Toaster.toast(\"Servidor no disponible para añadir a cola\")\r\n                                showServerList(actionRequest)\r\n                            } else {\r\n                                try {\r\n                                    CustomTabsIntent.Builder()\r\n                                            .setToolbarColor(Color.parseColor(\"#DA252D\"))\r\n                                            .setShowTitle(true).build().launchUrl(actionRequest.context, Uri.parse(server.option.url))\r\n                                } catch (e: Exception) {\r\n                                    actionRequest.context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(server.option.url)))\r\n                                }\r\n                                actionRequest.callback.call(CallbackState.EXTERNAL_LINK)\r\n                            }\r\n                            reset()\r\n                        }\r\n                        text.endsWith(\"(WEB)\") -> {\r\n                            delay(1000)\r\n                            openWebPlayer(actionRequest.context, server.option.url!!)\r\n                            actionRequest.callback.call(CallbackState.EXTERNAL_LINK)\r\n                            reset()\r\n                        }\r\n                        else ->\r\n                            when (actionRequest.type) {\r\n                                Type.CAST -> {\r\n                                    reset()\r\n                                    actionRequest.callback.call(CallbackState.START_CAST, server.option.url)\r\n                                }\r\n                                Type.STREAM -> startStreaming(actionRequest, server.option)\r\n                                else -> startDownload(actionRequest, server.option)\r\n                            }\r\n                    }\r\n                }\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun saveLastServer(name: String) {\r\n        PrefsUtil.lastServer = name\r\n    }\r\n\r\n    private fun showOptions(actionRequest: ActionRequest, server: VideoServer) {\r\n        actionRequest.owner.lifecycleScope.launch(Dispatchers.Main) {\r\n            try {\r\n                MaterialDialog(actionRequest.context).safeShow {\r\n                    lifecycleOwner(actionRequest.owner)\r\n                    title(text = server.name)\r\n                    listItemsSingleChoice(items = Option.getNames(server.options), initialSelection = 0) { _, index, _ ->\r\n                        saveLastServer(server.name)\r\n                        when (actionRequest.type) {\r\n                            Type.CAST -> {\r\n                                reset()\r\n                                actionRequest.callback.call(CallbackState.START_CAST, server.options[index].url)\r\n                            }\r\n                            Type.STREAM -> startStreaming(actionRequest, server.options[index])\r\n                            else -> startDownload(actionRequest, server.options[index])\r\n                        }\r\n                    }\r\n                    positiveButton(text =\r\n                    when {\r\n                        actionRequest.downloadObject.addQueue -> \"AÑADIR\"\r\n                        actionRequest.type == Type.CAST -> \"CAST\"\r\n                        else -> \"INICIAR\"\r\n                    })\r\n                    negativeButton(text = \"ATRAS\") { showServerList(actionRequest, false) }\r\n                    onDismiss {\r\n                        if (isCancelling(actionRequest.owner)) {\r\n                            reset()\r\n                            actionRequest.callback.call(CallbackState.LIFECYCLE_EXPIRED)\r\n                        }\r\n                    }\r\n                    setOnCancelListener { showServerList(actionRequest, false) }\r\n                }\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n                Toaster.toast(\"Error al mostrar lista de opciones\")\r\n                showServerList(actionRequest, false)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun startStreaming(actionRequest: ActionRequest, option: Option) {\r\n        reset()\r\n        if (actionRequest.item is AnimeObject.WebInfo.AnimeChapter && actionRequest.downloadObject.addQueue) {\r\n            QueueManager.add(Uri.parse(option.url), false, actionRequest.item)\r\n        } else {\r\n            AchievementManager.onPlayChapter()\r\n            try {\r\n                if (PreferenceManager.getDefaultSharedPreferences(App.context).getString(\"player_type\", \"0\") == \"0\") {\r\n                    App.context.startActivity(\r\n                            PrefsUtil.getPlayerIntent()\r\n                                    .setData(Uri.parse(option.url))\r\n                                    .putExtra(\"title\", actionRequest.downloadObject.title)\r\n                                    .putExtra(\"headers\", option.headers?.headers?.toArray())\r\n                                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))\r\n                } else {\r\n                    val intent = Intent(Intent.ACTION_VIEW)\r\n                            .setDataAndType(Uri.parse(option.url), \"video/mp4\")\r\n                            .putExtra(\"title\", actionRequest.downloadObject.title)\r\n                            .putExtra(\"headers\", option.headers?.headers?.toArray())\r\n                            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\r\n                    App.context.startActivity(intent)\r\n                }\r\n            } catch (e: ActivityNotFoundException) {\r\n                App.context.startActivity(\r\n                        PrefsUtil.getPlayerIntent()\r\n                                .setData(Uri.parse(option.url))\r\n                                .putExtra(\"title\", actionRequest.downloadObject.title)\r\n                                .putExtra(\"headers\", option.headers?.headers?.toArray())\r\n                                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))\r\n            }\r\n        }\r\n        actionRequest.callback.call(CallbackState.START_STREAM)\r\n    }\r\n\r\n    private fun startDownload(actionRequest: ActionRequest, option: Option) {\r\n        if (BuildConfig.DEBUG) Log.e(\"Download \" + option.server, \"${option.url}\")\r\n        actionRequest.downloadObject.server = option.server ?: \"\"\r\n        actionRequest.owner.lifecycleScope.launch(Dispatchers.IO) {\r\n            if (actionRequest.item is AnimeObject.WebInfo.AnimeChapter && actionRequest.downloadObject.addQueue && !CacheDB.INSTANCE.queueDAO().isInQueue(actionRequest.item.eid\r\n                            ?: \"0\")) {\r\n                CacheDB.INSTANCE.queueDAO().add(QueueObject(Uri.fromFile(FileAccessHelper.getFile(actionRequest.item.fileName)), true, actionRequest.item))\r\n                syncData { queue() }\r\n            }\r\n            actionRequest.downloadObject.link = option.url\r\n            actionRequest.downloadObject.headers = option.headers\r\n            if (PrefsUtil.downloaderType == 0) {\r\n                CacheDB.INSTANCE.downloadsDAO().insert(actionRequest.downloadObject)\r\n                actionRequest.context.service(Intent(App.context, DownloadService::class.java).putExtra(\"eid\", actionRequest.downloadObject.eid).setData(Uri.parse(option.url)))\r\n                reset()\r\n                actionRequest.callback.call(CallbackState.START_DOWNLOAD, true)\r\n            } else {\r\n                reset()\r\n                actionRequest.callback.call(CallbackState.START_DOWNLOAD, DownloadManagerCentral.start(actionRequest.downloadObject))\r\n            }\r\n        }\r\n    }\r\n\r\n    fun startPlay(context: Context, title: String, file_name: String) {\r\n        AchievementManager.onPlayChapter()\r\n        if (PreferenceManager.getDefaultSharedPreferences(context).getString(\"player_type\", \"0\") == \"0\") {\r\n            context.startActivity(PrefsUtil.getPlayerIntent()\r\n                    .setData(FileAccessHelper.getFileUri(file_name))\r\n                    .putExtra(\"isFile\", true)\r\n                    .putExtra(\"title\", title))\r\n        } else {\r\n            val intent = Intent(Intent.ACTION_VIEW, FileAccessHelper.getDataUri(file_name))\r\n                    .setDataAndType(FileAccessHelper.getDataUri(file_name), \"video/mp4\")\r\n                    .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)\r\n                    .putExtra(\"title\", title)\r\n            context.startActivity(intent)\r\n        }\r\n    }\r\n\r\n    private suspend fun checkPreconditions(context: Context, isDownload: Boolean): CallbackState? {\r\n        if (!isDownload) return null\r\n        return if (!FileAccessHelper.isStoragePermissionEnabledAsync()) {\r\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q || PrefsUtil.downloadType == \"1\")\r\n                FileAccessHelper.openTreeChooser(context)\r\n            else\r\n                Toaster.toastLong(\"¡Se necesita permiso de almacenamiento!\")\r\n            CallbackState.MISSING_PERMISSION\r\n        } else if (!MultipleDownloadManager.isSpaceAvailable(1)) {\r\n            Toaster.toast(\"¡No hay espacio suficiente para descargar!\")\r\n            CallbackState.LOW_STORAGE\r\n        } else\r\n            null\r\n    }\r\n\r\n    private fun getSnackManager(anchorView: View?): SnackProgressBarManager? {\r\n        val view = anchorView ?: return null\r\n        return SnackProgressBarManager(view)\r\n                .setProgressBarColor(EAHelper.getThemeColor())\r\n                .setOverlayLayoutAlpha(0.4f)\r\n                .setOverlayLayoutColor(android.R.color.background_dark)\r\n    }\r\n\r\n    private fun SnackProgressBarManager?.showSnack(text: String) {\r\n        this ?: return\r\n        dismissSnack()\r\n        showProgressSnackbar(text, SnackProgressBarManager.LENGTH_INDEFINITE)\r\n    }\r\n\r\n    private fun SnackProgressBarManager?.dismissSnack() {\r\n        this?.dismissAll()\r\n    }\r\n\r\n    private fun isCancelling(owner: LifecycleOwner) = owner.lifecycle.currentState.let { it == Lifecycle.State.DESTROYED }\r\n\r\n    fun reset() {\r\n        isExecuting = false\r\n        selected = 0\r\n        snackBarManager?.dismissAll()\r\n        snackBarManager = null\r\n        servers = mutableListOf()\r\n    }\r\n\r\n    class ActionRequest(\r\n            val context: Context,\r\n            val owner: LifecycleOwner,\r\n            val type: Type,\r\n            val url: String,\r\n            val item: Any,\r\n            val downloadObject: DownloadObject,\r\n            val callback: ActionCallback\r\n    )\r\n\r\n    enum class Type {\r\n        STREAM, DOWNLOAD, CAST\r\n    }\r\n\r\n    enum class CallbackState {\r\n        OPERATION_RUNNING,\r\n        MISSING_PERMISSION,\r\n        LOW_STORAGE,\r\n        USER_CANCELLED,\r\n        LIFECYCLE_EXPIRED,\r\n        UNEXPECTED_ERROR,\r\n        NO_SERVERS,\r\n        SERVER_ERROR,\r\n        EXTERNAL_LINK,\r\n        START_DOWNLOAD,\r\n        START_STREAM,\r\n        START_CAST\r\n    }\r\n}\r\n\r\ntypealias ActionCallback = (state: FileActions.CallbackState, extra: Any?) -> Unit\r\n\r\nfun ActionCallback.call(state: FileActions.CallbackState, extra: Any? = null) = this(state, extra)\r\n\r\nval noCallback: ActionCallback = { _, _ -> }"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/FireServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.videoservers.VideoServer.Names.FIRE\nimport org.jsoup.Jsoup\n\nclass FireServer internal constructor(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"efire.php\")\n\n    override val name: String\n        get() = FIRE\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                val frame = PatternUtil.extractLink(baseLink)\n                val mediaFunc = jsoupCookies(frame).get().select(\"script\").last().outerHtml()\n                val download = Jsoup.connect(PatternUtil.extractMediaLink(mediaFunc)).get().select(\"a[href~=http://download.*]\").first().attr(\"href\")\n                VideoServer(FIRE, Option(name, null, download))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n\n        }\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/GoCDNServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.videoservers.VideoServer.Names.GOCDN\nimport org.json.JSONObject\nimport java.net.URL\n\nclass GoCDNServer(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"gocdn\")\n\n    override val name: String\n        get() = GOCDN\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                val downLink = PatternUtil.extractLink(baseLink)\n                val json = JSONObject(URL(\"https://streamium.xyz/gocdn.php?v=${downLink.substringAfterLast(\"#\")}\").readText())\n                VideoServer(GOCDN, Option(GOCDN, null, json.getString(\"file\")))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/Headers.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.os.Parcel\nimport android.os.Parcelable\nimport knf.kuma.commons.noCrash\n\nclass Headers : Parcelable {\n    var headers: MutableList<Pair<String, String>> = mutableListOf()\n    private var cookies: MutableList<Pair<String, String>> = mutableListOf()\n\n    constructor()\n\n    constructor(block: MutableList<Pair<String, String>>.() -> Unit) {\n        block(headers)\n    }\n\n    constructor(parcel: Parcel) {\n        headers = parcel.readArrayList(null)?.filterIsInstance<Pair<String, String>>() as MutableList<Pair<String, String>>\n        cookies = parcel.readArrayList(null)?.filterIsInstance<Pair<String, String>>() as MutableList<Pair<String, String>>\n    }\n\n    fun createHeadersList(): List<String> = mutableListOf<String>().apply {\n        headers.forEach {\n            add(it.first)\n            add(it.second)\n        }\n        if (cookies.size > 0) {\n            add(\"Cookie\")\n            add(getCookies())\n        }\n    }\n\n    fun createHeaders(): List<Pair<String, String>> =\n            mutableListOf<Pair<String, String>>().apply {\n                addAll(headers)\n                if (cookies.size > 0)\n                    add(\"Cookie\" to getCookies())\n            }\n\n    fun createHeadersMap(): HashMap<String, String> {\n        val map = HashMap<String, String>()\n        createHeaders().forEach {\n            map[it.first] = it.second\n        }\n        return map\n    }\n\n    fun addHeader(key: String, value: String) {\n        headers.add(Pair(key, value))\n    }\n\n    fun addCookie(key: String, value: String) {\n        cookies.add(Pair(key, value))\n    }\n\n    fun getCookies(): String {\n        val builder = StringBuilder()\n        for (pair in cookies)\n            builder.append(pair.first)\n                    .append('=')\n                    .append(pair.second)\n                    .append(\"; \")\n        return builder.toString().trim { it <= ' ' }\n    }\n\n    override fun describeContents(): Int {\n        return 0\n    }\n\n    override fun writeToParcel(parcel: Parcel, i: Int) {\n        noCrash {\n            parcel.writeList(headers as List<*>?)\n            parcel.writeList(cookies as List<*>?)\n        }\n    }\n\n    override fun toString(): String {\n        return createHeadersList().toString()\n    }\n\n    companion object CREATOR : Parcelable.Creator<Headers> {\n        override fun createFromParcel(parcel: Parcel): Headers {\n            return Headers(parcel)\n        }\n\n        override fun newArray(size: Int): Array<Headers?> {\n            return arrayOfNulls(size)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/HyperionServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.videoservers.VideoServer.Names.HYPERION\nimport org.json.JSONObject\n\nclass HyperionServer(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"server=hyperion\")\n\n    override val name: String\n        get() = HYPERION\n\n    override val videoServer: VideoServer?\n        get() {\n            val downLink = PatternUtil.extractLink(baseLink)\n            try {\n                val options = JSONObject(jsoupCookies(downLink.replace(\"embed_hyperion\", \"check\")).get().body().text())\n                val array = options.getJSONArray(\"streams\")\n                val videoServer = VideoServer(HYPERION)\n                for (i in 0 until array.length()) {\n                    try {\n                        when (array.getJSONObject(i).getInt(\"label\")) {\n                            360 -> videoServer.addOption(Option(name, \"360p\", array.getJSONObject(i).getString(\"file\")))\n                            480 -> videoServer.addOption(Option(name, \"480p\", array.getJSONObject(i).getString(\"file\")))\n                            720 -> videoServer.addOption(Option(name, \"720p\", array.getJSONObject(i).getString(\"file\")))\n                        }\n                    } catch (e: Exception) {\n                        e.printStackTrace()\n                    }\n\n                }\n                try {\n                    videoServer.addOption(Option(name, \"Direct\", options.getString(\"direct\")))\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n\n                return videoServer\n            } catch (e: Exception) {\n                return null\n            }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/IzanagiServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.videoservers.VideoServer.Names.IZANAGI\nimport org.json.JSONObject\n\nclass IzanagiServer(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"s=izanagi\")\n\n    override val name: String\n        get() = IZANAGI\n\n    override val videoServer: VideoServer?\n        get() {\n            val downLink = PatternUtil.extractLink(baseLink)\n            return try {\n                val link = JSONObject(jsoupCookies(downLink.replace(\"embed\", \"check\")).get().body().text()).getString(\"file\").replace(\"\\\\\", \"\")\n                VideoServer(IZANAGI,\n                        mutableListOf(\n                                Option(name, null, link),\n                                Option(name, null, link.replace(\"/\".toRegex(), \"//\").replace(\":////\", \"://\"))\n                        ))\n            } catch (e: Exception) {\n                null\n            }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/KDecoder.kt",
    "content": "package knf.kuma.videoservers\n\nclass KDecoder {\n    companion object {\n        fun decodeMango(url: String, mask: Int): String {\n            val key = \"=/+9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA\"\n            val result = StringBuffer()\n            val u = url.replace(\"[^A-Za-z0-9+/=]\".toRegex(), \"\")\n            var idx = 0\n            while (idx < u.length) {\n                val a = key.indexOf(u.substring(idx, idx + 1))\n                idx++\n                val b = key.indexOf(u.substring(idx, idx + 1))\n                idx++\n                val c = key.indexOf(u.substring(idx, idx + 1))\n                idx++\n                val d = key.indexOf(u.substring(idx, idx + 1))\n                idx++\n                val s1 = a shl 0x2 or (b shr 0x4) xor mask\n                result.append(Character.valueOf(s1.toChar()))\n                val s2 = b and 0xf shl 0x4 or (c shr 0x2)\n                if (c != 0x40) {\n                    result.append(Character.valueOf(s2.toChar()))\n                }\n                val s3 = c and 0x3 shl 0x6 or d\n                if (d != 0x40) {\n                    result.append(Character.valueOf(s3.toChar()))\n                }\n            }\n            return result.toString()\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/MP4UploadServer.kt",
    "content": "package knf.kuma.videoservers\r\n\r\nimport android.content.Context\r\nimport knf.kuma.commons.PatternUtil\r\nimport knf.kuma.commons.jsoupCookies\r\nimport knf.kuma.videoservers.VideoServer.Names.MP4UPLOAD\r\nimport org.json.JSONObject\r\nimport java.util.regex.Pattern\r\n\r\nclass MP4UploadServer(context: Context, baseLink: String) : Server(context, baseLink) {\r\n\r\n    override val isValid: Boolean\r\n        get() = baseLink.contains(\"s=mp4upload\")\r\n\r\n    override val name: String\r\n        get() = MP4UPLOAD\r\n\r\n    override val videoServer: VideoServer?\r\n        get() {\r\n            return try {\r\n                val downLink = PatternUtil.extractLink(baseLink)\r\n                val link = JSONObject(jsoupCookies(downLink.replace(\"embed\", \"check\")).get().body().text()).getString(\"file\")\r\n                VideoServer(MP4UPLOAD, Option(name, null, link))\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n                null\r\n            }\r\n\r\n        }\r\n\r\n\r\n    private fun unpack(source: String): String? {\r\n        var decoded: String? = null\r\n        val pat = Pattern.compile(\"eval(.+),(\\\\d+),(\\\\d+),'(.+?)'\")\r\n        val m = pat.matcher(source)\r\n        try {\r\n            m.find()\r\n            var p = m.group(1).replace(\"\\\\\\\\\".toRegex(), \"\")\r\n            val a = Integer.parseInt(m.group(2))\r\n            var c = Integer.parseInt(m.group(3))\r\n            val k = m.group(4).split(\"\\\\|\".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()\r\n\r\n            while (c != 0) {\r\n                c--\r\n                if (k[c].isNotEmpty())\r\n                    p = p.replace((\"\\\\b\" + baseT(c, a) + \"\\\\b\").toRegex(), k[c])\r\n            }\r\n\r\n            decoded = p\r\n        } catch (e: Exception) {\r\n            e.printStackTrace()\r\n        }\r\n\r\n        return decoded\r\n    }\r\n\r\n    private fun baseT(num: Int, radix: Int): String {\r\n        var edRadix = radix\r\n        var mNum = num\r\n        val digits = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\".toCharArray()\r\n\r\n        if (edRadix < 2 || edRadix > 62) {\r\n            edRadix = 10\r\n        }\r\n        if (mNum < edRadix) {\r\n            return \"\" + digits[mNum]\r\n        }\r\n        var hayMas = true\r\n        var cadena = \"\"\r\n        while (hayMas) {\r\n            cadena = digits[mNum % edRadix] + cadena\r\n            mNum /= edRadix\r\n            if (mNum <= edRadix) {\r\n                hayMas = false\r\n                cadena = digits[mNum] + cadena\r\n            }\r\n        }\r\n        return cadena\r\n    }\r\n}\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/MangoServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.videoservers.VideoServer.Names.MANGO\nimport org.jsoup.Jsoup\nimport java.util.regex.Pattern\n\nclass MangoServer(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"streamango.com\") && !baseLink.contains(\"%\")\n\n    override val name: String\n        get() = MANGO\n\n    override val videoServer: VideoServer?\n        get() {\n            try {\n                val downLink = PatternUtil.extractLink(baseLink)\n                val html = Jsoup.connect(downLink).get().html()\n                val matcher = Pattern.compile(\"type:\\\"video/mp4\\\",src:d\\\\('([^']+)',(\\\\d+)\\\\)\").matcher(html)\n                matcher.find()\n                val hash = matcher.group(1)\n                val key = Integer.parseInt(matcher.group(2))\n                var file = KDecoder.decodeMango(hash, key)\n                if (file.isNullOrBlank())\n                    return null\n                if (file.startsWith(\"//\"))\n                    file = file.replaceFirst(\"//\".toRegex(), \"https://\")\n                return VideoServer(MANGO, Option(name, null, file))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                return null\n            }\n\n        }\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/MegaServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.urlDecode\nimport knf.kuma.videoservers.VideoServer.Names.MEGA\n\nclass MegaServer(context: Context, baseLink: String) : Server(context, baseLink) {\n    private val DOWNLOAD = \"D\"\n    private val STREAM = \"S\"\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"mega.nz\")\n\n    override val name: String\n        get() = \"$MEGA $type\"\n\n    private val type: String\n        get() = if (baseLink.contains(\"mega.nz\") && !baseLink.contains(\"embed\"))\n            DOWNLOAD\n        else\n            STREAM\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                if (type == STREAM) {\n                    VideoServer(name, Option(name, null, PatternUtil.extractLink(baseLink)))\n                } else\n                    VideoServer(name, Option(name, null, urlDecode(baseLink)))\n            } catch (e: Exception) {\n                null\n            }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/NatsukiServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.videoservers.VideoServer.Names.NATSUKI\nimport org.json.JSONObject\n\nclass NatsukiServer internal constructor(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"s=natsuki\")\n\n    override val name: String\n        get() = NATSUKI\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                val downLink = PatternUtil.extractLink(baseLink)\n                val link = JSONObject(jsoupCookies(downLink.replace(\"embed\", \"check\")).get().body().text()).getString(\"file\")\n                VideoServer(NATSUKI, Option(name, null, link))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/OkruServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.iterator\nimport knf.kuma.videoservers.VideoServer.Names.OKRU\nimport org.apache.commons.text.StringEscapeUtils\nimport org.json.JSONObject\nimport org.jsoup.Jsoup\nimport org.jsoup.helper.HttpConnection\n\nclass OkruServer(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"ok.ru\")\n\n    override val name: String\n        get() = OKRU\n\n    override val videoServer: VideoServer?\n        get() {\n            try {\n                val downLink = PatternUtil.extractLink(baseLink)\n                val (source) = Regex(\"data-options=\\\"(.*?)\\\"\").find(Jsoup.connect(downLink).get().html())?.destructured!!\n                val jsonText = StringEscapeUtils.unescapeHtml4(source)\n                val videos = JSONObject(JSONObject(jsonText).getJSONObject(\"flashvars\").getString(\"metadata\")).getJSONArray(\"videos\")\n                val options = mutableListOf<Option>()\n                for(video in videos){\n                    val url = video.getString(\"url\")\n                    val name = when(video.getString(\"name\")){\n                        \"mobile\" -> \"144p\"\n                        \"lowest\" -> \"240p\"\n                        \"low\" -> \"360p\"\n                        \"sd\" -> \"480p\"\n                        \"hd\" -> \"720p\"\n                        \"full\" -> \"1080p\"\n                        \"quad\" -> \"2000p\"\n                        \"ultra\" -> \"4000p\"\n                        else -> \"Default\"\n                    }\n                    options.add(Option(this.name, name, url, Headers { add(\"User-Agent\" to HttpConnection.DEFAULT_UA) }))//mapOf(\"User-agent\" to userAgent)\n                }\n                check(options.isNotEmpty())\n                return VideoServer(OKRU, options, true)\n            } catch (e: Exception) {\n                e.printStackTrace()\n                return null\n            }\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/Option.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.os.Parcel\nimport android.os.Parcelable\n\nopen class Option : Parcelable {\n    var server: String? = null\n    var name: String? = null\n    var url: String? = null\n    var headers: Headers? = null\n\n    /**\n     * Crea una opcion de descarga\n     *\n     * @param server  Nombre del servidor de donde viene la opcion [VideoServer.Names]\n     * @param name    Nombre de la opcion, null si es una opcion unica\n     * @param url     Url de la opcion\n     * @param headers Headers requeridos por la opcion\n     */\n    constructor(server: String, name: String?, url: String?, headers: Headers?) {\n        if (url == null || url.trim { it <= ' ' }.isEmpty())\n            throw IllegalStateException(\"Url is not valid!\")\n        this.server = server\n        this.name = name\n        this.url = url\n        this.headers = headers\n    }\n\n    constructor(server: String, name: String?, url: String?) {\n        if (url == null || url.trim { it <= ' ' }.isEmpty())\n            throw IllegalStateException(\"Url is not valid!\")\n        this.server = server\n        this.name = name\n        this.url = url\n    }\n\n    protected constructor(`in`: Parcel) {\n        server = `in`.readString()\n        name = `in`.readString()\n        url = `in`.readString()\n        headers = `in`.readParcelable(Headers::class.java.classLoader)\n    }\n\n    override fun describeContents(): Int {\n        return 0\n    }\n\n    override fun writeToParcel(dest: Parcel, flags: Int) {\n        dest.writeString(server)\n        dest.writeString(name)\n        dest.writeString(url)\n        dest.writeParcelable(headers, flags)\n    }\n\n    companion object {\n        @JvmField\n        val CREATOR: Parcelable.Creator<Option> = object : Parcelable.Creator<Option> {\n            override fun createFromParcel(parcel: Parcel): Option {\n                return Option(parcel)\n            }\n\n            override fun newArray(size: Int): Array<Option?> {\n                return arrayOfNulls(size)\n            }\n        }\n\n        fun getNames(options: MutableList<Option>): MutableList<String> {\n            val names = ArrayList<String>()\n            for (option in options)\n                names.add(option.name ?: \"\")\n            return names\n        }\n\n        fun getLinks(options: MutableList<Option>): MutableList<String> {\n            val links = ArrayList<String>()\n            for (option in options)\n                links.add(option.name ?: \"\")\n            return links\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/RVServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.videoservers.VideoServer.Names.RV\nimport org.jsoup.Jsoup\n\nclass RVServer(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"rapidvideo\") || baseLink.contains(\"&server=rv\")\n\n    override val name: String\n        get() = RV\n\n    override val videoServer: VideoServer?\n        get() {\n            try {\n                var downLink = PatternUtil.extractLink(baseLink).replace(\"&q=720p|&q=480p|&q=360p\".toRegex(), \"\")\n                if (downLink.contains(\"&server=rv\"))\n                    downLink = PatternUtil.getRapidLink(downLink)\n                val needPost = Jsoup.connect(downLink).get().html().contains(\"Please click on this button to open this video\")\n                val videoServer = VideoServer(RV)\n                try {\n                    val jsoup720 = PatternUtil.getRapidVideoLink(getHtml(\"$downLink&q=720p\", needPost))\n                    videoServer.addOption(Option(name, \"720p\", jsoup720))\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n\n                try {\n                    val jsoup480 = PatternUtil.getRapidVideoLink(getHtml(\"$downLink&q=480p\", needPost))\n                    videoServer.addOption(Option(name, \"480p\", jsoup480))\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n\n                try {\n                    val jsoup360 = PatternUtil.getRapidVideoLink(getHtml(\"$downLink&q=360p\", needPost))\n                    videoServer.addOption(Option(name, \"360p\", jsoup360))\n                } catch (e: Exception) {\n                    e.printStackTrace()\n                }\n\n                return if (videoServer.options.size > 0) videoServer else null\n            } catch (e: Exception) {\n                e.printStackTrace()\n                return null\n            }\n\n        }\n\n    private fun getHtml(link: String, needPost: Boolean): String {\n        return try {\n            if (needPost)\n                Jsoup.connect(\"$link#\").data(\"block\", \"1\").post().html()\n            else\n                Jsoup.connect(link).get().html()\n        } catch (e: Exception) {\n            \"\"\n        }\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/SBServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.retry\nimport knf.kuma.uagen.randomUA\nimport knf.kuma.videoservers.VideoServer.Names.SBVIDEO\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.runBlocking\nimport org.jsoup.Jsoup\n\nclass SBServer internal constructor(context: Context, baseLink: String) :\n    Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"sbvideo.net\") || baseLink.contains(\"playersb.com\") || baseLink.contains(\n            \"embedsb.com\"\n        )\n\n    override val name: String\n        get() = SBVIDEO\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                val downLink = PatternUtil.extractLink(baseLink).replace(\"/e/\", \"/d/\")\n                val userAgent = randomUA()\n                val html = Jsoup.connect(downLink).userAgent(userAgent).get().html()\n                val (videoId, type, hash) = Regex(\"download_video\\\\('(\\\\w+)','([nhl])','([\\\\w-]+)'\\\\)\").find(\n                    html\n                )?.destructured ?: throw IllegalStateException()\n                val downloadLink =\n                    \"${downLink.substringBeforeLast(\"/\")}/dl?op=download_orig&id=$videoId&mode=$type&hash=$hash\"\n                val tryCode = {\n                    val downCode =\n                        runBlocking(Dispatchers.Main) { Unpacker.getHtml(context, downloadLink).html }\n                    val downDoc = Jsoup.parse(downCode)\n                    val fLink = downDoc.select(\"a:contains(Download Link)\").attr(\"href\")\n                    check(fLink.isNotBlank())\n                    fLink\n                }\n                val directLink = retry(3, tryCode)\n                VideoServer(SBVIDEO, Option(name, null, directLink))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/Server.kt",
    "content": "package knf.kuma.videoservers\r\n\r\nimport android.content.Context\r\nimport android.os.Handler\r\nimport android.os.Looper\r\nimport android.util.Log\r\nimport android.webkit.JavascriptInterface\r\nimport android.webkit.WebView\r\nimport android.webkit.WebViewClient\r\nimport org.jsoup.Jsoup\r\nimport kotlin.coroutines.resume\r\nimport kotlin.coroutines.suspendCoroutine\r\n\r\nabstract class Server(internal var context: Context, internal var baseLink: String) : Comparable<Server> {\r\n    private var server: VideoServer? = null\r\n\r\n    abstract val isValid: Boolean\r\n\r\n    abstract val name: String\r\n\r\n    abstract val videoServer: VideoServer?\r\n\r\n    open val canStream: Boolean = true\r\n\r\n    open val canDownload: Boolean = canStream\r\n\r\n    val verified: VideoServer?\r\n        get() {\r\n            if (server == null)\r\n                server = verify(videoServer)\r\n            return server\r\n        }\r\n\r\n    protected suspend fun getFinishedHtml(link: String): String {\r\n        return suspendCoroutine {\r\n            WebView(context).apply {\r\n                settings.apply {\r\n                    javaScriptEnabled = true\r\n                }\r\n                addJavascriptInterface(object : ZippyServer.ZippyJSInterface() {\r\n                    @JavascriptInterface\r\n                    override fun printHtml(string: String) {\r\n                        it.resume(string)\r\n                    }\r\n                }, \"HtmlViewer\")\r\n                val handler = Handler(Looper.getMainLooper())\r\n                var isExecuted = false\r\n                val runnable = Runnable {\r\n                    if (!isExecuted) {\r\n                        isExecuted = true\r\n                        loadUrl(\r\n                            \"javascript:window.HtmlViewer.printHtml\" +\r\n                                    \"('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');\"\r\n                        )\r\n                    }\r\n                }\r\n                handler.postDelayed(runnable, 5000)\r\n                webViewClient = object : WebViewClient() {\r\n                    override fun onPageFinished(view: WebView?, url: String?) {\r\n                        handler.removeCallbacks(runnable)\r\n                        runnable.run()\r\n                    }\r\n                }\r\n                loadUrl(link)\r\n            }\r\n        }\r\n    }\r\n\r\n    private fun verify(videoServer: VideoServer?): VideoServer? {\r\n        if (videoServer == null)\r\n            return null\r\n        if (videoServer.skipVerification) return videoServer\r\n        for (option in ArrayList(videoServer.options))\r\n            try {\r\n                val request = Jsoup.connect(option.url ?: \"\")\r\n                    .ignoreHttpErrors(true)\r\n                    .ignoreContentType(true).apply {\r\n                        if (option.headers != null) {\r\n                            for (pair in option.headers?.createHeaders() ?: arrayListOf()) {\r\n                                header(pair.first, pair.second)\r\n                            }\r\n                        }\r\n                    }\r\n                val response = request.execute()\r\n                if (response.statusCode() > 300 || response.statusCode() < 200) {\r\n                    Log.e(\"Remove Option\", \"Server: \" + option.server + \"\\nUrl: \" + option.url + \"\\nCode: \" + response.statusCode())\r\n                    videoServer.options.remove(option)\r\n                }\r\n            } catch (e: Exception) {\r\n                e.printStackTrace()\r\n                videoServer.options.remove(option)\r\n            }\r\n\r\n        return if (videoServer.options.size == 0) null else videoServer\r\n    }\r\n\r\n    override fun compareTo(other: Server): Int {\r\n        return name.compareTo(other.name)\r\n    }\r\n\r\n    companion object {\r\n        const val TIMEOUT = 10000L\r\n\r\n        private fun getServers(context: Context, base: String): List<Server> {\r\n            return listOf(\r\n                FireServer(context, base),\r\n                NatsukiServer(context, base),\r\n                GoCDNServer(context, base),\r\n                StapeServer(context, base),\r\n                StreamWishServer(context, base),\r\n                //SBServer(context, base),\r\n                VeryStreamServer(context, base),\r\n                FembedServer(context, base),\r\n                FenixServer(context, base),\r\n                HyperionServer(context, base),\r\n                IzanagiServer(context, base),\r\n                MangoServer(context, base),\r\n                MegaServer(context, base),\r\n                OkruServer(context, base),\r\n                RVServer(context, base),\r\n                ZippyServer(context, base),\r\n                YUServer(context, base),\r\n                MP4UploadServer(context, base)\r\n            )\r\n        }\r\n\r\n        fun check(context: Context, base: String): Server? {\r\n            for (server in getServers(context, base)) {\r\n                if (server.isValid)\r\n                    return server\r\n            }\r\n            return null\r\n        }\r\n\r\n        fun getNames(servers: MutableList<Server>): MutableList<String> {\r\n            val names = ArrayList<String>()\r\n            for (server in servers) {\r\n                names.add(server.name)\r\n            }\r\n            return names\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/ServersFactory.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.annotation.SuppressLint\nimport android.app.PendingIntent\nimport android.content.ActivityNotFoundException\nimport android.content.Context\nimport android.content.Intent\nimport android.graphics.Color\nimport android.net.Uri\nimport android.os.Build\nimport android.util.Log\nimport android.view.View\nimport androidx.browser.customtabs.CustomTabsIntent\nimport androidx.preference.PreferenceManager\nimport com.afollestad.materialdialogs.MaterialDialog\nimport com.afollestad.materialdialogs.checkbox.checkBoxPrompt\nimport com.afollestad.materialdialogs.list.listItems\nimport com.afollestad.materialdialogs.list.listItemsSingleChoice\nimport knf.kuma.App\nimport knf.kuma.BuildConfig\nimport knf.kuma.achievements.AchievementManager\nimport knf.kuma.animeinfo.ktx.fileName\nimport knf.kuma.backup.firestore.syncData\nimport knf.kuma.commons.CastUtil\nimport knf.kuma.commons.EAHelper\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.commons.doOnUIGlobal\nimport knf.kuma.commons.isNull\nimport knf.kuma.commons.iterator\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.commons.safeShow\nimport knf.kuma.commons.showProgressSnackbar\nimport knf.kuma.commons.showSnackbar\nimport knf.kuma.commons.urlDecode\nimport knf.kuma.custom.exceptions.EJNFException\nimport knf.kuma.custom.snackbar.SnackProgressBarManager\nimport knf.kuma.database.CacheDB\nimport knf.kuma.download.DownloadManagerCentral\nimport knf.kuma.download.DownloadService\nimport knf.kuma.download.FileAccessHelper\nimport knf.kuma.download.MultipleDownloadManager\nimport knf.kuma.download.service\nimport knf.kuma.player.openWebPlayer\nimport knf.kuma.pojos.AnimeObject\nimport knf.kuma.pojos.DownloadObject\nimport knf.kuma.pojos.QueueObject\nimport knf.kuma.queue.QueueManager\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport org.jetbrains.anko.doAsync\nimport org.json.JSONObject\nimport xdroid.toaster.Toaster\nimport java.util.Locale\nimport kotlin.math.abs\n\n\nclass ServersFactory {\n    private var context: Context\n    private var url: String\n    private var chapter: AnimeObject.WebInfo.AnimeChapter? = null\n    private var downloadObject: DownloadObject\n    private var isStream: Boolean = false\n    private var isCasting: Boolean = false\n    private var serversInterface: ServersInterface\n    private var snackBarManager: SnackProgressBarManager? = null\n    private var servers: MutableList<Server> = ArrayList()\n    private var selected = 0\n\n    private constructor(context: Context, url: String, chapter: AnimeObject.WebInfo.AnimeChapter, isStream: Boolean, addQueue: Boolean, serversInterface: ServersInterface) {\n        this.context = context\n        this.url = url\n        this.chapter = chapter\n        this.downloadObject = DownloadObject.fromChapter(chapter, addQueue)\n        this.isStream = isStream\n        this.isCasting = isStream && CastUtil.get().connected()\n        this.serversInterface = serversInterface\n    }\n\n    private constructor(context: Context, url: String, downloadObject: DownloadObject, isStream: Boolean, serversInterface: ServersInterface) {\n        this.context = context\n        this.url = url\n        this.downloadObject = downloadObject\n        this.isStream = isStream\n        this.isCasting = isStream && CastUtil.get().connected()\n        this.serversInterface = serversInterface\n    }\n\n    private fun saveLastServer(name: String) {\n        PrefsUtil.lastServer = name\n    }\n\n    private fun processSelectedServer(index: Int, text: String, showName: Boolean = false) {\n        selected = index\n        doAsync {\n            try {\n                showSnack(\"Obteniendo link${if (showName) \" $text\" else \"\"}...\")\n                val server = servers[selected].verified\n                dismissSnack()\n                if (server == null && servers.size == 1) {\n                    Toaster.toast(\"Error en servidor, intente mas tarde\")\n                    callOnFinish(false, false)\n                } else if (server == null) {\n                    servers.removeAt(selected)\n                    selected = 0\n                    Toaster.toast(\"Error en servidor\")\n                    showServerList()\n                } else if (server.options.size == 0) {\n                    servers.removeAt(selected)\n                    selected = 0\n                    Toaster.toast(\"Error en servidor\")\n                    showServerList()\n                } else if (server.haveOptions()) {\n                    showOptions(server, isCasting)\n                } else {\n                    saveLastServer(text)\n                    when (text.lowercase(Locale.getDefault())) {\n                        \"mega d\", \"mega s\" -> {\n                            try {\n                                CustomTabsIntent.Builder()\n                                    .setToolbarColor(Color.parseColor(\"#DA252D\"))\n                                    .setShowTitle(true).build()\n                                    .launchUrl(context, Uri.parse(server.option.url))\n                            } catch (e: Exception) {\n                                this@ServersFactory.context.startActivity(\n                                    Intent(\n                                        Intent.ACTION_VIEW,\n                                        Uri.parse(server.option.url)\n                                    )\n                                )\n                            }\n                            callOnFinish(false, false)\n                        }\n                        else ->\n                            when {\n                                isCasting -> callOnCast(server.option.url)\n                                isStream -> startStreaming(server.option, servers[selected] is WebServer)\n                                else -> startDownload(server.option)\n                            }\n                    }\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n    }\n\n    private fun showServerList(useLast: Boolean = true) {\n        doOnUIGlobal {\n            try {\n                if (servers.size == 0) {\n                    Toaster.toast(\"Sin servidores disponibles\")\n                    callOnFinish(false, false)\n                } else {\n                    dismissSnack()\n                    val names = Server.getNames(servers)\n                    val lasServer = PrefsUtil.lastServer\n                    if (PrefsUtil.rememberServer && lasServer != null && names.contains(lasServer) && useLast)\n                        processSelectedServer(names.indexOf(lasServer), lasServer, true)\n                    else\n                        MaterialDialog(this@ServersFactory.context).safeShow {\n                            title(text = \"Selecciona servidor\")\n                            listItemsSingleChoice(items = names, initialSelection = selected) { _, index, text ->\n                                processSelectedServer(index, text.toString())\n                            }\n                            checkBoxPrompt(text = \"Recordar selección\", isCheckedDefault = PrefsUtil.rememberServer) {\n                                PrefsUtil.rememberServer = it\n                                if (!it) PrefsUtil.lastServer = null\n                            }\n                            positiveButton(text =\n                            when {\n                                downloadObject.addQueue -> \"AÑADIR\"\n                                isCasting -> \"CAST\"\n                                else -> \"INICIAR\"\n                            })\n                            negativeButton(text = \"CANCELAR\") {\n                                callOnFinish(false, false)\n                                if (PrefsUtil.lastServer.isNull()) PrefsUtil.rememberServer = false\n                            }\n                            setOnCancelListener {\n                                callOnFinish(false, false)\n                                if (PrefsUtil.lastServer.isNull()) PrefsUtil.rememberServer = false\n                            }\n                        }\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                Toaster.toast(\"Error al mostrar lista de servidores\")\n                callOnFinish(false, false)\n            }\n        }\n\n    }\n\n    private fun showOptions(server: VideoServer, isCast: Boolean) {\n        doOnUIGlobal {\n            try {\n                MaterialDialog(this@ServersFactory.context).safeShow {\n                    title(text = server.name)\n                    listItemsSingleChoice(items = Option.getNames(server.options), initialSelection = 0) { _, index, _ ->\n                        saveLastServer(server.name)\n                        when {\n                            isCast -> callOnCast(server.options[index].url)\n                            isStream -> startStreaming(server.options[index], false)\n                            else -> startDownload(server.options[index])\n                        }\n                    }\n                    positiveButton(text =\n                    when {\n                        downloadObject.addQueue -> \"AÑADIR\"\n                        isCasting -> \"CAST\"\n                        else -> \"INICIAR\"\n                    })\n                    negativeButton(text = \"ATRAS\") { showServerList(false) }\n                    setOnCancelListener { showServerList(false) }\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                Toaster.toast(\"Error al mostrar lista de opciones\")\n                showServerList(false)\n            }\n        }\n    }\n\n    fun start() {\n        try {\n            serversInterface.onProgressIndicator(true)\n            showSnack(\"Obteniendo servidores...\")\n            val main = jsoupCookies(url).get()\n            val servers = ArrayList<Server>()\n            val sScript = main.select(\"script\")\n            var j = \"\"\n            for (element in sScript) {\n                val sEl = element.outerHtml()\n                if (\"\\\\{\\\"[SUBLAT]+\\\":\\\\[.*\\\\]\\\\}\".toRegex().containsMatchIn(sEl)) {\n                    j = sEl\n                    break\n                }\n            }\n            val jsonObject = JSONObject(\"\\\\{\\\"[SUBLAT]+\\\":\\\\[.*\\\\]\\\\}\".toRegex().find(j)?.value\n                    ?: throw EJNFException())\n            if (jsonObject.length() > 1) {\n                doOnUIGlobal {\n                    MaterialDialog(context).safeShow {\n                        listItems(items = listOf(\"Subtitulado\", \"Latino\")) { _, index, _ ->\n                            doAsync {\n                                val downloads = main.select(\"table.RTbl.Dwnl tr:contains(${if (index == 0) \"SUB\" else \"LAT\"}) a.Button.Sm.fa-download\")\n                                for (e in downloads) {\n                                    var z = e.attr(\"href\")\n                                    z = z.substring(z.lastIndexOf(\"http\"))\n                                    val server = Server.check(context, z)\n                                    if (server != null)\n                                        servers.add(server)\n                                }\n                                val jsonArray =\n                                        when (index) {\n                                            1 -> jsonObject.getJSONArray(\"LAT\")\n                                            else -> jsonObject.getJSONArray(\"SUB\")\n                                        }\n                                for (baseLink in jsonArray) {\n                                    val server = Server.check(context, baseLink.optString(\"code\"))\n                                    if (server != null) {\n                                        try {\n                                            var skip = false\n                                            servers.forEach {\n                                                if (it.name == server.name) {\n                                                    skip = true\n                                                    return@forEach\n                                                }\n                                            }\n                                            if (!skip)\n                                                servers.add(server)\n                                        } catch (e: Exception) {\n                                            e.printStackTrace()\n                                        }\n                                    } else if (!baseLink.optString(\"code\").contains(\"linkinpork\")) {\n                                        servers.add(WebServer(context, baseLink.optString(\"code\"), baseLink.optString(\"title\")))\n                                    }\n                                }\n                                servers.sort()\n                                this@ServersFactory.servers = servers\n                                showServerList()\n                            }\n                        }\n                        setOnCancelListener { callOnFinish(false, false) }\n                    }\n                }\n            } else {\n                val downloads = main.select(\"table.RTbl.Dwnl tr:contains(SUB) a.Button.Sm.fa-download\")\n                for (e in downloads) {\n                    var z = e.attr(\"href\")\n                    z = urlDecode(z.substring(z.lastIndexOf(\"http\")))\n                    val server = Server.check(context, z)\n                    if (server != null)\n                        servers.add(server)\n                }\n                val jsonArray = jsonObject.getJSONArray(if (jsonObject.has(\"SUB\")) \"SUB\" else \"LAT\")\n                for (baseLink in jsonArray) {\n                    val server = Server.check(context, baseLink.optString(\"code\"))\n                    if (server != null) {\n                        try {\n                            var skip = false\n                            servers.forEach {\n                                if (it.name == server.name) {\n                                    skip = true\n                                    return@forEach\n                                }\n                            }\n                            if (!skip)\n                                servers.add(server)\n                        } catch (e: Exception) {\n                            e.printStackTrace()\n                        }\n                    } else if (!baseLink.optString(\"code\").contains(\"linkinpork\")) {\n                        servers.add(WebServer(context, baseLink.optString(\"code\"), baseLink.optString(\"title\")))\n                    }\n                }\n                servers.sort()\n                this@ServersFactory.servers = servers\n                showServerList()\n            }\n            this.servers = servers.filter {\n                if (downloadObject.addQueue || isCasting || !isStream) {\n                    it.canDownload\n                } else {\n                    true\n                }\n            }.toMutableList()\n        } catch (e: EJNFException) {\n            e.printStackTrace()\n            this@ServersFactory.servers = ArrayList()\n            Toaster.toast(\"Sin json de capitulos\")\n            callOnFinish(false, false)\n        } catch (e: Exception) {\n            e.printStackTrace()\n            this@ServersFactory.servers = ArrayList()\n            callOnFinish(false, false)\n        }\n    }\n\n    private fun startStreaming(option: Option, isWeb: Boolean) {\n        if (chapter != null && downloadObject.addQueue) {\n            QueueManager.add(Uri.parse(option.url), false, chapter)\n        } else {\n            AchievementManager.onPlayChapter()\n            try {\n                if (isWeb) {\n                    openWebPlayer(context, option.url!!)\n                } else if (PreferenceManager.getDefaultSharedPreferences(App.context).getString(\"player_type\", \"0\") == \"0\") {\n                    App.context.startActivity(\n                            PrefsUtil.getPlayerIntent()\n                                    .setData(Uri.parse(option.url))\n                                    .putExtra(\"title\", downloadObject.title)\n                                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))\n                } else {\n                    val intent = Intent(Intent.ACTION_VIEW)\n                            .setDataAndType(Uri.parse(option.url), \"video/mp4\")\n                            .putExtra(\"title\", downloadObject.title)\n                            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n                    App.context.startActivity(intent)\n                }\n            } catch (e: ActivityNotFoundException) {\n                App.context.startActivity(\n                        PrefsUtil.getPlayerIntent()\n                                .setData(Uri.parse(option.url))\n                                .putExtra(\"title\", downloadObject.title)\n                                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))\n            }\n        }\n        callOnFinish(false, true)\n    }\n\n    private fun startDownload(option: Option) {\n        doAsync{\n            if (BuildConfig.DEBUG) Log.e(\"Download \" + option.server, \"${option.url}\")\n            downloadObject.server = option.server ?: \"\"\n            if (chapter != null && CacheDB.INSTANCE.queueDAO().isInQueue(chapter?.eid ?: \"0\")) {\n                CacheDB.INSTANCE.queueDAO().add(QueueObject(Uri.fromFile(FileAccessHelper.getFile(chapter?.fileName\n                        ?: \"null\")), true, chapter))\n                syncData { queue() }\n            }\n            downloadObject.link = option.url\n            downloadObject.headers = option.headers\n            if (PrefsUtil.downloaderType == 0) {\n                CacheDB.INSTANCE.downloadsDAO().insert(downloadObject)\n                doOnUIGlobal {\n                    context.service(Intent(App.context, DownloadService::class.java).putExtra(\"eid\", downloadObject.eid).setData(Uri.parse(option.url)))\n                    callOnFinish(true, true)\n                }\n            } else\n                GlobalScope.launch(Dispatchers.Main) {\n                    callOnFinish(true, withContext(Dispatchers.IO) { DownloadManagerCentral.start(downloadObject) })\n                }\n        }\n    }\n\n    private fun callOnFinish(started: Boolean, success: Boolean) {\n        serversInterface.onProgressIndicator(false)\n        dismissSnack()\n        clear()\n        serversInterface.onFinish(started, success)\n    }\n\n    private fun callOnCast(url: String?) {\n        serversInterface.onProgressIndicator(false)\n        dismissSnack()\n        clear()\n        serversInterface.onCast(url)\n    }\n\n    private fun getSnackManager(): SnackProgressBarManager? {\n        val view = serversInterface.getView() ?: return null\n        return snackBarManager ?: SnackProgressBarManager(view)\n                .setProgressBarColor(EAHelper.getThemeColor())\n                .setOverlayLayoutAlpha(0.4f)\n                .setOverlayLayoutColor(android.R.color.background_dark).also { snackBarManager = it }\n    }\n\n    private fun showSnack(text: String) {\n        dismissSnack()\n        //snackbar = serversInterface.getView()?.showSnackbar(text, duration = Snackbar.LENGTH_INDEFINITE)\n        getSnackManager()?.showProgressSnackbar(text, SnackProgressBarManager.LENGTH_INDEFINITE)\n    }\n\n    private fun dismissSnack() {\n        //snackbar?.dismiss()\n        getSnackManager()?.dismissAll()\n    }\n\n    interface ServersInterface {\n        fun onFinish(started: Boolean, success: Boolean)\n\n        fun onCast(url: String?)\n\n        fun onProgressIndicator(boolean: Boolean)\n\n        fun getView(): View?\n    }\n\n\n    companion object {\n        @SuppressLint(\"StaticFieldLeak\")\n        private var INSTANCE: ServersFactory? = null\n\n        private fun isRunning(): Boolean = INSTANCE != null\n\n        fun start(\n                context: Context,\n                url: String,\n                chapter: AnimeObject.WebInfo.AnimeChapter,\n                isStream: Boolean = false,\n                addQueue: Boolean = false,\n                serversInterface: ServersInterface\n        ) {\n            if (!isRunning())\n                GlobalScope.launch(Dispatchers.Main) {\n                    INSTANCE = if (isStream)\n                        ServersFactory(context, url, chapter, isStream, addQueue, serversInterface).also { doAsync { it.start() } }\n                    else {\n                        if (!FileAccessHelper.isStoragePermissionEnabledAsync()) {\n                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q || PrefsUtil.downloadType == \"1\")\n                                FileAccessHelper.openTreeChooser(context)\n                            else\n                                Toaster.toastLong(\"¡Se necesita permiso de almacenamiento!\")\n                            serversInterface.onFinish(false, false)\n                            return@launch\n                        }\n                        if (!MultipleDownloadManager.isSpaceAvailable(1)) {\n                            serversInterface.getView()?.showSnackbar(\"Sin espacio suficiente\")\n                            serversInterface.onFinish(false, false)\n                            return@launch\n                        }\n                        ServersFactory(context, url, chapter, isStream, addQueue, serversInterface).also { doAsync { it.start() } }\n                    }\n                }\n            else {\n                serversInterface.onFinish(false, false)\n                Toaster.toast(\"Solo una petición a la vez\")\n            }\n        }\n\n        fun start(\n                context: Context,\n                url: String,\n                downloadObject: DownloadObject,\n                isStream: Boolean = false,\n                serversInterface: ServersInterface\n        ) {\n            if (!isRunning())\n                GlobalScope.launch(Dispatchers.Main) {\n                    INSTANCE = if (isStream)\n                        ServersFactory(context, url, downloadObject, isStream, serversInterface).also { doAsync { it.start() } }\n                    else {\n                        if (!FileAccessHelper.isStoragePermissionEnabledAsync()) {\n                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q || PrefsUtil.downloadType == \"1\")\n                                FileAccessHelper.openTreeChooser(context)\n                            else\n                                Toaster.toastLong(\"¡Se necesita permiso de almacenamiento!\")\n                            serversInterface.onFinish(false, false)\n                            return@launch\n                        }\n                        if (!MultipleDownloadManager.isSpaceAvailable(1)) {\n                            serversInterface.getView()?.showSnackbar(\"Sin espacio suficiente\")\n                            serversInterface.onFinish(false, false)\n                            return@launch\n                        }\n                        ServersFactory(context, url, downloadObject, isStream, serversInterface).also { doAsync { it.start() } }\n                    }\n                }\n            else {\n                serversInterface.onFinish(false, false)\n                Toaster.toast(\"Solo una petición a la vez\")\n            }\n        }\n\n        fun clear() {\n            INSTANCE?.snackBarManager?.dismissAll()\n            INSTANCE = null\n        }\n\n        fun startPlay(context: Context?, title: String, file_name: String) {\n            if (context == null) return\n            AchievementManager.onPlayChapter()\n            if (PreferenceManager.getDefaultSharedPreferences(context).getString(\"player_type\", \"0\") == \"0\") {\n                context.startActivity(PrefsUtil.getPlayerIntent()\n                    .setData(FileAccessHelper.getDataUri(file_name))\n                        .putExtra(\"isFile\", true)\n                        .putExtra(\"title\", title))\n            } else {\n                val intent = Intent(Intent.ACTION_VIEW, FileAccessHelper.getDataUri(file_name))\n                        .setDataAndType(FileAccessHelper.getDataUri(file_name), \"video/mp4\")\n                        .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)\n                        .putExtra(\"title\", title)\n                context.startActivity(intent)\n            }\n        }\n\n        private fun getEpTitle(title: String, file: String): String {\n            return title + \" \" + file.substring(file.lastIndexOf(\"-\") + 1, file.lastIndexOf(\".\"))\n        }\n\n        fun getPlayIntent(context: Context, title: String, file_name: String): PendingIntent {\n            return if (PreferenceManager.getDefaultSharedPreferences(context).getString(\"player_type\", \"0\") == \"0\") {\n                PendingIntent.getActivity(\n                    context,\n                    abs(file_name.hashCode()),\n                    PrefsUtil.getPlayerIntent()\n                        .setData(FileAccessHelper.getFileUri(file_name)).putExtra(\"isFile\", true)\n                        .putExtra(\"title\", getEpTitle(title, file_name))\n                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),\n                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\n                )\n            } else {\n                val intent = Intent(Intent.ACTION_VIEW, FileAccessHelper.getDataUri(file_name))\n                    .setDataAndType(FileAccessHelper.getDataUri(file_name), \"video/mp4\")\n                    .setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_ACTIVITY_NEW_TASK)\n                    .putExtra(\"title\", getEpTitle(title, file_name))\n                PendingIntent.getActivity(\n                    context,\n                    abs(file_name.hashCode()),\n                    intent,\n                    PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\n                )\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/StapeServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.videoservers.VideoServer.Names.STAPE\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.runBlocking\nimport kotlinx.coroutines.withContext\nimport org.jsoup.Jsoup\n\nclass StapeServer(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"streamtape.com\")\n\n    override val name: String\n        get() = STAPE\n\n    override val videoServer: VideoServer?\n        get() {\n            val downLink = PatternUtil.extractLink(baseLink)\n            return try {\n                val link = runBlocking {\n                    val html = withContext(Dispatchers.Main) { Unpacker.getHtml(context, downLink).html }\n                    val doc = Jsoup.parse(html, \"https://streamtape.com\")\n                    doc.select(\"video[id]\").attr(\"abs:src\")\n                }\n                val videoLink =\n                    Jsoup.connect(link).ignoreContentType(true).followRedirects(true).execute().url().toString()\n                check(!videoLink.contains(\"streamtape_do_not_delete.mp4\"))\n                VideoServer(STAPE, Option(name, null, videoLink))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/StreamWishServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport androidx.core.net.toUri\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.videoservers.VideoServer.Names.STREAMWISH\nimport kotlinx.coroutines.runBlocking\n\nclass StreamWishServer internal constructor(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"streamwish.to\")\n\n    override val name: String\n        get() = STREAMWISH\n\n    override val canStream: Boolean\n        get() = true\n\n    override val canDownload: Boolean\n        get() = false\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                val downLink = \"https://sfastwish.com/e/${PatternUtil.extractLink(baseLink).substringAfterLast(\"/\")}\"\n                for (i in 0..3) {\n                    val unpack = if (i >= 2) {\n                        runBlocking { Unpacker.unpackWeb(context, downLink) }\n                    } else {\n                        runBlocking { Unpacker.unpack(downLink) }\n                    }\n                    val host = unpack.url!!.toUri().let { it.scheme + \"://\" + it.host }\n                    val options = \"hls\\\\d\\\": ?\\\"([^\\\"]*)\".toRegex().findAll(unpack.unpacked).toList().reversed().mapIndexed { index, it ->\n                        val (link) = it.destructured\n                        Option(name, \"HLS${index + 1}\", if (link.startsWith(\"http\")) link else host + link)\n                    }.toMutableList()\n                    val selected = options.firstOrNull { option ->\n                        jsoupCookies(option.url)\n                            .ignoreContentType(true)\n                            .ignoreHttpErrors(true)\n                            .execute().let { it.statusCode() in (200..299) && it.body().startsWith(\"#\") }\n                    }\n                    if (selected == null) continue\n                    return VideoServer(name, selected)\n                }\n                null\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n        }\n}\n\n/**\n *var uas=[];var links={\"hls4\":\"/stream/c9o0NWswavouc9hYw-PUmQ/kjhhiuahiuhgihdf/1760171834/61398616/master.m3u8\",\"hls3\":\"https://18jij6rntf.gridsoftwareworks.space/6wyav2r9i6j/hls3/01/12279/01msn9tjtg1f_,l,n,.urlset/master.txt\",\"hls2\":\"https://18jij6rntf.premilkyway.com/hls2/01/12279/01msn9tjtg1f_,l,n,.urlset/master.m3u8?t=xOtUwpn24RvVVXZO5nikf9bfUEoV-A2S0A296hj2LgY&s=1760128634&e=129600&f=61398616&srv=6wyav2r9i6j&i=0.4&sp=500&p1=6wyav2r9i6j&p2=6wyav2r9i6j&asn=17072\"};jwplayer(\"vplayer\").setup({debug:\"1\",sources:[{file:links.hls4||links.hls3||links.hls2,type:\"hls\"}],image:\"https://pixoraa.cc/01msn9tjtg1f_xt.jpg\",width:\"100%\",height:\"100%\",stretching:\"uniform\",duration:\"1419.86\",preload:'auto',skin:{controlbar:{text:\"#1db0ef\",icons:\"#1db0ef\"},timeslider:{progress:\"#1db0ef\"},menus:{text:\"#1db0ef\"}},androidhls:\"true\",tracks:[{file:\"/dl?op=get_slides&length=1420&url=https://pixoraa.cc/01msn9tjtg1f0000.jpg\",kind:\"thumbnails\"}],captions:{userFontScale:1,color:'#FFFFFF',backgroundColor:'#FFFFFF',fontFamily:\"Tahoma\",backgroundOpacity:0,fontOpacity:'100',},\"advertising\":{\"client\":\"vast\",\"vpaidmode\":\"insecure\"},'qualityLabels':{\"1122\":\"720p\",\"532\":\"480p\"},abouttext:\"StreamHG\",aboutlink:\"https://streamhg.com\",logo:{file:\"/upload-data/logo_402.png\",link:\"https://www3.animeflv.net\",position:\"top-right\",margin:\"5\",hide:true},cast:{},playbackRateControls:true,playbackRates:[0.25,0.5,0.75,1,1.25,1.5,2]});var vvplay,vvad;var vastdone1=0,vastdone2=0,pop3done=0;var player=jwplayer();var prevt=0,tott=0,v2done=0,lastt=0;$.ajaxSetup({headers:{'Content-Cache':'no-cache'}});player.on('time',function(x){if(5>0&&x.position>=5&&vvad!=1){vvad=1;$('div.video_ad_fadein').fadeIn('slow')}var itads=0;uas.forEach(item=>{if(item.time<=x.position&&item.loaded==0){if(item.xtype=='vast'){if(item.link.startsWith('https://')){player.playAd(item.link)}else{var doc=new DOMParser().parseFromString(item.link,\"text/html\");item.link=\"data:application/xml;base64,\"+btoa(unescape(encodeURIComponent(doc.documentElement.textContent)));player.playAd(item.link)}}else if(item.xtype=='direct'){pickDirect(itads,item.link)}else{var code=item.link.trim();var script=document.createElement('script');if(code.startsWith('https://')){script.src=code;script.async=true}else{var doc=new DOMParser().parseFromString(code,\"text/html\");code=doc.documentElement.textContent;var match=code.match(/<script[^>]*>([\\s\\S]*?)<\\/script>/i);if(match){script.textContent=match[1]}else{script.textContent=code}}document.body.appendChild(script)}item.loaded=1}itads++});if(x.position>=lastt+5||x.position<lastt){lastt=x.position;ls.set('tt01msn9tjtg1f',Math.round(lastt),{ttl:60*60*24*7})}if(x.viewable){dt=x.position-prevt;if(dt>5)dt=1;tott+=dt}prevt=x.position;console.log(tott);if(tott>=60){$.post('https://logs.vectorrab.com/dl',{op:'view4',hash:'61398616-189-203-1760128633-498649b34b00770777c2f7b5775f6534',ss:parseInt(tott),file_id:61398616,file_real:'01msn9tjtg1f'},function(){},\"jsonp\");tott=0}if(pop3done!=1&&x.position>=1){pop3done=1;var a=document.createElement('script');a.src='/assets/jquery/p3anime.js?v=1.1';document.body.appendChild(a)}});player.on('seek',function(x){prevt=x.position});player.on('play',function(x){doPlay(x)});player.on('complete',function(){$('div.video_ad').show();ls.remove('tt01msn9tjtg1f')});player.on('pause',function(x){});function createCookieSec(name,value,sec){var date=new Date();date.setTime(date.getTime()+(sec*1000));document.cookie=name+\"=\"+value+\"; expires=\"+date.toGMTString()+\"; domain=.auvexiug.com; path=/; SameSite=None; Secure\"}function doPlay(x){$('div.video_ad').hide();$('#over_player_msg').hide();if(vvplay)return;vvplay=1;adb=0;const ggima=document.createElement('script');ggima.src='https://imasdk.googleapis.com/js/sdkloader/ima3.js';ggima.onerror=()=>{$.get('/dl?op=view&file_code=01msn9tjtg1f&hash=61398616-189-203-1760128633-498649b34b00770777c2f7b5775f6534&embed=1&referer=tryzendm.com&adb=1&hls4=1',function(data){$('#fviews').html(data)})};ggima.onload=()=>{$.get('/dl?op=view&file_code=01msn9tjtg1f&hash=61398616-189-203-1760128633-49\n */\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/Unpacker.kt",
    "content": "package knf.kuma.videoservers\r\n\r\nimport android.content.Context\r\nimport android.webkit.WebView\r\nimport com.venom.greendark.decoder.WebJS\r\nimport de.prosiebensat1digital.oasisjsbridge.JsBridge\r\nimport de.prosiebensat1digital.oasisjsbridge.JsBridgeConfig\r\nimport knf.kuma.commons.safeContext\r\nimport kotlinx.coroutines.Dispatchers\r\nimport kotlinx.coroutines.runBlocking\r\nimport kotlinx.coroutines.withContext\r\nimport org.jsoup.Jsoup\r\nimport java.util.regex.Pattern\r\nimport kotlin.coroutines.resume\r\nimport kotlin.coroutines.suspendCoroutine\r\n\r\nobject Unpacker {\r\n    private val packedRegex1 =\r\n        \"(function.*\\\\}\\\\s*\\\\('.*',\\\\s*.*?,\\\\s*\\\\d+,\\\\s*'.*?'\\\\.split\\\\('\\\\|'\\\\),\\\\d+,\\\\{.*\\\\}\\\\))\".toRegex()\r\n    private val packedRegex2 =\r\n        \"eval\\\\((function\\\\(p,a,c,k,e,?[dr]?\\\\).*.split\\\\('\\\\|'\\\\).*)\\\\)\".toRegex()\r\n\r\n    fun unpack(link: String): UnpackResult {\r\n        val result = Jsoup.connect(link).ignoreContentType(true).execute()\r\n        val html = result.body()\r\n        val packedCode = packedRegex2.find(html)?.destructured?.component1() ?: return UnpackResult(result.url().toString(), html)\r\n        val jsBridge = JsBridge(JsBridgeConfig.bareConfig(), safeContext)\r\n        return UnpackResult(result.url().toString(), jsBridge.evaluateBlocking(\"function prnt() {var txt = $packedCode; return txt;}prnt();\"))\r\n    }\r\n\r\n    suspend fun unpackWeb(context: Context, link: String): UnpackResult {\r\n        val html = getHtml(context, link)\r\n        val packedCode = packedRegex2.find(html.html)?.destructured?.component1() ?: return UnpackResult(html.url, html.html)\r\n        val jsBridge = JsBridge(JsBridgeConfig.bareConfig(), safeContext)\r\n        return UnpackResult(html.url, jsBridge.evaluateBlocking(\"function prnt() {var txt = $packedCode; return txt;}prnt();\"))\r\n    }\r\n\r\n    fun unpackHtml(html: String): String {\r\n        val packedCode = packedRegex2.find(html)?.destructured?.component1() ?: return html\r\n        val jsBridge = JsBridge(JsBridgeConfig.bareConfig(), safeContext)\r\n        return jsBridge.evaluateBlocking(\"function prnt() {var txt = $packedCode; return txt;}prnt();\")\r\n    }\r\n\r\n    fun evalJs(context: Context, code: String): String {\r\n        val evaluator = WebView(context)\r\n        return runBlocking(Dispatchers.Main) {\r\n            suspendCoroutine { continuation ->\r\n                evaluator.evaluateJavascript(code) {\r\n                    continuation.resume(it)\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    suspend fun getHtml(context: Context, link: String, delay: Long = 5000): HTMLResult {\r\n        return withContext(Dispatchers.Main) {\r\n            val evaluator = WebJS(context)\r\n            suspendCoroutine { continuation ->\r\n                evaluator.evalOnFinish(\r\n                    link,\r\n                    \"(\\\"<html>\\\"+document.getElementsByTagName(\\\"html\\\")[0].innerHTML+\\\"<\\\\/html>\\\")\",\r\n                    delay\r\n                ) { url, html ->\r\n                    continuation.resume(HTMLResult(url, html))\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    suspend fun listenResources(context: Context, link: String, pattern: Pattern, timeout: Long = 10000): String? {\r\n        return withContext(Dispatchers.Main) {\r\n            val evaluator = WebJS(context)\r\n            suspendCoroutine { continuation ->\r\n                evaluator.listenResources(\r\n                    link,\r\n                    pattern,\r\n                    timeout\r\n                ) {\r\n                    continuation.resume(it)\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    data class HTMLResult(\r\n        val url: String?,\r\n        val html: String\r\n    )\r\n\r\n    data class UnpackResult(\r\n        val url: String?,\r\n        val unpacked: String\r\n    )\r\n\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/VeryStreamServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.commons.jsoupCookies\nimport knf.kuma.videoservers.VideoServer.Names.VERYSTREAM\n\nclass VeryStreamServer internal constructor(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"verystream.com\")\n\n    override val name: String\n        get() = VERYSTREAM\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                val downLink = PatternUtil.extractLink(baseLink)\n                val link = \"https://verystream.com/gettoken/${jsoupCookies(downLink).get().select(\"videolink\").text()}?mime=true\"\n                VideoServer(name, Option(name, null, link))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/VideoServer.kt",
    "content": "package knf.kuma.videoservers\r\n\r\nimport android.os.Parcel\r\nimport android.os.Parcelable\r\n\r\nopen class VideoServer : Parcelable {\r\n    var name: String\r\n    var options: MutableList<Option> = ArrayList()\r\n    var skipVerification = false\r\n\r\n    val option: Option\r\n        get() = options[0]\r\n\r\n    constructor(name: String, skipVerification: Boolean = false) {\r\n        this.name = name\r\n        this.skipVerification = skipVerification\r\n    }\r\n\r\n    constructor(name: String, option: Option, skipVerification: Boolean = false) {\r\n        this.name = name\r\n        addOption(option)\r\n        this.skipVerification = skipVerification\r\n    }\r\n\r\n    constructor(name: String, options: MutableList<Option>, skipVerification: Boolean = false) {\r\n        this.name = name\r\n        this.options = options\r\n        this.skipVerification = skipVerification\r\n    }\r\n\r\n    fun addOption(option: Option) {\r\n        options.add(option)\r\n    }\r\n\r\n    fun haveOptions(): Boolean {\r\n        return options.size > 1\r\n    }\r\n\r\n    class Sorter : Comparator<VideoServer> {\r\n        override fun compare(videoServer: VideoServer, t1: VideoServer): Int {\r\n            return videoServer.name.compareTo(t1.name, ignoreCase = true)\r\n        }\r\n    }\r\n\r\n    protected constructor(parcel: Parcel) {\r\n        name = parcel.readString() ?: \"\"\r\n        options = parcel.createTypedArrayList(Option.CREATOR) ?: arrayListOf()\r\n    }\r\n\r\n    override fun describeContents(): Int {\r\n        return 0\r\n    }\r\n\r\n    override fun writeToParcel(dest: Parcel, flags: Int) {\r\n        dest.writeString(name)\r\n        dest.writeTypedList(options)\r\n    }\r\n\r\n    object Names {\r\n        const val IZANAGI = \"Izanagi\"\r\n        const val HYPERION = \"Hyperion\"\r\n        const val OKRU = \"Okru\"\r\n        const val FEMBED = \"Fembed\"\r\n        const val FIRE = \"Fire\"\r\n        const val MANGO = \"Mango\"\r\n        const val NATSUKI = \"Natsuki\"\r\n        const val VERYSTREAM = \"VeryStream\"\r\n        const val FENIX = \"Fenix\"\r\n        const val RV = \"RV\"\r\n        const val MP4UPLOAD = \"Mp4Upload\"\r\n        const val YOURUPLOAD = \"YourUpload\"\r\n        const val ZIPPYSHARE = \"Zippyshare\"\r\n        const val GOCDN = \"GoCDN\"\r\n        const val STAPE = \"Stape\"\r\n        const val STREAMWISH = \"Streamwish\"\r\n        const val SBVIDEO = \"SBVideo\"\r\n        const val MEGA = \"Mega\"\r\n\r\n        internal val downloadServers: Array<String>\r\n            get() = arrayOf(\r\n                IZANAGI,\r\n                HYPERION,\r\n                OKRU,\r\n                FEMBED,\r\n                FIRE,\r\n                NATSUKI,\r\n                SBVIDEO,\r\n                GOCDN,\r\n                STAPE,\r\n                STREAMWISH,\r\n                VERYSTREAM,\r\n                FENIX,\r\n                RV,\r\n                YOURUPLOAD,\r\n                ZIPPYSHARE,\r\n                MEGA,\r\n                MP4UPLOAD\r\n            )\r\n    }\r\n\r\n    companion object {\r\n        @JvmField\r\n        val CREATOR: Parcelable.Creator<VideoServer> = object : Parcelable.Creator<VideoServer> {\r\n            override fun createFromParcel(parcel: Parcel): VideoServer {\r\n                return VideoServer(parcel)\r\n            }\r\n\r\n            override fun newArray(size: Int): Array<VideoServer?> {\r\n                return arrayOfNulls(size)\r\n            }\r\n        }\r\n\r\n        fun filter(videoServers: MutableList<VideoServer>): MutableList<VideoServer> {\r\n            val names = ArrayList<String>()\r\n            val filtered = ArrayList<VideoServer>()\r\n            for (videoServer in videoServers) {\r\n                if (!names.contains(videoServer.name)) {\r\n                    names.add(videoServer.name)\r\n                    filtered.add(videoServer)\r\n                }\r\n            }\r\n            return filtered\r\n        }\r\n\r\n        fun getNames(videoServers: MutableList<VideoServer>): MutableList<String> {\r\n            val names = ArrayList<String>()\r\n            for (videoServer in videoServers) {\r\n                names.add(videoServer.name)\r\n            }\r\n            return names\r\n        }\r\n\r\n        private fun findPosition(videoServers: MutableList<VideoServer>, name: String): Int {\r\n            for ((i, videoServer) in videoServers.withIndex()) {\r\n                if (videoServer.name == name)\r\n                    return i\r\n            }\r\n            return 0\r\n        }\r\n\r\n        fun existServer(videoServers: MutableList<VideoServer>, position: Int): Boolean {\r\n            val name = Names.downloadServers[position - 1]\r\n            for (videoServer in videoServers) {\r\n                if (videoServer.name == name)\r\n                    return true\r\n            }\r\n            return false\r\n        }\r\n\r\n        fun findServer(videoServers: MutableList<VideoServer>, position: Int): VideoServer {\r\n            val name = Names.downloadServers[position - 1]\r\n            return videoServers[findPosition(videoServers, name)]\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/WebJS.kt",
    "content": "package com.venom.greendark.decoder\r\n\r\nimport android.content.Context\r\nimport android.os.Handler\r\nimport android.os.Looper\r\nimport android.webkit.JavascriptInterface\r\nimport android.webkit.WebResourceRequest\r\nimport android.webkit.WebResourceResponse\r\nimport android.webkit.WebView\r\nimport android.webkit.WebViewClient\r\nimport androidx.annotation.Keep\r\nimport java.util.regex.Pattern\r\n\r\nclass WebJS(context: Context) {\r\n    private val webView = WebView(context)\r\n    private var currentUrl: String? = null\r\n    private var callback: ((String?, String) -> Unit)? = null\r\n\r\n    init {\r\n        webView.settings.apply {\r\n            javaScriptEnabled = true\r\n        }\r\n        webView.addJavascriptInterface(JSInterface { callback?.invoke(currentUrl, it) }, \"myInterface\")\r\n    }\r\n\r\n    fun evalOnFinish(link: String, js: String, delay: Long = 5000, callback: (String?, String) -> Unit) {\r\n        this.callback = callback\r\n        var response = false\r\n        val handler = Handler(Looper.getMainLooper())\r\n        val run = Runnable {\r\n            if (!response) {\r\n                response = true\r\n                currentUrl = webView.url\r\n                webView.loadUrl(\"javascript:myInterface.returnResult(eval('try{$js}catch(e){e}'));\")\r\n            }\r\n        }\r\n        webView.webViewClient = object : WebViewClient() {\r\n            override fun onPageFinished(view: WebView?, url: String?) {\r\n                handler.removeCallbacks(run)\r\n                run.run()\r\n            }\r\n        }\r\n        handler.postDelayed(run, delay)\r\n        webView.loadUrl(link)\r\n    }\r\n\r\n    fun listenResources(link: String, pattern: Pattern, timeout: Long, callback: (String?) -> Unit) {\r\n        var response = false\r\n        val handler = Handler(Looper.getMainLooper())\r\n        val regex = pattern.toRegex()\r\n        val run = Runnable {\r\n            if (!response) {\r\n                response = true\r\n                callback(null)\r\n            }\r\n        }\r\n        webView.webViewClient = object : WebViewClient() {\r\n            override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {\r\n                if (!response && request?.url?.toString()?.matches(regex) == true) {\r\n                    handler.removeCallbacks(run)\r\n                    response = true\r\n                    callback(request.url.toString())\r\n                    webView.loadUrl(\"about:blank\")\r\n                }\r\n                return super.shouldInterceptRequest(view, request)\r\n            }\r\n        }\r\n        handler.postDelayed(run, timeout)\r\n        webView.loadUrl(link)\r\n    }\r\n\r\n    @Keep\r\n    class JSInterface(private val callback: (String) -> Unit) {\r\n        @JavascriptInterface\r\n        fun returnResult(result: String) {\r\n            callback(result)\r\n        }\r\n    }\r\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/WebServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\n\nclass WebServer (context: Context, baseLink: String, val serverName: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = true\n\n    override val name: String\n        get() = \"$serverName (WEB)\"\n\n    override val canStream: Boolean\n        get() = false\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                VideoServer(serverName, Option(name, null, PatternUtil.extractLink(baseLink)))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/YUServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.videoservers.VideoServer.Names.YOURUPLOAD\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.runBlocking\nimport okhttp3.ConnectionSpec\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\n\nclass YUServer(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"yourupload.com\")\n\n    override val name: String\n        get() = YOURUPLOAD\n\n    override val videoServer: VideoServer?\n        get() {\n            val yuLink = PatternUtil.extractLink(baseLink)\n            try {\n                val videoLink = PatternUtil.getYUvideoLink(runBlocking(Dispatchers.Main) { Unpacker.getHtml(context, yuLink, 8000).html })\n                val client = OkHttpClient().newBuilder()\n                        .connectionSpecs(listOf(ConnectionSpec.CLEARTEXT, ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)\n                                .allEnabledTlsVersions()\n                                .allEnabledCipherSuites()\n                                .build()))\n                        .followRedirects(false).build()\n                val request = Request.Builder()\n                        .url(videoLink)\n                        .addHeader(\"Referer\", yuLink)\n                        .build()\n                val response = client.newCall(request).execute()\n                val refVideoLink = response.header(\"Location\")\n                response.close()\n                val headers = Headers()\n                headers.addHeader(\"Range\", \"bytes=0-\")\n                headers.addHeader(\"Referer\", \"https://www.yourupload.com/\")\n                return VideoServer(YOURUPLOAD, Option(name, null, refVideoLink, headers))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                return null\n            }\n\n        }\n}"
  },
  {
    "path": "app/src/main/java/knf/kuma/videoservers/ZippyServer.kt",
    "content": "package knf.kuma.videoservers\n\nimport android.content.Context\nimport android.webkit.JavascriptInterface\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.runBlocking\nimport kotlinx.coroutines.withContext\nimport kotlinx.coroutines.withTimeout\nimport org.jsoup.Jsoup\nimport java.net.URLDecoder\n\nclass ZippyServer(context: Context, baseLink: String) : Server(context, baseLink) {\n\n    override val isValid: Boolean\n        get() = baseLink.contains(\"zippyshare\")\n\n    override val name: String\n        get() = VideoServer.Names.ZIPPYSHARE\n\n    override val videoServer: VideoServer?\n        get() {\n            return try {\n                val decoded = URLDecoder.decode(baseLink, \"utf-8\")\n                val linkData: String? = runBlocking(Dispatchers.IO) {\n                    val html = withContext(Dispatchers.Main) {\n                        withTimeout(TIMEOUT) {\n                            getFinishedHtml(decoded)\n                        }\n                    }\n                    val result = Jsoup.parse(html).select(\"a#dlbutton\").attr(\"href\")\n                    if (result.isBlank()) null else decoded.substringBefore(\"/v/\") + result\n                    /*suspendCoroutine {\n                        WebView(context).apply {\n                            settings.apply {\n                                javaScriptEnabled = true\n                            }\n                            addJavascriptInterface(object : ZippyJSInterface() {\n                                @JavascriptInterface\n                                override fun printHtml(string: String) {\n                                    val result = Jsoup.parse(string).select(\"a#dlbutton\").attr(\"href\")\n                                    it.resume(if (result.isBlank()) null else decoded.substringBefore(\"/v/\") + result)\n                                }\n                            }, \"HtmlViewer\")\n                            webViewClient = object : WebViewClient() {\n                                override fun onPageFinished(view: WebView?, url: String?) {\n                                    loadUrl(\"javascript:window.HtmlViewer.printHtml\" +\n                                            \"('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');\")\n                                }\n                            }\n                            loadUrl(decoded)\n                        }\n                    }*/\n                }\n                linkData ?: return null\n                VideoServer(name, Option(name, null, linkData))\n            } catch (e: Exception) {\n                e.printStackTrace()\n                null\n            }\n\n        }\n\n    abstract class ZippyJSInterface {\n        @JavascriptInterface\n        open fun printHtml(string: String) {\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/widgets/AdTemplateView.java",
    "content": "package knf.kuma.widgets;\r\n\r\nimport android.content.Context;\r\nimport android.content.res.TypedArray;\r\nimport android.graphics.Typeface;\r\nimport android.util.AttributeSet;\r\nimport android.view.LayoutInflater;\r\nimport android.widget.Button;\r\nimport android.widget.FrameLayout;\r\nimport android.widget.ImageView;\r\nimport android.widget.TextView;\r\n\r\nimport androidx.annotation.LayoutRes;\r\nimport androidx.annotation.Nullable;\r\n\r\nimport knf.kuma.R;\r\n\r\n/**\r\n * Base class for a template view. *\r\n */\r\npublic class AdTemplateView extends FrameLayout {\r\n\r\n    private static final String SMALL_TEMPLATE = \"small_template\";\r\n    private NativeTemplateStyle styles;\r\n    //private NativeAd nativeAd;\r\n    //private NativeAdView nativeAdView;\r\n    private TextView primaryView;\r\n    private TextView secondaryView;\r\n    private ImageView iconView;\r\n    private Button callToActionView;\r\n\r\n    public AdTemplateView(Context context) {\r\n        super(context);\r\n    }\r\n\r\n    public AdTemplateView(Context context, @Nullable AttributeSet attrs) {\r\n        super(context, attrs);\r\n        initView(context,attrs);\r\n    }\r\n\r\n    public AdTemplateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {\r\n        super(context, attrs, defStyleAttr);\r\n        initView(context,attrs);\r\n    }\r\n\r\n    public AdTemplateView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {\r\n        super(context, attrs, defStyleAttr, defStyleRes);\r\n        initView(context,attrs);\r\n    }\r\n\r\n    public void setStyles(NativeTemplateStyle styles) {\r\n        this.styles = styles;\r\n        this.applyStyles();\r\n    }\r\n\r\n    /*public NativeAdView getNativeAdView() {\r\n        return nativeAdView;\r\n    }*/\r\n\r\n    private void applyStyles() {\r\n\r\n        Typeface primary = styles.getPrimaryTextTypeface();\r\n        if (primary != null && primaryView != null) {\r\n            primaryView.setTypeface(primary);\r\n        }\r\n\r\n        Typeface secondary = styles.getSecondaryTextTypeface();\r\n        if (secondary != null && secondaryView != null) {\r\n            secondaryView.setTypeface(secondary);\r\n        }\r\n\r\n        Typeface ctaTypeface = styles.getCallToActionTextTypeface();\r\n        if (ctaTypeface != null && callToActionView != null) {\r\n            callToActionView.setTypeface(ctaTypeface);\r\n        }\r\n\r\n        float ctaTextSize = styles.getCallToActionTextSize();\r\n        if (ctaTextSize > 0 && callToActionView != null) {\r\n            callToActionView.setTextSize(ctaTextSize);\r\n        }\r\n\r\n        float primaryTextSize = styles.getPrimaryTextSize();\r\n        if (primaryTextSize > 0 && primaryView != null) {\r\n            primaryView.setTextSize(primaryTextSize);\r\n        }\r\n\r\n        float secondaryTextSize = styles.getSecondaryTextSize();\r\n        if (secondaryTextSize > 0 && secondaryView != null) {\r\n            secondaryView.setTextSize(secondaryTextSize);\r\n        }\r\n\r\n        invalidate();\r\n        requestLayout();\r\n    }\r\n\r\n    /*private boolean adHasOnlyStore(NativeAd nativeAd) {\r\n        String store = nativeAd.getStore();\r\n        String advertiser = nativeAd.getAdvertiser();\r\n        return !TextUtils.isEmpty(store) && TextUtils.isEmpty(advertiser);\r\n    }\r\n\r\n    public void setNativeAd(@NotNull NativeAd nativeAd) {\r\n        if (this.nativeAd != null) return;\r\n        this.nativeAd = nativeAd;\r\n\r\n        String store = nativeAd.getStore();\r\n        String advertiser = nativeAd.getAdvertiser();\r\n        String headline = nativeAd.getHeadline();\r\n        String cta = nativeAd.getCallToAction();\r\n        NativeAd.Image icon = nativeAd.getIcon();\r\n\r\n        String secondaryText;\r\n\r\n        nativeAdView.setCallToActionView(callToActionView);\r\n        nativeAdView.setHeadlineView(primaryView);\r\n        secondaryView.setVisibility(VISIBLE);\r\n        if (adHasOnlyStore(nativeAd)) {\r\n            nativeAdView.setStoreView(secondaryView);\r\n            secondaryText = store;\r\n        } else if (!TextUtils.isEmpty(advertiser)) {\r\n            nativeAdView.setAdvertiserView(secondaryView);\r\n            secondaryText = advertiser;\r\n        } else {\r\n            secondaryText = \"\";\r\n        }\r\n\r\n        primaryView.setText(headline);\r\n        callToActionView.setText(cta);\r\n\r\n        secondaryView.setText(secondaryText);\r\n        secondaryView.setVisibility(VISIBLE);\r\n\r\n        if (icon != null) {\r\n            iconView.setVisibility(VISIBLE);\r\n            iconView.setImageDrawable(icon.getDrawable());\r\n        } else {\r\n            iconView.setVisibility(GONE);\r\n        }\r\n\r\n        nativeAdView.setNativeAd(nativeAd);\r\n    }*/\r\n\r\n    /**\r\n     * To prevent memory leaks, make sure to destroy your ad when you don't need it anymore. This\r\n     * method does not destroy the template view.\r\n     * https://developers.google.com/admob/android/native-unified#destroy_ad\r\n     */\r\n    /*public void destroyNativeAd() {\r\n        nativeAd.destroy();\r\n    }*/\r\n\r\n    public String getTemplateTypeName() {\r\n        return SMALL_TEMPLATE;\r\n    }\r\n\r\n    private void initView(Context context, AttributeSet attrs) {\r\n        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AdTemplateView);\r\n        @LayoutRes int lay =  array.getResourceId(R.styleable.AdTemplateView_at_layout,R.layout.item_native_small);\r\n        array.recycle();\r\n        LayoutInflater inflater =\r\n                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);\r\n        inflater.inflate(lay, this);\r\n    }\r\n\r\n    @Override\r\n    public void onFinishInflate() {\r\n        super.onFinishInflate();\r\n        //nativeAdView = findViewById(R.id.native_ad_view);\r\n        //primaryView = findViewById(R.id.primary);\r\n        //secondaryView = findViewById(R.id.secondary);\r\n\r\n        //callToActionView = findViewById(R.id.cta);\r\n        iconView = findViewById(R.id.icon);\r\n    }\r\n}\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/widgets/NativeTemplateStyle.java",
    "content": "package knf.kuma.widgets;\r\n\r\nimport android.graphics.Typeface;\r\nimport android.graphics.drawable.ColorDrawable;\r\n\r\n/**\r\n * A class containing the optional styling options for the Native Template. *\r\n */\r\npublic class NativeTemplateStyle {\r\n\r\n    // Call to action typeface.\r\n    private Typeface callToActionTextTypeface;\r\n\r\n    // Size of call to action text.\r\n    private float callToActionTextSize;\r\n\r\n    // Call to action typeface color in the form 0xAARRGGBB.\r\n    private int callToActionTypefaceColor;\r\n\r\n    // Call to action background color.\r\n    private ColorDrawable callToActionBackgroundColor;\r\n\r\n    // All templates have a primary text area which is populated by the native ad's headline.\r\n\r\n    // Primary text typeface.\r\n    private Typeface primaryTextTypeface;\r\n\r\n    // Size of primary text.\r\n    private float primaryTextSize;\r\n\r\n    // Primary text typeface color in the form 0xAARRGGBB.\r\n    private int primaryTextTypefaceColor;\r\n\r\n    // Primary text background color.\r\n    private ColorDrawable primaryTextBackgroundColor;\r\n\r\n    // The typeface, typeface color, and background color for the second row of text in the template.\r\n    // All templates have a secondary text area which is populated either by the body of the ad or\r\n    // by the rating of the app.\r\n\r\n    // Secondary text typeface.\r\n    private Typeface secondaryTextTypeface;\r\n\r\n    // Size of secondary text.\r\n    private float secondaryTextSize;\r\n\r\n    // Secondary text typeface color in the form 0xAARRGGBB.\r\n    private int secondaryTextTypefaceColor;\r\n\r\n    // Secondary text background color.\r\n    private ColorDrawable secondaryTextBackgroundColor;\r\n\r\n    // The typeface, typeface color, and background color for the third row of text in the template.\r\n    // The third row is used to display store name or the default tertiary text.\r\n\r\n    // Tertiary text typeface.\r\n    private Typeface tertiaryTextTypeface;\r\n\r\n    // Size of tertiary text.\r\n    private float tertiaryTextSize;\r\n\r\n    // Tertiary text typeface color in the form 0xAARRGGBB.\r\n    private int tertiaryTextTypefaceColor;\r\n\r\n    // Tertiary text background color.\r\n    private ColorDrawable tertiaryTextBackgroundColor;\r\n\r\n    // The background color for the bulk of the ad.\r\n    private ColorDrawable mainBackgroundColor;\r\n\r\n    public Typeface getCallToActionTextTypeface() {\r\n        return callToActionTextTypeface;\r\n    }\r\n\r\n    public float getCallToActionTextSize() {\r\n        return callToActionTextSize;\r\n    }\r\n\r\n    public int getCallToActionTypefaceColor() {\r\n        return callToActionTypefaceColor;\r\n    }\r\n\r\n    public ColorDrawable getCallToActionBackgroundColor() {\r\n        return callToActionBackgroundColor;\r\n    }\r\n\r\n    public Typeface getPrimaryTextTypeface() {\r\n        return primaryTextTypeface;\r\n    }\r\n\r\n    public float getPrimaryTextSize() {\r\n        return primaryTextSize;\r\n    }\r\n\r\n    public int getPrimaryTextTypefaceColor() {\r\n        return primaryTextTypefaceColor;\r\n    }\r\n\r\n    public ColorDrawable getPrimaryTextBackgroundColor() {\r\n        return primaryTextBackgroundColor;\r\n    }\r\n\r\n    public Typeface getSecondaryTextTypeface() {\r\n        return secondaryTextTypeface;\r\n    }\r\n\r\n    public float getSecondaryTextSize() {\r\n        return secondaryTextSize;\r\n    }\r\n\r\n    public int getSecondaryTextTypefaceColor() {\r\n        return secondaryTextTypefaceColor;\r\n    }\r\n\r\n    public ColorDrawable getSecondaryTextBackgroundColor() {\r\n        return secondaryTextBackgroundColor;\r\n    }\r\n\r\n    public Typeface getTertiaryTextTypeface() {\r\n        return tertiaryTextTypeface;\r\n    }\r\n\r\n    public float getTertiaryTextSize() {\r\n        return tertiaryTextSize;\r\n    }\r\n\r\n    public int getTertiaryTextTypefaceColor() {\r\n        return tertiaryTextTypefaceColor;\r\n    }\r\n\r\n    public ColorDrawable getTertiaryTextBackgroundColor() {\r\n        return tertiaryTextBackgroundColor;\r\n    }\r\n\r\n    public ColorDrawable getMainBackgroundColor() {\r\n        return mainBackgroundColor;\r\n    }\r\n\r\n    /**\r\n     * A class that provides helper methods to build a style object. *\r\n     */\r\n    public static class Builder {\r\n\r\n        private final NativeTemplateStyle styles;\r\n\r\n        public Builder() {\r\n            this.styles = new NativeTemplateStyle();\r\n        }\r\n\r\n        public Builder withCallToActionTextTypeface(Typeface callToActionTextTypeface) {\r\n            this.styles.callToActionTextTypeface = callToActionTextTypeface;\r\n            return this;\r\n        }\r\n\r\n        public Builder withCallToActionTextSize(float callToActionTextSize) {\r\n            this.styles.callToActionTextSize = callToActionTextSize;\r\n            return this;\r\n        }\r\n\r\n        public Builder withCallToActionTypefaceColor(int callToActionTypefaceColor) {\r\n            this.styles.callToActionTypefaceColor = callToActionTypefaceColor;\r\n            return this;\r\n        }\r\n\r\n        public Builder withCallToActionBackgroundColor(ColorDrawable callToActionBackgroundColor) {\r\n            this.styles.callToActionBackgroundColor = callToActionBackgroundColor;\r\n            return this;\r\n        }\r\n\r\n        public Builder withPrimaryTextTypeface(Typeface primaryTextTypeface) {\r\n            this.styles.primaryTextTypeface = primaryTextTypeface;\r\n            return this;\r\n        }\r\n\r\n        public Builder withPrimaryTextSize(float primaryTextSize) {\r\n            this.styles.primaryTextSize = primaryTextSize;\r\n            return this;\r\n        }\r\n\r\n        public Builder withPrimaryTextTypefaceColor(int primaryTextTypefaceColor) {\r\n            this.styles.primaryTextTypefaceColor = primaryTextTypefaceColor;\r\n            return this;\r\n        }\r\n\r\n        public Builder withPrimaryTextBackgroundColor(ColorDrawable primaryTextBackgroundColor) {\r\n            this.styles.primaryTextBackgroundColor = primaryTextBackgroundColor;\r\n            return this;\r\n        }\r\n\r\n        public Builder withSecondaryTextTypeface(Typeface secondaryTextTypeface) {\r\n            this.styles.secondaryTextTypeface = secondaryTextTypeface;\r\n            return this;\r\n        }\r\n\r\n        public Builder withSecondaryTextSize(float secondaryTextSize) {\r\n            this.styles.secondaryTextSize = secondaryTextSize;\r\n            return this;\r\n        }\r\n\r\n        public Builder withSecondaryTextTypefaceColor(int secondaryTextTypefaceColor) {\r\n            this.styles.secondaryTextTypefaceColor = secondaryTextTypefaceColor;\r\n            return this;\r\n        }\r\n\r\n        public Builder withSecondaryTextBackgroundColor(ColorDrawable secondaryTextBackgroundColor) {\r\n            this.styles.secondaryTextBackgroundColor = secondaryTextBackgroundColor;\r\n            return this;\r\n        }\r\n\r\n        public Builder withTertiaryTextTypeface(Typeface tertiaryTextTypeface) {\r\n            this.styles.tertiaryTextTypeface = tertiaryTextTypeface;\r\n            return this;\r\n        }\r\n\r\n        public Builder withTertiaryTextSize(float tertiaryTextSize) {\r\n            this.styles.tertiaryTextSize = tertiaryTextSize;\r\n            return this;\r\n        }\r\n\r\n        public Builder withTertiaryTextTypefaceColor(int tertiaryTextTypefaceColor) {\r\n            this.styles.tertiaryTextTypefaceColor = tertiaryTextTypefaceColor;\r\n            return this;\r\n        }\r\n\r\n        public Builder withTertiaryTextBackgroundColor(ColorDrawable tertiaryTextBackgroundColor) {\r\n            this.styles.tertiaryTextBackgroundColor = tertiaryTextBackgroundColor;\r\n            return this;\r\n        }\r\n\r\n        public Builder withMainBackgroundColor(ColorDrawable mainBackgroundColor) {\r\n            this.styles.mainBackgroundColor = mainBackgroundColor;\r\n            return this;\r\n        }\r\n\r\n        public NativeTemplateStyle build() {\r\n            return styles;\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/widgets/emision/WEListItem.kt",
    "content": "package knf.kuma.widgets.emision\n\nclass WEListItem internal constructor(var key: Int, var link: String, var title: String, var aid: String, var img: String)\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/widgets/emision/WEListProvider.kt",
    "content": "package knf.kuma.widgets.emision\n\nimport android.app.PendingIntent\nimport android.content.Context\nimport android.graphics.Color\nimport android.widget.RemoteViews\nimport android.widget.RemoteViewsService\nimport androidx.preference.PreferenceManager\nimport knf.kuma.R\nimport knf.kuma.animeinfo.ActivityAnime\nimport knf.kuma.animeinfo.ActivityAnimeMaterial\nimport knf.kuma.commons.DesignUtils\nimport knf.kuma.commons.PatternUtil\nimport knf.kuma.database.CacheDB\nimport xdroid.toaster.Toaster\nimport java.util.Calendar\n\nclass WEListProvider internal constructor(private val context: Context) : RemoteViewsService.RemoteViewsFactory {\n    private val items = mutableListOf<WEListItem>()\n\n    private val actualDayCode: Int\n        get() {\n            return when (Calendar.getInstance().get(Calendar.DAY_OF_WEEK)) {\n                Calendar.MONDAY -> 2\n                Calendar.TUESDAY -> 3\n                Calendar.WEDNESDAY -> 4\n                Calendar.THURSDAY -> 5\n                Calendar.FRIDAY -> 6\n                Calendar.SATURDAY -> 7\n                Calendar.SUNDAY -> 1\n                else -> 2\n            }\n        }\n\n    private fun populateListItem() {\n        items.clear()\n        val list = CacheDB.INSTANCE.animeDAO().getByDayDirect(actualDayCode, getBlacklist(context))\n        for (obj in list) {\n            items.add(WEListItem(obj.key, obj.link, obj.name, obj.aid, PatternUtil.getCover(obj.aid)))\n        }\n    }\n\n    override fun onCreate() {\n\n    }\n\n    override fun onDataSetChanged() {\n        populateListItem()\n    }\n\n    override fun onDestroy() {\n\n    }\n\n    override fun getCount(): Int {\n        return items.size\n    }\n\n    override fun getViewAt(position: Int): RemoteViews {\n        val remoteView = RemoteViews(\n                context.packageName, R.layout.item_widget_list)\n        try {\n            val listItem = items[position]\n            remoteView.setTextViewText(R.id.heading, listItem.title)\n            remoteView.setTextColor(R.id.heading, getColor(true))\n            val clickIntent = if (DesignUtils.isFlat)\n                ActivityAnimeMaterial.getSimpleIntent(context, listItem)\n            else\n                ActivityAnime.getSimpleIntent(context, listItem)\n            remoteView.setOnClickPendingIntent(\n                R.id.linear,\n                PendingIntent.getActivity(\n                    context,\n                    324 + position,\n                    clickIntent,\n                    PendingIntent.FLAG_IMMUTABLE\n                )\n            )\n            remoteView.setInt(R.id.linear, \"setBackgroundColor\", getColor(false))\n        } catch (e: Exception) {\n            e.printStackTrace()\n            Toaster.toastLong(\"Error: ${e.message}\")\n        }\n\n        return remoteView\n    }\n\n    private fun getColor(isText: Boolean): Int {\n        return when (PreferenceManager.getDefaultSharedPreferences(context).getString(\"theme_value\", \"0\")) {\n            \"1\" -> if (isText)\n                Color.parseColor(\"#323232\")\n            else\n                Color.parseColor(\"#FFFFFF\")\n            \"2\" -> if (isText)\n                Color.parseColor(\"#bebebe\")\n            else\n                Color.parseColor(\"#282828\")\n            else -> if (isText)\n                Color.parseColor(\"#323232\")\n            else\n                Color.parseColor(\"#FFFFFFFF\")\n        }\n    }\n\n    override fun getLoadingView(): RemoteViews? {\n        return null\n    }\n\n    override fun getViewTypeCount(): Int {\n        return 1\n    }\n\n    override fun getItemId(position: Int): Long {\n        return try {\n            items[position].key.toLong()\n        } catch (e: Exception) {\n            0\n        }\n\n    }\n\n    override fun hasStableIds(): Boolean {\n        return true\n    }\n\n    private fun getBlacklist(context: Context): Set<String> {\n        return PreferenceManager.getDefaultSharedPreferences(context).getStringSet(\"emision_blacklist\", LinkedHashSet())\n                ?: setOf()\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/widgets/emision/WEmisionProvider.kt",
    "content": "package knf.kuma.widgets.emision\n\nimport android.app.PendingIntent\nimport android.appwidget.AppWidgetManager\nimport android.appwidget.AppWidgetProvider\nimport android.content.ComponentName\nimport android.content.Context\nimport android.content.Intent\nimport android.graphics.Color\nimport android.net.Uri\nimport android.widget.RemoteViews\nimport androidx.preference.PreferenceManager\nimport knf.kuma.R\nimport knf.kuma.commons.DesignUtils\nimport knf.kuma.database.CacheDB\nimport knf.kuma.emision.EmissionActivity\nimport knf.kuma.emision.EmissionActivityMaterial\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.util.Calendar\n\nclass WEmisionProvider : AppWidgetProvider() {\n\n    private val actualDay: String\n        get() {\n            return when (Calendar.getInstance().get(Calendar.DAY_OF_WEEK)) {\n                Calendar.MONDAY -> \"LUNES\"\n                Calendar.TUESDAY -> \"MARTES\"\n                Calendar.WEDNESDAY -> \"MIERCOLES\"\n                Calendar.THURSDAY -> \"JUEVES\"\n                Calendar.FRIDAY -> \"VIERNES\"\n                Calendar.SATURDAY -> \"SABADO\"\n                Calendar.SUNDAY -> \"DOMINGO\"\n                else -> \"DESCONOCIDO(LUNES POR DEFECTO)\"\n            }\n        }\n\n    private val actualDayCode: Int\n        get() {\n            return when (Calendar.getInstance().get(Calendar.DAY_OF_WEEK)) {\n                Calendar.MONDAY -> 2\n                Calendar.TUESDAY -> 3\n                Calendar.WEDNESDAY -> 4\n                Calendar.THURSDAY -> 5\n                Calendar.FRIDAY -> 6\n                Calendar.SATURDAY -> 7\n                Calendar.SUNDAY -> 1\n                else -> 2\n            }\n        }\n\n    override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {\n        GlobalScope.launch(Dispatchers.Main) {\n            for (i in appWidgetIds) {\n                val remoteViews = updateWidgetListView(context, i)\n                appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.words)\n                appWidgetManager.updateAppWidget(i, remoteViews)\n            }\n            super.onUpdate(context, appWidgetManager, appWidgetIds)\n        }\n    }\n\n    private suspend fun updateWidgetListView(context: Context, appWidgetId: Int): RemoteViews {\n        val remoteViews = RemoteViews(context.packageName,\n            R.layout.widget_emision\n        )\n        val svcIntent = Intent(context, WEmissionService::class.java)\n        svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)\n        svcIntent.data = Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME))\n        remoteViews.setRemoteAdapter(R.id.words, svcIntent)\n        val clickIntent = if (DesignUtils.isFlat) Intent(\n            context,\n            EmissionActivityMaterial::class.java\n        ) else Intent(context, EmissionActivity::class.java)\n        remoteViews.setTextViewText(R.id.title_day, actualDay)\n        remoteViews.setTextColor(R.id.title_day, getColor(context, true))\n        remoteViews.setTextViewText(\n            R.id.title_count,\n            withContext(Dispatchers.IO) {\n                CacheDB.INSTANCE.animeDAO()\n                    .getByDayDirect(actualDayCode, getBlacklist(context)).size.toString()\n            })\n        remoteViews.setTextColor(R.id.title_count, getColor(context, true))\n        remoteViews.setOnClickPendingIntent(\n            R.id.back_layout,\n            PendingIntent.getActivity(\n                context,\n                555,\n                clickIntent,\n                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE\n            )\n        )\n        remoteViews.setInt(R.id.back_layout, \"setBackgroundColor\", getColor(context, false))\n        remoteViews.setEmptyView(R.id.words, R.id.empty)\n        return remoteViews\n    }\n\n    private fun getColor(context: Context, isText: Boolean): Int {\n        return when (PreferenceManager.getDefaultSharedPreferences(context).getString(\"theme_value\", \"0\")) {\n            \"1\" -> if (isText)\n                Color.parseColor(\"#323232\")\n            else\n                Color.parseColor(\"#FFFFFF\")\n            \"2\" -> if (isText)\n                Color.parseColor(\"#bebebe\")\n            else\n                Color.parseColor(\"#282828\")\n            else -> if (isText)\n                Color.parseColor(\"#323232\")\n            else\n                Color.parseColor(\"#FFFFFFFF\")\n        }\n    }\n\n    private fun getBlacklist(context: Context): Set<String> {\n        return PreferenceManager.getDefaultSharedPreferences(context).getStringSet(\"emision_blacklist\", LinkedHashSet())\n                ?: setOf()\n    }\n\n    companion object {\n\n        fun update(context: Context?) {\n            if (context == null) return\n            val intent = Intent(context, WEmisionProvider::class.java)\n            intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE\n            val ids = AppWidgetManager.getInstance(context)\n                    .getAppWidgetIds(ComponentName(context, WEmisionProvider::class.java))\n            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids)\n            context.sendBroadcast(intent)\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/widgets/emision/WEmissionService.kt",
    "content": "package knf.kuma.widgets.emision\n\nimport android.content.Intent\nimport android.widget.RemoteViewsService\nimport androidx.core.app.NotificationCompat\nimport knf.kuma.R\nimport knf.kuma.commons.PrefsUtil\nimport knf.kuma.download.foreground\n\nclass WEmissionService : RemoteViewsService() {\n\n    companion object {\n        const val CHANNEL = \"widget-service\"\n    }\n\n    override fun onCreate() {\n        foreground(5987, NotificationCompat.Builder(this, CHANNEL).apply {\n            setSmallIcon(R.drawable.ic_service)\n            priority = NotificationCompat.PRIORITY_MIN\n            if (PrefsUtil.collapseDirectoryNotification)\n                setSubText(\"Actualizando widget\")\n            else\n                setContentTitle(\"Actualizando widget\")\n        }.build())\n        super.onCreate()\n    }\n\n    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {\n        foreground(5987, NotificationCompat.Builder(this, CHANNEL).apply {\n            setSmallIcon(R.drawable.ic_service)\n            priority = NotificationCompat.PRIORITY_MIN\n            if (PrefsUtil.collapseDirectoryNotification)\n                setSubText(\"Actualizando widget\")\n            else\n                setContentTitle(\"Actualizando widget\")\n        }.build())\n        return super.onStartCommand(intent, flags, startId)\n    }\n\n    override fun onDestroy() {\n        stopForeground(true)\n        super.onDestroy()\n    }\n\n    override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {\n        return WEListProvider(applicationContext)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/knf/kuma/widgets/test.kt",
    "content": "package knf.kuma.widgets\n\nimport org.jetbrains.anko.doAsync\n\nobject Work{\n\n    fun doWork(callback: (Any) -> Unit){\n        doAsync {\n            val result: Any = Object()\n            //Some heavy work\n            callback(result)\n        }\n    }\n\n    fun doWork(callback: Inter){\n        doAsync {\n            val result: Any = Object()\n            //Some heavy work\n            callback.func1(result)\n            callback.func2(result)\n        }\n    }\n\n    fun doWork(callback: Abs){\n        doAsync {\n            val result: Any = Object()\n            //Some heavy work\n            callback.func1(result)\n            callback.func2(result)\n            callback.func3(result)\n            callback.func4(result)\n        }\n    }\n\n}\n\nclass Main{\n\n    fun main(){\n        //Lamda\n        Work.doWork {\n\n        }\n        //Interfaz\n        Work.doWork(object : Inter{\n            override fun func1(any: Any) {\n                //Obligatorio implementar\n            }\n\n            override fun func2(any: Any) {\n                //Obligatorio implementar\n            }\n        })\n        //Abstracto\n        Work.doWork(object : Abs(){\n            override fun func1(any: Any) {\n                //Opcional implementar\n            }\n\n            override fun func4(any: Any) {\n                //Opcional implementar\n            }\n        })\n    }\n\n}\n\ninterface Inter{\n    fun func1(any: Any)\n    fun func2(any: Any)\n}\n\nabstract class Abs{\n    open fun func1(any: Any){}\n    open fun func2(any: Any){}\n    open fun func3(any: Any){}\n    open fun func4(any: Any){}\n}\n"
  },
  {
    "path": "app/src/main/res/anim/anim_fall_down.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n     android:duration=\"600\">\n    <translate\n        android:fromYDelta=\"-15%\"\n        android:interpolator=\"@android:anim/decelerate_interpolator\"\n        android:toYDelta=\"0\"/>\n\n    <alpha\n        android:fromAlpha=\"0\"\n        android:interpolator=\"@android:anim/decelerate_interpolator\"\n        android:toAlpha=\"1\"/>\n\n    <scale\n        android:fromXScale=\"105%\"\n        android:fromYScale=\"105%\"\n        android:interpolator=\"@android:anim/decelerate_interpolator\"\n        android:pivotX=\"50%\"\n        android:pivotY=\"50%\"\n        android:toXScale=\"100%\"\n        android:toYScale=\"100%\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/anim_fall_up.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\"\n     android:duration=\"600\">\n    <translate\n        android:fromYDelta=\"15%\"\n        android:interpolator=\"@android:anim/decelerate_interpolator\"\n        android:toYDelta=\"0\"/>\n\n    <alpha\n        android:fromAlpha=\"0\"\n        android:interpolator=\"@android:anim/decelerate_interpolator\"\n        android:toAlpha=\"1\"/>\n\n    <scale\n        android:fromXScale=\"105%\"\n        android:fromYScale=\"105%\"\n        android:interpolator=\"@android:anim/decelerate_interpolator\"\n        android:pivotX=\"50%\"\n        android:pivotY=\"50%\"\n        android:toXScale=\"100%\"\n        android:toYScale=\"100%\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/fade_in.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<alpha xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:duration=\"@android:integer/config_shortAnimTime\"\r\n    android:fromAlpha=\"0.0\" android:interpolator=\"@anim/decelerate_cubic\"\r\n    android:toAlpha=\"1.0\" />"
  },
  {
    "path": "app/src/main/res/anim/fade_out.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<alpha xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:duration=\"@android:integer/config_shortAnimTime\"\r\n    android:fromAlpha=\"1.0\" android:interpolator=\"@anim/decelerate_cubic\"\r\n    android:toAlpha=\"0.0\" />"
  },
  {
    "path": "app/src/main/res/anim/fadein.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/linear_interpolator\">\n    <alpha\n        android:duration=\"@android:integer/config_shortAnimTime\"\n        android:fromAlpha=\"0.0\"\n        android:toAlpha=\"1.0\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/fadeout.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/linear_interpolator\">\n    <alpha\n        android:duration=\"@android:integer/config_shortAnimTime\"\n        android:fromAlpha=\"1.0\"\n        android:toAlpha=\"0.0\" />\n</set>"
  },
  {
    "path": "app/src/main/res/anim/grid_fall_down.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<gridLayoutAnimation\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:animation=\"@anim/anim_fall_up\"\n    android:animationOrder=\"normal\"\n    android:columnDelay=\"15%\"\n    android:direction=\"top_to_bottom|left_to_right\"\n    android:rowDelay=\"15%\"/>\n"
  },
  {
    "path": "app/src/main/res/anim/layout_fall_down.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layoutAnimation xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                 android:animation=\"@anim/anim_fall_down\"\n                 android:animationOrder=\"normal\"\n                 android:delay=\"15%\">\n\n</layoutAnimation>"
  },
  {
    "path": "app/src/main/res/anim/scale_down.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n        android:duration=\"200\"\n        android:fromXScale=\"1.0\"\n        android:fromYScale=\"1.0\"\n        android:interpolator=\"@android:anim/linear_interpolator\"\n        android:pivotX=\"50%\"\n        android:pivotY=\"50%\"\n        android:toXScale=\"0\"\n        android:toYScale=\"0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/anim/scale_up.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n        android:duration=\"200\"\n        android:fromXScale=\"0\"\n        android:fromYScale=\"0\"\n        android:interpolator=\"@android:anim/linear_interpolator\"\n        android:pivotX=\"50%\"\n        android:pivotY=\"50%\"\n        android:toXScale=\"1.0\"\n        android:toYScale=\"1.0\"/>\n</set>"
  },
  {
    "path": "app/src/main/res/color/accent_button_state.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <item android:color=\"@color/text_disable\" android:state_enabled=\"false\"/>\r\n    <item android:color=\"?attr/colorSecondary\"/>\r\n</selector>"
  },
  {
    "path": "app/src/main/res/color/firebase_selector.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <item android:color=\"@color/firestore\" android:state_enabled=\"true\" />\r\n    <item android:alpha=\"0.12\" android:color=\"?attr/colorOnSurface\" />\r\n</selector>"
  },
  {
    "path": "app/src/main/res/color/raised_button_text_state.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <item android:color=\"#fff\" android:state_enabled=\"true\" />\r\n    <item android:alpha=\"0.38\" android:color=\"?attr/colorOnSurface\" />\r\n</selector>"
  },
  {
    "path": "app/src/main/res/color/sync_button_color.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:color=\"@color/text_disable\" android:state_enabled=\"false\"/>\n    <item android:color=\"@android:color/white\"/>\n</selector>"
  },
  {
    "path": "app/src/main/res/color/text_secondary.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <item android:alpha=\"?android:disabledAlpha\"\r\n        android:color=\"?android:colorForeground\"\r\n        android:state_enabled=\"false\"/>\r\n    <item android:alpha=\"0\"\r\n        android:color=\"?android:colorForeground\"/>\r\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/action_chapter.xml",
    "content": "<!-- drawable/dots_vertical.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,16A2,2 0 0,1 14,18A2,2 0 0,1 12,20A2,2 0 0,1 10,18A2,2 0 0,1 12,16M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10M12,4A2,2 0 0,1 14,6A2,2 0 0,1 12,8A2,2 0 0,1 10,6A2,2 0 0,1 12,4Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/action_expand.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#000\"\n        android:pathData=\"M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/action_search.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/action_shrink.xml",
    "content": "<!-- drawable/chevron_up.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#000\"\n        android:pathData=\"M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/anim_check_sync.xml",
    "content": "<animated-vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\">\n    <aapt:attr name=\"android:drawable\">\n        <vector\n            android:name=\"vector\"\n            android:width=\"24dp\"\n            android:height=\"24dp\"\n            android:viewportWidth=\"24\"\n            android:viewportHeight=\"24\">\n            <path\n                android:name=\"path\"\n                android:fillColor=\"#8A000000\"\n                android:pathData=\"M 12 18 C 10.409 18 8.882 17.367 7.757 16.243 C 6.633 15.118 6 13.591 6 12 C 6 11 6.25 10.03 6.7 9.2 L 5.24 7.74 C 4.46 8.97 4 10.43 4 12 C 4 14.121 4.843 16.157 6.343 17.657 C 7.843 19.157 9.879 20 12 20 L 12 23 L 16 19 L 12 15 M 12 4 L 12 1 L 8 5 L 12 9 L 12 6 C 13.591 6 15.118 6.633 16.243 7.757 C 17.367 8.882 18 10.409 18 12 C 18 13 17.75 13.97 17.3 14.8 L 18.76 16.26 C 19.54 15.03 20 13.57 20 12 C 20 9.879 19.157 7.843 17.657 6.343 C 16.157 4.843 14.121 4 12 4 Z\"\n                android:strokeWidth=\"1\" />\n        </vector>\n    </aapt:attr>\n    <target android:name=\"path\">\n        <aapt:attr name=\"android:animation\">\n            <set>\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/fast_out_slow_in\"\n                    android:propertyName=\"pathData\"\n                    android:valueFrom=\"M 9 20.42 L 9 20.42 L 7.758 19.178 L 6.516 17.936 C 6.102 17.522 5.688 17.108 5.274 16.694 C 4.86 16.28 4.446 15.866 4.032 15.452 C 3.618 15.038 3.204 14.624 2.79 14.21 L 3.733 13.267 C 4.048 12.952 4.362 12.638 4.677 12.323 C 4.991 12.009 5.306 11.694 5.62 11.38 C 6.747 12.51 7.873 13.64 9 14.77 C 12.293 11.473 15.587 8.177 18.88 4.88 C 19.823 5.823 20.767 6.767 21.71 7.71 C 17.473 11.947 13.237 16.183 9 20.42 C 9 20.42 9 20.42 9 20.42 M 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 L 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125\"\n                    android:valueTo=\"M 12 15 L 16 19 L 12 23 L 12 20 C 9.879 20 7.843 19.157 6.343 17.657 C 4.843 16.157 4 14.121 4 12 C 4 10.43 4.46 8.97 5.24 7.74 L 6.7 9.2 C 6.25 10.03 6 11 6 12 C 6 13.591 6.633 15.118 7.757 16.243 C 8.038 16.524 8.345 16.774 8.671 16.992 C 8.834 17.101 9.002 17.201 9.174 17.293 C 9.347 17.385 9.524 17.468 9.704 17.543 C 10.064 17.692 10.44 17.807 10.824 17.884 C 11.209 17.96 11.602 18 12 18 M 12 6 L 12 9 L 8 5 L 12 1 L 12 4 L 12 4 C 14.121 4 16.157 4.843 17.657 6.343 C 19.157 7.843 20 9.879 20 12 C 20 13.57 19.54 15.03 18.76 16.26 L 17.3 14.8 C 17.75 13.97 18 13 18 12 C 18 10.409 17.367 8.882 16.243 7.757 C 15.118 6.633 13.591 6 12 6\"\n                    android:valueType=\"pathType\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/fast_out_slow_in\"\n                    android:propertyName=\"fillColor\"\n                    android:valueFrom=\"#64dd17\"\n                    android:valueTo=\"#8A000000\"\n                    android:valueType=\"colorType\" />\n            </set>\n        </aapt:attr>\n    </target>\n</animated-vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/anim_sync_check.xml",
    "content": "<animated-vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\">\n    <aapt:attr name=\"android:drawable\">\n        <vector\n            android:name=\"vector\"\n            android:width=\"24dp\"\n            android:height=\"24dp\"\n            android:viewportWidth=\"24\"\n            android:viewportHeight=\"24\">\n            <path\n                android:name=\"path\"\n                android:fillColor=\"#8A000000\"\n                android:pathData=\"M 12 18 C 10.409 18 8.882 17.367 7.757 16.243 C 6.633 15.118 6 13.591 6 12 C 6 11 6.25 10.03 6.7 9.2 L 5.24 7.74 C 4.46 8.97 4 10.43 4 12 C 4 14.121 4.843 16.157 6.343 17.657 C 7.843 19.157 9.879 20 12 20 L 12 23 L 16 19 L 12 15 M 12 4 L 12 1 L 8 5 L 12 9 L 12 6 C 13.591 6 15.118 6.633 16.243 7.757 C 17.367 8.882 18 10.409 18 12 C 18 13 17.75 13.97 17.3 14.8 L 18.76 16.26 C 19.54 15.03 20 13.57 20 12 C 20 9.879 19.157 7.843 17.657 6.343 C 16.157 4.843 14.121 4 12 4 Z\"\n                android:strokeWidth=\"1\" />\n        </vector>\n    </aapt:attr>\n    <target android:name=\"path\">\n        <aapt:attr name=\"android:animation\">\n            <set>\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/fast_out_slow_in\"\n                    android:propertyName=\"pathData\"\n                    android:valueFrom=\"M 12 15 L 16 19 L 12 23 L 12 20 C 9.879 20 7.843 19.157 6.343 17.657 C 4.843 16.157 4 14.121 4 12 C 4 10.43 4.46 8.97 5.24 7.74 L 6.7 9.2 C 6.25 10.03 6 11 6 12 C 6 13.591 6.633 15.118 7.757 16.243 C 8.038 16.524 8.345 16.774 8.671 16.992 C 8.997 17.209 9.343 17.394 9.704 17.543 C 10.064 17.692 10.44 17.807 10.824 17.884 C 11.209 17.96 11.602 18 12 18 M 12 6 L 12 9 L 8 5 L 12 1 L 12 4 L 12 4 C 14.121 4 16.157 4.843 17.657 6.343 C 19.157 7.843 20 9.879 20 12 C 20 13.57 19.54 15.03 18.76 16.26 L 17.3 14.8 C 17.75 13.97 18 13 18 12 C 18 10.409 17.367 8.882 16.243 7.757 C 15.118 6.633 13.591 6 12 6\"\n                    android:valueTo=\"M 9 20.42 L 7.758 19.178 L 6.516 17.936 L 5.274 16.694 C 4.86 16.28 4.446 15.866 4.032 15.452 C 3.618 15.038 3.204 14.624 2.79 14.21 C 3.104 13.896 3.419 13.581 3.733 13.267 L 4.677 12.323 C 4.991 12.009 5.306 11.694 5.62 11.38 C 6.747 12.51 7.873 13.64 9 14.77 C 12.293 11.473 15.587 8.177 18.88 4.88 C 19.823 5.823 20.767 6.767 21.71 7.71 C 17.473 11.947 13.237 16.183 9 20.42 C 9 20.42 9 20.42 9 20.42 M 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 L 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125\"\n                    android:valueType=\"pathType\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/fast_out_slow_in\"\n                    android:propertyName=\"fillColor\"\n                    android:valueFrom=\"#8A000000\"\n                    android:valueTo=\"#64dd17\"\n                    android:valueType=\"colorType\" />\n            </set>\n        </aapt:attr>\n    </target>\n</animated-vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/background_ripple.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:color=\"?android:colorControlHighlight\"/>"
  },
  {
    "path": "app/src/main/res/drawable/bottom_directory.xml",
    "content": "<!-- drawable/view_list.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#000\"\n        android:pathData=\"M9,5V9H21V5M9,19H21V15H9M9,14H21V10H9M4,9H8V5H4M4,19H8V15H4M4,14H8V10H4V14Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/bottom_recents.xml",
    "content": "<!-- drawable/history.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#000\"\n        android:pathData=\"M11,7V12.11L15.71,14.9L16.5,13.62L12.5,11.25V7M12.5,2C8.97,2 5.91,3.92 4.27,6.77L2,4.5V11H8.5L5.75,8.25C6.96,5.73 9.5,4 12.5,4A7.5,7.5 0 0,1 20,11.5A7.5,7.5 0 0,1 12.5,19C9.23,19 6.47,16.91 5.44,14H3.34C4.44,18.03 8.11,21 12.5,21C17.74,21 22,16.75 22,11.5A9.5,9.5 0 0,0 12.5,2Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/bottom_settings.xml",
    "content": "<!-- drawable/settings.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#000\"\n        android:pathData=\"M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/bottom_state.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:color=\"?colorAccent\" android:state_checked=\"true\"/>\n    <item android:color=\"?android:attr/textColorSecondary\"/>\n</selector>"
  },
  {
    "path": "app/src/main/res/drawable/chip_change.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=\"#107307\"/>\n\n    <padding\n        android:bottom=\"6dp\"\n        android:left=\"12dp\"\n        android:right=\"12dp\"\n        android:top=\"6dp\"/>\n\n    <corners android:radius=\"30dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/chip_error.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=\"#ae1315\"/>\n\n    <padding\n        android:bottom=\"6dp\"\n        android:left=\"12dp\"\n        android:right=\"12dp\"\n        android:top=\"6dp\"/>\n\n    <corners android:radius=\"30dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/chip_new.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=\"#d4b621\"/>\n\n    <padding\n        android:bottom=\"6dp\"\n        android:left=\"12dp\"\n        android:right=\"12dp\"\n        android:top=\"6dp\"/>\n\n    <corners android:radius=\"30dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/chip_ripple.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ripple xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:color=\"?android:attr/colorControlHighlight\">\n    <item android:id=\"@android:id/mask\">\n        <shape android:shape=\"rectangle\">\n            <solid android:color=\"?colorAccent\"/>\n            <padding\n                android:bottom=\"6dp\"\n                android:left=\"12dp\"\n                android:right=\"12dp\"\n                android:top=\"6dp\"/>\n            <corners android:radius=\"30dp\"/>\n        </shape>\n    </item>\n    <item android:drawable=\"@drawable/chip_shape\"/>\n</ripple>"
  },
  {
    "path": "app/src/main/res/drawable/chip_shape.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=\"?colorAccent\"/>\n\n    <padding\n        android:bottom=\"6dp\"\n        android:left=\"12dp\"\n        android:right=\"12dp\"\n        android:top=\"6dp\"/>\n\n    <corners android:radius=\"30dp\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/circular_shade.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    <gradient\n        android:angle=\"225\"\n        android:centerColor=\"#00000000\"\n        android:endColor=\"#00000000\"\n        android:startColor=\"#E6000000\" />\n\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/drawable_splash.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <item android:drawable=\"@color/colorSplash\" />\r\n\r\n    <item>\r\n        <bitmap\r\n            android:gravity=\"center\"\r\n            android:src=\"@drawable/ic_launcher\"/>\r\n    </item>\r\n\r\n</layer-list>"
  },
  {
    "path": "app/src/main/res/drawable/faq_indicator.xml",
    "content": "<!-- drawable/chevron_right.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/grad_1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <gradient\n        android:angle=\"-90\"\n        android:endColor=\"#f75b4d\"\n        android:startColor=\"@color/ic_launcher_background\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/grad_2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <gradient\n        android:angle=\"-90\"\n        android:endColor=\"#4d6cf7\"\n        android:startColor=\"@color/ic_launcher_background\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/grad_3.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <gradient\n        android:angle=\"-90\"\n        android:endColor=\"#4df7f1\"\n        android:startColor=\"@color/ic_launcher_background\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/grad_4.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <gradient\n        android:angle=\"-90\"\n        android:endColor=\"#9c4df7\"\n        android:startColor=\"@color/ic_launcher_background\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/heart_broken.xml",
    "content": "<!-- drawable/heart_broken.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C8.17,3 8.82,3.12 9.44,3.33L13,9.35L9,14.35L12,21.35V21.35M16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35L11,14.35L15.5,9.35L12.85,4.27C13.87,3.47 15.17,3 16.5,3Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/heart_empty.xml",
    "content": "<!-- drawable/heart_outline.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M12.1,18.55L12,18.65L11.89,18.55C7.14,14.24 4,11.39 4,8.5C4,6.5 5.5,5 7.5,5C9.04,5 10.54,6 11.07,7.36H12.93C13.46,6 14.96,5 16.5,5C18.5,5 20,6.5 20,8.5C20,11.39 16.86,14.24 12.1,18.55M16.5,3C14.76,3 13.09,3.81 12,5.08C10.91,3.81 9.24,3 7.5,3C4.42,3 2,5.41 2,8.5C2,12.27 5.4,15.36 10.55,20.03L12,21.35L13.45,20.03C18.6,15.36 22,12.27 22,8.5C22,5.41 19.58,3 16.5,3Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/heart_full.xml",
    "content": "<!-- drawable/heart.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_account_edit.xml",
    "content": "<!-- drawable/account_edit.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M21.7,13.35L20.7,14.35L18.65,12.3L19.65,11.3C19.86,11.09 20.21,11.09 20.42,11.3L21.7,12.58C21.91,12.79 21.91,13.14 21.7,13.35M12,18.94L18.06,12.88L20.11,14.93L14.06,21H12V18.94M12,14C7.58,14 4,15.79 4,18V20H10V18.11L14,14.11C13.34,14.03 12.67,14 12,14M12,4A4,4 0 0,0 8,8A4,4 0 0,0 12,12A4,4 0 0,0 16,8A4,4 0 0,0 12,4Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_airplane.xml",
    "content": "<!-- drawable/airplane_takeoff.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M2.5,19H21.5V21H2.5V19M22.07,9.64C21.86,8.84 21.03,8.36 20.23,8.58L14.92,10L8,3.57L6.09,4.08L10.23,11.25L5.26,12.58L3.29,11.04L1.84,11.43L3.66,14.59L4.43,15.92L6.03,15.5L11.34,14.07L15.69,12.91L21,11.5C21.81,11.26 22.28,10.44 22.07,9.64Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_battery.xml",
    "content": "<!-- drawable/battery_alert.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M13,14H11V9H13M13,18H11V16H13M16.67,4H15V2H9V4H7.33A1.33,1.33 0 0,0 6,5.33V20.67C6,21.4 6.6,22 7.33,22H16.67A1.33,1.33 0 0,0 18,20.67V5.33C18,4.6 17.4,4 16.67,4Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_bored.xml",
    "content": "<!-- drawable/account_question.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M13,8A4,4 0 0,1 9,12A4,4 0 0,1 5,8A4,4 0 0,1 9,4A4,4 0 0,1 13,8M17,18V20H1V18C1,15.79 4.58,14 9,14C13.42,14 17,15.79 17,18M20.5,14.5V16H19V14.5H20.5M18.5,9.5H17V9A3,3 0 0,1 20,6A3,3 0 0,1 23,9C23,9.97 22.5,10.88 21.71,11.41L21.41,11.6C20.84,12 20.5,12.61 20.5,13.3V13.5H19V13.3C19,12.11 19.6,11 20.59,10.35L20.88,10.16C21.27,9.9 21.5,9.47 21.5,9A1.5,1.5 0 0,0 20,7.5A1.5,1.5 0 0,0 18.5,9V9.5Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_calendar.xml",
    "content": "<!-- drawable/calendar_multiple.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M21,17V8H7V17H21M21,3A2,2 0 0,1 23,5V17A2,2 0 0,1 21,19H7C5.89,19 5,18.1 5,17V5A2,2 0 0,1 7,3H8V1H10V3H18V1H20V3H21M3,21H17V23H3C1.89,23 1,22.1 1,21V9H3V21M19,15H15V11H19V15Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_cast.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M21,3H3C1.89,3 1,3.89 1,5V8H3V5H21V19H14V21H21A2,2 0 0,0 23,19V5C23,3.89 22.1,3 21,3M1,10V12A9,9 0 0,1 10,21H12C12,14.92 7.07,10 1,10M19,7H5V8.63C8.96,9.91 12.09,13.04 13.37,17H19M1,14V16A5,5 0 0,1 6,21H8A7,7 0 0,0 1,14M1,18V21H4A3,3 0 0,0 1,18Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_clock.xml",
    "content": "<!-- drawable/restore_clock.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M13,3A9,9 0 0,0 4,12H1L4.89,15.89L4.96,16.03L9,12H6A7,7 0 0,1 13,5A7,7 0 0,1 20,12A7,7 0 0,1 13,19C11.07,19 9.32,18.21 8.06,16.94L6.64,18.36C8.27,20 10.5,21 13,21A9,9 0 0,0 22,12A9,9 0 0,0 13,3M12,8V13L16.28,15.54L17,14.33L13.5,12.25V8H12Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_cloud.xml",
    "content": "<!-- drawable/cloud_check.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M10,17L6.5,13.5L7.91,12.08L10,14.17L15.18,9L16.59,10.41M19.35,10.03C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.03C2.34,8.36 0,10.9 0,14A6,6 0 0,0 6,20H19A5,5 0 0,0 24,15C24,12.36 21.95,10.22 19.35,10.03Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_completed.xml",
    "content": "<!-- drawable/format_list_checks.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M3,5H9V11H3V5M5,7V9H7V7H5M11,7H21V9H11V7M11,15H21V17H11V15M5,20L1.5,16.5L2.91,15.09L5,17.17L9.59,12.59L11,14L5,20Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_droped.xml",
    "content": "<!-- drawable/delete_variant.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M21.03,3L18,20.31C17.83,21.27 17,22 16,22H8C7,22 6.17,21.27 6,20.31L2.97,3H21.03M5.36,5L8,20H16L18.64,5H5.36M9,18V14H13V18H9M13,13.18L9.82,10L13,6.82L16.18,10L13,13.18Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_egg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"2250\"\n        android:viewportHeight=\"2250\">\n\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1044 2239 c-89 -8 -128 -21 -225 -71 -90 -46 -185 -122 -254 -203 -43 -51 -46 -58 -25 -52 299 75 871 75 1170 0 21 -6 18 1 -25 52 -69 81 -164 157 -255 205 -122 63 -238 84 -386 69z\"\n        android:strokeWidth=\"1\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M900 1814 c-180 -16 -470 -74 -488 -97 -32 -41 -82 -250 -82 -346 l0 -56 88 -88 87 -87 100 100 c55 55 104 100 109 100 5 0 53 -44 108 -97 l98 -97 98 97 c54 53 102 97 107 97 5 0 53 -44 107 -97 l98 -97 98 97 c55 53 103 97 108 97 5 0 54 -45 109 -100 l100 -100 88 88 89 87 -6 90 c-5 96 -22 172 -59 263 l-22 57 -105 26 c-181 45 -316 61 -560 64 -124 2 -245 1 -270 -1z m-334 -228 c38 -38 44 -77 19 -126 -17 -32 -61 -60 -95 -60 -29 0 -76 26 -94 52 -9 12 -16 40 -16 61 0 31 7 46 34 73 28 28 42 34 76 34 34 0 48 -6 76 -34z m403 20 c55 -29 68 -114 25 -165 -50 -60 -144 -48 -178 24 -20 41 -20 58 -1 95 30 57 94 77 154 46z m434 -7 c15 -11 32 -37 38 -58 23 -76 -46 -152 -124 -137 -98 18 -120 156 -32 204 33 18 90 14 118 -9z m433 -13 c38 -38 44 -77 19 -126 -17 -32 -61 -60 -95 -60 -34 0 -78 28 -95 60 -25 49 -19 88 19 126 28 28 42 34 76 34 34 0 48 -6 76 -34z\"\n        android:strokeWidth=\"1\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M610 1055 c-52 -52 -101 -95 -110 -95 -8 0 -43 28 -77 62 -35 34 -63 58 -63 53 0 -26 54 -212 91 -313 48 -131 44 -127 199 -166 160 -39 267 -50 475 -50 208 0 315 11 475 50 155 39 151 35 199 166 37 101 91 287 91 313 0 5 -28 -19 -63 -53 -34 -34 -69 -62 -77 -62 -8 0 -59 44 -112 97 l-98 98 -98 -98 c-53 -53 -104 -97 -112 -97 -9 0 -58 43 -110 95 l-95 95 -95 -95 c-52 -52 -102 -95 -110 -95 -9 0 -58 43 -110 95 -52 52 -97 95 -100 95 -3 0 -48 -43 -100 -95z m181 -214 c80 -81 -9 -222 -113 -178 -62 26 -87 75 -68 132 26 78 124 103 181 46z m402 9 c106 -84 -14 -250 -128 -176 -91 59 -49 196 60 196 27 0 51 -7 68 -20z m410 0 c14 -11 31 -36 37 -55 25 -77 -58 -160 -135 -135 -78 26 -103 124 -46 181 37 36 104 41 144 9z\"\n        android:strokeWidth=\"1\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M631 383 c101 -164 220 -286 336 -340 65 -32 81 -35 159 -35 79 0 92 3 163 38 98 48 214 162 304 299 36 55 64 101 63 103 -2 1 -36 -5 -77 -13 -274 -58 -634 -58 -907 0 -40 8 -75 15 -78 15 -2 0 15 -30 37 -67z\"\n        android:strokeWidth=\"1\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_evangelion.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"7200\"\n        android:viewportHeight=\"7200\">\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M3672,6204c-13,-24 -31,-115 -36,-179 -2,-27 -6,-57 -9,-65 -3,-8 -13,-71 -22,-140 -91,-710 -292,-1624 -496,-2255 -28,-88 -53,-167 -56,-175 -2,-8 -39,-34 -81,-58 -93,-51 -195,-129 -187,-143 4,-5 25,6 48,25 23,19 87,61 142,93 88,53 102,64 113,99 145,429 287,970 397,1516 76,381 173,1003 161,1034 -3,7 -1,16 3,19 5,2 12,26 15,52 14,103 18,123 25,123 5,0 11,-35 15,-77 6,-75 17,-106 30,-85 4,6 2,53 -4,104 -8,67 -16,98 -29,112 -19,18 -19,18 -29,0z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M3725,5961c-6,-12 41,-442 52,-471 3,-8 5,-27 4,-42 -1,-14 2,-29 7,-32 6,-3 8,-15 5,-26 -3,-11 -2,-28 2,-37 4,-10 7,-30 6,-45 -1,-14 2,-29 8,-32 6,-4 8,-13 4,-21 -3,-8 -2,-23 2,-32 4,-10 7,-30 6,-45 -1,-14 2,-29 7,-32 6,-3 8,-15 5,-26 -3,-11 -2,-28 2,-37 5,-10 7,-28 6,-40 -1,-11 3,-24 8,-28 15,-8 25,21 16,43 -5,9 -7,27 -6,39 1,13 -1,28 -5,35 -5,7 -7,25 -5,40 1,14 -2,29 -8,32 -6,4 -8,13 -4,21 3,8 2,23 -2,33 -4,9 -7,29 -6,44 1,14 -2,29 -7,32 -6,3 -8,15 -5,26 3,11 2,28 -2,37 -4,10 -7,30 -6,45 1,14 -3,29 -9,33 -5,3 -8,11 -4,16 7,13 -46,461 -56,472 -4,5 -11,4 -15,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M3854,4986c-3,-9 -3,-24 1,-33 4,-10 9,-37 11,-61 2,-24 7,-48 11,-55 4,-7 6,-22 5,-34 -2,-11 1,-24 6,-27 6,-3 8,-15 5,-26 -3,-11 0,-26 6,-33 6,-8 8,-16 5,-19 -7,-7 16,-141 26,-152 5,-5 6,-14 4,-20 -13,-34 154,-728 231,-961 76,-228 100,-272 186,-340 94,-75 194,-174 245,-245 99,-135 179,-304 210,-438 8,-37 17,-74 21,-82 3,-8 5,-25 4,-37 -1,-13 1,-28 5,-34 3,-6 7,-41 8,-78 0,-36 6,-68 11,-71 12,-6 20,105 9,129 -4,9 -6,26 -5,38 1,13 -1,28 -5,34 -3,6 -8,28 -9,48 -5,58 -61,214 -115,320 -85,164 -206,309 -363,432 -64,50 -101,119 -164,303 -48,141 -175,630 -218,841 -14,72 -29,137 -32,145 -4,8 -5,19 -4,23 2,11 -18,128 -26,147 -3,8 -5,25 -4,37 1,11 -2,24 -8,27 -6,4 -8,13 -4,21 3,8 2,23 -2,33 -4,9 -9,36 -11,60 -2,24 -7,48 -11,55 -4,7 -6,22 -5,34 4,26 -16,41 -24,19z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2684,3107c-87,-90 -151,-177 -207,-277 -36,-66 -98,-214 -95,-228 1,-4 -4,-20 -11,-36 -6,-16 -10,-35 -7,-42 3,-8 1,-16 -5,-19 -5,-4 -9,-12 -8,-18 1,-7 -1,-20 -5,-29 -10,-22 0,-51 15,-43 5,4 9,17 7,28 -1,12 1,28 6,35 4,7 5,16 2,19 -3,3 -1,11 4,18 5,7 12,25 14,41 2,16 7,38 11,49 5,11 16,41 26,67 59,153 150,296 267,419 45,48 79,90 74,93 -5,3 -45,-31 -88,-77z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2964,2860c-89,-28 -181,-123 -205,-213 -35,-129 33,-270 164,-339 60,-32 184,-32 244,0 63,33 106,74 139,134 25,46 29,63 29,133 0,70 -4,87 -29,133 -55,98 -140,153 -246,158 -36,2 -79,-1 -96,-6zM3145,2823c171,-58 222,-306 90,-438 -100,-100 -280,-100 -380,0 -100,100 -100,280 0,380 70,71 186,94 290,58z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M4104,2850c-89,-28 -181,-123 -205,-213 -35,-129 33,-270 164,-339 60,-32 184,-32 244,0 100,52 161,140 170,242 3,32 2,67 -2,77 -4,10 -9,25 -10,34 -3,28 -53,106 -86,133 -75,63 -192,91 -275,66zM4281,2815c102,-35 174,-138 170,-244 -6,-166 -110,-271 -266,-271 -154,0 -265,111 -265,265 0,112 67,215 161,248 57,20 144,21 200,2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2335,2387c-9,-22 -2,-62 10,-60 6,1 11,14 13,29 4,32 -14,56 -23,31z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2325,2240c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M4845,2198c-9,-24 -1,-103 10,-103 14,0 19,95 6,108 -7,7 -12,5 -16,-5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2336,2133c-10,-10 -7,-61 4,-68 5,-3 7,-12 3,-20 -3,-8 -2,-23 2,-32 5,-10 7,-25 6,-35 -1,-9 3,-19 8,-22 6,-4 8,-13 5,-20 -3,-8 0,-17 5,-21 6,-3 9,-10 6,-15 -8,-13 42,-145 93,-243 64,-126 174,-273 193,-261 5,3 -12,31 -38,62 -87,107 -150,220 -197,352 -15,41 -29,82 -33,90 -3,8 -5,20 -4,27 1,6 -3,14 -8,17 -5,3 -7,15 -4,25 3,10 0,22 -6,25 -5,4 -8,13 -4,21 3,8 2,23 -2,33 -4,9 -7,31 -6,48 2,31 -10,50 -23,37z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M4836,2069c-2,-8 -9,-43 -16,-79 -17,-97 -65,-232 -117,-333 -122,-236 -327,-430 -576,-547 -80,-38 -241,-90 -278,-90 -10,0 -20,-4 -24,-10 -3,-5 -12,-7 -20,-3 -8,3 -23,2 -32,-2 -10,-4 -34,-8 -53,-9 -19,0 -36,-5 -38,-11 -3,-12 44,-19 66,-9 10,4 27,6 39,5 11,-1 24,2 27,7 3,6 14,8 24,6 27,-8 188,43 288,90 319,151 543,388 664,704 43,109 77,269 62,284 -9,9 -12,8 -16,-3z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2686,1362c-3,-5 3,-17 13,-26 11,-10 22,-13 25,-8 3,5 -3,17 -13,26 -11,10 -22,13 -25,8z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2756,1302c-3,-5 5,-19 18,-31 13,-13 26,-18 30,-13 3,5 -5,19 -18,31 -13,13 -26,18 -30,13z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2815,1249c-20,-31 341,-222 440,-233 11,-1 26,-6 33,-10 7,-4 16,-5 21,-1 5,3 13,1 16,-5 4,-6 14,-10 23,-9 10,1 25,-1 34,-6 22,-9 51,1 43,16 -4,5 -17,9 -28,8 -12,-1 -30,2 -40,6 -10,4 -21,5 -24,1 -3,-3 -12,-1 -20,6 -7,6 -16,8 -20,5 -3,-4 -11,-3 -17,2 -6,4 -42,19 -81,31 -99,32 -197,80 -293,143 -45,30 -85,51 -87,46z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M3445,990c-3,-5 0,-13 9,-16 21,-8 71,-1 71,11 0,14 -72,19 -80,5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M3682,6204c-19,-38 -27,-82 -67,-384 -98,-736 -292,-1623 -486,-2225 -28,-88 -55,-173 -60,-190 -7,-23 -25,-39 -81,-70 -162,-90 -341,-253 -441,-403 -108,-161 -183,-363 -207,-552 -14,-117 -13,-205 6,-329 69,-475 410,-872 874,-1019 138,-43 227,-56 385,-56 333,2 626,120 867,352 281,269 415,614 387,998 -18,241 -96,452 -242,654 -50,69 -183,202 -261,260 -49,37 -65,57 -92,115 -77,167 -209,641 -288,1035 -90,446 -180,1051 -257,1725 -11,95 -21,119 -37,89zM3182,2813c130,-73 175,-242 101,-376 -73,-129 -242,-174 -376,-100 -129,73 -174,242 -100,376 31,54 98,108 157,127 59,18 159,6 218,-27zM4322,2803c130,-73 175,-242 101,-376 -73,-129 -242,-174 -376,-100 -129,73 -174,242 -100,376 31,54 98,108 157,127 59,18 159,6 218,-27z\"\n        android:strokeColor=\"#00000000\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_fav.xml",
    "content": "<!-- drawable/heart.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_following.xml",
    "content": "<!-- drawable/eye_plus.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C12.36,19.5 12.72,19.5 13.08,19.45C13.03,19.13 13,18.82 13,18.5C13,17.94 13.08,17.38 13.24,16.84C12.83,16.94 12.42,17 12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12C17,12.29 16.97,12.59 16.92,12.88C17.58,12.63 18.29,12.5 19,12.5C20.17,12.5 21.31,12.84 22.29,13.5C22.56,13 22.8,12.5 23,12C21.27,7.61 17,4.5 12,4.5M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M18,14.5V17.5H15V19.5H18V22.5H20V19.5H23V17.5H20V14.5H18Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_memory.xml",
    "content": "<!-- drawable/account_question.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M13,8A4,4 0 0,1 9,12A4,4 0 0,1 5,8A4,4 0 0,1 9,4A4,4 0 0,1 13,8M17,18V20H1V18C1,15.79 4.58,14 9,14C13.42,14 17,15.79 17,18M20.5,14.5V16H19V14.5H20.5M18.5,9.5H17V9A3,3 0 0,1 20,6A3,3 0 0,1 23,9C23,9.97 22.5,10.88 21.71,11.41L21.41,11.6C20.84,12 20.5,12.61 20.5,13.3V13.5H19V13.3C19,12.11 19.6,11 20.59,10.35L20.88,10.16C21.27,9.9 21.5,9.47 21.5,9A1.5,1.5 0 0,0 20,7.5A1.5,1.5 0 0,0 18.5,9V9.5Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_midoriya.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"10790\"\n        android:viewportHeight=\"10790\">\n    <path\n        android:fillColor=\"@color/textPrimary\"\n        android:pathData=\"M4584,10252c-25,-20 -44,-90 -44,-165 0,-77 28,-254 60,-377 5,-19 12,-48 15,-65 4,-16 10,-39 15,-50 4,-11 14,-40 21,-65 7,-25 16,-49 21,-54 4,-6 8,-20 8,-32 0,-13 5,-26 10,-29 12,-8 13,-69 1,-93 -5,-9 -14,-28 -20,-42 -6,-14 -17,-34 -23,-45 -27,-41 -63,-101 -82,-135 -10,-19 -37,-60 -60,-90 -23,-30 -59,-81 -79,-112 -38,-58 -76,-93 -132,-122 -28,-15 -32,-14 -145,46 -467,249 -608,299 -748,269 -128,-27 -430,-254 -586,-439 -39,-47 -89,-103 -111,-126 -41,-42 -49,-55 -118,-186 -22,-41 -46,-82 -53,-91 -8,-8 -14,-21 -14,-28 0,-7 -13,-40 -29,-74 -16,-34 -32,-73 -34,-87 -3,-14 -13,-50 -22,-80 -9,-30 -21,-73 -27,-95 -5,-22 -14,-49 -18,-60 -5,-11 -12,-56 -15,-100 -4,-62 -2,-87 10,-109 8,-15 15,-35 15,-42 0,-8 7,-17 15,-20 8,-3 17,-15 21,-26 6,-20 193,-261 219,-283 7,-5 18,-26 25,-45 21,-54 41,-80 60,-80 10,0 28,-13 39,-29l20,-28 -24,-49c-13,-27 -45,-69 -70,-94 -51,-50 -53,-60 -35,-209 6,-48 15,-122 21,-166 18,-154 74,-462 100,-560 6,-22 15,-58 21,-80 29,-119 64,-230 120,-380 17,-44 51,-141 78,-215 26,-74 54,-151 61,-170 23,-59 163,-325 184,-350 7,-8 27,-42 44,-75 45,-86 103,-180 276,-445 108,-167 133,-203 204,-305 38,-55 91,-131 118,-170 123,-179 560,-750 682,-891 20,-22 63,-74 96,-114 33,-40 83,-99 110,-130 28,-31 95,-108 150,-171 319,-364 850,-893 1184,-1179 35,-30 101,-87 147,-127 53,-47 92,-73 110,-75 49,-5 47,4 -106,427 -37,105 -92,237 -141,343 -22,46 -39,87 -39,92 0,5 -40,90 -90,188 -49,99 -90,182 -90,186 0,4 46,-32 103,-81 128,-111 371,-315 492,-413 51,-41 138,-113 195,-160 157,-130 392,-316 564,-449 39,-30 98,-76 131,-101 140,-108 193,-148 261,-195 39,-27 113,-79 164,-115 51,-36 100,-69 109,-75 8,-5 49,-32 90,-59 87,-57 218,-129 327,-178 30,-14 68,-6 72,14 2,9 -11,47 -28,85 -17,37 -45,100 -62,138 -17,39 -43,98 -59,133 -16,34 -29,66 -29,71 0,8 -63,145 -165,356 -88,183 -328,662 -339,675 -7,8 -34,58 -61,110 -43,86 -68,131 -133,240 -12,19 -35,60 -52,90 -17,30 -40,71 -53,91 -12,19 -35,57 -51,85 -86,145 -257,410 -339,524 -212,294 -353,468 -519,638 -66,67 -115,122 -109,122 5,0 13,-4 16,-10 3,-5 23,-10 44,-10 20,0 41,-4 47,-9 20,-19 281,-44 484,-45 240,-1 245,-13 -135,290 -139,110 -358,277 -465,353 -95,67 -460,311 -466,311 -3,0 -25,14 -49,30 -24,17 -48,30 -52,30 -20,0 -32,23 -22,42 7,14 21,18 60,18 42,0 52,3 56,20 3,11 10,20 17,20 15,0 242,230 336,340 95,111 112,146 109,220 -2,57 -1,60 44,110 59,65 95,139 103,213 4,33 12,57 18,57 17,0 93,75 111,109 49,96 63,203 46,361 -17,152 -21,183 -30,205 -5,11 -14,40 -21,65 -15,58 -42,141 -69,210 -33,83 -52,133 -58,154 -4,11 -48,104 -99,207l-93,188 54,56c35,35 55,64 55,79 0,42 -45,112 -116,182 -60,59 -60,58 -69,274 -20,474 100,913 318,1168 39,47 34,77 -13,76 -147,-6 -255,-6 -380,1l-145,8 -80,70c-75,65 -186,147 -200,147 -6,0 -108,69 -202,137 -164,119 -373,295 -542,456 -137,131 -264,227 -300,227 -11,0 -23,5 -26,10 -10,17 -98,11 -121,-8zM3589,9054c121,-35 324,-136 891,-442 406,-218 641,-365 798,-496 173,-146 246,-264 287,-462 25,-126 69,-458 80,-609 7,-87 6,-89 -10,-65 -30,43 -207,219 -290,289 -276,231 -681,488 -1175,743 -432,223 -964,421 -1338,497l-84,17 60,75c114,142 276,282 457,394 42,26 93,54 113,61 51,18 147,17 211,-2zM3660,7810c86,-31 119,-46 328,-146 169,-81 305,-160 339,-196 28,-30 58,-97 145,-328 105,-280 158,-408 197,-485 56,-107 104,-139 378,-249l228,-92 13,-64c7,-35 10,-65 7,-68 -6,-6 -250,78 -390,135 -144,58 -235,107 -275,146 -44,43 -110,179 -241,494 -141,341 -167,391 -240,456 -146,132 -513,306 -599,284 -14,-3 -97,-70 -185,-148 -431,-382 -595,-474 -649,-363 -9,20 -16,37 -14,38 2,2 24,10 50,20 95,35 284,186 567,455 79,75 156,139 170,142 37,9 85,0 171,-31zM3674,7459c199,-54 297,-198 282,-414 -8,-122 -64,-453 -86,-510 -4,-11 -18,-56 -29,-100 -41,-150 -103,-360 -116,-390 -7,-16 -31,-86 -54,-155 -23,-69 -45,-130 -49,-137 -8,-12 -33,24 -137,187 -26,41 -56,87 -66,102 -11,15 -19,29 -19,32 0,2 -23,44 -51,93 -70,120 -168,324 -223,464 -42,106 -106,323 -106,360 0,8 19,49 43,90 24,41 52,89 63,107 10,19 45,69 77,113 60,81 112,129 140,129 9,0 19,5 22,10 3,6 21,10 38,11 18,0 41,4 52,9 29,13 171,12 219,-1z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M3378,9076c-47,-17 -166,-91 -270,-168 -166,-123 -391,-365 -367,-394 6,-8 22,-14 35,-14 35,0 350,-83 492,-129 471,-155 915,-365 1447,-684 256,-153 453,-290 630,-438 84,-70 240,-229 289,-293 15,-21 32,-34 36,-29 4,4 -1,87 -11,184 -42,415 -81,626 -134,734 -113,228 -380,429 -1045,787 -567,306 -770,407 -891,442 -64,19 -160,20 -211,2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M3490,7863c-14,-3 -74,-53 -138,-114 -327,-315 -566,-499 -649,-499 -33,0 -34,-11 -5,-65 18,-32 36,-52 55,-58 85,-28 248,79 612,402 88,78 171,145 185,148 82,21 444,-148 589,-274 62,-54 93,-115 230,-446 188,-454 222,-508 358,-580 146,-76 577,-235 588,-216 4,5 1,43 -6,85 -14,89 14,70 -272,184 -129,51 -228,98 -262,122 -75,53 -105,117 -285,593 -91,241 -115,294 -153,333 -44,46 -168,119 -349,206 -324,155 -426,192 -498,179z\"\n        android:strokeColor=\"#00000000\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_news.xml",
    "content": "<!-- drawable/newspaper.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M20,11H4V8H20M20,15H13V13H20M20,19H13V17H20M11,19H4V13H11M20.33,4.67L18.67,3L17,4.67L15.33,3L13.67,4.67L12,3L10.33,4.67L8.67,3L7,4.67L5.33,3L3.67,4.67L2,3V19A2,2 0 0,0 4,21H20A2,2 0 0,0 22,19V3L20.33,4.67Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_onepiece.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"5000\"\n        android:viewportHeight=\"5000\">\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1064,4526c-60,-31 -105,-66 -99,-77 4,-5 2,-9 -4,-9 -5,0 -13,-10 -17,-22 -4,-13 -12,-26 -18,-30 -6,-4 -11,-40 -11,-88l0,-80 -51,0c-69,0 -140,-32 -190,-88 -46,-49 -64,-96 -64,-163 0,-47 16,-115 31,-133 5,-6 19,-24 30,-39 12,-16 40,-40 63,-55 37,-24 50,-27 131,-27 56,0 96,5 105,12 8,7 32,26 52,43 21,18 44,30 51,28 8,-2 62,-48 121,-103 59,-55 129,-119 154,-143 81,-74 252,-234 325,-304 39,-38 76,-68 84,-68 15,0 18,36 3,45 -5,3 -10,17 -10,31 0,13 -4,24 -9,24 -5,0 -11,15 -14,33 -3,17 -10,50 -15,72 -25,103 -33,159 -39,280l-6,130 -78,75c-176,169 -221,210 -229,210 -21,0 -18,33 5,56 14,14 28,36 31,49 3,14 10,25 15,25 5,0 9,38 9,85 0,47 -4,85 -9,85 -5,0 -12,11 -15,25 -9,35 -68,91 -127,121 -62,31 -145,31 -205,0z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M3759,4527c-54,-34 -85,-60 -99,-87 -7,-14 -17,-28 -23,-31 -26,-17 -25,-199 2,-231 6,-7 22,-27 35,-44l25,-30 -26,-20c-15,-10 -64,-55 -109,-99 -45,-44 -107,-102 -137,-129l-55,-50 -1,-90c-1,-83 -9,-140 -42,-306 -6,-30 -15,-59 -19,-65 -4,-5 -11,-26 -15,-45 -4,-19 -16,-54 -26,-77 -40,-89 -14,-85 88,15 44,42 126,121 184,175 57,53 128,120 157,147 30,28 59,50 65,50 5,0 8,3 4,6 -3,3 14,25 38,48 24,22 71,67 105,99l61,58 20,-25c10,-13 41,-37 67,-52 39,-23 59,-27 119,-27 54,0 78,4 91,16 10,10 24,17 30,17 18,0 72,51 100,94 23,36 27,51 27,126 0,78 -2,89 -30,130 -43,63 -104,106 -171,120 -31,7 -70,9 -85,6 -28,-5 -40,6 -19,19 13,8 13,90 0,113 -5,9 -14,28 -20,42 -22,56 -52,87 -123,128 -54,31 -166,30 -218,-1z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2355,4509c-86,-13 -189,-41 -206,-55 -8,-8 -20,-14 -25,-14 -13,0 -101,-48 -125,-68 -53,-44 -116,-111 -139,-147 -14,-22 -31,-49 -38,-60 -7,-11 -18,-32 -25,-47 -6,-16 -14,-28 -18,-28 -4,0 -12,-30 -19,-67 -7,-38 -17,-73 -22,-80 -11,-13 -25,-243 -15,-243 9,0 60,23 72,33 35,26 89,58 110,63 14,3 25,10 25,15 0,4 19,14 43,21 23,6 44,15 47,19 3,5 28,14 55,21 28,7 52,16 55,20 5,7 113,29 240,50 76,12 368,5 396,-10 10,-5 52,-15 93,-21 41,-6 79,-15 85,-20 6,-4 26,-11 44,-15 34,-6 46,-11 165,-65 37,-17 72,-31 77,-31 6,0 10,-4 10,-8 0,-8 58,-32 78,-32 21,0 13,119 -14,225 -14,55 -26,106 -26,113 -1,6 -5,12 -10,12 -4,0 -8,6 -8,13 0,33 -83,160 -145,221 -31,30 -111,86 -124,86 -6,0 -11,4 -11,10 0,5 -12,12 -27,16 -16,4 -38,12 -49,20 -26,15 -125,42 -204,54 -68,10 -277,10 -345,-1z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2413,3902c-46,-2 -83,-6 -83,-11 0,-4 -38,-13 -85,-20 -47,-7 -85,-16 -85,-20 0,-4 -15,-11 -32,-16 -24,-7 -33,-15 -32,-30 4,-49 32,-216 37,-221 7,-7 143,14 172,26 11,5 62,12 113,16 50,3 92,10 93,15 4,74 -1,253 -7,257 -5,4 -46,6 -91,4z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2556,3892c-2,-4 -4,-64 -5,-134l0,-126 77,-7c42,-3 86,-10 97,-15 11,-5 52,-12 91,-15 69,-7 71,-6 77,17 4,12 7,35 7,50 0,15 4,29 9,32 15,10 20,138 6,152 -7,8 -54,19 -103,25 -50,7 -89,16 -86,21 3,4 -33,8 -80,8 -47,0 -87,-3 -90,-8z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2966,3783c-3,-21 -6,-52 -6,-70 0,-17 -4,-35 -10,-38 -5,-3 -10,-30 -10,-60l0,-53 43,-7c23,-4 51,-12 62,-19 11,-7 41,-18 68,-26 26,-7 47,-17 47,-21 0,-5 8,-9 18,-9 9,0 32,-9 50,-20 51,-31 58,-27 72,48 24,133 24,135 -7,162 -15,14 -43,32 -60,39 -18,7 -33,17 -33,21 0,4 -18,13 -40,20 -22,7 -40,16 -40,20 0,4 -20,13 -45,20 -25,7 -45,17 -45,21 0,5 -13,9 -29,9 -25,0 -29,-4 -35,-37z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1993,3788c-18,-6 -33,-14 -33,-18 0,-4 -18,-13 -40,-20 -22,-7 -40,-16 -40,-20 0,-4 -13,-13 -30,-20 -16,-7 -30,-16 -30,-20 0,-4 -14,-14 -32,-21 -18,-7 -40,-21 -50,-31 -18,-18 -25,-48 -10,-48 4,0 6,-18 4,-41 -3,-22 1,-46 7,-52 6,-6 11,-25 11,-43 0,-18 6,-34 13,-37 13,-4 75,21 95,40 7,7 24,16 38,19 13,3 24,9 24,13 0,5 19,14 43,21 23,8 51,20 62,27 11,7 28,13 38,13 18,0 19,6 12,98 -4,53 -11,101 -16,107 -5,5 -9,17 -9,27 0,20 -10,21 -57,6z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2410,3583c-41,-2 -77,-7 -80,-12 -3,-4 -43,-13 -89,-20 -80,-12 -127,-35 -104,-49 6,-4 17,-58 24,-120l13,-114 80,7c45,4 83,11 86,16 3,4 41,9 85,11l80,3 5,130c5,117 -1,159 -19,153 -3,-1 -40,-4 -81,-5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2553,3572c-14,-15 -17,-32 -5,-32 4,0 7,-53 7,-117l0,-118 80,-3c44,-2 82,-7 85,-11 3,-4 32,-11 65,-15l61,-7 13,78c7,43 13,105 14,138l2,60 -60,9c-33,5 -62,12 -65,16 -3,4 -45,9 -94,11 -65,3 -93,0 -103,-9z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2926,3498c-3,-13 -6,-34 -6,-48 0,-15 -4,-30 -9,-35 -5,-6 -12,-43 -15,-82 -6,-62 -5,-73 8,-73 9,0 16,-4 16,-8 0,-4 27,-14 60,-20 33,-7 60,-17 60,-22 0,-5 18,-13 41,-16 22,-4 47,-13 55,-21 16,-17 60,-13 56,5 -1,6 2,12 8,12 5,0 10,8 10,18 0,9 11,40 25,67 28,58 34,125 10,125 -8,0 -15,4 -15,8 0,5 -18,14 -40,21 -22,6 -40,16 -40,20 0,5 -22,14 -50,21 -27,7 -50,15 -50,19 0,7 -87,31 -110,31 -4,0 -10,-10 -14,-22z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2048,3503c-10,-2 -18,-8 -18,-12 0,-5 -20,-14 -45,-21 -25,-7 -45,-16 -45,-20 0,-4 -18,-13 -40,-20 -22,-7 -40,-16 -40,-20 0,-4 -15,-14 -32,-21 -18,-7 -39,-19 -45,-25 -15,-15 -17,-40 -4,-48 5,-3 14,-29 21,-57 7,-27 15,-47 18,-44 4,3 12,-9 18,-27 10,-29 15,-33 44,-31 18,1 35,6 39,11 3,5 26,16 51,23 25,7 50,19 57,25 7,6 32,15 58,18 52,8 50,-1 33,146 -14,128 -19,137 -70,123z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M2310,3228c-52,-5 -97,-13 -100,-18 -3,-4 -38,-13 -77,-20 -40,-7 -73,-16 -73,-20 0,-4 -19,-12 -42,-19 -41,-12 -120,-47 -143,-64 -5,-4 -39,-26 -74,-50 -36,-23 -71,-46 -79,-52 -33,-22 -212,-210 -212,-222 0,-3 -11,-19 -25,-37 -14,-18 -25,-38 -25,-44 0,-7 -4,-12 -8,-12 -4,0 -14,-16 -21,-35 -7,-19 -16,-35 -21,-35 -5,0 -15,-18 -21,-40 -7,-22 -15,-40 -19,-40 -5,0 -11,-12 -15,-27 -3,-16 -13,-41 -20,-58 -8,-16 -19,-50 -25,-75 -6,-25 -15,-54 -20,-65 -8,-21 -30,-128 -30,-152 0,-11 219,-13 1275,-13l1275,0 0,50c0,28 -4,50 -9,50 -4,0 -14,28 -21,63 -8,34 -19,71 -26,82 -7,11 -16,37 -19,58 -4,20 -11,37 -16,37 -5,0 -9,5 -9,11 0,12 -62,141 -71,149 -3,3 -12,16 -19,30 -38,72 -198,255 -272,310 -11,8 -28,22 -37,30 -46,41 -182,120 -207,120 -8,0 -14,4 -14,9 0,5 -22,14 -50,21 -27,7 -50,15 -50,19 0,4 -30,13 -67,20 -38,8 -73,17 -78,22 -15,11 -234,29 -345,28 -52,-1 -138,-6 -190,-11zM2597,3074c54,-15 74,-102 33,-139 -44,-40 -146,-38 -191,4 -12,11 -19,21 -15,21 5,0 3,7 -4,15 -7,8 -8,20 -4,27 5,7 9,15 9,18 1,13 22,38 40,48 22,12 96,15 132,6zM2080,2890c0,-5 11,-10 24,-10 31,0 86,-20 86,-31 0,-5 6,-9 13,-9 23,0 107,-98 133,-155 34,-73 35,-187 4,-247 -34,-65 -83,-126 -112,-139 -16,-6 -28,-15 -28,-19 0,-5 -17,-14 -37,-21 -21,-6 -41,-17 -45,-23 -9,-14 -197,-14 -206,0 -4,6 -21,16 -39,22 -37,12 -123,94 -123,117 0,8 -4,15 -9,15 -11,0 -25,39 -41,111 -9,42 -10,61 -1,77 6,11 11,31 11,44 0,36 51,127 96,172 61,60 84,76 126,83 21,3 38,9 38,14 0,5 25,9 55,9 30,0 55,-4 55,-10zM3175,2870c14,-5 31,-14 38,-20 64,-53 87,-76 87,-87 0,-7 4,-13 10,-13 9,0 36,-54 47,-95 23,-90 20,-180 -9,-235 -29,-55 -74,-110 -100,-121 -16,-6 -28,-15 -28,-20 0,-5 -20,-14 -45,-21 -25,-7 -45,-16 -45,-20 0,-4 -38,-8 -85,-8 -47,0 -85,4 -85,9 0,5 -17,11 -38,14 -20,4 -48,14 -60,24 -48,37 -92,81 -92,92 0,6 -7,14 -14,17 -24,9 -39,102 -34,206 3,84 7,101 32,139 35,54 77,98 93,99 6,0 18,6 26,14 8,8 30,19 48,24 45,13 221,15 254,2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M650,2082c0,-4 -13,-13 -30,-20 -27,-13 -30,-18 -30,-62 0,-38 6,-55 24,-74l23,-26 1914,0 1913,0 24,28c19,22 23,35 19,69 -2,23 -12,49 -21,58 -9,9 -16,21 -16,26 0,5 -741,9 -1910,9 -1050,0 -1910,-3 -1910,-8z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1253,1853c-15,-6 -18,-113 -4,-113 5,0 13,-25 16,-56 4,-30 13,-60 19,-67 6,-7 18,-32 25,-57 7,-25 18,-48 25,-52 6,-4 552,-8 1214,-8 948,0 1202,3 1201,13 -4,33 2,56 14,52 7,-3 13,5 14,22 4,56 16,108 26,115 6,3 11,39 11,80l1,73 -1275,2c-701,1 -1281,-1 -1287,-4z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1134,1697c-22,-23 -80,-78 -127,-122 -97,-89 -241,-225 -303,-285 -44,-44 -55,-47 -74,-25 -6,8 -33,27 -58,42 -40,23 -58,27 -122,27 -78,0 -119,-17 -175,-69 -60,-55 -90,-172 -65,-259 15,-53 89,-141 127,-151 15,-3 31,-11 34,-17 3,-5 35,-10 70,-11l64,-2 1,-75c0,-83 11,-108 74,-171 108,-109 261,-105 366,8 38,42 74,125 74,173 0,33 -41,127 -70,159 -22,23 -26,34 -17,41 38,31 131,117 217,200 54,52 119,114 144,138 44,41 57,74 36,87 -5,3 -14,24 -20,45 -6,22 -15,40 -19,40 -5,0 -15,24 -21,53 -7,28 -16,54 -20,57 -10,7 -30,94 -30,129 0,45 -35,40 -86,-12z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M3854,1693c-4,-20 -13,-48 -20,-62 -8,-14 -14,-33 -14,-41 0,-8 -6,-26 -13,-40 -8,-14 -20,-47 -27,-73 -8,-26 -17,-47 -21,-47 -9,0 -29,-57 -29,-80 0,-19 17,-37 155,-165 47,-44 115,-108 150,-142 36,-34 73,-66 82,-71 15,-9 13,-14 -19,-44 -69,-68 -73,-231 -7,-314 52,-66 93,-88 183,-100 44,-5 137,19 168,44 36,30 68,66 74,85 3,9 9,17 14,17 14,0 23,126 12,160 -10,27 -9,30 9,30 10,0 19,-4 19,-10 0,-13 37,-13 45,0 3,6 17,10 31,10 14,0 39,6 57,14 37,15 113,83 110,97 -2,5 1,9 5,9 13,0 32,72 32,119 0,52 -19,131 -32,131 -5,0 -7,4 -4,9 3,5 -13,24 -35,43 -23,18 -47,38 -54,45 -22,21 -98,35 -154,29 -63,-8 -110,-28 -145,-63l-25,-25 -28,23c-47,40 -104,91 -172,156 -36,34 -97,90 -135,125 -38,35 -93,87 -123,116 -31,28 -61,52 -69,52 -7,0 -16,-16 -20,-37z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1380,1446c0,-21 21,-76 29,-76 4,0 13,-18 20,-40 7,-23 18,-40 26,-40 8,0 15,-9 15,-20 0,-11 11,-30 25,-42 14,-12 25,-25 25,-30 0,-11 298,-308 310,-308 5,0 7,-6 4,-14 -4,-11 0,-13 14,-9 11,2 23,0 26,-6 4,-6 14,-11 22,-11 9,0 22,-7 31,-15 8,-9 28,-19 44,-22 16,-3 29,-9 29,-12 0,-4 33,-16 73,-26 39,-10 74,-21 77,-25 30,-37 656,-37 668,0 2,5 14,10 27,10 31,0 169,31 175,40 3,4 29,13 58,20 28,6 52,16 52,20 0,4 14,13 30,20 17,7 30,16 30,20 0,3 12,13 27,21 14,8 41,29 60,47 18,17 38,32 43,32 12,0 190,172 190,184 0,4 15,22 34,39 18,18 37,43 41,57 4,14 16,31 26,38 11,7 19,20 19,28 0,8 4,14 8,14 5,0 15,18 22,40 7,22 17,40 22,40 4,0 8,9 8,20 0,20 -7,20 -1155,20 -963,0 -1155,-2 -1155,-14zM3404,1395c3,-8 2,-15 -2,-15 -4,0 -13,-24 -20,-52 -6,-29 -18,-57 -25,-63 -6,-5 -19,-23 -27,-40 -18,-35 -68,-85 -86,-85 -7,0 -12,9 -11,20 1,11 7,20 14,20 7,0 13,7 13,15 0,8 9,19 20,25 11,6 20,17 20,25 0,8 5,15 11,15 6,0 9,6 7,12 -3,7 2,19 9,27 8,7 17,26 20,42 3,16 9,29 14,29 4,0 11,9 14,20 8,24 21,26 29,5zM1924,1384c9,-3 13,-11 10,-16 -4,-6 0,-14 7,-19 8,-5 14,-25 14,-45 0,-23 5,-39 14,-42 10,-3 12,1 8,17 -3,11 -1,19 4,15 5,-3 9,-12 9,-20 0,-8 6,-17 14,-20 16,-6 42,-61 33,-70 -8,-8 -47,6 -47,17 0,5 -8,18 -17,28 -34,37 -40,47 -52,84 -7,20 -17,37 -22,37 -5,0 -9,9 -9,20 0,21 8,24 34,14zM3104,1384c17,-7 22,-44 6,-44 -5,0 -10,-10 -11,-22 0,-22 -1,-22 -10,-3 -8,16 -8,14 -5,-11 5,-33 -24,-81 -42,-70 -11,6 -4,54 9,62 5,3 9,14 9,25 0,10 5,19 10,19 6,0 10,11 10,25 0,27 1,28 24,19zM2158,1322c2,-12 7,-22 12,-22 5,0 14,-9 20,-20 9,-16 8,-22 -4,-26 -20,-8 -65,44 -66,74 0,31 34,26 38,-6zM1720,1325c0,-8 5,-15 11,-15 5,0 7,-4 4,-10 -3,-5 1,-10 9,-10 9,0 16,-7 16,-15 0,-8 5,-15 11,-15 5,0 8,-4 5,-8 -3,-5 11,-23 29,-41 19,-18 35,-39 35,-47 0,-8 7,-14 15,-14 15,0 19,-11 16,-39 -2,-7 2,-10 8,-7 5,4 12,2 16,-4 8,-13 -11,-13 -35,0 -12,7 -17,16 -13,27 4,10 2,14 -4,10 -12,-7 -83,53 -83,69 0,5 -11,22 -25,38 -14,16 -25,35 -25,41 0,7 -7,15 -15,19 -22,8 -18,36 5,36 11,0 20,-7 20,-15z\"\n        android:strokeColor=\"#00000000\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_otaku.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"7050\"\r\n        android:viewportHeight=\"7050\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M3500,6170c0,-5 -11,-10 -25,-10 -14,0 -25,-4 -25,-10 0,-5 -7,-10 -15,-10 -8,0 -15,-4 -15,-10 0,-5 -12,-10 -28,-10 -16,0 -32,-8 -40,-20 -7,-11 -21,-20 -32,-20 -11,0 -20,-4 -20,-10 0,-5 -8,-10 -18,-10 -10,0 -24,-9 -32,-20 -8,-11 -20,-20 -27,-20 -7,0 -13,-4 -13,-10 0,-5 -6,-10 -13,-10 -7,0 -19,-9 -27,-20 -8,-11 -19,-20 -25,-20 -6,0 -17,-9 -25,-20 -8,-11 -21,-20 -28,-20 -8,0 -27,-13 -42,-30 -15,-16 -37,-30 -48,-30 -12,0 -23,-9 -28,-22 -3,-11 -30,-45 -60,-74 -29,-29 -61,-68 -70,-85 -9,-18 -23,-39 -30,-47 -8,-7 -14,-18 -14,-23 0,-5 -34,-9 -75,-9 -48,0 -75,-4 -75,-11 0,-7 -9,-9 -24,-5 -17,4 -28,0 -42,-19 -10,-14 -26,-25 -34,-25 -9,0 -22,-9 -30,-20 -8,-11 -20,-20 -27,-20 -7,0 -13,-4 -13,-10 0,-5 -7,-10 -15,-10 -8,0 -15,-5 -15,-11 0,-14 -56,-69 -69,-69 -5,0 -13,-9 -16,-20 -3,-11 -9,-20 -13,-20 -4,0 -25,-16 -47,-35 -22,-19 -43,-35 -46,-35 -3,0 -15,-8 -27,-17 -51,-44 -63,-53 -67,-53 -2,0 -25,-22 -51,-50 -26,-27 -52,-50 -58,-50 -6,0 -19,-14 -28,-30 -9,-17 -24,-30 -33,-30 -8,0 -15,-5 -15,-11 0,-6 -31,-45 -69,-87 -38,-43 -101,-120 -139,-172 -39,-52 -77,-102 -84,-110 -12,-15 -48,-85 -48,-95 0,-8 55,19 74,37 11,10 30,18 43,18 13,0 23,4 23,10 0,13 154,90 180,90 27,0 26,-33 -3,-62 -12,-13 -34,-39 -47,-58 -30,-43 -50,-67 -72,-92 -10,-10 -18,-24 -18,-32 0,-8 -4,-16 -8,-18 -10,-4 -114,-170 -145,-233 -72,-145 -124,-305 -153,-471 -41,-233 -6,-861 46,-829 5,3 26,40 46,81 20,41 40,74 45,74 5,0 9,7 9,16 0,16 149,246 192,296 13,15 38,45 56,68 34,41 67,54 58,23 -12,-45 -51,-369 -62,-515 -6,-93 10,-268 26,-268 3,0 17,-35 31,-77 13,-43 27,-79 31,-81 5,-2 8,-8 8,-14 0,-12 35,-96 95,-228 24,-52 48,-106 54,-120 6,-14 20,-38 30,-55 11,-16 20,-37 20,-47 1,-9 5,-18 9,-20 8,-3 24,-30 104,-175 17,-32 36,-65 43,-73 7,-8 23,-35 36,-60 13,-25 34,-56 47,-70 12,-14 22,-33 22,-42 0,-10 3,-18 8,-18 4,0 21,-21 39,-47 36,-56 123,-168 124,-162 0,2 2,49 4,104 14,400 22,505 40,505 6,0 36,-48 66,-108 30,-59 62,-116 72,-126 9,-11 17,-26 17,-33 0,-7 4,-13 8,-13 5,0 14,-12 21,-27 7,-16 23,-44 35,-63 99,-152 136,-211 136,-219 0,-5 3,-11 8,-13 4,-2 21,-23 37,-48 17,-25 65,-91 108,-148 42,-57 77,-106 78,-110 0,-4 15,-19 33,-34l33,-28 7,113c7,121 36,409 42,416 5,6 44,-30 44,-41 0,-5 11,-21 26,-36 14,-15 28,-39 31,-54 3,-15 11,-29 19,-32 19,-7 78,-129 104,-216 12,-41 26,-89 31,-106 16,-55 30,-247 23,-322 -4,-44 -3,-72 3,-72 31,0 335,342 463,521 13,19 28,39 32,44 8,10 84,127 140,217 14,24 36,64 49,90 13,27 27,48 31,48 4,0 8,6 8,13 0,8 24,63 54,124 30,61 69,153 87,204 18,52 36,96 41,97 4,2 8,9 8,15 0,25 65,247 73,247 15,0 32,-23 68,-90 18,-36 37,-67 40,-70 12,-9 39,-69 39,-85 0,-8 4,-15 8,-15 5,0 32,-49 61,-110 45,-93 55,-107 67,-95 8,7 14,25 14,39 0,14 18,99 40,188 51,214 115,541 136,703 22,170 15,469 -15,627 -11,59 -22,112 -26,118 -11,18 31,10 53,-10 12,-11 26,-20 31,-20 6,0 16,-9 23,-20 7,-11 17,-20 23,-20 5,0 22,-10 37,-23 58,-49 64,-54 81,-60 9,-3 17,-13 17,-22 0,-8 8,-15 19,-15 10,0 24,-7 31,-14 6,-8 34,-29 61,-46 27,-18 49,-38 49,-45 0,-7 11,-12 25,-12 14,0 25,2 25,6 0,3 -11,52 -25,109 -14,57 -25,116 -25,132 0,15 -4,30 -8,32 -5,2 -30,66 -56,143 -53,158 -68,193 -173,425 -41,91 -80,179 -86,195 -7,17 -15,32 -18,35 -4,3 -28,48 -54,100 -26,52 -56,107 -66,122 -11,14 -19,33 -19,41 0,9 -3,17 -7,19 -15,6 -84,128 -81,141 2,11 31,7 128,-17 69,-16 127,-34 128,-38 2,-4 16,-8 31,-8 35,0 94,-20 103,-34 5,-8 11,-7 19,1 13,13 -27,72 -115,168 -25,28 -48,58 -52,68 -3,9 -12,17 -20,17 -8,0 -23,13 -32,30 -9,16 -20,30 -25,30 -4,0 -43,36 -88,80 -44,44 -83,80 -86,80 -18,0 -102,85 -118,119 -10,23 -21,41 -25,41 -4,0 -10,13 -13,28 -6,30 -57,92 -76,92 -6,0 -11,4 -11,9 0,13 -56,71 -68,71 -6,0 -14,9 -17,20 -4,13 -15,20 -31,20 -13,0 -24,5 -24,10 0,6 -5,10 -10,10 -6,0 -20,9 -32,20 -12,11 -30,20 -40,20 -10,0 -18,5 -18,10 0,6 -31,10 -73,10l-74,0 -18,40c-10,22 -24,40 -32,40 -7,0 -13,4 -13,8 0,19 -122,152 -139,152 -6,0 -16,9 -23,20 -7,11 -18,20 -25,20 -6,0 -15,9 -18,20 -3,11 -15,20 -25,20 -10,0 -22,9 -25,20 -3,11 -13,20 -21,20 -8,0 -14,5 -14,10 0,6 -9,10 -20,10 -11,0 -20,5 -20,10 0,6 -7,10 -15,10 -8,0 -15,5 -15,10 0,6 -6,10 -13,10 -7,0 -23,9 -35,20 -12,11 -26,20 -32,20 -5,0 -10,5 -10,10 0,6 -9,10 -20,10 -11,0 -20,5 -20,10 0,6 -7,10 -15,10 -8,0 -15,5 -15,10 0,6 -7,10 -15,10 -8,0 -15,5 -15,10 0,6 -9,10 -20,10 -11,0 -20,5 -20,10 0,6 -13,10 -30,10 -16,0 -30,5 -30,10 0,6 -18,10 -40,10 -22,0 -40,-4 -40,-10zM3374,5263c4,-9 3,-20 -1,-24 -8,-7 -255,-114 -480,-207 -122,-51 -122,-51 -110,-24 93,199 100,208 174,217 31,4 97,11 147,15 112,11 194,24 203,33 13,14 61,7 67,-10zM3815,5264c22,-2 56,-9 75,-14 19,-5 67,-12 105,-15 155,-12 195,-18 206,-31 17,-21 109,-207 104,-212 -4,-5 -187,69 -355,143 -58,25 -138,60 -177,76 -67,28 -72,32 -62,51 8,15 17,19 37,14 15,-4 45,-9 67,-12z\"/>\r\n</vector>\r\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_pig.xml",
    "content": "<!-- drawable/pig.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M9.5,9A1.5,1.5 0 0,0 8,10.5A1.5,1.5 0 0,0 9.5,12A1.5,1.5 0 0,0 11,10.5A1.5,1.5 0 0,0 9.5,9M14.5,9A1.5,1.5 0 0,0 13,10.5A1.5,1.5 0 0,0 14.5,12A1.5,1.5 0 0,0 16,10.5A1.5,1.5 0 0,0 14.5,9M12,4L12.68,4.03C13.62,3.24 14.82,2.59 15.72,2.35C17.59,1.85 20.88,2.23 21.31,3.83C21.62,5 20.6,6.45 19.03,7.38C20.26,8.92 21,10.87 21,13A9,9 0 0,1 12,22A9,9 0 0,1 3,13C3,10.87 3.74,8.92 4.97,7.38C3.4,6.45 2.38,5 2.69,3.83C3.12,2.23 6.41,1.85 8.28,2.35C9.18,2.59 10.38,3.24 11.32,4.03L12,4M10,16A1,1 0 0,1 11,17A1,1 0 0,1 10,18A1,1 0 0,1 9,17A1,1 0 0,1 10,16M14,16A1,1 0 0,1 15,17A1,1 0 0,1 14,18A1,1 0 0,1 13,17A1,1 0 0,1 14,16M12,13C9.24,13 7,15.34 7,17C7,18.66 9.24,20 12,20C14.76,20 17,18.66 17,17C17,15.34 14.76,13 12,13M7.76,4.28C7.31,4.16 4.59,4.35 4.59,4.35C4.59,4.35 6.8,6.1 7.24,6.22C7.69,6.34 9.77,6.43 9.91,5.9C10.06,5.36 8.2,4.4 7.76,4.28M16.24,4.28C15.8,4.4 13.94,5.36 14.09,5.9C14.23,6.43 16.31,6.34 16.76,6.22C17.2,6.1 19.41,4.35 19.41,4.35C19.41,4.35 16.69,4.16 16.24,4.28Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_question.xml",
    "content": "<!-- drawable/comment_question.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22V22H9A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2M12.19,5.5C11.3,5.5 10.59,5.68 10.05,6.04C9.5,6.4 9.22,7 9.27,7.69H11.24C11.24,7.41 11.34,7.2 11.5,7.06C11.7,6.92 11.92,6.85 12.19,6.85C12.5,6.85 12.77,6.93 12.95,7.11C13.13,7.28 13.22,7.5 13.22,7.8C13.22,8.08 13.14,8.33 13,8.54C12.83,8.76 12.62,8.94 12.36,9.08C11.84,9.4 11.5,9.68 11.29,9.92C11.1,10.16 11,10.5 11,11H13C13,10.72 13.05,10.5 13.14,10.32C13.23,10.15 13.4,10 13.66,9.85C14.12,9.64 14.5,9.36 14.79,9C15.08,8.63 15.23,8.24 15.23,7.8C15.23,7.1 14.96,6.54 14.42,6.12C13.88,5.71 13.13,5.5 12.19,5.5M11,12V14H13V12H11Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_sad.xml",
    "content": "<!-- drawable/emoticon_sad.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12M15.5,8C16.3,8 17,8.7 17,9.5C17,10.3 16.3,11 15.5,11C14.7,11 14,10.3 14,9.5C14,8.7 14.7,8 15.5,8M10,9.5C10,10.3 9.3,11 8.5,11C7.7,11 7,10.3 7,9.5C7,8.7 7.7,8 8.5,8C9.3,8 10,8.7 10,9.5M12,14C13.75,14 15.29,14.72 16.19,15.81L14.77,17.23C14.32,16.5 13.25,16 12,16C10.75,16 9.68,16.5 9.23,17.23L7.81,15.81C8.71,14.72 10.25,14 12,14Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_share.xml",
    "content": "<!-- drawable/share_variant.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M18,16.08C17.24,16.08 16.56,16.38 16.04,16.85L8.91,12.7C8.96,12.47 9,12.24 9,12C9,11.76 8.96,11.53 8.91,11.3L15.96,7.19C16.5,7.69 17.21,8 18,8A3,3 0 0,0 21,5A3,3 0 0,0 18,2A3,3 0 0,0 15,5C15,5.24 15.04,5.47 15.09,5.7L8.04,9.81C7.5,9.31 6.79,9 6,9A3,3 0 0,0 3,12A3,3 0 0,0 6,15C6.79,15 7.5,14.69 8.04,14.19L15.16,18.34C15.11,18.55 15.08,18.77 15.08,19C15.08,20.61 16.39,21.91 18,21.91C19.61,21.91 20.92,20.61 20.92,19A2.92,2.92 0 0,0 18,16.08Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_start.xml",
    "content": "<!-- drawable/flag.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M14.4,6L14,4H5V21H7V14H12.6L13,16H20V6H14.4Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievement_vampire.xml",
    "content": "<!-- drawable/coffin.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M8,22L5,8L8,2H16L19,8L16,22H8M11,6V8H9V10H11V15H13V10H15V8H13V6H11Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_achievements.xml",
    "content": "<!-- drawable/star_circle.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M16.23,18L12,15.45L7.77,18L8.89,13.19L5.16,9.96L10.08,9.54L12,5L13.92,9.53L18.84,9.95L15.11,13.18L16.23,18M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_action_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_add_category.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M2,16H10V14H2M18,14V10H16V14H12V16H16V20H18V16H22V14M14,6H2V8H14M14,10H2V12H14V10Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_add_list.xml",
    "content": "<!-- drawable/playlist_plus.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M2,16H10V14H2M18,14V10H16V14H12V16H16V20H18V16H22V14M14,6H2V8H14M14,10H2V12H14V10Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_animations.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M15,2A7,7 0 0,1 22,9C22,11.71 20.46,14.05 18.22,15.22C17.55,16.5 16.5,17.55 15.22,18.22C14.05,20.46 11.71,22 9,22A7,7 0 0,1 2,15C2,12.29 3.54,9.95 5.78,8.78C6.45,7.5 7.5,6.45 8.78,5.78C9.95,3.54 12.29,2 15,2M12,19A7,7 0 0,1 5,12C4.37,12.84 4,13.87 4,15A5,5 0 0,0 9,20C10.13,20 11.16,19.63 12,19M15,16A7,7 0 0,1 8,9H8C7.37,9.84 7,10.87 7,12A5,5 0 0,0 12,17C13.13,17 14.16,16.63 15,16V16M15,4C13.87,4 12.84,4.37 12,5V5A7,7 0 0,1 19,12H19C19.63,11.16 20,10.13 20,9A5,5 0 0,0 15,4M10,9A5,5 0 0,0 15,14C15.6,14 16.17,13.9 16.7,13.7C16.9,13.17 17,12.6 17,12A5,5 0 0,0 12,7C11.4,7 10.83,7.1 10.3,7.3C10.1,7.83 10,8.4 10,9Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_arrow_left.xml",
    "content": "<!-- drawable/arrow_left.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:height=\"24dp\"\r\n    android:width=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path android:fillColor=\"#fff\" android:pathData=\"M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_author.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M19,22H5V20H19V22M17,10C15.58,10 14.26,10.77 13.55,12H13V7H16V5H13V2H11V5H8V7H11V12H10.45C9.35,10.09 6.9,9.43 5,10.54C3.07,11.64 2.42,14.09 3.5,16C4.24,17.24 5.57,18 7,18H17A4,4 0 0,0 21,14A4,4 0 0,0 17,10Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_backup.xml",
    "content": "<!-- drawable/cloud_upload.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M14,13V17H10V13H7L12,8L17,13M19.35,10.03C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.03C2.34,8.36 0,10.9 0,14A6,6 0 0,0 6,20H19A5,5 0 0,0 24,15C24,12.36 21.95,10.22 19.35,10.03Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_beta.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M9.23,17.59V23.12H6.88V6.72C6.88,5.27 7.31,4.13 8.16,3.28C9,2.43 10.17,2 11.61,2C13,2 14.07,2.34 14.87,3C15.66,3.68 16.05,4.62 16.05,5.81C16.05,6.63 15.79,7.4 15.27,8.11C14.75,8.82 14.08,9.31 13.25,9.58V9.62C14.5,9.82 15.47,10.27 16.13,11C16.79,11.71 17.12,12.62 17.12,13.74C17.12,15.06 16.66,16.14 15.75,16.97C14.83,17.8 13.63,18.21 12.13,18.21C11.07,18.21 10.1,18 9.23,17.59M10.72,10.75V8.83C11.59,8.72 12.3,8.4 12.87,7.86C13.43,7.31 13.71,6.7 13.71,6C13.71,4.62 13,3.92 11.6,3.92C10.84,3.92 10.25,4.16 9.84,4.65C9.43,5.14 9.23,5.82 9.23,6.71V15.5C10.14,16.03 11.03,16.29 11.89,16.29C12.73,16.29 13.39,16.07 13.86,15.64C14.33,15.2 14.56,14.58 14.56,13.79C14.56,12 13.28,11 10.72,10.75Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_blacklist.xml",
    "content": "<!-- drawable/clipboard_alert.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,5A1,1 0 0,1 11,4A1,1 0 0,1 12,3A1,1 0 0,1 13,4A1,1 0 0,1 12,5M13,14H11V8H13M13,18H11V16H13M19,3H14.82C14.4,1.84 13.3,1 12,1C10.7,1 9.6,1.84 9.18,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_buffer.xml",
    "content": "<!-- drawable/clock_fast.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M15,4A8,8 0 0,1 23,12A8,8 0 0,1 15,20A8,8 0 0,1 7,12A8,8 0 0,1 15,4M15,6A6,6 0 0,0 9,12A6,6 0 0,0 15,18A6,6 0 0,0 21,12A6,6 0 0,0 15,6M14,8H15.5V11.78L17.83,14.11L16.77,15.17L14,12.4V8M2,18A1,1 0 0,1 1,17A1,1 0 0,1 2,16H5.83C6.14,16.71 6.54,17.38 7,18H2M3,13A1,1 0 0,1 2,12A1,1 0 0,1 3,11H5.05L5,12L5.05,13H3M4,8A1,1 0 0,1 3,7A1,1 0 0,1 4,6H7C6.54,6.62 6.14,7.29 5.83,8H4Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_bug.xml",
    "content": "<!-- drawable/bug.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M14,12H10V10H14M14,16H10V14H14M20,8H17.19C16.74,7.22 16.12,6.55 15.37,6.04L17,4.41L15.59,3L13.42,5.17C12.96,5.06 12.5,5 12,5C11.5,5 11.04,5.06 10.59,5.17L8.41,3L7,4.41L8.62,6.04C7.88,6.55 7.26,7.22 6.81,8H4V10H6.09C6.04,10.33 6,10.66 6,11V12H4V14H6V15C6,15.34 6.04,15.67 6.09,16H4V18H6.81C7.85,19.79 9.78,21 12,21C14.22,21 16.15,19.79 17.19,18H20V16H17.91C17.96,15.67 18,15.34 18,15V14H20V12H18V11C18,10.66 17.96,10.33 17.91,10H20V8Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_cash.xml",
    "content": "<!-- drawable/cash_usd.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M20,18H4V6H20M20,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6C22,4.89 21.1,4 20,4M11,17H13V16H14A1,1 0 0,0 15,15V12A1,1 0 0,0 14,11H11V10H15V8H13V7H11V8H10A1,1 0 0,0 9,9V12A1,1 0 0,0 10,13H13V14H9V16H11V17Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_cash_multi.xml",
    "content": "<!-- drawable/cash_multiple.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M5,6H23V18H5V6M14,9A3,3 0 0,1 17,12A3,3 0 0,1 14,15A3,3 0 0,1 11,12A3,3 0 0,1 14,9M9,8A2,2 0 0,1 7,10V14A2,2 0 0,1 9,16H19A2,2 0 0,1 21,14V10A2,2 0 0,1 19,8H9M1,10H3V20H19V22H1V10Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_casting.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M21,3H3C1.89,3 1,3.89 1,5V8H3V5H21V19H14V21H21A2,2 0 0,0 23,19V5C23,3.89 22.1,3 21,3M1,10V12A9,9 0 0,1 10,21H12C12,14.92 7.07,10 1,10M19,7H5V8.63C8.96,9.91 12.09,13.04 13.37,17H19M1,14V16A5,5 0 0,1 6,21H8A7,7 0 0,0 1,14M1,18V21H4A3,3 0 0,0 1,18Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_casting_menu.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M21,3H3C1.89,3 1,3.89 1,5V8H3V5H21V19H14V21H21A2,2 0 0,0 23,19V5C23,3.89 22.1,3 21,3M1,10V12A9,9 0 0,1 10,21H12C12,14.92 7.07,10 1,10M19,7H5V8.63C8.96,9.91 12.09,13.04 13.37,17H19M1,14V16A5,5 0 0,1 6,21H8A7,7 0 0,0 1,14M1,18V21H4A3,3 0 0,0 1,18Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_changelog_get.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M14,2L6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6zM16,18L8,18v-2h8v2zM16,14L8,14v-2h8v2zM13,9L13,3.5L18.5,9L13,9z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_chap_down.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M20,6A2,2 0 0,1 22,8V18A2,2 0 0,1 20,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H20M19.25,13H16V9H14V13H10.75L15,17.25\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_check.xml",
    "content": "<!-- drawable/check.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#fff\"\r\n        android:pathData=\"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_check_bold.xml",
    "content": "<!-- drawable/check_bold.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#64dd17\"\r\n        android:pathData=\"M9,20.42L2.79,14.21L5.62,11.38L9,14.77L18.88,4.88L21.71,7.71L9,20.42Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_check_tv.xml",
    "content": "<!-- drawable/checkbox_marked_circle.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@color/colorAccent\"\n        android:pathData=\"M10,17L5,12L6.41,10.58L10,14.17L17.59,6.58L19,8M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_clear.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M15,16H19V18H15V16M15,8H22V10H15V8M15,12H21V14H15V12M3,18A2,2 0 0,0 5,20H11A2,2 0 0,0 13,18V8H3V18M14,5H11L10,4H6L5,5H2V7H14V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_clear_all.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M5,13H19V11H5M3,17H17V15H3M7,7V9H21V7\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_clear_white.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M15,16H19V18H15V16M15,8H22V10H15V8M15,12H21V14H15V12M3,18A2,2 0 0,0 5,20H11A2,2 0 0,0 13,18V8H3V18M14,5H11L10,4H6L5,5H2V7H14V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_clock.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22C6.47,22 2,17.5 2,12A10,10 0 0,1 12,2M12.5,7V12.25L17,14.92L16.25,16.15L11,13V7H12.5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_close.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_cloud.xml",
    "content": "<!-- drawable/cloud.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path android:fillColor=\"?colorControlNormal\" android:pathData=\"M19.35,10.03C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.03C2.34,8.36 0,10.9 0,14A6,6 0 0,0 6,20H19A5,5 0 0,0 24,15C24,12.36 21.95,10.22 19.35,10.03Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_cloud_download.xml",
    "content": "<!-- drawable/cloud_download.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path android:fillColor=\"?colorControlNormal\" android:pathData=\"M17,13L12,18L7,13H10V9H14V13M19.35,10.03C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.03C2.34,8.36 0,10.9 0,14A6,6 0 0,0 6,20H19A5,5 0 0,0 24,15C24,12.36 21.95,10.22 19.35,10.03Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_cloud_firestore.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"192\"\n    android:viewportHeight=\"192\">\n    <path\n        android:fillAlpha=\"1\"\n        android:fillColor=\"#fff\"\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M96,104l-72,32v-32l72,-32 72,32v28,-6 10zM96,16l72,32v32L96,48 24,80L24,48zM123,132l36,16 -63,28v-32z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_cloud_upload.xml",
    "content": "<!-- drawable/cloud_upload.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M14,13V17H10V13H7L12,8L17,13M19.35,10.03C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.03C2.34,8.36 0,10.9 0,14A6,6 0 0,0 6,20H19A5,5 0 0,0 24,15C24,12.36 21.95,10.22 19.35,10.03Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_coin.xml",
    "content": "<!-- drawable/coin.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M12 2A10 10 0 1 0 22 12A10 10 0 0 0 12 2M15 10H11V11H14A1 1 0 0 1 15 12V15A1 1 0 0 1 14 16H13V17H11V16H9V14H13V13H10A1 1 0 0 1 9 12V9A1 1 0 0 1 10 8H11V7H13V8H15Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_coin_ach.xml",
    "content": "<!-- drawable/coin.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#000\"\r\n        android:pathData=\"M12 2A10 10 0 1 0 22 12A10 10 0 0 0 12 2M15 10H11V11H14A1 1 0 0 1 15 12V15A1 1 0 0 1 14 16H13V17H11V16H9V14H13V13H10A1 1 0 0 1 9 12V9A1 1 0 0 1 10 8H11V7H13V8H15Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_collapse.xml",
    "content": "<!-- drawable/arrow_collapse.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M19.5,3.09L15,7.59V4H13V11H20V9H16.41L20.91,4.5L19.5,3.09M4,13V15H7.59L3.09,19.5L4.5,20.91L9,16.41V20H11V13H4Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_comments.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M9,22A1,1 0 0,1 8,21V18H4A2,2 0 0,1 2,16V4C2,2.89 2.9,2 4,2H20A2,2 0 0,1 22,4V16A2,2 0 0,1 20,18H13.9L10.2,21.71C10,21.9 9.75,22 9.5,22V22H9M5,5V7H19V5H5M5,9V11H13V9H5M5,13V15H15V13H5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_completed.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M14.4,6H20V16H13L12.6,14H7V21H5V4H14L14.4,6M14,14H16V12H18V10H16V8H14V10L13,8V6H11V8H9V6H7V8H9V10H7V12H9V10H11V12H13V10L14,12V14M11,10V8H13V10H11M14,10H16V12H14V10Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_considering.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M6,1V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3H18V1H16V3H8V1H6M5,8H19V19H5V8M12.19,9C11.32,9 10.62,9.2 10.08,9.59C9.56,10 9.3,10.57 9.31,11.36L9.32,11.39H11.25C11.26,11.09 11.35,10.86 11.53,10.7C11.71,10.55 11.93,10.47 12.19,10.47C12.5,10.47 12.76,10.57 12.94,10.75C13.12,10.94 13.2,11.2 13.2,11.5C13.2,11.82 13.13,12.09 12.97,12.32C12.83,12.55 12.62,12.75 12.36,12.91C11.85,13.25 11.5,13.55 11.31,13.82C11.11,14.08 11,14.5 11,15H13C13,14.69 13.04,14.44 13.13,14.26C13.22,14.08 13.39,13.9 13.64,13.74C14.09,13.5 14.46,13.21 14.75,12.81C15.04,12.41 15.19,12 15.19,11.5C15.19,10.74 14.92,10.13 14.38,9.68C13.85,9.23 13.12,9 12.19,9M11,16V18H13V16H11Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_cuplogo.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"16000\"\n        android:viewportHeight=\"16000\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M1655,13093c-83,-11 -329,-80 -388,-109 -16,-8 -36,-14 -46,-14 -9,0 -21,-4 -27,-8 -5,-5 -45,-24 -89,-42 -69,-29 -105,-48 -195,-100 -79,-46 -150,-94 -150,-101 0,-5 -5,-9 -11,-9 -28,0 -309,-254 -309,-280 0,-5 -4,-10 -8,-10 -8,0 -131,-160 -145,-189 -4,-9 -16,-29 -26,-46 -29,-44 -111,-214 -111,-229 0,-6 -4,-16 -9,-21 -13,-15 -76,-228 -95,-320 -51,-252 -48,-56 -42,-3882 3,-1952 10,-3732 14,-3958 8,-426 12,-467 58,-558 8,-16 14,-33 14,-39 0,-33 134,-208 160,-208 5,0 10,-3 10,-8 0,-4 24,-18 52,-32l53,-25 6210,0c5759,0 6215,1 6275,17 36,9 97,24 135,33 39,9 90,23 115,30 149,44 229,69 258,81 18,8 39,14 47,14 8,0 29,6 47,14 18,8 85,35 148,61 242,99 514,241 712,371 119,78 275,188 288,203 3,3 28,24 55,46 28,21 63,51 80,65 56,48 364,355 365,363 0,4 10,18 23,30 13,12 45,51 72,87 27,36 52,67 55,70 3,3 33,43 65,90 33,47 63,87 67,88 4,2 8,8 8,13 0,6 20,40 44,77 24,37 58,96 77,132 18,36 35,67 38,70 10,8 63,121 141,295 64,146 157,431 190,585 4,19 12,55 18,80 32,138 62,314 87,520 21,173 21,728 0,895 -30,235 -77,476 -120,610 -7,22 -18,60 -25,85 -6,25 -18,60 -26,78 -8,18 -14,39 -14,47 0,8 -6,29 -14,47 -8,18 -38,89 -66,158 -52,124 -166,352 -215,429 -14,23 -25,43 -25,46 0,8 -44,69 -52,73 -5,2 -8,8 -8,13 0,11 -42,72 -53,77 -4,2 -7,8 -7,13 0,6 -4,15 -10,22 -5,7 -44,57 -86,112 -43,55 -87,111 -99,125 -176,198 -266,288 -389,393 -12,10 -32,28 -46,40 -14,13 -47,41 -75,62 -27,22 -51,43 -53,48 -2,4 -10,7 -18,7 -8,0 -14,4 -14,8 0,4 -18,19 -40,32 -22,14 -40,28 -40,33 0,4 -5,7 -10,7 -6,0 -16,5 -23,10 -27,23 -103,77 -117,83 -8,4 -27,15 -42,25 -195,126 -501,278 -743,369 -22,8 -55,21 -73,29 -18,8 -39,14 -47,14 -8,0 -29,6 -47,14 -67,29 -349,105 -518,140 -194,40 -325,60 -570,87 -58,7 -264,14 -457,16l-353,5 0,196c0,196 -17,393 -46,522 -8,36 -14,74 -14,84 0,11 -6,42 -14,70 -8,28 -22,80 -32,116 -21,84 -63,216 -80,258 -98,230 -201,407 -321,551 -41,50 -194,204 -233,236 -75,60 -109,85 -118,85 -5,0 -12,6 -15,13 -2,7 -23,22 -46,32 -22,11 -41,23 -41,26 0,3 -27,19 -60,35 -33,16 -60,32 -60,37 0,4 -5,7 -10,7 -6,0 -38,13 -73,29 -34,16 -82,36 -107,46 -25,9 -53,21 -62,26 -10,5 -24,9 -33,9 -8,0 -29,6 -47,14 -18,8 -62,22 -98,31 -36,9 -87,23 -115,31 -37,11 -134,18 -360,24 -491,15 -7754,36 -7850,23zM5851,10972c41,-26 519,-470 964,-896 807,-773 1508,-1492 1770,-1816 395,-488 566,-1154 440,-1714 -109,-482 -423,-862 -895,-1085 -250,-117 -488,-171 -753,-171 -157,0 -289,18 -452,60 -361,93 -759,323 -1063,615l-109,104 -44,-46c-129,-133 -340,-303 -494,-395 -579,-349 -1284,-414 -1860,-173 -486,203 -786,588 -881,1130 -27,151 -24,468 5,640 63,373 192,710 383,992 57,86 164,216 302,368 124,137 658,670 911,910 255,241 493,466 585,550 42,39 134,124 205,191 72,66 227,210 345,319 118,109 256,237 305,284 134,127 140,131 182,147 46,17 115,11 154,-14zM12320,8645c253,-15 347,-27 397,-50 17,-8 36,-15 42,-15 6,0 27,-8 48,-17 21,-9 58,-25 83,-36 104,-46 229,-109 278,-142 30,-19 56,-35 59,-35 12,0 184,-141 256,-209 75,-72 194,-220 240,-299 11,-20 24,-39 27,-42 11,-11 100,-199 129,-275 53,-140 95,-314 125,-530 22,-150 22,-561 1,-677 -30,-161 -84,-360 -114,-416 -5,-9 -26,-51 -46,-92 -20,-41 -45,-88 -56,-105 -10,-16 -22,-37 -26,-45 -10,-22 -153,-211 -182,-241 -14,-15 -40,-43 -58,-63 -17,-20 -34,-36 -37,-36 -3,0 -19,-13 -35,-29 -78,-76 -270,-213 -386,-275 -27,-15 -57,-31 -65,-36 -18,-11 -106,-50 -170,-74 -25,-10 -60,-24 -78,-32 -27,-11 -139,-14 -617,-14l-585,0 0,1890 0,1890 58,1c31,1 102,5 157,9 166,11 308,10 555,-5z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_danger.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M23,16.06C23,16.29 23,16.5 22.96,16.7C22.78,14.14 20.64,12.11 18,12.11C17.63,12.11 17.27,12.16 16.92,12.23C16.96,12.5 17,12.73 17,13C17,15.35 15.31,17.32 13.07,17.81C13.42,20.05 15.31,21.79 17.65,21.96C17.43,22 17.22,22 17,22C14.92,22 13.07,20.94 12,19.34C10.93,20.94 9.09,22 7,22C6.78,22 6.57,22 6.35,21.96C8.69,21.79 10.57,20.06 10.93,17.81C8.68,17.32 7,15.35 7,13C7,12.73 7.04,12.5 7.07,12.23C6.73,12.16 6.37,12.11 6,12.11C3.36,12.11 1.22,14.14 1.03,16.7C1,16.5 1,16.29 1,16.06C1,12.85 3.59,10.24 6.81,10.14C6.3,9.27 6,8.25 6,7.17C6,4.94 7.23,3 9.06,2C7.81,2.9 7,4.34 7,6C7,7.35 7.56,8.59 8.47,9.5C9.38,8.59 10.62,8.04 12,8.04C13.37,8.04 14.62,8.59 15.5,9.5C16.43,8.59 17,7.35 17,6C17,4.34 16.18,2.9 14.94,2C16.77,3 18,4.94 18,7.17C18,8.25 17.7,9.27 17.19,10.14C20.42,10.24 23,12.85 23,16.06M9.27,10.11C10.05,10.62 11,10.92 12,10.92C13,10.92 13.95,10.62 14.73,10.11C14,9.45 13.06,9.03 12,9.03C10.94,9.03 10,9.45 9.27,10.11M12,14.47C12.82,14.47 13.5,13.8 13.5,13A1.5,1.5 0 0,0 12,11.5A1.5,1.5 0 0,0 10.5,13C10.5,13.8 11.17,14.47 12,14.47M10.97,16.79C10.87,14.9 9.71,13.29 8.05,12.55C8.03,12.7 8,12.84 8,13C8,14.82 9.27,16.34 10.97,16.79M15.96,12.55C14.29,13.29 13.12,14.9 13,16.79C14.73,16.34 16,14.82 16,13C16,12.84 15.97,12.7 15.96,12.55Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_delete.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_delete_all.xml",
    "content": "<!-- drawable/delete_sweep.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M15,16H19V18H15V16M15,8H22V10H15V8M15,12H21V14H15V12M3,18A2,2 0 0,0 5,20H11A2,2 0 0,0 13,18V8H3V18M14,5H11L10,4H6L5,5H2V7H14V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_design_ab.xml",
    "content": "<!-- drawable/ab_testing.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path android:fillColor=\"?colorControlNormal\" android:pathData=\"M4 2A2 2 0 0 0 2 4V12H4V8H6V12H8V4A2 2 0 0 0 6 2H4M4 4H6V6H4M22 15.5V14A2 2 0 0 0 20 12H16V22H20A2 2 0 0 0 22 20V18.5A1.54 1.54 0 0 0 20.5 17A1.54 1.54 0 0 0 22 15.5M20 20H18V18H20V20M20 16H18V14H20M5.79 21.61L4.21 20.39L18.21 2.39L19.79 3.61Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_diagnostic.xml",
    "content": "<!-- drawable/stethoscope.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M19,8C19.56,8 20,8.43 20,9A1,1 0 0,1 19,10C18.43,10 18,9.55 18,9C18,8.43 18.43,8 19,8M2,2V11C2,13.96 4.19,16.5 7.14,16.91C7.76,19.92 10.42,22 13.5,22A6.5,6.5 0 0,0 20,15.5V11.81C21.16,11.39 22,10.29 22,9A3,3 0 0,0 19,6A3,3 0 0,0 16,9C16,10.29 16.84,11.4 18,11.81V15.41C18,17.91 16,19.91 13.5,19.91C11.5,19.91 9.82,18.7 9.22,16.9C12,16.3 14,13.8 14,11V2H10V5H12V11A4,4 0 0,1 8,15A4,4 0 0,1 4,11V5H6V2H2Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_dir_update.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M3,5H9V11H3V5M5,7V9H7V7H5M11,7H21V9H11V7M11,15H21V17H11V15M5,20L1.5,16.5L2.91,15.09L5,17.17L9.59,12.59L11,14L5,20Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_directory.xml",
    "content": "<!-- drawable/view_list.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M9,5V9H21V5M9,19H21V15H9M9,14H21V10H9M4,9H8V5H4M4,19H8V15H4M4,14H8V10H4V14Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_directory_not.xml",
    "content": "<!-- drawable/view_list.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M9,5V9H21V5M9,19H21V15H9M9,14H21V10H9M4,9H8V5H4M4,19H8V15H4M4,14H8V10H4V14Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_discord.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M22,24L16.75,19L17.38,21H4.5A2.5,2.5 0 0,1 2,18.5V3.5A2.5,2.5 0 0,1 4.5,1H19.5A2.5,2.5 0 0,1 22,3.5V24M12,6.8C9.32,6.8 7.44,7.95 7.44,7.95C8.47,7.03 10.27,6.5 10.27,6.5L10.1,6.33C8.41,6.36 6.88,7.53 6.88,7.53C5.16,11.12 5.27,14.22 5.27,14.22C6.67,16.03 8.75,15.9 8.75,15.9L9.46,15C8.21,14.73 7.42,13.62 7.42,13.62C7.42,13.62 9.3,14.9 12,14.9C14.7,14.9 16.58,13.62 16.58,13.62C16.58,13.62 15.79,14.73 14.54,15L15.25,15.9C15.25,15.9 17.33,16.03 18.73,14.22C18.73,14.22 18.84,11.12 17.12,7.53C17.12,7.53 15.59,6.36 13.9,6.33L13.73,6.5C13.73,6.5 15.53,7.03 16.56,7.95C16.56,7.95 14.68,6.8 12,6.8M9.93,10.59C10.58,10.59 11.11,11.16 11.1,11.86C11.1,12.55 10.58,13.13 9.93,13.13C9.29,13.13 8.77,12.55 8.77,11.86C8.77,11.16 9.28,10.59 9.93,10.59M14.1,10.59C14.75,10.59 15.27,11.16 15.27,11.86C15.27,12.55 14.75,13.13 14.1,13.13C13.46,13.13 12.94,12.55 12.94,11.86C12.94,11.16 13.45,10.59 14.1,10.59Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_download.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_download_multiple.xml",
    "content": "<!-- drawable/download_multiple.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M9,1V7H5L12,14L19,7H15V1H9M5,16V18H19V16H5M5,20V22H19V20H5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_download_progress.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M13,2.03C17.73,2.5 21.5,6.25 21.95,11C22.5,16.5 18.5,21.38 13,21.93V19.93C16.64,19.5 19.5,16.61 19.96,12.97C20.5,8.58 17.39,4.59 13,4.05V2.05L13,2.03M11,2.06V4.06C9.57,4.26 8.22,4.84 7.1,5.74L5.67,4.26C7.19,3 9.05,2.25 11,2.06M4.26,5.67L5.69,7.1C4.8,8.23 4.24,9.58 4.05,11H2.05C2.25,9.04 3,7.19 4.26,5.67M2.06,13H4.06C4.24,14.42 4.81,15.77 5.69,16.9L4.27,18.33C3.03,16.81 2.26,14.96 2.06,13M7.1,18.37C8.23,19.25 9.58,19.82 11,20V22C9.04,21.79 7.18,21 5.67,19.74L7.1,18.37M12,16.5L7.5,12H11V8H13V12H16.5L12,16.5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_downloader.xml",
    "content": "<!-- drawable/download_network.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M17,3A2,2 0 0,1 19,5V15A2,2 0 0,1 17,17H13V19H14A1,1 0 0,1 15,20H22V22H15A1,1 0 0,1 14,23H10A1,1 0 0,1 9,22H2V20H9A1,1 0 0,1 10,19H11V17H7C5.89,17 5,16.1 5,15V5A2,2 0 0,1 7,3H17M12,14.5L16.5,10H13V6H11V10H7.5L12,14.5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_drag.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M9,3H11V5H9V3M13,3H15V5H13V3M9,7H11V9H9V7M13,7H15V9H13V7M9,11H11V13H9V11M13,11H15V13H13V11M9,15H11V17H9V15M13,15H15V17H13V15M9,19H11V21H9V19M13,19H15V21H13V19Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_drive.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M7.71,3.5L1.15,15L4.58,21L11.13,9.5M9.73,15L6.3,21H19.42L22.85,15M22.28,14L15.42,2H8.58L8.57,2L15.43,14H22.28Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_dropbox.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"235.45\"\n        android:viewportHeight=\"200.0\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M58.86,0l-58.86,37.5l58.86,37.5l58.87,-37.5l-58.87,-37.5z\"/>\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M176.59,0l-58.86,37.5l58.86,37.5l58.86,-37.5l-58.86,-37.5z\"/>\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M0,112.5l58.86,37.5l58.87,-37.5l-58.87,-37.5l-58.86,37.5z\"/>\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M176.59,75l-58.86,37.5l58.86,37.5l58.86,-37.5l-58.86,-37.5z\"/>\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M58.86,162.5l58.87,37.5l58.86,-37.5l-58.86,-37.5l-58.87,37.5z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_droped.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M9,3V4H4V6H5V19A2,2 0 0,0 7,21H17A2,2 0 0,0 19,19V6H20V4H15V3H9M9,8H11V17H9V8M13,8H15V17H13V8Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_edit.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_egg.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"2250\"\n        android:viewportHeight=\"2250\">\n\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M1044 2239 c-89 -8 -128 -21 -225 -71 -90 -46 -185 -122 -254 -203 -43 -51 -46 -58 -25 -52 299 75 871 75 1170 0 21 -6 18 1 -25 52 -69 81 -164 157 -255 205 -122 63 -238 84 -386 69z\"\n        android:strokeWidth=\"1\"/>\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M900 1814 c-180 -16 -470 -74 -488 -97 -32 -41 -82 -250 -82 -346 l0 -56 88 -88 87 -87 100 100 c55 55 104 100 109 100 5 0 53 -44 108 -97 l98 -97 98 97 c54 53 102 97 107 97 5 0 53 -44 107 -97 l98 -97 98 97 c55 53 103 97 108 97 5 0 54 -45 109 -100 l100 -100 88 88 89 87 -6 90 c-5 96 -22 172 -59 263 l-22 57 -105 26 c-181 45 -316 61 -560 64 -124 2 -245 1 -270 -1z m-334 -228 c38 -38 44 -77 19 -126 -17 -32 -61 -60 -95 -60 -29 0 -76 26 -94 52 -9 12 -16 40 -16 61 0 31 7 46 34 73 28 28 42 34 76 34 34 0 48 -6 76 -34z m403 20 c55 -29 68 -114 25 -165 -50 -60 -144 -48 -178 24 -20 41 -20 58 -1 95 30 57 94 77 154 46z m434 -7 c15 -11 32 -37 38 -58 23 -76 -46 -152 -124 -137 -98 18 -120 156 -32 204 33 18 90 14 118 -9z m433 -13 c38 -38 44 -77 19 -126 -17 -32 -61 -60 -95 -60 -34 0 -78 28 -95 60 -25 49 -19 88 19 126 28 28 42 34 76 34 34 0 48 -6 76 -34z\"\n        android:strokeWidth=\"1\"/>\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M610 1055 c-52 -52 -101 -95 -110 -95 -8 0 -43 28 -77 62 -35 34 -63 58 -63 53 0 -26 54 -212 91 -313 48 -131 44 -127 199 -166 160 -39 267 -50 475 -50 208 0 315 11 475 50 155 39 151 35 199 166 37 101 91 287 91 313 0 5 -28 -19 -63 -53 -34 -34 -69 -62 -77 -62 -8 0 -59 44 -112 97 l-98 98 -98 -98 c-53 -53 -104 -97 -112 -97 -9 0 -58 43 -110 95 l-95 95 -95 -95 c-52 -52 -102 -95 -110 -95 -9 0 -58 43 -110 95 -52 52 -97 95 -100 95 -3 0 -48 -43 -100 -95z m181 -214 c80 -81 -9 -222 -113 -178 -62 26 -87 75 -68 132 26 78 124 103 181 46z m402 9 c106 -84 -14 -250 -128 -176 -91 59 -49 196 60 196 27 0 51 -7 68 -20z m410 0 c14 -11 31 -36 37 -55 25 -77 -58 -160 -135 -135 -78 26 -103 124 -46 181 37 36 104 41 144 9z\"\n        android:strokeWidth=\"1\"/>\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M631 383 c101 -164 220 -286 336 -340 65 -32 81 -35 159 -35 79 0 92 3 163 38 98 48 214 162 304 299 36 55 64 101 63 103 -2 1 -36 -5 -77 -13 -274 -58 -634 -58 -907 0 -40 8 -75 15 -78 15 -2 0 15 -30 37 -67z\"\n        android:strokeWidth=\"1\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_emision.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M15,13H16.5V15.82L18.94,17.23L18.19,18.53L15,16.69V13M19,8H5V19H9.67C9.24,18.09 9,17.07 9,16A7,7 0 0,1 16,9C17.07,9 18.09,9.24 19,9.67V8M5,21C3.89,21 3,20.1 3,19V5C3,3.89 3.89,3 5,3H6V1H8V3H16V1H18V3H19A2,2 0 0,1 21,5V11.1C22.24,12.36 23,14.09 23,16A7,7 0 0,1 16,23C14.09,23 12.36,22.24 11.1,21H5M16,11.15A4.85,4.85 0 0,0 11.15,16C11.15,18.68 13.32,20.85 16,20.85A4.85,4.85 0 0,0 20.85,16C20.85,13.32 18.68,11.15 16,11.15Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_emision_not.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M15,13H16.5V15.82L18.94,17.23L18.19,18.53L15,16.69V13M19,8H5V19H9.67C9.24,18.09 9,17.07 9,16A7,7 0 0,1 16,9C17.07,9 18.09,9.24 19,9.67V8M5,21C3.89,21 3,20.1 3,19V5C3,3.89 3.89,3 5,3H6V1H8V3H16V1H18V3H19A2,2 0 0,1 21,5V11.1C22.24,12.36 23,14.09 23,16A7,7 0 0,1 16,23C14.09,23 12.36,22.24 11.1,21H5M16,11.15A4.85,4.85 0 0,0 11.15,16C11.15,18.68 13.32,20.85 16,20.85A4.85,4.85 0 0,0 20.85,16C20.85,13.32 18.68,11.15 16,11.15Z\" />\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_error.xml",
    "content": "<!-- drawable/alert_octagram.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#fff\"\r\n        android:pathData=\"M2.2,16.06L3.88,12L2.2,7.94L6.26,6.26L7.94,2.2L12,3.88L16.06,2.2L17.74,6.26L21.8,7.94L20.12,12L21.8,16.06L17.74,17.74L16.06,21.8L12,20.12L7.94,21.8L6.26,17.74L2.2,16.06M13,17V15H11V17H13M13,13V7H11V13H13Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_experimental.xml",
    "content": "<!-- drawable/test_tube.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M7,2V4H8V18A4,4 0 0,0 12,22A4,4 0 0,0 16,18V4H17V2H7M11,16C10.4,16 10,15.6 10,15C10,14.4 10.4,14 11,14C11.6,14 12,14.4 12,15C12,15.6 11.6,16 11,16M13,12C12.4,12 12,11.6 12,11C12,10.4 12.4,10 13,10C13.6,10 14,10.4 14,11C14,11.6 13.6,12 13,12M14,7H10V4H14V7Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_facebook.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3M18,5H15.5A3.5,3.5 0 0,0 12,8.5V11H10V14H12V21H15V14H18V11H15V9A1,1 0 0,1 16,8H18V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_facebook_group.xml",
    "content": "<!-- drawable/account_group.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,6A3,3 0 0,0 9,9A3,3 0 0,0 12,12A3,3 0 0,0 15,9A3,3 0 0,0 12,6M6,8.17A2.5,2.5 0 0,0 3.5,10.67A2.5,2.5 0 0,0 6,13.17C6.88,13.17 7.65,12.71 8.09,12.03C7.42,11.18 7,10.15 7,9C7,8.8 7,8.6 7.04,8.4C6.72,8.25 6.37,8.17 6,8.17M18,8.17C17.63,8.17 17.28,8.25 16.96,8.4C17,8.6 17,8.8 17,9C17,10.15 16.58,11.18 15.91,12.03C16.35,12.71 17.12,13.17 18,13.17A2.5,2.5 0 0,0 20.5,10.67A2.5,2.5 0 0,0 18,8.17M12,14C10,14 6,15 6,17V19H18V17C18,15 14,14 12,14M4.67,14.97C3,15.26 1,16.04 1,17.33V19H4V17C4,16.22 4.29,15.53 4.67,14.97M19.33,14.97C19.71,15.53 20,16.22 20,17V19H23V17.33C23,16.04 21,15.26 19.33,14.97Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_faq.xml",
    "content": "<!-- drawable/help_circle.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_ff.xml",
    "content": "<!-- drawable/home_heart.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M2,12L12,3L22,12H19V20H5V12H2M12,18L12.72,17.34C15.3,15 17,13.46 17,11.57C17,10.03 15.79,8.82 14.25,8.82C13.38,8.82 12.55,9.23 12,9.87C11.45,9.23 10.62,8.82 9.75,8.82C8.21,8.82 7,10.03 7,11.57C7,13.46 8.7,15 11.28,17.34L12,18Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_ffwd.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorAccent\"\n        android:pathData=\"M13,6V18L21.5,12M4,18L12.5,12L4,6V18Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_files.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M22,4H14L12,2H6A2,2 0 0,0 4,4V16A2,2 0 0,0 6,18H22A2,2 0 0,0 24,16V6A2,2 0 0,0 22,4M2,6H0V11H0V20A2,2 0 0,0 2,22H20V20H2V6Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_filter.xml",
    "content": "<!-- drawable/filter_variant.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M6,13H18V11H6M3,6V8H21V6M10,18H14V16H10V18Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_0.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3M19,19H5V5H19V19M17,8.4L13.4,12L17,15.6L15.6,17L12,13.4L8.4,17L7,15.6L10.6,12L7,8.4L8.4,7L12,10.6L15.6,7L17,8.4Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_1.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M19,19H5V5H19M19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3M12,17H14V7H10V9H12\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_2.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M17,13H13V11H15A2,2 0 0,0 17,9V7C17,5.89 16.1,5 15,5H11V7H15V9H13A2,2 0 0,0 11,11V15H17M21,17H7V3H21M21,1H7A2,2 0 0,0 5,3V17A2,2 0 0,0 7,19H21A2,2 0 0,0 23,17V3A2,2 0 0,0 21,1M3,5H1V21A2,2 0 0,0 3,23H19V21H3V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_3.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M17,13V11.5A1.5,1.5 0 0,0 15.5,10A1.5,1.5 0 0,0 17,8.5V7C17,5.89 16.1,5 15,5H11V7H15V9H13V11H15V13H11V15H15A2,2 0 0,0 17,13M3,5H1V21A2,2 0 0,0 3,23H19V21H3M21,17H7V3H21M21,1H7A2,2 0 0,0 5,3V17A2,2 0 0,0 7,19H21A2,2 0 0,0 23,17V3A2,2 0 0,0 21,1Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_4.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M21,17H7V3H21M21,1H7A2,2 0 0,0 5,3V17A2,2 0 0,0 7,19H21A2,2 0 0,0 23,17V3A2,2 0 0,0 21,1M15,15H17V5H15V9H13V5H11V11H15M3,5H1V21A2,2 0 0,0 3,23H19V21H3V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_5.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M17,13V11C17,9.89 16.1,9 15,9H13V7H17V5H11V11H15V13H11V15H15A2,2 0 0,0 17,13M3,5H1V21A2,2 0 0,0 3,23H19V21H3M21,17H7V3H21M21,1H7A2,2 0 0,0 5,3V17A2,2 0 0,0 7,19H21A2,2 0 0,0 23,17V3A2,2 0 0,0 21,1Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_6.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M13,11H15V13H13M13,15H15A2,2 0 0,0 17,13V11C17,9.89 16.1,9 15,9H13V7H17V5H13A2,2 0 0,0 11,7V13C11,14.11 11.9,15 13,15M21,17H7V3H21M21,1H7A2,2 0 0,0 5,3V17A2,2 0 0,0 7,19H21A2,2 0 0,0 23,17V3A2,2 0 0,0 21,1M3,5H1V21A2,2 0 0,0 3,23H19V21H3V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_7.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M13,15L17,7V5H11V7H15L11,15M21,17H7V3H21M21,1H7A2,2 0 0,0 5,3V17A2,2 0 0,0 7,19H21A2,2 0 0,0 23,17V3A2,2 0 0,0 21,1M3,5H1V21A2,2 0 0,0 3,23H19V21H3V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_8.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M13,11H15V13H13M13,7H15V9H13M13,15H15A2,2 0 0,0 17,13V11.5A1.5,1.5 0 0,0 15.5,10A1.5,1.5 0 0,0 17,8.5V7C17,5.89 16.1,5 15,5H13A2,2 0 0,0 11,7V8.5A1.5,1.5 0 0,0 12.5,10A1.5,1.5 0 0,0 11,11.5V13C11,14.11 11.9,15 13,15M21,17H7V3H21M21,1H7A2,2 0 0,0 5,3V17A2,2 0 0,0 7,19H21A2,2 0 0,0 23,17V3A2,2 0 0,0 21,1M3,5H1V21A2,2 0 0,0 3,23H19V21H3V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_9.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M15,9H13V7H15M15,5H13A2,2 0 0,0 11,7V9C11,10.11 11.9,11 13,11H15V13H11V15H15A2,2 0 0,0 17,13V7C17,5.89 16.1,5 15,5M21,17H7V3H21M21,1H7A2,2 0 0,0 5,3V17A2,2 0 0,0 7,19H21A2,2 0 0,0 23,17V3A2,2 0 0,0 21,1M3,5H1V21A2,2 0 0,0 3,23H19V21H3V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_genres_more.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M21,9H19V7H17V9H15V11H17V13H19V11H21V17H7V3H21M21,1H7A2,2 0 0,0 5,3V17A2,2 0 0,0 7,19H21A2,2 0 0,0 23,17V3A2,2 0 0,0 21,1M11,9V8H12V9M14,12V8C14,6.89 13.1,6 12,6H11A2,2 0 0,0 9,8V9C9,10.11 9.9,11 11,11H12V12H9V14H12A2,2 0 0,0 14,12M3,5H1V21A2,2 0 0,0 3,23H19V21H3V5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_github.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21H14.56C14.24,20.93 14.23,20.32 14.23,20.11L14.24,17.64C14.24,16.8 13.95,16.25 13.63,15.97C15.64,15.75 17.74,15 17.74,11.53C17.74,10.55 17.39,9.74 16.82,9.11C16.91,8.89 17.22,7.97 16.73,6.73C16.73,6.73 15.97,6.5 14.25,7.66C13.53,7.46 12.77,7.36 12,7.35C11.24,7.36 10.46,7.46 9.75,7.66C8.03,6.5 7.27,6.73 7.27,6.73C6.78,7.97 7.09,8.89 7.18,9.11C6.61,9.74 6.26,10.55 6.26,11.53C6.26,15 8.36,15.75 10.36,16C10.1,16.2 9.87,16.6 9.79,17.18C9.27,17.41 7.97,17.81 7.17,16.43C7.17,16.43 6.69,15.57 5.79,15.5C5.79,15.5 4.91,15.5 5.73,16.05C5.73,16.05 6.32,16.33 6.73,17.37C6.73,17.37 7.25,19.12 9.76,18.58L9.77,20.11C9.77,20.32 9.75,20.93 9.43,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_group.xml",
    "content": "<!-- drawable/group.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M1,1V5H2V19H1V23H5V22H19V23H23V19H22V5H23V1H19V2H5V1M5,4H19V5H20V19H19V20H5V19H4V5H5M6,6V14H9V18H18V9H14V6M8,8H12V12H8M14,11H16V16H11V14H14\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_grouped.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M5,10A2,2 0 0,0 3,12C3,13.11 3.9,14 5,14C6.11,14 7,13.11 7,12A2,2 0 0,0 5,10M5,16A4,4 0 0,1 1,12A4,4 0 0,1 5,8A4,4 0 0,1 9,12A4,4 0 0,1 5,16M10.5,11H14V8L18,12L14,16V13H10.5V11M5,6C4.55,6 4.11,6.05 3.69,6.14C5.63,3.05 9.08,1 13,1C19.08,1 24,5.92 24,12C24,18.08 19.08,23 13,23C9.08,23 5.63,20.95 3.69,17.86C4.11,17.95 4.55,18 5,18C5.8,18 6.56,17.84 7.25,17.56C8.71,19.07 10.74,20 13,20A8,8 0 0,0 21,12A8,8 0 0,0 13,4C10.74,4 8.71,4.93 7.25,6.44C6.56,6.16 5.8,6 5,6Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_hash.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M5.41,21L6.12,17H2.12L2.47,15H6.47L7.53,9H3.53L3.88,7H7.88L8.59,3H10.59L9.88,7H15.88L16.59,3H18.59L17.88,7H21.88L21.53,9H17.53L16.47,15H20.47L20.12,17H16.12L15.41,21H13.41L14.12,17H8.12L7.41,21H5.41M9.53,9L8.47,15H14.47L15.53,9H9.53Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_heart.xml",
    "content": "<!-- drawable/heart.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_heart_full_menu.xml",
    "content": "<!-- drawable/heart.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_hide.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorAccent\"\n        android:pathData=\"M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_hide_pref.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_home.xml",
    "content": "<!-- drawable/home_city.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M0,21V10L7.5,5L15,10V21H10V14H5V21H0M24,2V21H17V8.93L16,8.27V6H14V6.93L10,4.27V2H24M21,14H19V16H21V14M21,10H19V12H21V10M21,6H19V8H21V6Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_img.xml",
    "content": "<!-- drawable/image.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M8.5,13.5L11,16.5L14.5,12L19,18H5M21,19V5C21,3.89 20.1,3 19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_import.xml",
    "content": "<!-- drawable/import.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M14,12L10,8V11H2V13H10V16M20,18V6C20,4.89 19.1,4 18,4H6A2,2 0 0,0 4,6V9H6V6H18V18H6V15H4V18A2,2 0 0,0 6,20H18A2,2 0 0,0 20,18Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_incognito.xml",
    "content": "<!-- drawable/incognito.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M12,3C9.31,3 7.41,4.22 7.41,4.22L6,9H18L16.59,4.22C16.59,4.22 14.69,3 12,3M12,11C9.27,11 5.39,11.54 5.13,11.59C4.09,11.87 3.25,12.15 2.59,12.41C1.58,12.75 1,13 1,13H23C23,13 22.42,12.75 21.41,12.41C20.75,12.15 19.89,11.87 18.84,11.59C18.84,11.59 14.82,11 12,11M7.5,14A3.5,3.5 0 0,0 4,17.5A3.5,3.5 0 0,0 7.5,21A3.5,3.5 0 0,0 11,17.5C11,17.34 11,17.18 10.97,17.03C11.29,16.96 11.63,16.9 12,16.91C12.37,16.91 12.71,16.96 13.03,17.03C13,17.18 13,17.34 13,17.5A3.5,3.5 0 0,0 16.5,21A3.5,3.5 0 0,0 20,17.5A3.5,3.5 0 0,0 16.5,14C15.03,14 13.77,14.9 13.25,16.19C12.93,16.09 12.55,16 12,16C11.45,16 11.07,16.09 10.75,16.19C10.23,14.9 8.97,14 7.5,14M7.5,15A2.5,2.5 0 0,1 10,17.5A2.5,2.5 0 0,1 7.5,20A2.5,2.5 0 0,1 5,17.5A2.5,2.5 0 0,1 7.5,15M16.5,15A2.5,2.5 0 0,1 19,17.5A2.5,2.5 0 0,1 16.5,20A2.5,2.5 0 0,1 14,17.5A2.5,2.5 0 0,1 16.5,15Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_info.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M13,9H11V7H13M13,17H11V11H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_info_white.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M13,9H11V7H13M13,17H11V11H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_key.xml",
    "content": "<!-- drawable/account_key.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M11,10V12H10V14H8V12H5.83C5.42,13.17 4.31,14 3,14A3,3 0 0,1 0,11A3,3 0 0,1 3,8C4.31,8 5.42,8.83 5.83,10H11M3,10A1,1 0 0,0 2,11A1,1 0 0,0 3,12A1,1 0 0,0 4,11A1,1 0 0,0 3,10M16,14C18.67,14 24,15.34 24,18V20H8V18C8,15.34 13.33,14 16,14M16,12A4,4 0 0,1 12,8A4,4 0 0,1 16,4A4,4 0 0,1 20,8A4,4 0 0,1 16,12Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"4596.8247\"\n    android:viewportHeight=\"4596.8247\">\n    <group\n        android:translateX=\"275.80948\"\n        android:translateY=\"275.80948\">\n        <group\n            android:translateX=\"546.1027\"\n            android:translateY=\"546.1027\">\n            <path\n                android:name=\"UKIKU\"\n                android:fillColor=\"#fff\"\n                android:pathData=\"m395.4 1256.4v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.2 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3zm533.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm164 0v440.5h79.9v-440.5zm173.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm154.5 0v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.3 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3z\" />\n        </group>\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_lay_type.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M6,2H18A2,2 0 0,1 20,4V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V4A2,2 0 0,1 6,2M6,8V16H18V8H6Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_library_video.xml",
    "content": "<!-- drawable/library_video.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M4,6H2V20A2,2 0 0,0 4,22H18V20H4V6M20,2H8A2,2 0 0,0 6,4V16A2,2 0 0,0 8,18H20A2,2 0 0,0 22,16V4A2,2 0 0,0 20,2M12,14.5V5.5L18,10L12,14.5Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_list_placeholder.xml",
    "content": "<!-- drawable/format_list_triangle.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M5,15.5L7.5,20H2.5L5,15.5M9,19H21V17H9V19M5,9.5L7.5,14H2.5L5,9.5M9,13H21V11H9V13M5,3.5L7.5,8H2.5L5,3.5M9,7H21V5H9V7Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_locked.xml",
    "content": "<!-- drawable/lock.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"@color/textSecondary\"\r\n        android:pathData=\"M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_locked_solid.xml",
    "content": "<!-- drawable/lock.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#fff\"\r\n        android:pathData=\"M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_magic.xml",
    "content": "<!-- drawable/auto_fix.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M7.5,5.6L5,7L6.4,4.5L5,2L7.5,3.4L10,2L8.6,4.5L10,7L7.5,5.6M19.5,15.4L22,14L20.6,16.5L22,19L19.5,17.6L17,19L18.4,16.5L17,14L19.5,15.4M22,2L20.6,4.5L22,7L19.5,5.6L17,7L18.4,4.5L17,2L19.5,3.4L22,2M13.34,12.78L15.78,10.34L13.66,8.22L11.22,10.66L13.34,12.78M14.37,7.29L16.71,9.63C17.1,10 17.1,10.65 16.71,11.04L5.04,22.71C4.65,23.1 4,23.1 3.63,22.71L1.29,20.37C0.9,20 0.9,19.35 1.29,18.96L12.96,7.29C13.35,6.9 14,6.9 14.37,7.29Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_map.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M15,19L9,16.89V5L15,7.11M20.5,3C20.44,3 20.39,3 20.34,3L15,5.1L9,3L3.36,4.9C3.15,4.97 3,5.15 3,5.38V20.5A0.5,0.5 0 0,0 3.5,21C3.55,21 3.61,21 3.66,20.97L9,18.9L15,21L20.64,19.1C20.85,19 21,18.85 21,18.62V3.5A0.5,0.5 0 0,0 20.5,3Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_menu.xml",
    "content": "<!-- drawable/menu.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_menu_ham.xml",
    "content": "<!-- drawable/menu.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path android:fillColor=\"?colorControlNormal\" android:pathData=\"M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_move.xml",
    "content": "<!-- drawable/folder_move.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M14,18V15H10V11H14V8L19,13M20,6H12L10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_new.xml",
    "content": "<!-- drawable/alert_decagram.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#000\"\n        android:pathData=\"M23,12L20.56,9.22L20.9,5.54L17.29,4.72L15.4,1.54L12,3L8.6,1.54L6.71,4.72L3.1,5.53L3.44,9.21L1,12L3.44,14.78L3.1,18.47L6.71,19.29L8.6,22.47L12,21L15.4,22.46L17.29,19.28L20.9,18.46L20.56,14.78L23,12M13,17H11V15H13V17M13,13H11V7H13V13Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_new_recent.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M17,13H13V17H11V13H7V11H11V7H13V11H17M19,3H5C3.89,3 3,3.89 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_news.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M20,11H4V8H20M20,15H13V13H20M20,19H13V17H20M11,19H4V13H11M20.33,4.67L18.67,3L17,4.67L15.33,3L13.67,4.67L12,3L10.33,4.67L8.67,3L7,4.67L5.33,3L3.67,4.67L2,3V19A2,2 0 0,0 4,21H20A2,2 0 0,0 22,19V3L20.33,4.67Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_next.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorAccent\"\n        android:pathData=\"M16,18H18V6H16M6,18L14.5,12L6,6V18Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_no_downloading.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M10,17L6,13L7.41,11.59L10,14.17L16.59,7.58L18,9M12,3A1,1 0 0,1 13,4A1,1 0 0,1 12,5A1,1 0 0,1 11,4A1,1 0 0,1 12,3M19,3H14.82C14.4,1.84 13.3,1 12,1C10.7,1 9.6,1.84 9.18,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_no_downloads.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M13,9H14V11H11V7H13V9M18.5,9L16.38,6.88L17.63,5.63L20,8V10H18V11H15V9H18.5M13,3.5V2H12V4H13V6H11V4H9V2H8V4H6V5H4V4C4,2.89 4.89,2 6,2H14L16.36,4.36L15.11,5.61L13,3.5M20,20A2,2 0 0,1 18,22H16V20H18V19H20V20M18,15H20V18H18V15M12,22V20H15V22H12M8,22V20H11V22H8M6,22C4.89,22 4,21.1 4,20V18H6V20H7V22H6M4,14H6V17H4V14M4,10H6V13H4V10M18,11H20V14H18V11M4,6H6V9H4V6Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_no_emision.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M19,19H5V8H19M19,3H18V1H16V3H8V1H6V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5A2,2 0 0,0 19,3M9.31,17L11.75,14.56L14.19,17L15.25,15.94L12.81,13.5L15.25,11.06L14.19,10L11.75,12.44L9.31,10L8.25,11.06L10.69,13.5L8.25,15.94L9.31,17Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_no_genres.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M14.76,20.83L17.6,18L14.76,15.17L16.17,13.76L19,16.57L21.83,13.76L23.24,15.17L20.43,18L23.24,20.83L21.83,22.24L19,19.4L16.17,22.24L14.76,20.83M12,12V19.88C12.04,20.18 11.94,20.5 11.71,20.71C11.32,21.1 10.69,21.1 10.3,20.71L8.29,18.7C8.06,18.47 7.96,18.16 8,17.87V12H7.97L2.21,4.62C1.87,4.19 1.95,3.56 2.38,3.22C2.57,3.08 2.78,3 3,3V3H17V3C17.22,3 17.43,3.08 17.62,3.22C18.05,3.56 18.13,4.19 17.79,4.62L12.03,12H12Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_no_network.xml",
    "content": "<!-- drawable/wifi_strength_off.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M3.27,1.44L2,2.72L4.05,4.77C2.75,5.37 1.5,6.11 0.38,7C4.41,12.06 12,21.5 12,21.5L15.91,16.63L19.23,19.95L20.5,18.68M12,3C10.6,3 9.21,3.17 7.86,3.5L18.18,13.81C20,11.5 22.05,9 23.65,7C20.32,4.41 16.22,3 12,3Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_no_recents.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22C14.25,22 16.33,21.24 18,20V17.28C16.53,18.94 14.39,20 12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4C15.36,4 18.23,6.07 19.41,9H21.54C20.27,4.94 16.5,2 12,2M11,7V13L16.25,16.15L17,14.92L12.5,12.25V7H11M20,11V18H22V11H20M20,20V22H22V20H20Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_no_records.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_no_thumb.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M19,3A2,2 0 0,1 21,5V11H19V13H19L17,13V15H15V17H13V19H11V21H5C3.89,21 3,20.1 3,19V5A2,2 0 0,1 5,3H19M21,15V19A2,2 0 0,1 19,21H19L15,21V19H17V17H19V15H21M19,8.5A0.5,0.5 0 0,0 18.5,8H5.5A0.5,0.5 0 0,0 5,8.5V15.5A0.5,0.5 0 0,0 5.5,16H11V15H13V13H15V11H17V9H19V8.5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_not_found.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M10,19H13V22H10V19M12,2C17.35,2.22 19.68,7.62 16.5,11.67C15.67,12.67 14.33,13.33 13.67,14.17C13,15 13,16 13,17H10C10,15.33 10,13.92 10.67,12.92C11.33,11.92 12.67,11.33 13.5,10.67C15.92,8.43 15.32,5.26 12,5A3,3 0 0,0 9,8H6A6,6 0 0,1 12,2Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_not_seeing.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M2,5.27L3.28,4L20,20.72L18.73,22L17.05,20.31L12,17.27L5.82,21L7.45,13.97L2,9.24L5.66,8.93L2,5.27M12,2L14.81,8.62L22,9.24L16.54,13.97L16.77,14.95L9.56,7.74L12,2Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_not_update.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M17,1H7A2,2 0 0,0 5,3V21A2,2 0 0,0 7,23H17A2,2 0 0,0 19,21V3A2,2 0 0,0 17,1M17,19H7V5H17V19M16,13H13V8H11V13H8L12,17L16,13Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_note.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M12,3V12.26C11.5,12.09 11,12 10.5,12C8,12 6,14 6,16.5C6,19 8,21 10.5,21C13,21 15,19 15,16.5V6H19V3H12Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_number.xml",
    "content": "<!-- drawable/pound.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M5.41,21L6.12,17H2.12L2.47,15H6.47L7.53,9H3.53L3.88,7H7.88L8.59,3H10.59L9.88,7H15.88L16.59,3H18.59L17.88,7H21.88L21.53,9H17.53L16.47,15H20.47L20.12,17H16.12L15.41,21H13.41L14.12,17H8.12L7.41,21H5.41M9.53,9L8.47,15H14.47L15.53,9H9.53Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_open.xml",
    "content": "<!-- drawable/open_in_app.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M12,10L8,14H11V20H13V14H16M19,4H5C3.89,4 3,4.9 3,6V18A2,2 0 0,0 5,20H9V18H5V8H19V18H15V20H19A2,2 0 0,0 21,18V6A2,2 0 0,0 19,4Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_option_not_seen.xml",
    "content": "<!-- drawable/eye_off.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M11.83,9L15,12.16C15,12.11 15,12.05 15,12A3,3 0 0,0 12,9C11.94,9 11.89,9 11.83,9M7.53,9.8L9.08,11.35C9.03,11.56 9,11.77 9,12A3,3 0 0,0 12,15C12.22,15 12.44,14.97 12.65,14.92L14.2,16.47C13.53,16.8 12.79,17 12,17A5,5 0 0,1 7,12C7,11.21 7.2,10.47 7.53,9.8M2,4.27L4.28,6.55L4.73,7C3.08,8.3 1.78,10 1,12C2.73,16.39 7,19.5 12,19.5C13.55,19.5 15.03,19.2 16.38,18.66L16.81,19.08L19.73,22L21,20.73L3.27,3M12,7A5,5 0 0,1 17,12C17,12.64 16.87,13.26 16.64,13.82L19.57,16.75C21.07,15.5 22.27,13.86 23,12C21.27,7.61 17,4.5 12,4.5C10.6,4.5 9.26,4.75 8,5.2L10.17,7.35C10.74,7.13 11.35,7 12,7Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_option_seen.xml",
    "content": "<!-- drawable/eye.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_palette.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M17.5,12A1.5,1.5 0 0,1 16,10.5A1.5,1.5 0 0,1 17.5,9A1.5,1.5 0 0,1 19,10.5A1.5,1.5 0 0,1 17.5,12M14.5,8A1.5,1.5 0 0,1 13,6.5A1.5,1.5 0 0,1 14.5,5A1.5,1.5 0 0,1 16,6.5A1.5,1.5 0 0,1 14.5,8M9.5,8A1.5,1.5 0 0,1 8,6.5A1.5,1.5 0 0,1 9.5,5A1.5,1.5 0 0,1 11,6.5A1.5,1.5 0 0,1 9.5,8M6.5,12A1.5,1.5 0 0,1 5,10.5A1.5,1.5 0 0,1 6.5,9A1.5,1.5 0 0,1 8,10.5A1.5,1.5 0 0,1 6.5,12M12,3A9,9 0 0,0 3,12A9,9 0 0,0 12,21A1.5,1.5 0 0,0 13.5,19.5C13.5,19.11 13.35,18.76 13.11,18.5C12.88,18.23 12.73,17.88 12.73,17.5A1.5,1.5 0 0,1 14.23,16H16A5,5 0 0,0 21,11C21,6.58 16.97,3 12,3Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_patreon.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M14.73,3C18.45,3 21.47,6.03 21.47,9.76C21.47,13.47 18.45,16.5 14.73,16.5C11,16.5 7.97,13.47 7.97,9.76C7.97,6.03 11,3 14.73,3M2.7,21V3H6V21H2.7Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_pause.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorAccent\"\n        android:pathData=\"M14,19H18V5H14M6,19H10V5H6V19Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_pause_normal.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M14,19H18V5H14M6,19H10V5H6V19Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_pause_not.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M14,19H18V5H14M6,19H10V5H6V19Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_paused.xml",
    "content": "<!-- drawable/pause_circle.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M15,16H13V8H15M11,16H9V8H11M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_paypal.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M8.32,21.97C8.21,21.92 8.08,21.76 8.06,21.65C8.03,21.5 8,21.76 8.66,17.56C9.26,13.76 9.25,13.82 9.33,13.71C9.46,13.54 9.44,13.54 10.94,13.53C12.26,13.5 12.54,13.5 13.13,13.41C16.38,12.96 18.39,11.05 19.09,7.75C19.13,7.53 19.17,7.34 19.18,7.34C19.18,7.33 19.25,7.38 19.33,7.44C20.36,8.22 20.71,9.66 20.32,11.58C19.86,13.87 18.64,15.39 16.74,16.04C15.93,16.32 15.25,16.43 14.05,16.46C13.25,16.5 13.23,16.5 13,16.65C12.83,16.82 12.84,16.79 12.45,19.2C12.18,20.9 12.08,21.45 12.04,21.55C11.97,21.71 11.83,21.85 11.67,21.93L11.56,22H10C8.71,22 8.38,22 8.32,21.97V21.97M3.82,19.74C3.63,19.64 3.5,19.47 3.5,19.27C3.5,19 6.11,2.68 6.18,2.5C6.27,2.32 6.5,2.13 6.68,2.06L6.83,2H10.36C14.27,2 14.12,2 15,2.2C17.62,2.75 18.82,4.5 18.37,7.13C17.87,10.06 16.39,11.8 13.87,12.43C13,12.64 12.39,12.7 10.73,12.7C9.42,12.7 9.32,12.71 9.06,12.85C8.8,13 8.59,13.27 8.5,13.6C8.46,13.67 8.23,15.07 7.97,16.7C7.71,18.33 7.5,19.69 7.5,19.72L7.47,19.78H5.69C4.11,19.78 3.89,19.78 3.82,19.74V19.74Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_pip.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorAccent\"\n        android:pathData=\"M14,14H19V16H16V19H14V14M5,14H10V19H8V16H5V14M8,5H10V10H5V8H8V5M19,8V10H14V5H16V8H19Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_pip_exit.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M9.5,13.09L10.91,14.5L6.41,19H10V21H3V14H5V17.59L9.5,13.09M10.91,9.5L9.5,10.91L5,6.41V10H3V3H10V5H6.41L10.91,9.5M14.5,13.09L19,17.59V14H21V21H14V19H17.59L13.09,14.5L14.5,13.09M13.09,9.5L17.59,5H14V3H21V10H19V6.41L14.5,10.91L13.09,9.5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_play.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorAccent\"\n        android:pathData=\"M8,5.14V19.14L19,12.14L8,5.14Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_play_all.xml",
    "content": "<!-- drawable/playlist_play.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#fff\"\r\n        android:pathData=\"M19,9H2V11H19V9M19,5H2V7H19V5M2,15H15V13H2V15M17,13V19L22,16L17,13Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_play_not.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M8,5.14V19.14L19,12.14L8,5.14Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_play_queue.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M8,5.14V19.14L19,12.14L8,5.14Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_player.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M19,19H5V5H19M19,3H5A2,2 0 0,0 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V5C21,3.89 20.1,3 19,3M10,8V16L15,12L10,8Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_podium.xml",
    "content": "<!-- drawable/podium.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M12,7.09L14.45,8.58L13.8,5.77L16,3.89L13.11,3.64L12,1L10.87,3.64L8,3.89L10.18,5.77L9.5,8.58L12,7.09M4,13.09L6.45,14.58L5.8,11.77L8,9.89L5.11,9.64L4,7L2.87,9.64L0,9.89L2.18,11.77L1.5,14.58L4,13.09M20,10.09L22.45,11.58L21.8,8.77L24,6.89L21.11,6.64L20,4L18.87,6.64L16,6.89L18.18,8.77L17.5,11.58L20,10.09M15,23H9V10H15V23M7,23H1V17H7V23M23,23H17V13H23V23Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_previous.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorAccent\"\n        android:pathData=\"M6,18V6H8V18H6M9.5,12L18,6V18L9.5,12Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_queue_file.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M10,4L12,6H20A2,2 0 0,1 22,8V18A2,2 0 0,1 20,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10M15,9V12H12V14H15V17H17V14H20V12H17V9H15Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_queue_list.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M9,5V9H21V5M9,19H21V15H9M9,14H21V10H9M4,9H8V5H4M4,19H8V15H4M4,14H8V10H4V14Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_queue_normal.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_random.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M14.83,13.41L13.42,14.82L16.55,17.95L14.5,20H20V14.5L17.96,16.54L14.83,13.41M14.5,4L16.54,6.04L4,18.59L5.41,20L17.96,7.46L20,9.5V4M10.59,9.17L5.41,4L4,5.41L9.17,10.58L10.59,9.17Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_rating.xml",
    "content": "<!-- drawable/chart_bar.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M22,21H2V3H4V19H6V10H10V19H12V6H16V19H18V14H22V21Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_recents.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M11,7V12.11L15.71,14.9L16.5,13.62L12.5,11.25V7M12.5,2C8.97,2 5.91,3.92 4.27,6.77L2,4.5V11H8.5L5.75,8.25C6.96,5.73 9.5,4 12.5,4A7.5,7.5 0 0,1 20,11.5A7.5,7.5 0 0,1 12.5,19C9.23,19 6.47,16.91 5.44,14H3.34C4.44,18.03 8.11,21 12.5,21C17.74,21 22,16.75 22,11.5A9.5,9.5 0 0,0 12.5,2Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_recents_group.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M12.6,2.86C15.27,4.1 18,5.39 20.66,6.63C20.81,6.7 21,6.75 21,6.95C21,7.15 20.81,7.19 20.66,7.26C18,8.5 15.3,9.77 12.62,11C12.21,11.21 11.79,11.21 11.38,11C8.69,9.76 6,8.5 3.32,7.25C3.18,7.19 3,7.14 3,6.94C3,6.76 3.18,6.71 3.31,6.65C6,5.39 8.74,4.1 11.44,2.85C11.73,2.72 12.3,2.73 12.6,2.86M12,21.15C11.8,21.15 11.66,21.07 11.38,20.97C8.69,19.73 6,18.47 3.33,17.22C3.19,17.15 3,17.11 3,16.9C3,16.7 3.19,16.66 3.34,16.59C3.78,16.38 4.23,16.17 4.67,15.96C5.12,15.76 5.56,15.76 6,15.97C7.79,16.8 9.57,17.63 11.35,18.46C11.79,18.67 12.23,18.66 12.67,18.46C14.45,17.62 16.23,16.79 18,15.96C18.44,15.76 18.87,15.75 19.29,15.95C19.77,16.16 20.24,16.39 20.71,16.61C20.78,16.64 20.85,16.68 20.91,16.73C21.04,16.83 21.04,17 20.91,17.08C20.83,17.14 20.74,17.19 20.65,17.23C18,18.5 15.33,19.72 12.66,20.95C12.46,21.05 12.19,21.15 12,21.15M12,16.17C11.9,16.17 11.55,16.07 11.36,16C8.68,14.74 6,13.5 3.34,12.24C3.2,12.18 3,12.13 3,11.93C3,11.72 3.2,11.68 3.35,11.61C3.8,11.39 4.25,11.18 4.7,10.97C5.13,10.78 5.56,10.78 6,11C7.78,11.82 9.58,12.66 11.38,13.5C11.79,13.69 12.21,13.69 12.63,13.5C14.43,12.65 16.23,11.81 18.04,10.97C18.45,10.78 18.87,10.78 19.29,10.97C19.76,11.19 20.24,11.41 20.71,11.63C20.77,11.66 20.84,11.69 20.9,11.74C21.04,11.85 21.04,12 20.89,12.12C20.84,12.16 20.77,12.19 20.71,12.22C18,13.5 15.31,14.75 12.61,16C12.42,16.09 12.08,16.17 12,16.17Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_record.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_remember.xml",
    "content": "<!-- drawable/flash.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M7,2V13H10V22L17,10H13L17,2H7Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_resize.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M1.88,0.46L0.46,1.88L5.59,7H2V9H9V2H7V5.59M11,7V9H21V15H23V9A2,2 0 0,0 21,7M7,11V21A2,2 0 0,0 9,23H15V21H9V11M15.88,14.46L14.46,15.88L19.6,21H17V23H23V17H21V19.59\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_restore.xml",
    "content": "<!-- drawable/cloud_download.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M17,13L12,18L7,13H10V9H14V13M19.35,10.03C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.03C2.34,8.36 0,10.9 0,14A6,6 0 0,0 6,20H19A5,5 0 0,0 24,15C24,12.36 21.95,10.22 19.35,10.03Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_rewind.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorAccent\"\n        android:pathData=\"M11.5,12L20,18V6M11,18V6L2.5,12L11,18Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_samsung_tv.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M21,17H3V5H21M21,3H3A2,2 0 0,0 1,5V17A2,2 0 0,0 3,19H8V21H16V19H21A2,2 0 0,0 23,17V5A2,2 0 0,0 21,3Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_save.xml",
    "content": "<!-- drawable/content_save.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_save_w.xml",
    "content": "<!-- drawable/content_save.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#fff\"\r\n        android:pathData=\"M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_scale.xml",
    "content": "<!-- drawable/relative_scale.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M20,18H4V6H20M20,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6C22,4.89 21.1,4 20,4M12,10H10V12H12M8,10H6V12H8M16,14H14V16H16M16,10H14V12H16V10Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_search_black_24dp.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24.0\"\n        android:viewportHeight=\"24.0\">\n    <path\n        android:fillColor=\"#FF000000\"\n        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/ic_sectioned_favs.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M2,16H10V14H2M18,14V10H16V14H12V16H16V20H18V16H22V14M14,6H2V8H14M14,10H2V12H14V10Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_seeing.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M12,15.4V6.1L13.71,10.13L18.09,10.5L14.77,13.39L15.76,17.67M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_seeing_drawer.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,15.4V6.1L13.71,10.13L18.09,10.5L14.77,13.39L15.76,17.67M22,9.24L14.81,8.63L12,2L9.19,8.63L2,9.24L7.45,13.97L5.82,21L12,17.27L18.18,21L16.54,13.97L22,9.24Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_seen.xml",
    "content": "<!-- drawable/eye.xml -->\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorAccent\"\n        android:pathData=\"M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_server_running.xml",
    "content": "<!-- drawable/folder_network.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#000\"\r\n        android:pathData=\"M3,14V4A2,2 0 0,1 5,2H11L13,4H19A2,2 0 0,1 21,6V14A2,2 0 0,1 19,16H13V18H14A1,1 0 0,1 15,19H22V21H15A1,1 0 0,1 14,22H10A1,1 0 0,1 9,21H2V19H9A1,1 0 0,1 10,18H11V16H5A2,2 0 0,1 3,14Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_service.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9A3,3 0 0,1 15,12Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_setting_asc_list.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,18.17L8.83,15L7.42,16.41L12,21L16.59,16.41L15.17,15M12,5.83L15.17,9L16.58,7.59L12,3L7.41,7.59L8.83,9L12,5.83Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_setting_gps.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M3.05,13H1V11H3.05C3.5,6.83 6.83,3.5 11,3.05V1H13V3.05C17.17,3.5 20.5,6.83 20.95,11H23V13H20.95C20.5,17.17 17.17,20.5 13,20.95V23H11V20.95C6.83,20.5 3.5,17.17 3.05,13M12,5A7,7 0 0,0 5,12A7,7 0 0,0 12,19A7,7 0 0,0 19,12A7,7 0 0,0 12,5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_settings_reload.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M19,12H22.32L17.37,16.95L12.42,12H16.97C17,10.46 16.42,8.93 15.24,7.75C12.9,5.41 9.1,5.41 6.76,7.75C4.42,10.09 4.42,13.9 6.76,16.24C8.6,18.08 11.36,18.47 13.58,17.41L15.05,18.88C12,20.69 8,20.29 5.34,17.65C2.22,14.53 2.23,9.47 5.35,6.35C8.5,3.22 13.53,3.21 16.66,6.34C18.22,7.9 19,9.95 19,12Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_share.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M18,16.08C17.24,16.08 16.56,16.38 16.04,16.85L8.91,12.7C8.96,12.47 9,12.24 9,12C9,11.76 8.96,11.53 8.91,11.3L15.96,7.19C16.5,7.69 17.21,8 18,8A3,3 0 0,0 21,5A3,3 0 0,0 18,2A3,3 0 0,0 15,5C15,5.24 15.04,5.47 15.09,5.7L8.04,9.81C7.5,9.31 6.79,9 6,9A3,3 0 0,0 3,12A3,3 0 0,0 6,15C6.79,15 7.5,14.69 8.04,14.19L15.16,18.34C15.11,18.55 15.08,18.77 15.08,19C15.08,20.61 16.39,21.91 18,21.91C19.61,21.91 20.92,20.61 20.92,19A2.92,2.92 0 0,0 18,16.08Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_show.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,9A3,3 0 0,0 9,12A3,3 0 0,0 12,15A3,3 0 0,0 15,12A3,3 0 0,0 12,9M12,17A5,5 0 0,1 7,12A5,5 0 0,1 12,7A5,5 0 0,1 17,12A5,5 0 0,1 12,17M12,4.5C7,4.5 2.73,7.61 1,12C2.73,16.39 7,19.5 12,19.5C17,19.5 21.27,16.39 23,12C21.27,7.61 17,4.5 12,4.5Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_skip.xml",
    "content": "<!-- drawable/debug_step_over.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorAccent\"\r\n        android:pathData=\"M12,14A2,2 0 0,1 14,16A2,2 0 0,1 12,18A2,2 0 0,1 10,16A2,2 0 0,1 12,14M23.46,8.86L21.87,15.75L15,14.16L18.8,11.78C17.39,9.5 14.87,8 12,8C8.05,8 4.77,10.86 4.12,14.63L2.15,14.28C2.96,9.58 7.06,6 12,6C15.58,6 18.73,7.89 20.5,10.72L23.46,8.86Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_star_heart.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"480\"\n        android:viewportHeight=\"480\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M104,403c3,-10 10,-40 16,-68l12,-50 -53,-47c-29,-26 -50,-50 -47,-53 3,-3 35,-8 71,-12l65,-6 30,-66 30,-66 1,160 1,160 -56,33c-63,36 -78,39 -70,15z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M250,251c0,-164 1,-170 22,-185 13,-9 43,-16 71,-16 40,0 53,5 78,29 24,24 29,38 29,76 0,72 -42,134 -151,226l-49,41 0,-171z\"\n        android:strokeColor=\"#00000000\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_stop.xml",
    "content": "<!-- drawable/stop.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#000\"\r\n        android:pathData=\"M18,18H6V6H18V18Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_suggestions.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M13,16V18H14A1,1 0 0,1 15,19H22V21H15A1,1 0 0,1 14,22H10A1,1 0 0,1 9,21H2V19H9A1,1 0 0,1 10,18H11V16H5V14.5C5,12.57 8.13,11 12,11C15.87,11 19,12.57 19,14.5V16H13M12,2A3.5,3.5 0 0,1 15.5,5.5A3.5,3.5 0 0,1 12,9A3.5,3.5 0 0,1 8.5,5.5A3.5,3.5 0 0,1 12,2Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_sync.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#fff\"\n        android:pathData=\"M12,4C15.64,4 18.67,6.59 19.35,10.04C21.95,10.22 24,12.36 24,15A5,5 0 0,1 19,20H6A6,6 0 0,1 0,14C0,10.91 2.34,8.36 5.35,8.04C6.6,5.64 9.11,4 12,4M7.5,9.69C6.06,11.5 6.2,14.06 7.82,15.68C8.66,16.5 9.81,17 11,17V18.86L13.83,16.04L11,13.21V15C10.34,15 9.7,14.74 9.23,14.27C8.39,13.43 8.26,12.11 8.92,11.12L7.5,9.69M9.17,8.97L10.62,10.42L12,11.79V10C12.66,10 13.3,10.26 13.77,10.73C14.61,11.57 14.74,12.89 14.08,13.88L15.5,15.31C16.94,13.5 16.8,10.94 15.18,9.32C14.34,8.5 13.19,8 12,8V6.14L9.17,8.97Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_sync_menu.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M12,4C15.64,4 18.67,6.59 19.35,10.04C21.95,10.22 24,12.36 24,15A5,5 0 0,1 19,20H6A6,6 0 0,1 0,14C0,10.91 2.34,8.36 5.35,8.04C6.6,5.64 9.11,4 12,4M7.5,9.69C6.06,11.5 6.2,14.06 7.82,15.68C8.66,16.5 9.81,17 11,17V18.86L13.83,16.04L11,13.21V15C10.34,15 9.7,14.74 9.23,14.27C8.39,13.43 8.26,12.11 8.92,11.12L7.5,9.69M9.17,8.97L10.62,10.42L12,11.79V10C12.66,10 13.3,10.26 13.77,10.73C14.61,11.57 14.74,12.89 14.08,13.88L15.5,15.31C16.94,13.5 16.8,10.94 15.18,9.32C14.34,8.5 13.19,8 12,8V6.14L9.17,8.97Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_sync_rotate.xml",
    "content": "<!-- drawable/sync.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M12,18A6,6 0 0,1 6,12C6,11 6.25,10.03 6.7,9.2L5.24,7.74C4.46,8.97 4,10.43 4,12A8,8 0 0,0 12,20V23L16,19L12,15M12,4V1L8,5L12,9V6A6,6 0 0,1 18,12C18,13 17.75,13.97 17.3,14.8L18.76,16.26C19.54,15.03 20,13.57 20,12A8,8 0 0,0 12,4Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_tag.xml",
    "content": "<!-- drawable/tag.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#fff\"\r\n        android:pathData=\"M5.5,7A1.5,1.5 0 0,1 4,5.5A1.5,1.5 0 0,1 5.5,4A1.5,1.5 0 0,1 7,5.5A1.5,1.5 0 0,1 5.5,7M21.41,11.58L12.41,2.58C12.05,2.22 11.55,2 11,2H4C2.89,2 2,2.89 2,4V11C2,11.55 2.22,12.05 2.59,12.41L11.58,21.41C11.95,21.77 12.45,22 13,22C13.55,22 14.05,21.77 14.41,21.41L21.41,14.41C21.78,14.05 22,13.55 22,13C22,12.44 21.77,11.94 21.41,11.58Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_terminal.xml",
    "content": "<!-- drawable/console_line.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#fff\"\r\n        android:pathData=\"M13,19V16H21V19H13M8.5,13L2.47,7H6.71L11.67,11.95C12.25,12.54 12.25,13.5 11.67,14.07L6.74,19H2.5L8.5,13Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_theme.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M7.5,2C5.71,3.15 4.5,5.18 4.5,7.5C4.5,9.82 5.71,11.85 7.53,13C4.46,13 2,10.54 2,7.5A5.5,5.5 0 0,1 7.5,2M19.07,3.5L20.5,4.93L4.93,20.5L3.5,19.07L19.07,3.5M12.89,5.93L11.41,5L9.97,6L10.39,4.3L9,3.24L10.75,3.12L11.33,1.47L12,3.1L13.73,3.13L12.38,4.26L12.89,5.93M9.59,9.54L8.43,8.81L7.31,9.59L7.65,8.27L6.56,7.44L7.92,7.35L8.37,6.06L8.88,7.33L10.24,7.36L9.19,8.23L9.59,9.54M19,13.5A5.5,5.5 0 0,1 13.5,19C12.28,19 11.15,18.6 10.24,17.93L17.93,10.24C18.6,11.15 19,12.28 19,13.5M14.6,20.08L17.37,18.93L17.13,22.28L14.6,20.08M18.93,17.38L20.08,14.61L22.28,17.15L18.93,17.38M20.08,12.42L18.94,9.64L22.28,9.88L20.08,12.42M9.63,18.93L12.4,20.08L9.87,22.27L9.63,18.93Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_timeout.xml",
    "content": "<!-- drawable/timer_sand.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M6,2H18V8H18V8L14,12L18,16V16H18V22H6V16H6V16L10,12L6,8V8H6V2M16,16.5L12,12.5L8,16.5V20H16V16.5M12,11.5L16,7.5V4H8V7.5L12,11.5M10,6H14V6.75L12,8.75L10,6.75V6Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_treasure.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"48\"\n        android:viewportHeight=\"48\">\n    <path\n        android:fillColor=\"#4E342E\"\n        android:pathData=\"M6,25l3,-7l-3,-5l36,0l-3,5l3,7z\"/>\n    <path\n        android:fillColor=\"#795548\"\n        android:pathData=\"M42,42H6V25h36V42zM42,13c0,0 -0.125,-7 -5,-7S15.813,6 11,6c-5,0 -5,7 -5,7H42z\"/>\n    <path\n        android:fillColor=\"#5D4037\"\n        android:pathData=\"M42,32H6v-2h36V32zM42,36H6v2h36V36z\"/>\n    <path\n        android:fillColor=\"#FFAB00\"\n        android:pathData=\"M28,25v4c0,2.2 -1.8,4 -4,4s-4,-1.8 -4,-4v-4H28zM6,42h6c0,-3.313 -2.686,-6 -6,-6V42zM42,36c-3.314,0 -6,2.687 -6,6h6V36zM24,9c-2.2,0 -4,1.8 -4,4h8C28,10.8 26.2,9 24,9z\"/>\n    <path\n        android:fillColor=\"#212121\"\n        android:pathData=\"M9,18l-3,-5l36,0l-3,5z\"/>\n    <path\n        android:fillColor=\"#FFC400\"\n        android:pathData=\"M38,25c0,-1.657 -1.343,-3 -3,-3c0,-1.657 -1.343,-3 -3,-3c-0.473,0 -0.914,0.119 -1.312,0.314C30.265,18.535 29.449,18 28.5,18c-0.488,0 -0.941,0.146 -1.326,0.388C26.844,18.146 26.44,18 26,18c-0.375,0 -0.721,0.109 -1.021,0.289C24.87,17.009 23.808,16 22.5,16c-1.231,0 -2.249,0.892 -2.456,2.063C19.868,18.024 19.687,18 19.5,18c-1.308,0 -2.37,1.009 -2.479,2.289C16.721,20.109 16.375,20 16,20c-1.105,0 -2,0.896 -2,2c0,0.018 0.005,0.034 0.005,0.051C13.842,22.018 13.673,22 13.5,22c-1.381,0 -2.5,1.119 -2.5,2.5c0,0.171 0.018,0.338 0.05,0.5H38z\"/>\n    <path\n        android:fillColor=\"#FFE57F\"\n        android:pathData=\"M37.942,24.424c-0.026,-0.134 -0.071,-0.26 -0.114,-0.386c-0.016,-0.045 -0.025,-0.093 -0.043,-0.138c-0.065,-0.165 -0.146,-0.319 -0.238,-0.468c-0.001,-0.001 -0.002,-0.003 -0.002,-0.004C37.016,22.574 36.078,22 35,22c-0.786,0 -1.496,0.309 -2.031,0.804C32.989,22.706 33,22.604 33,22.5c0,-0.829 -0.672,-1.5 -1.5,-1.5c-0.756,0 -1.375,0.562 -1.479,1.289C29.721,22.109 29.375,22 29,22c-0.16,0 -0.313,0.023 -0.463,0.059C28.085,21.42 27.343,21 26.5,21c-0.59,0 -1.126,0.213 -1.554,0.556C24.744,20.666 23.951,20 23,20c-0.873,0 -1.608,0.563 -1.88,1.343C20.8,21.126 20.415,21 20,21c-0.873,0 -1.608,0.563 -1.88,1.343C17.8,22.126 17.415,22 17,22c-0.676,0 -1.272,0.338 -1.634,0.852C14.908,22.333 14.246,22 13.5,22c-0.815,0 -1.532,0.396 -1.989,1h0c0,0 0,0 0,0c-0.068,0.09 -0.128,0.186 -0.183,0.285c-0.017,0.03 -0.034,0.061 -0.05,0.092c-0.043,0.085 -0.082,0.171 -0.116,0.262c-0.025,0.065 -0.043,0.133 -0.062,0.201c-0.019,0.068 -0.04,0.135 -0.053,0.206C11.018,24.193 11,24.344 11,24.5c0,0.171 0.018,0.338 0.05,0.5h7.672h5.789h6.211H32h6C38,24.802 37.979,24.61 37.942,24.424z\"/>\n    <path\n        android:fillColor=\"#FF1744\"\n        android:pathData=\"M22,21l-1,2l-2,-1l1,-2L22,21zM30,20l-2,1l1,2l2,-1L30,20z\"/>\n    <path\n        android:fillColor=\"#3E2723\"\n        android:pathData=\"M24,31L24,31c-0.55,0 -1,-0.45 -1,-1v-1c0,-0.55 0.45,-1 1,-1h0c0.55,0 1,0.45 1,1v1C25,30.55 24.55,31 24,31z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_trophy.xml",
    "content": "<!-- drawable/trophy_variant.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#fff\"\r\n        android:pathData=\"M20.2,4H20H17V2H7V4H4.5H3.8H2V11C2,12 3,13 4,13H7.2C7.6,14.9 8.6,16.6 11,16.9V19C8,19.2 8,20.3 8,21.6V22H16V21.7C16,20.4 16,19.3 13,19.1V17C15.5,16.7 16.5,15 16.8,13.1H20C21,13.1 22,12.1 22,11.1V4H20.2M4,11V6H7V8V11C5.6,11 4.4,11 4,11M20,11C19.6,11 18.4,11 17,11V6H18H20V11Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_trophy_bronze.xml",
    "content": "<!-- drawable/trophy_variant.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#CD7F32\"\r\n        android:pathData=\"M20.2,4H20H17V2H7V4H4.5H3.8H2V11C2,12 3,13 4,13H7.2C7.6,14.9 8.6,16.6 11,16.9V19C8,19.2 8,20.3 8,21.6V22H16V21.7C16,20.4 16,19.3 13,19.1V17C15.5,16.7 16.5,15 16.8,13.1H20C21,13.1 22,12.1 22,11.1V4H20.2M4,11V6H7V8V11C5.6,11 4.4,11 4,11M20,11C19.6,11 18.4,11 17,11V6H18H20V11Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_trophy_gold.xml",
    "content": "<!-- drawable/trophy_variant.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#FFD700\"\r\n        android:pathData=\"M20.2,4H20H17V2H7V4H4.5H3.8H2V11C2,12 3,13 4,13H7.2C7.6,14.9 8.6,16.6 11,16.9V19C8,19.2 8,20.3 8,21.6V22H16V21.7C16,20.4 16,19.3 13,19.1V17C15.5,16.7 16.5,15 16.8,13.1H20C21,13.1 22,12.1 22,11.1V4H20.2M4,11V6H7V8V11C5.6,11 4.4,11 4,11M20,11C19.6,11 18.4,11 17,11V6H18H20V11Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_trophy_normal.xml",
    "content": "<!-- drawable/trophy_variant.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M20.2,4H20H17V2H7V4H4.5H3.8H2V11C2,12 3,13 4,13H7.2C7.6,14.9 8.6,16.6 11,16.9V19C8,19.2 8,20.3 8,21.6V22H16V21.7C16,20.4 16,19.3 13,19.1V17C15.5,16.7 16.5,15 16.8,13.1H20C21,13.1 22,12.1 22,11.1V4H20.2M4,11V6H7V8V11C5.6,11 4.4,11 4,11M20,11C19.6,11 18.4,11 17,11V6H18H20V11Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_trophy_silver.xml",
    "content": "<!-- drawable/trophy_variant.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:width=\"24dp\"\r\n    android:height=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#C0C0C0\"\r\n        android:pathData=\"M20.2,4H20H17V2H7V4H4.5H3.8H2V11C2,12 3,13 4,13H7.2C7.6,14.9 8.6,16.6 11,16.9V19C8,19.2 8,20.3 8,21.6V22H16V21.7C16,20.4 16,19.3 13,19.1V17C15.5,16.7 16.5,15 16.8,13.1H20C21,13.1 22,12.1 22,11.1V4H20.2M4,11V6H7V8V11C5.6,11 4.4,11 4,11M20,11C19.6,11 18.4,11 17,11V6H18H20V11Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_umaru.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"2250.0\"\n        android:viewportHeight=\"2250.0\">\n    <path\n        android:fillColor=\"#d75781\"\n        android:pathData=\"M1340,1911c-40,-5 -45,-9 -48,-34 -2,-15 -12,-32 -23,-38 -11,-5 -17,-14 -14,-20 7,-11 152,-12 158,-1 8,13 -8,95 -18,97 -5,1 -30,-1 -55,-4z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#d75781\"\n        android:pathData=\"M714,1898c-5,-7 -9,-24 -9,-38 0,-24 2,-25 65,-22 36,2 68,6 72,10 4,4 2,18 -5,32 -10,21 -21,25 -63,28 -33,2 -54,-2 -60,-10z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M715,2081c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M1351,2077c-6,-8 -8,-17 -5,-20 10,-9 45,13 39,24 -9,13 -21,11 -34,-4z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M1305,1910c-3,-5 0,-13 9,-16 21,-8 71,-1 71,11 0,14 -72,19 -80,5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M1137,1881c-61,-8 -61,-23 1,-36 27,-5 57,-17 67,-25 23,-19 199,-28 220,-10 7,6 25,10 39,8 41,-5 33,15 -15,39 -48,23 -63,21 -56,-8 5,-17 -1,-19 -45,-19 -29,0 -47,4 -43,10 3,5 1,19 -5,30 -11,21 -55,24 -163,11z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M765,1850c-8,-13 20,-24 41,-16 20,8 9,26 -16,26 -10,0 -22,-5 -25,-10z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M705,1841c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M731,1226c-7,-8 -8,-17 -3,-20 6,-3 15,1 21,8 7,8 8,17 3,20 -6,3 -15,-1 -21,-8z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M691,1196c-7,-8 -8,-17 -3,-20 6,-3 15,1 21,8 7,8 8,17 3,20 -6,3 -15,-1 -21,-8z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M982,1176c-43,-11 -55,-33 -17,-29 89,8 108,15 78,31 -11,5 -34,5 -61,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M1125,1160c-3,-5 0,-13 8,-16 23,-8 82,0 82,11 0,14 -82,19 -90,5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M621,1136c-13,-13 -18,-26 -13,-30 5,-3 19,5 31,18 13,13 18,26 13,30 -5,3 -19,-5 -31,-18z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M1235,1150c-8,-12 20,-24 35,-15 6,3 8,11 5,16 -8,12 -32,12 -40,-1z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M862,569c-7,-17 0,-45 26,-108 19,-47 39,-92 44,-98 28,-35 39,41 12,82 -9,14 -24,50 -34,82 -19,63 -36,77 -48,42z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M1260,535c-18,-48 -22,-73 -11,-79 13,-8 54,71 47,90 -8,22 -26,16 -36,-11z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M785,440c-3,-4 4,-19 14,-31 15,-19 22,-21 32,-12 6,6 9,18 6,26 -6,16 -45,29 -52,17z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M1326,418c-11,-15 -13,-25 -6,-32 14,-14 45,6 45,29 0,27 -21,29 -39,3z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M1170,381c-32,-9 -32,-35 0,-39 30,-3 66,20 56,36 -8,13 -18,14 -56,3z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#deb9c5\"\n        android:pathData=\"M1026,312c-3,-6 1,-15 8,-21 8,-7 17,-8 20,-3 3,6 -1,15 -8,21 -8,7 -17,8 -20,3z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M730,2110c-7,-4 -28,-6 -45,-3 -18,3 -35,0 -39,-5 -4,-6 -13,-9 -20,-6 -8,3 -17,0 -21,-5 -3,-6 -10,-9 -15,-6 -24,15 -167,-75 -154,-97 4,-5 15,-1 28,10 25,23 143,82 150,75 2,-3 10,-2 17,3 7,4 35,8 63,9 28,1 53,3 56,4 3,1 73,3 155,4 92,1 150,6 150,12 0,12 -305,17 -325,5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1105,2100c-3,-5 0,-13 8,-15 24,-10 232,-1 230,10 -4,14 -229,19 -238,5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1435,2090c-3,-6 0,-12 7,-14 16,-5 107,-20 128,-21 8,0 21,-4 28,-8 6,-5 12,-5 12,-1 0,3 6,1 14,-5 10,-8 16,-9 21,-1 3,5 4,11 1,11 -16,4 -26,7 -31,9 -3,1 -8,3 -12,5 -5,1 -15,4 -23,8 -61,25 -135,33 -145,17z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1115,2040c-5,-9 -121,-80 -130,-80 -2,0 -5,14 -7,32 -7,68 -81,27 -108,-59 -7,-21 -19,-46 -27,-55 -13,-15 -12,-18 6,-28 24,-12 21,-16 41,61 6,25 22,59 35,75l24,29 2,-40c1,-22 1,-45 0,-52 -3,-20 18,-24 28,-5 5,10 36,33 68,50 65,34 100,66 84,76 -5,4 -12,2 -16,-4z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1156,2041c-7,-10 22,-99 35,-106 11,-8 41,53 33,67 -5,7 -11,6 -20,-6 -11,-15 -13,-14 -19,13 -7,33 -20,47 -29,32z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1314,2024c-19,-61 -20,-61 -38,-26 -9,18 -21,30 -27,27 -12,-8 42,-111 56,-107 17,5 40,101 27,114 -8,8 -13,6 -18,-8z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M686,2013c-3,-3 -6,-14 -6,-23 0,-17 -76,-97 -88,-92 -11,4 -23,-81 -13,-91 5,-5 20,15 34,46 14,30 40,67 61,83 22,18 36,38 36,51 0,23 -13,37 -24,26z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1488,2005c-4,-4 13,-31 39,-59 25,-28 55,-71 65,-95 13,-28 23,-40 30,-33 14,14 -22,80 -79,142 -26,28 -51,49 -55,45z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1455,1980c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M370,1930c-17,-22 -33,-46 -34,-53 -1,-6 -5,-17 -9,-24 -4,-6 -3,-14 3,-18 10,-6 11,-5 14,15 0,5 18,32 38,59 45,60 34,79 -12,21z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1397,1964c-3,-3 11,-28 31,-55 21,-28 40,-45 45,-40 11,11 5,57 -6,53 -5,-2 -21,8 -36,22 -15,15 -30,23 -34,20z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M806,1952c-9,-15 12,-54 25,-47 12,8 11,18 -4,40 -10,12 -16,14 -21,7z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M547,1902c-21,-23 -60,-112 -53,-119 3,-4 1,-12 -5,-19 -13,-16 -4,-48 11,-39 6,4 10,14 9,23 -1,10 3,30 9,45 7,16 12,31 12,35 0,4 11,24 25,44 26,38 20,61 -8,30z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1847,1884c-9,-10 22,-66 33,-59 6,4 4,18 -5,36 -17,31 -18,32 -28,23z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1634,1817c-36,-31 -18,-42 20,-12 16,13 24,25 18,29 -6,3 -23,-4 -38,-17z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M397,1763c-8,-15 -2,-63 8,-63 12,0 16,58 5,65 -5,3 -10,2 -13,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1896,1751c-4,-5 -2,-12 4,-16 6,-4 8,-10 5,-15 -3,-5 -1,-11 4,-14 5,-4 12,-2 15,3 4,5 2,12 -4,16 -6,4 -8,10 -5,15 3,5 1,11 -4,14 -5,4 -12,2 -15,-3z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M445,1740c-6,-10 13,-89 26,-104 10,-11 31,41 26,63 -2,9 -9,15 -15,14 -7,-2 -12,3 -12,11 0,19 -17,29 -25,16z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1666,1728c-2,-7 -7,-38 -10,-68 -3,-30 -19,-103 -36,-162 -38,-137 -37,-133 -20,-133 8,0 17,13 21,30 4,17 21,83 38,148 17,65 31,134 31,152 0,34 -17,57 -24,33z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M294,1666c-4,-10 -2,-22 4,-28 8,-8 13,-7 18,6 4,10 2,22 -4,28 -8,8 -13,7 -18,-6z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M408,1663c-7,-14 -3,-33 6,-33 12,-1 17,28 6,35 -5,3 -10,2 -12,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1927,1624c-4,-4 -4,-11 0,-17 3,-5 6,-34 7,-63 1,-30 6,-55 11,-56 12,-4 19,78 9,101 -4,9 -8,19 -8,23 -2,11 -12,18 -19,12z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M295,1597c-9,-22 -2,-62 10,-60 6,1 11,14 13,29 4,32 -14,56 -23,31z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M295,1510c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1934,1456c-8,-21 3,-49 16,-41 5,3 10,15 10,25 0,25 -18,36 -26,16z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M297,1403c-9,-15 -2,-88 8,-88 12,0 17,83 5,90 -5,3 -11,2 -13,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1925,1380c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M305,1190c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M662,1070c-46,-33 -58,-48 -46,-60 5,-5 30,11 57,35 55,51 48,68 -11,25z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M314,1046c-4,-10 -2,-22 4,-28 8,-8 13,-7 18,6 4,10 2,22 -4,28 -8,8 -13,7 -18,-6z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M325,950c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1804,796c-4,-10 -2,-22 4,-28 8,-8 13,-7 18,6 4,10 2,22 -4,28 -8,8 -13,7 -18,-6z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M375,680c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M450,390c-11,-21 -5,-44 9,-35 13,7 20,44 11,50 -5,3 -14,-4 -20,-15z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M585,300c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1061,252c-7,-14 -6,-24 4,-38 16,-21 16,-21 19,19 2,35 -9,44 -23,19z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1021,242c-8,-15 -7,-23 3,-31 16,-13 26,-3 22,22 -4,27 -14,30 -25,9z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M905,161c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M995,150c-3,-5 0,-13 8,-16 23,-8 102,0 102,11 0,14 -102,19 -110,5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#c56941\"\n        android:pathData=\"M1125,150c-8,-12 20,-24 35,-15 6,3 8,11 5,16 -8,12 -32,12 -40,-1z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M737,2073c-7,-13 52,-135 63,-128 5,3 -1,29 -16,63 -27,62 -39,78 -47,65z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M705,2047c-9,-22 -2,-62 10,-60 6,1 11,14 13,29 4,32 -14,56 -23,31z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1335,2050c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1120,2025c-8,-9 -32,-26 -54,-37 -23,-11 -56,-31 -73,-45l-33,-24 0,50c0,27 -4,52 -9,55 -13,9 -58,-63 -75,-122 -19,-65 -14,-68 82,-58 37,4 94,9 127,12 225,18 220,17 219,41 0,12 4,21 10,20 6,-1 11,5 12,13 1,8 6,26 11,40 6,14 8,29 6,33 -8,13 -26,-10 -28,-35 -3,-36 -19,-31 -48,18 -30,49 -42,50 -52,4 -10,-45 -22,-45 -37,2 -16,46 -37,58 -58,33z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1376,1993c-10,-10 -7,-45 8,-88 12,-35 22,-44 85,-76 40,-20 80,-39 90,-42 17,-4 16,-14 -19,-153 -62,-243 -69,-278 -60,-288 5,-5 30,-5 61,0 59,10 46,-15 104,207 31,117 44,250 26,262 -7,4 -20,0 -29,-9 -16,-14 -19,-12 -34,32 -10,26 -38,71 -64,100 -55,62 -74,58 -74,-17l0,-46 -35,40c-19,22 -34,48 -35,57 0,19 -14,31 -24,21z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M664,1938c-20,-18 -46,-46 -56,-63l-19,-30 2,30c2,47 0,49 -22,29 -34,-30 -56,-84 -73,-174 -9,-46 -18,-85 -20,-87 -1,-2 -9,23 -16,54 -17,75 -20,80 -37,58 -35,-49 -10,-174 84,-415 41,-106 44,-118 33,-153 -9,-31 -14,-36 -25,-27 -11,9 -16,7 -24,-9 -27,-49 -28,-161 -5,-356 19,-161 28,-180 136,-281 66,-61 194,-135 258,-149 73,-16 87,-18 178,-22 71,-3 93,-1 97,9 3,8 7,73 8,146 2,137 -6,163 -33,105 -8,-18 -17,-33 -20,-33 -3,0 -13,27 -23,59 -21,67 -44,104 -58,95 -32,-20 -88,-202 -89,-289l0,-50 -35,85c-19,46 -42,91 -50,99 -12,13 -16,11 -25,-15 -7,-16 -12,-54 -13,-86l-2,-56 -50,85c-27,46 -62,105 -78,131 -48,81 -65,125 -75,187 -10,62 -1,147 18,170 6,7 6,15 -1,22 -6,6 -12,33 -14,60 -2,27 -7,62 -11,77 -6,25 0,34 57,87 35,33 62,65 61,72 -23,79 -75,307 -90,390l-19,106 49,13c34,8 53,19 58,33 11,30 7,118 -7,122 -6,2 -28,-11 -49,-29z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M805,1920c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1728,1396c-53,-12 -61,-32 -13,-29 43,3 87,21 80,33 -7,11 -4,11 -67,-4z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1615,1370c-8,-12 20,-24 35,-15 6,3 8,11 5,16 -8,12 -32,12 -40,-1z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1762,1353c-4,-10 -8,-25 -8,-33 1,-22 21,-23 22,-1 1,10 4,23 8,29 3,6 2,13 -3,17 -6,3 -14,-2 -19,-12z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1701,1336c-7,-8 -8,-17 -3,-20 6,-3 15,1 21,8 7,8 8,17 3,20 -6,3 -15,-1 -21,-8z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1627,1304c-38,-20 -24,-38 14,-19 16,9 27,20 24,25 -7,12 -4,13 -38,-6z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1127,1303c-4,-4 -15,-8 -25,-9 -62,-10 -88,-11 -99,-2 -7,5 -17,7 -23,3 -14,-9 -1,-28 15,-21 8,3 19,-2 26,-10 12,-14 26,-13 79,9 14,6 30,11 35,11 13,1 19,20 8,23 -5,2 -12,0 -16,-4z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1255,1301c-6,-11 13,-26 22,-17 3,3 18,-3 32,-13 42,-29 49,-32 55,-22 6,9 -37,42 -60,45 -7,1 -17,5 -20,9 -10,10 -22,9 -29,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M886,1291c-4,-6 -13,-8 -20,-5 -17,6 -31,-12 -16,-21 5,-3 16,-3 23,2 6,4 17,8 22,8 14,0 19,19 7,23 -6,2 -13,-1 -16,-7z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1525,1270c-8,-13 20,-24 41,-16 20,8 9,26 -16,26 -10,0 -22,-5 -25,-10z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1385,1261c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1468,1235c-3,-3 6,-48 19,-101 18,-71 21,-99 13,-109 -8,-10 -8,-15 1,-21 8,-5 10,-45 7,-144 -4,-117 -8,-140 -24,-156 -10,-11 -28,-37 -38,-59 -25,-53 -28,-58 -49,-88 -21,-30 -59,-165 -48,-171 16,-10 119,61 182,123 78,78 117,136 125,188 4,21 7,112 7,203 1,150 -1,171 -24,235 -15,45 -29,70 -39,70 -11,0 -14,-9 -12,-35l3,-35 -29,35c-30,36 -85,73 -94,65z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1045,1171c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M906,1151c-4,-6 -13,-8 -20,-5 -8,3 -17,0 -21,-5 -3,-6 -11,-9 -16,-6 -5,4 -14,3 -21,-1 -7,-4 -22,-9 -34,-10 -32,-3 -106,-43 -99,-54 3,-5 24,-1 48,9 69,30 82,34 91,32 4,-1 14,3 20,9 7,5 16,7 19,4 3,-3 12,-2 19,2 7,5 18,9 23,9 14,0 19,19 7,23 -6,2 -13,-1 -16,-7z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1306,1121c-4,-5 -2,-12 4,-16 5,-3 10,-4 10,-1 0,3 12,-1 27,-9 15,-8 31,-11 36,-8 12,7 -8,26 -30,28 -10,0 -24,4 -30,8 -6,4 -14,3 -17,-2z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M656,1051c-10,-11 -13,-22 -8,-25 5,-3 17,3 26,13 10,11 13,22 8,25 -5,3 -17,-3 -26,-13z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M339,1044c-7,-9 -13,-26 -13,-37 0,-27 49,-83 59,-67 4,6 13,9 21,6 16,-6 28,9 19,24 -5,8 -11,8 -20,0 -11,-9 -18,-5 -31,15 -19,29 -16,35 18,39 31,3 50,15 42,27 -4,6 -11,6 -19,-1 -10,-8 -19,-8 -34,-1 -25,14 -26,14 -42,-5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1297,553c-26,-30 -89,-173 -83,-190 5,-12 15,-14 42,-8 79,14 79,15 82,101 3,94 -12,129 -41,97z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M436,492c-8,-14 36,-74 47,-63 6,6 2,20 -12,40 -24,33 -27,35 -35,23z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M466,332c-3,-5 5,-19 18,-31 13,-13 26,-18 30,-13 3,5 -5,19 -18,31 -13,13 -26,18 -30,13z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1610,295c-7,-9 -18,-14 -24,-13 -6,2 -11,-1 -11,-7 0,-5 8,-10 17,-10 21,-2 54,30 40,39 -5,3 -15,-1 -22,-9z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1061,276c-7,-8 -8,-17 -3,-20 6,-3 15,1 21,8 7,8 8,17 3,20 -6,3 -15,-1 -21,-8z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#fccdaa\"\n        android:pathData=\"M1626,241c-10,-11 -13,-22 -8,-25 5,-3 17,3 26,13 10,11 13,22 8,25 -5,3 -17,-3 -26,-13z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#f7ebe2\"\n        android:pathData=\"M715,2070c-9,-14 -10,-154 -1,-169 11,-17 95,-14 102,4 7,17 -65,167 -83,172 -6,2 -14,-1 -18,-7z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#f7ebe2\"\n        android:pathData=\"M1353,2068c-14,-17 -53,-155 -45,-162 8,-9 80,-7 84,2 2,4 2,43 -1,86 -6,78 -17,100 -38,74z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#f7ebe2\"\n        android:pathData=\"M1281,1877c-18,-22 -66,-26 -159,-12 -52,8 -97,9 -120,4 -20,-5 -65,-9 -99,-9 -112,0 -268,-27 -299,-51 -8,-7 -6,-38 8,-116 18,-103 83,-377 92,-392 3,-4 -21,-31 -54,-59 -65,-58 -75,-77 -60,-116l10,-27 73,59c39,32 98,71 129,86 65,32 159,44 209,27 27,-8 45,-7 83,4 77,23 174,20 227,-9 42,-22 50,-23 151,-15 90,7 117,14 177,42 59,29 74,32 88,22 25,-18 61,7 58,40 -4,34 -15,47 -32,41 -17,-7 -122,-22 -209,-31l-61,-6 15,63c24,106 83,340 89,354 6,16 -35,36 -114,56 -26,7 -52,18 -56,26 -11,17 -27,6 -27,-19 0,-17 -7,-19 -77,-18 -43,1 -68,4 -55,6 26,5 49,40 35,54 -6,6 -14,4 -22,-4z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#f7ebe2\"\n        android:pathData=\"M895,1146c-147,-38 -197,-60 -241,-108 -48,-53 -54,-62 -63,-114 -17,-88 7,-179 76,-296 16,-25 45,-75 65,-111 43,-72 74,-105 87,-91 5,5 13,34 18,64 6,44 12,55 27,55 13,0 24,-16 41,-60 30,-82 46,-78 61,15 7,41 25,106 41,144l27,69 15,-34c8,-19 22,-61 31,-94 10,-34 23,-60 30,-60 7,0 19,18 26,40 12,37 13,31 11,-80l-2,-120 33,2c43,1 60,17 73,67 26,96 29,102 50,103 19,2 20,-3 18,-57 -1,-33 0,-63 4,-66 3,-4 17,0 30,9 16,10 27,32 36,71 8,36 19,60 31,66 11,6 24,27 30,48 13,46 33,74 51,70 17,-4 26,71 28,218 1,97 0,101 -26,126 -47,43 -90,68 -149,88 -31,11 -63,25 -70,31 -7,5 -57,14 -111,20 -54,5 -109,11 -123,13 -14,2 -84,-10 -155,-28z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#f7ebe2\"\n        android:pathData=\"M467,1094c-40,-38 -64,-55 -80,-53 -30,4 -70,-19 -60,-34 4,-7 8,-19 8,-27 0,-8 6,-14 14,-12 12,3 12,0 2,-12 -15,-18 4,-33 23,-17 9,7 16,7 24,-1 8,-8 14,-5 21,14 5,14 23,35 40,47 21,15 31,31 33,54 2,24 8,32 22,32 19,0 41,47 28,59 -10,11 -17,6 -75,-50z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#f7ebe2\"\n        android:pathData=\"M501,386c-16,-19 28,-72 52,-63 22,8 21,19 -4,51 -23,30 -32,32 -48,12z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#f7ebe2\"\n        android:pathData=\"M1579,311c-23,-19 -23,-21 -6,-38 16,-17 18,-16 43,9 42,42 9,67 -37,29z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#f7ebe2\"\n        android:pathData=\"M1014,298c-8,-13 13,-35 34,-33 25,2 44,15 39,28 -4,14 -65,18 -73,5z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#ec8557\"\n        android:pathData=\"M734,2097c-2,-7 16,-58 41,-112 24,-55 45,-105 45,-111 0,-6 6,-17 14,-23 25,-21 51,3 65,57 7,28 19,58 26,69 13,16 14,13 15,-34 0,-60 12,-74 35,-40 9,14 42,39 74,56 32,17 64,38 71,46 19,23 27,18 40,-22 7,-21 15,-41 19,-45 10,-11 51,20 51,38 0,28 18,13 40,-31 12,-25 26,-47 30,-50 15,-9 22,15 9,31 -10,12 -10,15 2,12 8,-2 14,4 14,12 1,8 6,25 13,36 6,12 13,41 14,65l3,44 -140,6c-263,12 -475,10 -481,-4z\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:fillColor=\"#ec8557\"\n        android:pathData=\"M595,2086c-96,-30 -177,-92 -237,-181 -30,-44 -56,-132 -59,-201 -2,-25 -6,-47 -11,-50 -10,-6 -11,-318 -1,-328 7,-7 21,-143 37,-354 12,-157 79,-445 113,-484 8,-9 15,-22 17,-30 1,-7 5,-19 9,-25 4,-7 3,-21 -3,-32 -18,-34 -11,-61 25,-97 41,-40 101,-57 111,-31 4,12 18,6 70,-30 93,-65 182,-92 333,-102 68,-4 153,-6 189,-4 80,4 210,36 272,68 47,24 48,24 65,5 30,-33 66,-25 115,25 42,43 44,47 33,76 -11,28 -9,36 16,73 72,105 120,263 141,466 8,73 28,174 56,275 77,279 84,409 34,600 -39,145 -103,235 -211,297 -53,31 -192,66 -275,70l-59,3 1,-73c2,-62 5,-76 25,-95 13,-12 34,-35 45,-51 29,-40 44,-26 44,42l1,57 36,-40c39,-44 72,-108 73,-142 0,-33 20,-39 40,-13l18,23 4,-44c3,-24 1,-48 -3,-53 -5,-6 -9,-21 -9,-35 0,-15 -14,-78 -31,-141 -34,-126 -41,-167 -29,-175 4,-3 43,2 86,10 81,15 102,11 90,-20 -4,-11 -12,-14 -26,-10 -12,4 -50,-7 -97,-28 -67,-29 -93,-35 -183,-40 -94,-5 -108,-3 -138,15 -50,31 -142,34 -221,9 -41,-12 -69,-17 -76,-11 -23,19 -91,22 -155,5 -74,-18 -150,-65 -228,-139l-53,-50 6,-51c4,-27 9,-54 12,-58 8,-13 52,34 46,49 -3,8 0,15 6,15 20,3 26,5 66,26 39,20 265,85 295,84 82,-1 246,-24 259,-35 9,-8 30,-18 46,-22 39,-9 111,-46 154,-78 49,-37 58,-22 38,66 -9,40 -20,84 -23,97 -7,23 -7,23 20,6 15,-10 38,-37 52,-61 28,-47 43,-49 45,-6 1,23 4,20 17,-18 11,-34 15,-86 15,-210 0,-91 -3,-182 -7,-203 -8,-51 -48,-111 -121,-183 -109,-107 -239,-153 -428,-154 -54,0 -130,7 -170,16 -138,31 -294,132 -366,238 -25,35 -31,59 -45,177 -9,75 -16,155 -16,178 0,27 -5,44 -14,47 -18,7 -66,-24 -66,-43 0,-8 -4,-12 -9,-8 -5,3 -13,0 -16,-5 -5,-7 -12,-5 -20,7 -7,10 -11,21 -9,25 2,4 0,10 -6,13 -8,5 -7,11 1,21 8,10 16,11 31,3 15,-8 26,-5 54,16 20,15 44,41 55,59 10,17 19,27 19,22 0,-19 40,28 50,60 11,31 7,48 -43,182 -58,154 -91,258 -90,280 4,66 5,67 21,15 19,-59 39,-86 46,-62 2,8 11,58 20,112 9,54 25,115 36,135 21,40 22,38 24,-38 2,-45 19,-36 37,20 13,40 30,66 62,95 40,36 45,46 49,92 8,80 -29,100 -127,69zM540,365c7,-9 10,-18 7,-22 -8,-7 -37,15 -37,28 0,14 16,11 30,-6zM1620,300c0,-12 -28,-25 -36,-17 -9,9 6,27 22,27 8,0 14,-5 14,-10zM1070,278c0,-13 -32,-6 -37,9 -3,7 3,9 16,6 12,-3 21,-10 21,-15z\"\n        android:strokeColor=\"#00000000\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_umaru_simple.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"2250.0\"\n        android:viewportHeight=\"2250.0\">\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1340,1911c-40,-5 -45,-9 -48,-34 -2,-15 -12,-32 -23,-38 -11,-5 -17,-14 -14,-20 7,-11 152,-12 158,-1 8,13 -8,95 -18,97 -5,1 -30,-1 -55,-4z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M714,1898c-5,-7 -9,-24 -9,-38 0,-24 2,-25 65,-22 36,2 68,6 72,10 4,4 2,18 -5,32 -10,21 -21,25 -63,28 -33,2 -54,-2 -60,-10z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M715,2081c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1351,2077c-6,-8 -8,-17 -5,-20 10,-9 45,13 39,24 -9,13 -21,11 -34,-4z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1305,1910c-3,-5 0,-13 9,-16 21,-8 71,-1 71,11 0,14 -72,19 -80,5z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1137,1881c-61,-8 -61,-23 1,-36 27,-5 57,-17 67,-25 23,-19 199,-28 220,-10 7,6 25,10 39,8 41,-5 33,15 -15,39 -48,23 -63,21 -56,-8 5,-17 -1,-19 -45,-19 -29,0 -47,4 -43,10 3,5 1,19 -5,30 -11,21 -55,24 -163,11z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M765,1850c-8,-13 20,-24 41,-16 20,8 9,26 -16,26 -10,0 -22,-5 -25,-10z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M705,1841c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M731,1226c-7,-8 -8,-17 -3,-20 6,-3 15,1 21,8 7,8 8,17 3,20 -6,3 -15,-1 -21,-8z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M691,1196c-7,-8 -8,-17 -3,-20 6,-3 15,1 21,8 7,8 8,17 3,20 -6,3 -15,-1 -21,-8z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M982,1176c-43,-11 -55,-33 -17,-29 89,8 108,15 78,31 -11,5 -34,5 -61,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1125,1160c-3,-5 0,-13 8,-16 23,-8 82,0 82,11 0,14 -82,19 -90,5z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M621,1136c-13,-13 -18,-26 -13,-30 5,-3 19,5 31,18 13,13 18,26 13,30 -5,3 -19,-5 -31,-18z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1235,1150c-8,-12 20,-24 35,-15 6,3 8,11 5,16 -8,12 -32,12 -40,-1z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M862,569c-7,-17 0,-45 26,-108 19,-47 39,-92 44,-98 28,-35 39,41 12,82 -9,14 -24,50 -34,82 -19,63 -36,77 -48,42z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1260,535c-18,-48 -22,-73 -11,-79 13,-8 54,71 47,90 -8,22 -26,16 -36,-11z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M785,440c-3,-4 4,-19 14,-31 15,-19 22,-21 32,-12 6,6 9,18 6,26 -6,16 -45,29 -52,17z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1326,418c-11,-15 -13,-25 -6,-32 14,-14 45,6 45,29 0,27 -21,29 -39,3z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1170,381c-32,-9 -32,-35 0,-39 30,-3 66,20 56,36 -8,13 -18,14 -56,3z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1026,312c-3,-6 1,-15 8,-21 8,-7 17,-8 20,-3 3,6 -1,15 -8,21 -8,7 -17,8 -20,3z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M730,2110c-7,-4 -28,-6 -45,-3 -18,3 -35,0 -39,-5 -4,-6 -13,-9 -20,-6 -8,3 -17,0 -21,-5 -3,-6 -10,-9 -15,-6 -24,15 -167,-75 -154,-97 4,-5 15,-1 28,10 25,23 143,82 150,75 2,-3 10,-2 17,3 7,4 35,8 63,9 28,1 53,3 56,4 3,1 73,3 155,4 92,1 150,6 150,12 0,12 -305,17 -325,5z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1105,2100c-3,-5 0,-13 8,-15 24,-10 232,-1 230,10 -4,14 -229,19 -238,5z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1435,2090c-3,-6 0,-12 7,-14 16,-5 107,-20 128,-21 8,0 21,-4 28,-8 6,-5 12,-5 12,-1 0,3 6,1 14,-5 10,-8 16,-9 21,-1 3,5 4,11 1,11 -16,4 -26,7 -31,9 -3,1 -8,3 -12,5 -5,1 -15,4 -23,8 -61,25 -135,33 -145,17z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1115,2040c-5,-9 -121,-80 -130,-80 -2,0 -5,14 -7,32 -7,68 -81,27 -108,-59 -7,-21 -19,-46 -27,-55 -13,-15 -12,-18 6,-28 24,-12 21,-16 41,61 6,25 22,59 35,75l24,29 2,-40c1,-22 1,-45 0,-52 -3,-20 18,-24 28,-5 5,10 36,33 68,50 65,34 100,66 84,76 -5,4 -12,2 -16,-4z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1156,2041c-7,-10 22,-99 35,-106 11,-8 41,53 33,67 -5,7 -11,6 -20,-6 -11,-15 -13,-14 -19,13 -7,33 -20,47 -29,32z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1314,2024c-19,-61 -20,-61 -38,-26 -9,18 -21,30 -27,27 -12,-8 42,-111 56,-107 17,5 40,101 27,114 -8,8 -13,6 -18,-8z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M686,2013c-3,-3 -6,-14 -6,-23 0,-17 -76,-97 -88,-92 -11,4 -23,-81 -13,-91 5,-5 20,15 34,46 14,30 40,67 61,83 22,18 36,38 36,51 0,23 -13,37 -24,26z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1488,2005c-4,-4 13,-31 39,-59 25,-28 55,-71 65,-95 13,-28 23,-40 30,-33 14,14 -22,80 -79,142 -26,28 -51,49 -55,45z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1455,1980c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M370,1930c-17,-22 -33,-46 -34,-53 -1,-6 -5,-17 -9,-24 -4,-6 -3,-14 3,-18 10,-6 11,-5 14,15 0,5 18,32 38,59 45,60 34,79 -12,21z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1397,1964c-3,-3 11,-28 31,-55 21,-28 40,-45 45,-40 11,11 5,57 -6,53 -5,-2 -21,8 -36,22 -15,15 -30,23 -34,20z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M806,1952c-9,-15 12,-54 25,-47 12,8 11,18 -4,40 -10,12 -16,14 -21,7z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M547,1902c-21,-23 -60,-112 -53,-119 3,-4 1,-12 -5,-19 -13,-16 -4,-48 11,-39 6,4 10,14 9,23 -1,10 3,30 9,45 7,16 12,31 12,35 0,4 11,24 25,44 26,38 20,61 -8,30z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1847,1884c-9,-10 22,-66 33,-59 6,4 4,18 -5,36 -17,31 -18,32 -28,23z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1634,1817c-36,-31 -18,-42 20,-12 16,13 24,25 18,29 -6,3 -23,-4 -38,-17z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M397,1763c-8,-15 -2,-63 8,-63 12,0 16,58 5,65 -5,3 -10,2 -13,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1896,1751c-4,-5 -2,-12 4,-16 6,-4 8,-10 5,-15 -3,-5 -1,-11 4,-14 5,-4 12,-2 15,3 4,5 2,12 -4,16 -6,4 -8,10 -5,15 3,5 1,11 -4,14 -5,4 -12,2 -15,-3z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M445,1740c-6,-10 13,-89 26,-104 10,-11 31,41 26,63 -2,9 -9,15 -15,14 -7,-2 -12,3 -12,11 0,19 -17,29 -25,16z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1666,1728c-2,-7 -7,-38 -10,-68 -3,-30 -19,-103 -36,-162 -38,-137 -37,-133 -20,-133 8,0 17,13 21,30 4,17 21,83 38,148 17,65 31,134 31,152 0,34 -17,57 -24,33z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M294,1666c-4,-10 -2,-22 4,-28 8,-8 13,-7 18,6 4,10 2,22 -4,28 -8,8 -13,7 -18,-6z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M408,1663c-7,-14 -3,-33 6,-33 12,-1 17,28 6,35 -5,3 -10,2 -12,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1927,1624c-4,-4 -4,-11 0,-17 3,-5 6,-34 7,-63 1,-30 6,-55 11,-56 12,-4 19,78 9,101 -4,9 -8,19 -8,23 -2,11 -12,18 -19,12z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M295,1597c-9,-22 -2,-62 10,-60 6,1 11,14 13,29 4,32 -14,56 -23,31z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M295,1510c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1934,1456c-8,-21 3,-49 16,-41 5,3 10,15 10,25 0,25 -18,36 -26,16z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M297,1403c-9,-15 -2,-88 8,-88 12,0 17,83 5,90 -5,3 -11,2 -13,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1925,1380c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M305,1190c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M662,1070c-46,-33 -58,-48 -46,-60 5,-5 30,11 57,35 55,51 48,68 -11,25z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M314,1046c-4,-10 -2,-22 4,-28 8,-8 13,-7 18,6 4,10 2,22 -4,28 -8,8 -13,7 -18,-6z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M325,950c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1804,796c-4,-10 -2,-22 4,-28 8,-8 13,-7 18,6 4,10 2,22 -4,28 -8,8 -13,7 -18,-6z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M375,680c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M450,390c-11,-21 -5,-44 9,-35 13,7 20,44 11,50 -5,3 -14,-4 -20,-15z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M585,300c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1061,252c-7,-14 -6,-24 4,-38 16,-21 16,-21 19,19 2,35 -9,44 -23,19z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1021,242c-8,-15 -7,-23 3,-31 16,-13 26,-3 22,22 -4,27 -14,30 -25,9z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M905,161c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M995,150c-3,-5 0,-13 8,-16 23,-8 102,0 102,11 0,14 -102,19 -110,5z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1125,150c-8,-12 20,-24 35,-15 6,3 8,11 5,16 -8,12 -32,12 -40,-1z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M737,2073c-7,-13 52,-135 63,-128 5,3 -1,29 -16,63 -27,62 -39,78 -47,65z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M705,2047c-9,-22 -2,-62 10,-60 6,1 11,14 13,29 4,32 -14,56 -23,31z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1335,2050c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1120,2025c-8,-9 -32,-26 -54,-37 -23,-11 -56,-31 -73,-45l-33,-24 0,50c0,27 -4,52 -9,55 -13,9 -58,-63 -75,-122 -19,-65 -14,-68 82,-58 37,4 94,9 127,12 225,18 220,17 219,41 0,12 4,21 10,20 6,-1 11,5 12,13 1,8 6,26 11,40 6,14 8,29 6,33 -8,13 -26,-10 -28,-35 -3,-36 -19,-31 -48,18 -30,49 -42,50 -52,4 -10,-45 -22,-45 -37,2 -16,46 -37,58 -58,33z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1376,1993c-10,-10 -7,-45 8,-88 12,-35 22,-44 85,-76 40,-20 80,-39 90,-42 17,-4 16,-14 -19,-153 -62,-243 -69,-278 -60,-288 5,-5 30,-5 61,0 59,10 46,-15 104,207 31,117 44,250 26,262 -7,4 -20,0 -29,-9 -16,-14 -19,-12 -34,32 -10,26 -38,71 -64,100 -55,62 -74,58 -74,-17l0,-46 -35,40c-19,22 -34,48 -35,57 0,19 -14,31 -24,21z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M664,1938c-20,-18 -46,-46 -56,-63l-19,-30 2,30c2,47 0,49 -22,29 -34,-30 -56,-84 -73,-174 -9,-46 -18,-85 -20,-87 -1,-2 -9,23 -16,54 -17,75 -20,80 -37,58 -35,-49 -10,-174 84,-415 41,-106 44,-118 33,-153 -9,-31 -14,-36 -25,-27 -11,9 -16,7 -24,-9 -27,-49 -28,-161 -5,-356 19,-161 28,-180 136,-281 66,-61 194,-135 258,-149 73,-16 87,-18 178,-22 71,-3 93,-1 97,9 3,8 7,73 8,146 2,137 -6,163 -33,105 -8,-18 -17,-33 -20,-33 -3,0 -13,27 -23,59 -21,67 -44,104 -58,95 -32,-20 -88,-202 -89,-289l0,-50 -35,85c-19,46 -42,91 -50,99 -12,13 -16,11 -25,-15 -7,-16 -12,-54 -13,-86l-2,-56 -50,85c-27,46 -62,105 -78,131 -48,81 -65,125 -75,187 -10,62 -1,147 18,170 6,7 6,15 -1,22 -6,6 -12,33 -14,60 -2,27 -7,62 -11,77 -6,25 0,34 57,87 35,33 62,65 61,72 -23,79 -75,307 -90,390l-19,106 49,13c34,8 53,19 58,33 11,30 7,118 -7,122 -6,2 -28,-11 -49,-29z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M805,1920c-4,-6 -3,-16 3,-22 6,-6 12,-6 17,2 4,6 3,16 -3,22 -6,6 -12,6 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1728,1396c-53,-12 -61,-32 -13,-29 43,3 87,21 80,33 -7,11 -4,11 -67,-4z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1615,1370c-8,-12 20,-24 35,-15 6,3 8,11 5,16 -8,12 -32,12 -40,-1z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1762,1353c-4,-10 -8,-25 -8,-33 1,-22 21,-23 22,-1 1,10 4,23 8,29 3,6 2,13 -3,17 -6,3 -14,-2 -19,-12z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1701,1336c-7,-8 -8,-17 -3,-20 6,-3 15,1 21,8 7,8 8,17 3,20 -6,3 -15,-1 -21,-8z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1627,1304c-38,-20 -24,-38 14,-19 16,9 27,20 24,25 -7,12 -4,13 -38,-6z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1127,1303c-4,-4 -15,-8 -25,-9 -62,-10 -88,-11 -99,-2 -7,5 -17,7 -23,3 -14,-9 -1,-28 15,-21 8,3 19,-2 26,-10 12,-14 26,-13 79,9 14,6 30,11 35,11 13,1 19,20 8,23 -5,2 -12,0 -16,-4z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1255,1301c-6,-11 13,-26 22,-17 3,3 18,-3 32,-13 42,-29 49,-32 55,-22 6,9 -37,42 -60,45 -7,1 -17,5 -20,9 -10,10 -22,9 -29,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M886,1291c-4,-6 -13,-8 -20,-5 -17,6 -31,-12 -16,-21 5,-3 16,-3 23,2 6,4 17,8 22,8 14,0 19,19 7,23 -6,2 -13,-1 -16,-7z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1525,1270c-8,-13 20,-24 41,-16 20,8 9,26 -16,26 -10,0 -22,-5 -25,-10z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1385,1261c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1468,1235c-3,-3 6,-48 19,-101 18,-71 21,-99 13,-109 -8,-10 -8,-15 1,-21 8,-5 10,-45 7,-144 -4,-117 -8,-140 -24,-156 -10,-11 -28,-37 -38,-59 -25,-53 -28,-58 -49,-88 -21,-30 -59,-165 -48,-171 16,-10 119,61 182,123 78,78 117,136 125,188 4,21 7,112 7,203 1,150 -1,171 -24,235 -15,45 -29,70 -39,70 -11,0 -14,-9 -12,-35l3,-35 -29,35c-30,36 -85,73 -94,65z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1045,1171c-7,-12 12,-24 25,-16 11,7 4,25 -10,25 -5,0 -11,-4 -15,-9z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M906,1151c-4,-6 -13,-8 -20,-5 -8,3 -17,0 -21,-5 -3,-6 -11,-9 -16,-6 -5,4 -14,3 -21,-1 -7,-4 -22,-9 -34,-10 -32,-3 -106,-43 -99,-54 3,-5 24,-1 48,9 69,30 82,34 91,32 4,-1 14,3 20,9 7,5 16,7 19,4 3,-3 12,-2 19,2 7,5 18,9 23,9 14,0 19,19 7,23 -6,2 -13,-1 -16,-7z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1306,1121c-4,-5 -2,-12 4,-16 5,-3 10,-4 10,-1 0,3 12,-1 27,-9 15,-8 31,-11 36,-8 12,7 -8,26 -30,28 -10,0 -24,4 -30,8 -6,4 -14,3 -17,-2z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M656,1051c-10,-11 -13,-22 -8,-25 5,-3 17,3 26,13 10,11 13,22 8,25 -5,3 -17,-3 -26,-13z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M339,1044c-7,-9 -13,-26 -13,-37 0,-27 49,-83 59,-67 4,6 13,9 21,6 16,-6 28,9 19,24 -5,8 -11,8 -20,0 -11,-9 -18,-5 -31,15 -19,29 -16,35 18,39 31,3 50,15 42,27 -4,6 -11,6 -19,-1 -10,-8 -19,-8 -34,-1 -25,14 -26,14 -42,-5z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1297,553c-26,-30 -89,-173 -83,-190 5,-12 15,-14 42,-8 79,14 79,15 82,101 3,94 -12,129 -41,97z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M436,492c-8,-14 36,-74 47,-63 6,6 2,20 -12,40 -24,33 -27,35 -35,23z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M466,332c-3,-5 5,-19 18,-31 13,-13 26,-18 30,-13 3,5 -5,19 -18,31 -13,13 -26,18 -30,13z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1610,295c-7,-9 -18,-14 -24,-13 -6,2 -11,-1 -11,-7 0,-5 8,-10 17,-10 21,-2 54,30 40,39 -5,3 -15,-1 -22,-9z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1061,276c-7,-8 -8,-17 -3,-20 6,-3 15,1 21,8 7,8 8,17 3,20 -6,3 -15,-1 -21,-8z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1626,241c-10,-11 -13,-22 -8,-25 5,-3 17,3 26,13 10,11 13,22 8,25 -5,3 -17,-3 -26,-13z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M715,2070c-9,-14 -10,-154 -1,-169 11,-17 95,-14 102,4 7,17 -65,167 -83,172 -6,2 -14,-1 -18,-7z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1353,2068c-14,-17 -53,-155 -45,-162 8,-9 80,-7 84,2 2,4 2,43 -1,86 -6,78 -17,100 -38,74z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1281,1877c-18,-22 -66,-26 -159,-12 -52,8 -97,9 -120,4 -20,-5 -65,-9 -99,-9 -112,0 -268,-27 -299,-51 -8,-7 -6,-38 8,-116 18,-103 83,-377 92,-392 3,-4 -21,-31 -54,-59 -65,-58 -75,-77 -60,-116l10,-27 73,59c39,32 98,71 129,86 65,32 159,44 209,27 27,-8 45,-7 83,4 77,23 174,20 227,-9 42,-22 50,-23 151,-15 90,7 117,14 177,42 59,29 74,32 88,22 25,-18 61,7 58,40 -4,34 -15,47 -32,41 -17,-7 -122,-22 -209,-31l-61,-6 15,63c24,106 83,340 89,354 6,16 -35,36 -114,56 -26,7 -52,18 -56,26 -11,17 -27,6 -27,-19 0,-17 -7,-19 -77,-18 -43,1 -68,4 -55,6 26,5 49,40 35,54 -6,6 -14,4 -22,-4z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M895,1146c-147,-38 -197,-60 -241,-108 -48,-53 -54,-62 -63,-114 -17,-88 7,-179 76,-296 16,-25 45,-75 65,-111 43,-72 74,-105 87,-91 5,5 13,34 18,64 6,44 12,55 27,55 13,0 24,-16 41,-60 30,-82 46,-78 61,15 7,41 25,106 41,144l27,69 15,-34c8,-19 22,-61 31,-94 10,-34 23,-60 30,-60 7,0 19,18 26,40 12,37 13,31 11,-80l-2,-120 33,2c43,1 60,17 73,67 26,96 29,102 50,103 19,2 20,-3 18,-57 -1,-33 0,-63 4,-66 3,-4 17,0 30,9 16,10 27,32 36,71 8,36 19,60 31,66 11,6 24,27 30,48 13,46 33,74 51,70 17,-4 26,71 28,218 1,97 0,101 -26,126 -47,43 -90,68 -149,88 -31,11 -63,25 -70,31 -7,5 -57,14 -111,20 -54,5 -109,11 -123,13 -14,2 -84,-10 -155,-28z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M467,1094c-40,-38 -64,-55 -80,-53 -30,4 -70,-19 -60,-34 4,-7 8,-19 8,-27 0,-8 6,-14 14,-12 12,3 12,0 2,-12 -15,-18 4,-33 23,-17 9,7 16,7 24,-1 8,-8 14,-5 21,14 5,14 23,35 40,47 21,15 31,31 33,54 2,24 8,32 22,32 19,0 41,47 28,59 -10,11 -17,6 -75,-50z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M501,386c-16,-19 28,-72 52,-63 22,8 21,19 -4,51 -23,30 -32,32 -48,12z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1579,311c-23,-19 -23,-21 -6,-38 16,-17 18,-16 43,9 42,42 9,67 -37,29z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M1014,298c-8,-13 13,-35 34,-33 25,2 44,15 39,28 -4,14 -65,18 -73,5z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M734,2097c-2,-7 16,-58 41,-112 24,-55 45,-105 45,-111 0,-6 6,-17 14,-23 25,-21 51,3 65,57 7,28 19,58 26,69 13,16 14,13 15,-34 0,-60 12,-74 35,-40 9,14 42,39 74,56 32,17 64,38 71,46 19,23 27,18 40,-22 7,-21 15,-41 19,-45 10,-11 51,20 51,38 0,28 18,13 40,-31 12,-25 26,-47 30,-50 15,-9 22,15 9,31 -10,12 -10,15 2,12 8,-2 14,4 14,12 1,8 6,25 13,36 6,12 13,41 14,65l3,44 -140,6c-263,12 -475,10 -481,-4z\"/>\n    <path\n        android:fillColor=\"@color/textSecondary\"\n        android:pathData=\"M595,2086c-96,-30 -177,-92 -237,-181 -30,-44 -56,-132 -59,-201 -2,-25 -6,-47 -11,-50 -10,-6 -11,-318 -1,-328 7,-7 21,-143 37,-354 12,-157 79,-445 113,-484 8,-9 15,-22 17,-30 1,-7 5,-19 9,-25 4,-7 3,-21 -3,-32 -18,-34 -11,-61 25,-97 41,-40 101,-57 111,-31 4,12 18,6 70,-30 93,-65 182,-92 333,-102 68,-4 153,-6 189,-4 80,4 210,36 272,68 47,24 48,24 65,5 30,-33 66,-25 115,25 42,43 44,47 33,76 -11,28 -9,36 16,73 72,105 120,263 141,466 8,73 28,174 56,275 77,279 84,409 34,600 -39,145 -103,235 -211,297 -53,31 -192,66 -275,70l-59,3 1,-73c2,-62 5,-76 25,-95 13,-12 34,-35 45,-51 29,-40 44,-26 44,42l1,57 36,-40c39,-44 72,-108 73,-142 0,-33 20,-39 40,-13l18,23 4,-44c3,-24 1,-48 -3,-53 -5,-6 -9,-21 -9,-35 0,-15 -14,-78 -31,-141 -34,-126 -41,-167 -29,-175 4,-3 43,2 86,10 81,15 102,11 90,-20 -4,-11 -12,-14 -26,-10 -12,4 -50,-7 -97,-28 -67,-29 -93,-35 -183,-40 -94,-5 -108,-3 -138,15 -50,31 -142,34 -221,9 -41,-12 -69,-17 -76,-11 -23,19 -91,22 -155,5 -74,-18 -150,-65 -228,-139l-53,-50 6,-51c4,-27 9,-54 12,-58 8,-13 52,34 46,49 -3,8 0,15 6,15 20,3 26,5 66,26 39,20 265,85 295,84 82,-1 246,-24 259,-35 9,-8 30,-18 46,-22 39,-9 111,-46 154,-78 49,-37 58,-22 38,66 -9,40 -20,84 -23,97 -7,23 -7,23 20,6 15,-10 38,-37 52,-61 28,-47 43,-49 45,-6 1,23 4,20 17,-18 11,-34 15,-86 15,-210 0,-91 -3,-182 -7,-203 -8,-51 -48,-111 -121,-183 -109,-107 -239,-153 -428,-154 -54,0 -130,7 -170,16 -138,31 -294,132 -366,238 -25,35 -31,59 -45,177 -9,75 -16,155 -16,178 0,27 -5,44 -14,47 -18,7 -66,-24 -66,-43 0,-8 -4,-12 -9,-8 -5,3 -13,0 -16,-5 -5,-7 -12,-5 -20,7 -7,10 -11,21 -9,25 2,4 0,10 -6,13 -8,5 -7,11 1,21 8,10 16,11 31,3 15,-8 26,-5 54,16 20,15 44,41 55,59 10,17 19,27 19,22 0,-19 40,28 50,60 11,31 7,48 -43,182 -58,154 -91,258 -90,280 4,66 5,67 21,15 19,-59 39,-86 46,-62 2,8 11,58 20,112 9,54 25,115 36,135 21,40 22,38 24,-38 2,-45 19,-36 37,20 13,40 30,66 62,95 40,36 45,46 49,92 8,80 -29,100 -127,69zM540,365c7,-9 10,-18 7,-22 -8,-7 -37,15 -37,28 0,14 16,11 30,-6zM1620,300c0,-12 -28,-25 -36,-17 -9,9 6,27 22,27 8,0 14,-5 14,-10zM1070,278c0,-13 -32,-6 -37,9 -3,7 3,9 16,6 12,-3 21,-10 21,-15z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_unlock.xml",
    "content": "<!-- drawable/lock_open.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V10A2,2 0 0,1 6,8H15V6A3,3 0 0,0 12,3A3,3 0 0,0 9,6H7A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,17A2,2 0 0,0 14,15A2,2 0 0,0 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_unlocked.xml",
    "content": "<!-- drawable/lock_open.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:height=\"24dp\"\r\n    android:width=\"24dp\"\r\n    android:viewportWidth=\"24\"\r\n    android:viewportHeight=\"24\">\r\n    <path android:fillColor=\"#80FFFFFF\" android:pathData=\"M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V10A2,2 0 0,1 6,8H15V6A3,3 0 0,0 12,3A3,3 0 0,0 9,6H7A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,17A2,2 0 0,0 14,15A2,2 0 0,0 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17Z\" />\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_version.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M5.41,21L6.12,17H2.12L2.47,15H6.47L7.53,9H3.53L3.88,7H7.88L8.59,3H10.59L9.88,7H15.88L16.59,3H18.59L17.88,7H21.88L21.53,9H17.53L16.47,15H20.47L20.12,17H16.12L15.41,21H13.41L14.12,17H8.12L7.41,21H5.41M9.53,9L8.47,15H14.47L15.53,9H9.53Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_warning.xml",
    "content": "<!-- drawable/alert.xml -->\r\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"#fff\"\r\n        android:pathData=\"M13,14H11V10H13M13,18H11V16H13M1,21H23L12,2L1,21Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_watching.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n        android:width=\"24dp\"\r\n        android:height=\"24dp\"\r\n        android:viewportWidth=\"24\"\r\n        android:viewportHeight=\"24\">\r\n    <path\r\n        android:fillColor=\"?colorControlNormal\"\r\n        android:pathData=\"M10,16.5V7.5L16,12M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\"/>\r\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_web.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"24dp\"\n        android:height=\"24dp\"\n        android:viewportWidth=\"24\"\n        android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"?colorControlNormal\"\n        android:pathData=\"M16.36,14C16.44,13.34 16.5,12.68 16.5,12C16.5,11.32 16.44,10.66 16.36,10H19.74C19.9,10.64 20,11.31 20,12C20,12.69 19.9,13.36 19.74,14M14.59,19.56C15.19,18.45 15.65,17.25 15.97,16H18.92C17.96,17.65 16.43,18.93 14.59,19.56M14.34,14H9.66C9.56,13.34 9.5,12.68 9.5,12C9.5,11.32 9.56,10.65 9.66,10H14.34C14.43,10.65 14.5,11.32 14.5,12C14.5,12.68 14.43,13.34 14.34,14M12,19.96C11.17,18.76 10.5,17.43 10.09,16H13.91C13.5,17.43 12.83,18.76 12,19.96M8,8H5.08C6.03,6.34 7.57,5.06 9.4,4.44C8.8,5.55 8.35,6.75 8,8M5.08,16H8C8.35,17.25 8.8,18.45 9.4,19.56C7.57,18.93 6.03,17.65 5.08,16M4.26,14C4.1,13.36 4,12.69 4,12C4,11.31 4.1,10.64 4.26,10H7.64C7.56,10.66 7.5,11.32 7.5,12C7.5,12.68 7.56,13.34 7.64,14M12,4.03C12.83,5.23 13.5,6.57 13.91,8H10.09C10.5,6.57 11.17,5.23 12,4.03M18.92,8H15.97C15.65,6.75 15.19,5.55 14.59,4.44C16.43,5.07 17.96,6.34 18.92,8M12,2C6.47,2 2,6.5 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\"/>\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/material_tab_indicator.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:shape=\"rectangle\">\r\n    <size\r\n        android:width=\"100dp\"\r\n        android:height=\"2.5dp\" />\r\n    <corners\r\n        android:topLeftRadius=\"8dp\"\r\n        android:topRightRadius=\"8dp\">\r\n    </corners>\r\n    <solid\r\n        android:color=\"?colorAccent\">\r\n    </solid>\r\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/progressbar_circle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n       android:innerRadiusRatio=\"3\"\r\n       android:shape=\"ring\"\r\n       android:thickness=\"3dp\"\r\n       android:useLevel=\"true\">\r\n\r\n    <solid android:color=\"@color/colorAccent\"/>\r\n\r\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shadow_gradient.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:shape=\"rectangle\">\r\n\r\n    <gradient\r\n        android:angle=\"270\"\r\n        android:endColor=\"#00ffffff\"\r\n        android:startColor=\"#B7FFFFFF\"\r\n        android:type=\"linear\" />\r\n\r\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/shape_circle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<shape\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:shape=\"oval\">\r\n\r\n    <solid android:color=\"?colorAccentLight\"/>\r\n\r\n    <size\r\n        android:width=\"40dp\"\r\n        android:height=\"40dp\"/>\r\n\r\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#e53935\"\n        android:endColor=\"#ab000d\"\n        android:startColor=\"#ff6f60\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_amber.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#ffa000\"\n        android:endColor=\"#c67100\"\n        android:startColor=\"#ffd149\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_blue.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#1976d2\"\n        android:endColor=\"#004ba0\"\n        android:startColor=\"#63a4ff\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_blue_gray.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#455a64\"\n        android:endColor=\"#1c313a\"\n        android:startColor=\"#718792\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_brown.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#5d4037\"\n        android:endColor=\"#321911\"\n        android:startColor=\"#8b6b61\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_cyan.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#0097a7\"\n        android:endColor=\"#006978\"\n        android:startColor=\"#56c8d8\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_deep_orange.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#e64a19\"\n        android:endColor=\"#ac0800\"\n        android:startColor=\"#ff7d47\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_deep_purple.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#512da8\"\n        android:endColor=\"#140078\"\n        android:startColor=\"#8559da\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_gray.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#616161\"\n        android:endColor=\"#373737\"\n        android:startColor=\"#8e8e8e\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_green.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#388e3c\"\n        android:endColor=\"#00600f\"\n        android:startColor=\"#6abf69\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_indigo.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#303f9f\"\n        android:endColor=\"#001970\"\n        android:startColor=\"#666ad1\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_light_blue.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#0288d1\"\n        android:endColor=\"#005b9f\"\n        android:startColor=\"#5eb8ff\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_light_green.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#689f38\"\n        android:endColor=\"#387002\"\n        android:startColor=\"#99d066\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_lime.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#afb42b\"\n        android:endColor=\"#7c8500\"\n        android:startColor=\"#e4e65e\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_orange.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#f57c00\"\n        android:endColor=\"#bb4d00\"\n        android:startColor=\"#ffad42\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_pink.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#c2185b\"\n        android:endColor=\"#8c0032\"\n        android:startColor=\"#fa5788\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_purple.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#7b1fa2\"\n        android:endColor=\"#4a0072\"\n        android:startColor=\"#ae52d4\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_teal.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#00796b\"\n        android:endColor=\"#004c40\"\n        android:startColor=\"#48a999\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/side_nav_bar_yellow.xml",
    "content": "<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       android:shape=\"rectangle\">\n    <gradient\n        android:angle=\"135\"\n        android:centerColor=\"#fbc02d\"\n        android:endColor=\"#c49000\"\n        android:startColor=\"#fff263\"\n        android:type=\"linear\"/>\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/updater_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<animation-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item\n        android:drawable=\"@drawable/grad_1\"\n        android:duration=\"2500\"/>\n    <item\n        android:drawable=\"@drawable/grad_2\"\n        android:duration=\"2500\"/>\n    <item\n        android:drawable=\"@drawable/grad_3\"\n        android:duration=\"2500\"/>\n    <item\n        android:drawable=\"@drawable/grad_4\"\n        android:duration=\"2500\"/>\n\n</animation-list>"
  },
  {
    "path": "app/src/main/res/drawable-night/anim_check_sync.xml",
    "content": "<animated-vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\">\n    <aapt:attr name=\"android:drawable\">\n        <vector\n            android:name=\"vector\"\n            android:width=\"24dp\"\n            android:height=\"24dp\"\n            android:viewportWidth=\"24\"\n            android:viewportHeight=\"24\">\n            <path\n                android:name=\"path\"\n                android:fillColor=\"#B2FFFFFF\"\n                android:pathData=\"M 12 18 C 10.409 18 8.882 17.367 7.757 16.243 C 6.633 15.118 6 13.591 6 12 C 6 11 6.25 10.03 6.7 9.2 L 5.24 7.74 C 4.46 8.97 4 10.43 4 12 C 4 14.121 4.843 16.157 6.343 17.657 C 7.843 19.157 9.879 20 12 20 L 12 23 L 16 19 L 12 15 M 12 4 L 12 1 L 8 5 L 12 9 L 12 6 C 13.591 6 15.118 6.633 16.243 7.757 C 17.367 8.882 18 10.409 18 12 C 18 13 17.75 13.97 17.3 14.8 L 18.76 16.26 C 19.54 15.03 20 13.57 20 12 C 20 9.879 19.157 7.843 17.657 6.343 C 16.157 4.843 14.121 4 12 4 Z\"\n                android:strokeWidth=\"1\" />\n        </vector>\n    </aapt:attr>\n    <target android:name=\"path\">\n        <aapt:attr name=\"android:animation\">\n            <set>\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/fast_out_slow_in\"\n                    android:propertyName=\"pathData\"\n                    android:valueFrom=\"M 9 20.42 L 9 20.42 L 7.758 19.178 L 6.516 17.936 C 6.102 17.522 5.688 17.108 5.274 16.694 C 4.86 16.28 4.446 15.866 4.032 15.452 C 3.618 15.038 3.204 14.624 2.79 14.21 L 3.733 13.267 C 4.048 12.952 4.362 12.638 4.677 12.323 C 4.991 12.009 5.306 11.694 5.62 11.38 C 6.747 12.51 7.873 13.64 9 14.77 C 12.293 11.473 15.587 8.177 18.88 4.88 C 19.823 5.823 20.767 6.767 21.71 7.71 C 17.473 11.947 13.237 16.183 9 20.42 C 9 20.42 9 20.42 9 20.42 M 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 L 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125\"\n                    android:valueTo=\"M 12 15 L 16 19 L 12 23 L 12 20 C 9.879 20 7.843 19.157 6.343 17.657 C 4.843 16.157 4 14.121 4 12 C 4 10.43 4.46 8.97 5.24 7.74 L 6.7 9.2 C 6.25 10.03 6 11 6 12 C 6 13.591 6.633 15.118 7.757 16.243 C 8.038 16.524 8.345 16.774 8.671 16.992 C 8.834 17.101 9.002 17.201 9.174 17.293 C 9.347 17.385 9.524 17.468 9.704 17.543 C 10.064 17.692 10.44 17.807 10.824 17.884 C 11.209 17.96 11.602 18 12 18 M 12 6 L 12 9 L 8 5 L 12 1 L 12 4 L 12 4 C 14.121 4 16.157 4.843 17.657 6.343 C 19.157 7.843 20 9.879 20 12 C 20 13.57 19.54 15.03 18.76 16.26 L 17.3 14.8 C 17.75 13.97 18 13 18 12 C 18 10.409 17.367 8.882 16.243 7.757 C 15.118 6.633 13.591 6 12 6\"\n                    android:valueType=\"pathType\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/fast_out_slow_in\"\n                    android:propertyName=\"fillColor\"\n                    android:valueFrom=\"#64dd17\"\n                    android:valueTo=\"#B2FFFFFF\"\n                    android:valueType=\"colorType\" />\n            </set>\n        </aapt:attr>\n    </target>\n</animated-vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-night/anim_sync_check.xml",
    "content": "<animated-vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\">\n    <aapt:attr name=\"android:drawable\">\n        <vector\n            android:name=\"vector\"\n            android:width=\"24dp\"\n            android:height=\"24dp\"\n            android:viewportWidth=\"24\"\n            android:viewportHeight=\"24\">\n            <path\n                android:name=\"path\"\n                android:fillColor=\"#B2FFFFFF\"\n                android:pathData=\"M 12 18 C 10.409 18 8.882 17.367 7.757 16.243 C 6.633 15.118 6 13.591 6 12 C 6 11 6.25 10.03 6.7 9.2 L 5.24 7.74 C 4.46 8.97 4 10.43 4 12 C 4 14.121 4.843 16.157 6.343 17.657 C 7.843 19.157 9.879 20 12 20 L 12 23 L 16 19 L 12 15 M 12 4 L 12 1 L 8 5 L 12 9 L 12 6 C 13.591 6 15.118 6.633 16.243 7.757 C 17.367 8.882 18 10.409 18 12 C 18 13 17.75 13.97 17.3 14.8 L 18.76 16.26 C 19.54 15.03 20 13.57 20 12 C 20 9.879 19.157 7.843 17.657 6.343 C 16.157 4.843 14.121 4 12 4 Z\"\n                android:strokeWidth=\"1\" />\n        </vector>\n    </aapt:attr>\n    <target android:name=\"path\">\n        <aapt:attr name=\"android:animation\">\n            <set>\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/fast_out_slow_in\"\n                    android:propertyName=\"pathData\"\n                    android:valueFrom=\"M 12 15 L 16 19 L 12 23 L 12 20 C 9.879 20 7.843 19.157 6.343 17.657 C 4.843 16.157 4 14.121 4 12 C 4 10.43 4.46 8.97 5.24 7.74 L 6.7 9.2 C 6.25 10.03 6 11 6 12 C 6 13.591 6.633 15.118 7.757 16.243 C 8.038 16.524 8.345 16.774 8.671 16.992 C 8.997 17.209 9.343 17.394 9.704 17.543 C 10.064 17.692 10.44 17.807 10.824 17.884 C 11.209 17.96 11.602 18 12 18 M 12 6 L 12 9 L 8 5 L 12 1 L 12 4 L 12 4 C 14.121 4 16.157 4.843 17.657 6.343 C 19.157 7.843 20 9.879 20 12 C 20 13.57 19.54 15.03 18.76 16.26 L 17.3 14.8 C 17.75 13.97 18 13 18 12 C 18 10.409 17.367 8.882 16.243 7.757 C 15.118 6.633 13.591 6 12 6\"\n                    android:valueTo=\"M 9 20.42 L 7.758 19.178 L 6.516 17.936 L 5.274 16.694 C 4.86 16.28 4.446 15.866 4.032 15.452 C 3.618 15.038 3.204 14.624 2.79 14.21 C 3.104 13.896 3.419 13.581 3.733 13.267 L 4.677 12.323 C 4.991 12.009 5.306 11.694 5.62 11.38 C 6.747 12.51 7.873 13.64 9 14.77 C 12.293 11.473 15.587 8.177 18.88 4.88 C 19.823 5.823 20.767 6.767 21.71 7.71 C 17.473 11.947 13.237 16.183 9 20.42 C 9 20.42 9 20.42 9 20.42 M 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 L 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 L 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125 C 10.625 5.125 10.625 5.125 10.625 5.125\"\n                    android:valueType=\"pathType\" />\n                <objectAnimator\n                    android:duration=\"500\"\n                    android:interpolator=\"@android:interpolator/fast_out_slow_in\"\n                    android:propertyName=\"fillColor\"\n                    android:valueFrom=\"#B2FFFFFF\"\n                    android:valueTo=\"#64dd17\"\n                    android:valueType=\"colorType\" />\n            </set>\n        </aapt:attr>\n    </target>\n</animated-vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-night/shadow_gradient.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:shape=\"rectangle\">\r\n\r\n    <gradient\r\n        android:angle=\"270\"\r\n        android:endColor=\"#00000000\"\r\n        android:startColor=\"#CC000000\"\r\n        android:type=\"linear\" />\r\n\r\n</shape>"
  },
  {
    "path": "app/src/main/res/layout/activity_achievement_profile.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <androidx.coordinatorlayout.widget.CoordinatorLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"0dp\"\r\n            android:layout_weight=\"1\">\r\n\r\n            <com.google.android.material.appbar.AppBarLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:backgroundTint=\"?colorSurface\"\r\n                android:fitsSystemWindows=\"true\"\r\n                android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\">\r\n\r\n                <com.google.android.material.appbar.CollapsingToolbarLayout\r\n                    android:layout_width=\"wrap_content\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:contentScrim=\"@color/colorPrimary\"\r\n                    app:expandedTitleTextAppearance=\"@style/NoTitleStyle\"\r\n                    app:layout_scrollFlags=\"scroll|exitUntilCollapsed\"\r\n                    app:toolbarId=\"@id/toolbar\">\r\n\r\n                    <LinearLayout\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_gravity=\"center_horizontal\"\r\n                        android:layout_marginTop=\"16dp\"\r\n                        android:layout_marginBottom=\"?actionBarSize\"\r\n                        android:orientation=\"vertical\">\r\n\r\n                        <RelativeLayout\r\n                            android:layout_width=\"96dp\"\r\n                            android:layout_height=\"96dp\"\r\n                            android:layout_gravity=\"center_horizontal\"\r\n                            android:layout_margin=\"16dp\">\r\n\r\n                            <com.mikhaellopez.circularprogressbar.CircularProgressBar\r\n                                android:id=\"@+id/progress\"\r\n                                android:layout_width=\"match_parent\"\r\n                                android:layout_height=\"match_parent\"\r\n                                app:cpb_background_progressbar_color=\"@color/color_bottom_line_disabled\"\r\n                                app:cpb_background_progressbar_width=\"4dp\"\r\n                                app:cpb_progressbar_color=\"?colorPrimary\"\r\n                                app:cpb_progressbar_width=\"5dp\" />\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/level\"\r\n                                android:layout_width=\"wrap_content\"\r\n                                android:layout_height=\"wrap_content\"\r\n                                android:layout_centerInParent=\"true\"\r\n                                android:textColor=\"@color/textPrimary\"\r\n                                android:textSize=\"24sp\"\r\n                                android:textStyle=\"bold\"\r\n                                tools:text=\"99\" />\r\n                        </RelativeLayout>\r\n\r\n                        <LinearLayout\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_gravity=\"center_horizontal\"\r\n                            android:gravity=\"center_vertical\"\r\n                            android:orientation=\"horizontal\">\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/countdown\"\r\n                                android:layout_width=\"wrap_content\"\r\n                                android:layout_height=\"wrap_content\"\r\n                                android:textColor=\"?colorAccent\"\r\n                                android:textSize=\"14sp\"\r\n                                tools:text=\"10,000 XP\" />\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/progress_ind_text\"\r\n                                android:layout_width=\"wrap_content\"\r\n                                android:layout_height=\"wrap_content\"\r\n                                android:text=\" para siguiente nivel\"\r\n                                android:textColor=\"@color/textPrimary\"\r\n                                android:textSize=\"14sp\" />\r\n                        </LinearLayout>\r\n                    </LinearLayout>\r\n\r\n                    <androidx.appcompat.widget.Toolbar\r\n                        android:id=\"@+id/toolbar\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"?actionBarSize\"\r\n                        android:layout_gravity=\"top\"\r\n                        android:layout_marginBottom=\"48dp\"\r\n                        app:layout_collapseMode=\"pin\"\r\n                        app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\r\n\r\n                    <com.google.android.material.tabs.TabLayout\r\n                        android:id=\"@+id/tabs\"\r\n                        style=\"@style/Widget.MaterialComponents.TabLayout\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_gravity=\"bottom\"\r\n                        android:background=\"@android:color/transparent\"\r\n                        app:layout_scrollFlags=\"scroll|enterAlways\"\r\n                        app:tabBackground=\"@android:color/transparent\">\r\n\r\n                        <com.google.android.material.tabs.TabItem\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:text=\"DESBLOQUEADOS\" />\r\n\r\n                        <com.google.android.material.tabs.TabItem\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:text=\"BLOQUEADOS\" />\r\n                    </com.google.android.material.tabs.TabLayout>\r\n                </com.google.android.material.appbar.CollapsingToolbarLayout>\r\n            </com.google.android.material.appbar.AppBarLayout>\r\n\r\n            <androidx.viewpager.widget.ViewPager\r\n                android:id=\"@+id/pager\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"match_parent\"\r\n                app:layout_behavior=\"@string/appbar_scrolling_view_behavior\" />\r\n        </androidx.coordinatorlayout.widget.CoordinatorLayout>\r\n\r\n        <knf.kuma.custom.BannerContainerView\r\n            android:id=\"@+id/adContainer\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\" />\r\n    </LinearLayout>\r\n\r\n    <com.google.android.material.card.MaterialCardView\r\n        android:id=\"@+id/sheet\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:clickable=\"true\"\r\n        app:behavior_hideable=\"true\"\r\n        app:behavior_peekHeight=\"auto\"\r\n        app:behavior_skipCollapsed=\"true\"\r\n        app:contentPadding=\"16dp\"\r\n        app:layout_behavior=\"@string/bottom_sheet_behavior\">\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\">\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:gravity=\"center_horizontal\"\r\n                android:orientation=\"vertical\">\r\n\r\n                <ImageView\r\n                    android:id=\"@+id/achievement_icon\"\r\n                    android:layout_width=\"72dp\"\r\n                    android:layout_height=\"72dp\"\r\n                    android:layout_marginTop=\"8dp\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    tools:srcCompat=\"@drawable/ic_locked\" />\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"wrap_content\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    android:orientation=\"horizontal\">\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/achievement_xp\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:textColor=\"?colorAccent\"\r\n                        tools:text=\"100 XP\" />\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/achievement_state\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginStart=\"8dp\"\r\n                        android:textColor=\"?android:attr/textColorSecondary\"\r\n                        tools:text=\"Bloqueado\" />\r\n                </LinearLayout>\r\n\r\n                <LinearLayout\r\n                    android:id=\"@+id/progress_indicator\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:gravity=\"center|center_horizontal\"\r\n                    android:orientation=\"horizontal\"\r\n                    android:visibility=\"visible\">\r\n\r\n                    <ProgressBar\r\n                        android:id=\"@+id/progress_bar\"\r\n                        style=\"@android:style/Widget.Material.Light.ProgressBar.Horizontal\"\r\n                        android:layout_width=\"0dp\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_gravity=\"center_vertical\"\r\n                        android:layout_weight=\"1\" />\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/progress_text\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginStart=\"8dp\"\r\n                        tools:text=\"100 / 5000\" />\r\n                </LinearLayout>\r\n\r\n                <TextView\r\n                    android:id=\"@+id/achievement_name\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginStart=\"32dp\"\r\n                    android:layout_marginEnd=\"32dp\"\r\n                    android:textAlignment=\"center\"\r\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Headline\"\r\n                    tools:text=\"Logro secreto\" />\r\n\r\n                <TextView\r\n                    android:id=\"@+id/achievement_description\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginStart=\"32dp\"\r\n                    android:layout_marginEnd=\"32dp\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    android:textAlignment=\"center\"\r\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Subhead\"\r\n                    android:textColor=\"?android:attr/textColorSecondary\"\r\n                    tools:text=\"Usa mas la app para desbloquear\" />\r\n            </LinearLayout>\r\n\r\n            <com.google.android.material.button.MaterialButton\r\n                android:id=\"@+id/buyButton\"\r\n                style=\"@style/Widget.MaterialComponents.Button.OutlinedButton.Icon\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_alignParentStart=\"true\"\r\n                android:layout_alignParentTop=\"true\"\r\n                android:visibility=\"gone\"\r\n                app:icon=\"@drawable/ic_coin_ach\"\r\n                app:strokeColor=\"?colorSecondary\"\r\n                tools:text=\"5000\"\r\n                tools:visibility=\"visible\" />\r\n        </RelativeLayout>\r\n    </com.google.android.material.card.MaterialCardView>\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_achievement_profile_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <androidx.coordinatorlayout.widget.CoordinatorLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"0dp\"\r\n            android:layout_weight=\"1\">\r\n\r\n            <com.google.android.material.appbar.AppBarLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:backgroundTint=\"?colorSurface\"\r\n                android:fitsSystemWindows=\"true\"\r\n                android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\"\r\n                app:elevation=\"0dp\">\r\n\r\n                <com.google.android.material.appbar.CollapsingToolbarLayout\r\n                    android:layout_width=\"wrap_content\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:contentScrim=\"?colorSurface\"\r\n                    app:expandedTitleTextAppearance=\"@style/NoTitleStyle\"\r\n                    app:layout_scrollFlags=\"scroll|exitUntilCollapsed\"\r\n                    app:toolbarId=\"@id/toolbar\">\r\n\r\n                    <LinearLayout\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_gravity=\"center_horizontal\"\r\n                        android:layout_marginTop=\"16dp\"\r\n                        android:layout_marginBottom=\"?actionBarSize\"\r\n                        android:orientation=\"vertical\">\r\n\r\n                        <RelativeLayout\r\n                            android:layout_width=\"96dp\"\r\n                            android:layout_height=\"96dp\"\r\n                            android:layout_gravity=\"center_horizontal\"\r\n                            android:layout_margin=\"16dp\">\r\n\r\n                            <com.mikhaellopez.circularprogressbar.CircularProgressBar\r\n                                android:id=\"@+id/progress\"\r\n                                android:layout_width=\"match_parent\"\r\n                                android:layout_height=\"match_parent\"\r\n                                app:cpb_background_progressbar_color=\"@color/color_bottom_line_disabled\"\r\n                                app:cpb_background_progressbar_width=\"4dp\"\r\n                                app:cpb_progressbar_color=\"?colorPrimary\"\r\n                                app:cpb_progressbar_width=\"5dp\" />\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/level\"\r\n                                android:layout_width=\"wrap_content\"\r\n                                android:layout_height=\"wrap_content\"\r\n                                android:layout_centerInParent=\"true\"\r\n                                android:textColor=\"@color/textPrimary\"\r\n                                android:textSize=\"24sp\"\r\n                                android:textStyle=\"bold\"\r\n                                tools:text=\"99\" />\r\n                        </RelativeLayout>\r\n\r\n                        <LinearLayout\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_gravity=\"center_horizontal\"\r\n                            android:gravity=\"center_vertical\"\r\n                            android:orientation=\"horizontal\">\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/countdown\"\r\n                                android:layout_width=\"wrap_content\"\r\n                                android:layout_height=\"wrap_content\"\r\n                                android:textColor=\"?colorAccent\"\r\n                                android:textSize=\"14sp\"\r\n                                tools:text=\"10,000 XP\" />\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/progress_ind_text\"\r\n                                android:layout_width=\"wrap_content\"\r\n                                android:layout_height=\"wrap_content\"\r\n                                android:text=\" para siguiente nivel\"\r\n                                android:textColor=\"@color/textPrimary\"\r\n                                android:textSize=\"14sp\" />\r\n                        </LinearLayout>\r\n                    </LinearLayout>\r\n\r\n                    <androidx.appcompat.widget.Toolbar\r\n                        android:id=\"@+id/toolbar\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"?actionBarSize\"\r\n                        android:layout_gravity=\"top\"\r\n                        android:layout_marginBottom=\"48dp\"\r\n                        app:layout_collapseMode=\"pin\"\r\n                        app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\r\n\r\n                    <com.google.android.material.tabs.TabLayout\r\n                        android:id=\"@+id/tabs\"\r\n                        style=\"@style/Widget.MaterialComponents.TabLayout\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_gravity=\"bottom\"\r\n                        android:background=\"@android:color/transparent\"\r\n                        app:layout_scrollFlags=\"scroll|enterAlways\"\r\n                        app:tabBackground=\"@android:color/transparent\"\r\n                        app:tabIndicator=\"@drawable/material_tab_indicator\">\r\n\r\n                        <com.google.android.material.tabs.TabItem\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:text=\"DESBLOQUEADOS\" />\r\n\r\n                        <com.google.android.material.tabs.TabItem\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:text=\"BLOQUEADOS\" />\r\n                    </com.google.android.material.tabs.TabLayout>\r\n                </com.google.android.material.appbar.CollapsingToolbarLayout>\r\n            </com.google.android.material.appbar.AppBarLayout>\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"match_parent\"\r\n                android:orientation=\"vertical\"\r\n                app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\r\n                <View\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"@dimen/separator_size\"\r\n                    android:background=\"@color/separator\"/>\r\n\r\n                <androidx.viewpager.widget.ViewPager\r\n                    android:id=\"@+id/pager\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"match_parent\"\r\n                    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\" />\r\n            </LinearLayout>\r\n        </androidx.coordinatorlayout.widget.CoordinatorLayout>\r\n\r\n        <knf.kuma.custom.BannerContainerView\r\n            android:id=\"@+id/adContainer\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\" />\r\n    </LinearLayout>\r\n\r\n    <com.google.android.material.card.MaterialCardView\r\n        android:id=\"@+id/sheet\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:clickable=\"true\"\r\n        app:behavior_hideable=\"true\"\r\n        app:behavior_peekHeight=\"auto\"\r\n        app:behavior_skipCollapsed=\"true\"\r\n        app:contentPadding=\"16dp\"\r\n        app:layout_behavior=\"@string/bottom_sheet_behavior\">\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\">\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:gravity=\"center_horizontal\"\r\n                android:orientation=\"vertical\">\r\n\r\n                <ImageView\r\n                    android:id=\"@+id/achievement_icon\"\r\n                    android:layout_width=\"72dp\"\r\n                    android:layout_height=\"72dp\"\r\n                    android:layout_marginTop=\"8dp\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    tools:srcCompat=\"@drawable/ic_locked\" />\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"wrap_content\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    android:orientation=\"horizontal\">\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/achievement_xp\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:textColor=\"?colorAccent\"\r\n                        tools:text=\"100 XP\" />\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/achievement_state\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginStart=\"8dp\"\r\n                        android:textColor=\"?android:attr/textColorSecondary\"\r\n                        tools:text=\"Bloqueado\" />\r\n                </LinearLayout>\r\n\r\n                <LinearLayout\r\n                    android:id=\"@+id/progress_indicator\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:gravity=\"center|center_horizontal\"\r\n                    android:orientation=\"horizontal\"\r\n                    android:visibility=\"visible\">\r\n\r\n                    <ProgressBar\r\n                        android:id=\"@+id/progress_bar\"\r\n                        style=\"@android:style/Widget.Material.Light.ProgressBar.Horizontal\"\r\n                        android:layout_width=\"0dp\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_gravity=\"center_vertical\"\r\n                        android:layout_weight=\"1\" />\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/progress_text\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginStart=\"8dp\"\r\n                        tools:text=\"100 / 5000\" />\r\n                </LinearLayout>\r\n\r\n                <TextView\r\n                    android:id=\"@+id/achievement_name\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginStart=\"32dp\"\r\n                    android:layout_marginEnd=\"32dp\"\r\n                    android:textAlignment=\"center\"\r\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Headline\"\r\n                    tools:text=\"Logro secreto\" />\r\n\r\n                <TextView\r\n                    android:id=\"@+id/achievement_description\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginStart=\"32dp\"\r\n                    android:layout_marginEnd=\"32dp\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    android:textAlignment=\"center\"\r\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Subhead\"\r\n                    android:textColor=\"?android:attr/textColorSecondary\"\r\n                    tools:text=\"Usa mas la app para desbloquear\" />\r\n            </LinearLayout>\r\n\r\n            <com.google.android.material.button.MaterialButton\r\n                android:id=\"@+id/buyButton\"\r\n                style=\"@style/Widget.MaterialComponents.Button.OutlinedButton.Icon\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_alignParentStart=\"true\"\r\n                android:layout_alignParentTop=\"true\"\r\n                android:visibility=\"gone\"\r\n                app:icon=\"@drawable/ic_coin_ach\"\r\n                app:strokeColor=\"?colorSecondary\"\r\n                tools:text=\"5000\"\r\n                tools:visibility=\"visible\" />\r\n        </RelativeLayout>\r\n    </com.google.android.material.card.MaterialCardView>\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_ads_settings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:background=\"?colorSurface\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:background=\"?colorSurface\"\r\n        android:fitsSystemWindows=\"true\"\r\n        app:elevation=\"0dp\">\r\n\r\n        <androidx.appcompat.widget.Toolbar\r\n            android:id=\"@+id/toolbar\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\" />\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <androidx.core.widget.NestedScrollView\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:orientation=\"vertical\">\r\n\r\n            <LinearLayout\r\n                android:id=\"@+id/preferenceNative\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:baselineAligned=\"false\"\r\n                android:clickable=\"true\"\r\n                android:focusable=\"true\"\r\n                android:foreground=\"?selectableItemBackground\"\r\n                android:gravity=\"center_vertical\"\r\n                android:minHeight=\"?android:attr/listPreferredItemHeight\"\r\n                android:paddingStart=\"?android:attr/listPreferredItemPaddingStart\"\r\n                android:paddingEnd=\"?android:attr/listPreferredItemPaddingEnd\">\r\n\r\n                <RelativeLayout\r\n                    android:layout_width=\"0dp\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_weight=\"1\"\r\n                    android:paddingTop=\"16dp\"\r\n                    android:paddingBottom=\"16dp\">\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/nativeTitle\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:ellipsize=\"marquee\"\r\n                        android:singleLine=\"true\"\r\n                        android:text=\"Usar anuncios nativos\"\r\n                        android:textAppearance=\"?attr/textAppearanceListItem\"\r\n                        android:textColor=\"?android:textColorPrimary\" />\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/nativeSummary\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_below=\"@+id/nativeTitle\"\r\n                        android:layout_alignStart=\"@+id/nativeTitle\"\r\n                        android:maxLines=\"10\"\r\n                        android:text=\"Anuncios insertados en listas\"\r\n                        android:textAppearance=\"@style/TextAppearance.AppCompat.Body1\"\r\n                        android:textColor=\"?android:textColorSecondary\"\r\n                        android:typeface=\"sans\" />\r\n\r\n                </RelativeLayout>\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"wrap_content\"\r\n                    android:layout_height=\"match_parent\"\r\n                    android:gravity=\"center_vertical\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <Switch\r\n                        android:id=\"@+id/switchNative\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:clickable=\"false\" />\r\n                </LinearLayout>\r\n            </LinearLayout>\r\n\r\n            <LinearLayout\r\n                android:id=\"@+id/preferenceFull\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:baselineAligned=\"false\"\r\n                android:clickable=\"true\"\r\n                android:focusable=\"true\"\r\n                android:foreground=\"?selectableItemBackground\"\r\n                android:gravity=\"center_vertical\"\r\n                android:minHeight=\"?android:attr/listPreferredItemHeight\"\r\n                android:paddingStart=\"?android:attr/listPreferredItemPaddingStart\"\r\n                android:paddingEnd=\"?android:attr/listPreferredItemPaddingEnd\">\r\n\r\n                <RelativeLayout\r\n                    android:layout_width=\"0dp\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_weight=\"1\"\r\n                    android:paddingTop=\"16dp\"\r\n                    android:paddingBottom=\"16dp\">\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/fullTitle\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:ellipsize=\"marquee\"\r\n                        android:singleLine=\"true\"\r\n                        android:text=\"Mostrar anuncios a pantalla completa\"\r\n                        android:textAppearance=\"?attr/textAppearanceListItem\"\r\n                        android:textColor=\"?android:textColorPrimary\" />\r\n\r\n                </RelativeLayout>\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"wrap_content\"\r\n                    android:layout_height=\"match_parent\"\r\n                    android:gravity=\"center_vertical\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <Switch\r\n                        android:id=\"@+id/switchFull\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:clickable=\"false\" />\r\n                </LinearLayout>\r\n            </LinearLayout>\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:baselineAligned=\"false\"\r\n                android:gravity=\"center_vertical\"\r\n                android:minHeight=\"?android:attr/listPreferredItemHeight\"\r\n                android:paddingStart=\"10dp\"\r\n                android:paddingEnd=\"?android:attr/listPreferredItemPaddingEnd\">\r\n\r\n                <RelativeLayout\r\n                    android:layout_width=\"0dp\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_weight=\"1\"\r\n                    android:paddingTop=\"16dp\"\r\n                    android:paddingBottom=\"16dp\">\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/preferenceFullText\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginStart=\"6dp\"\r\n                        android:ellipsize=\"marquee\"\r\n                        android:singleLine=\"true\"\r\n                        android:text=\"Probabilidad de anuncios en información\"\r\n                        android:textAppearance=\"?attr/textAppearanceListItem\"\r\n                        android:textColor=\"?android:textColorPrimary\" />\r\n\r\n                    <LinearLayout\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_below=\"@+id/preferenceFullText\"\r\n                        android:layout_marginEnd=\"10dp\"\r\n                        android:gravity=\"center_vertical\"\r\n                        android:orientation=\"horizontal\">\r\n\r\n                        <com.google.android.material.slider.Slider\r\n                            android:id=\"@+id/sliderFull\"\r\n                            android:layout_width=\"0dp\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_weight=\"1\"\r\n                            android:stepSize=\"5.0\"\r\n                            android:valueFrom=\"10.0\"\r\n                            android:valueTo=\"100.0\" />\r\n\r\n                        <TextView\r\n                            android:id=\"@+id/probabilityFull\"\r\n                            android:layout_width=\"42dp\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:textAlignment=\"textEnd\"\r\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n                            tools:text=\"0%\" />\r\n                    </LinearLayout>\r\n\r\n                </RelativeLayout>\r\n            </LinearLayout>\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:baselineAligned=\"false\"\r\n                android:gravity=\"center_vertical\"\r\n                android:minHeight=\"?android:attr/listPreferredItemHeight\"\r\n                android:paddingStart=\"10dp\"\r\n                android:paddingEnd=\"?android:attr/listPreferredItemPaddingEnd\">\r\n\r\n                <RelativeLayout\r\n                    android:layout_width=\"0dp\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_weight=\"1\"\r\n                    android:paddingTop=\"16dp\"\r\n                    android:paddingBottom=\"16dp\">\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/preferenceFullTextExtra\"\r\n                        android:layout_width=\"wrap_content\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginStart=\"6dp\"\r\n                        android:ellipsize=\"marquee\"\r\n                        android:singleLine=\"true\"\r\n                        android:text=\"Probabilidad de anuncios en otras pantallas\"\r\n                        android:textAppearance=\"?attr/textAppearanceListItem\"\r\n                        android:textColor=\"?android:textColorPrimary\" />\r\n\r\n                    <LinearLayout\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_below=\"@+id/preferenceFullTextExtra\"\r\n                        android:layout_marginEnd=\"10dp\"\r\n                        android:gravity=\"center_vertical\"\r\n                        android:orientation=\"horizontal\">\r\n\r\n                        <com.google.android.material.slider.Slider\r\n                            android:id=\"@+id/sliderFullExtra\"\r\n                            android:layout_width=\"0dp\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_weight=\"1\"\r\n                            android:stepSize=\"5.0\"\r\n                            android:valueFrom=\"0.0\"\r\n                            android:valueTo=\"100.0\" />\r\n\r\n                        <TextView\r\n                            android:id=\"@+id/probabilityFullExtra\"\r\n                            android:layout_width=\"42dp\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:textAlignment=\"textEnd\"\r\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n                            tools:text=\"0%\" />\r\n                    </LinearLayout>\r\n\r\n                </RelativeLayout>\r\n            </LinearLayout>\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"16dp\"\r\n                android:layout_marginEnd=\"16dp\"\r\n                android:gravity=\"center\"\r\n                android:orientation=\"horizontal\">\r\n\r\n                <ImageView\r\n                    android:layout_width=\"18dp\"\r\n                    android:layout_height=\"18dp\"\r\n                    android:layout_marginTop=\"1dp\"\r\n                    android:layout_marginEnd=\"4dp\"\r\n                    app:srcCompat=\"@drawable/ic_info\" />\r\n\r\n                <TextView\r\n                    android:layout_width=\"wrap_content\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:text=\"¡Los anuncios a pantalla completa otorgan loli-coins!\" />\r\n            </LinearLayout>\r\n        </LinearLayout>\r\n    </androidx.core.widget.NestedScrollView>\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_anime_info.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    android:id=\"@+id/coordinator\"\n    android:fitsSystemWindows=\"true\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:id=\"@+id/appBar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\">\n\n        <com.google.android.material.appbar.CollapsingToolbarLayout\n            android:id=\"@+id/collapsingToolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"250dp\"\n            android:fitsSystemWindows=\"true\"\n            android:background=\"@color/colorPrimary\"\n            app:contentScrim=\"@color/colorPrimary\"\n            app:expandedTitleMarginBottom=\"?actionBarSize\"\n            app:expandedTitleMarginEnd=\"64dp\"\n            app:expandedTitleMarginStart=\"48dp\"\n            app:expandedTitleTextAppearance=\"@style/ExpandedTextWhite\"\n            app:layout_scrollFlags=\"scroll|exitUntilCollapsed\"\n            app:toolbarId=\"@id/toolbar\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:adjustViewBounds=\"true\"\n                android:clickable=\"true\"\n                android:fitsSystemWindows=\"true\"\n                android:foreground=\"?selectableItemBackground\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\"\n                app:layout_collapseMode=\"parallax\"/>\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:alpha=\"0.3\"\n                android:background=\"@android:color/black\"\n                android:fitsSystemWindows=\"true\"/>\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"120dp\"\n                android:layout_gravity=\"top\"\n                android:background=\"@drawable/shadow_gradient\"\n                android:fitsSystemWindows=\"true\" />\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                android:layout_gravity=\"top\"\n                android:layout_marginBottom=\"48dp\"\n                app:layout_collapseMode=\"pin\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n            <com.google.android.material.tabs.TabLayout\n                android:id=\"@+id/tabs\"\n                style=\"@style/Widget.MaterialComponents.TabLayout\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"bottom\"\n                android:background=\"@android:color/transparent\"\n                app:layout_scrollFlags=\"scroll|enterAlways\"\n                app:tabBackground=\"@android:color/transparent\"\n                app:tabIndicatorColor=\"?colorSecondary\"\n                app:tabMode=\"scrollable\">\n\n                <com.google.android.material.tabs.TabItem\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"INFO\" />\n\n                <com.google.android.material.tabs.TabItem\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"EPISODIOS\" />\n            </com.google.android.material.tabs.TabLayout>\n        </com.google.android.material.appbar.CollapsingToolbarLayout>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.viewpager.widget.ViewPager\n        android:id=\"@+id/pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\n\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\n        android:id=\"@+id/fab\"\n        style=\"@style/Widget.MaterialComponents.FloatingActionButton\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"16dp\"\n        android:visibility=\"visible\"\n        app:fabSize=\"normal\"\n        app:layout_anchor=\"@+id/appBar\"\n        app:layout_anchorGravity=\"bottom|end\"\n        tools:srcCompat=\"@drawable/heart_empty\"/>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_anime_info_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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:id=\"@+id/coordinator\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:id=\"@+id/appBar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\"\n        app:elevation=\"0dp\">\n\n        <com.google.android.material.appbar.CollapsingToolbarLayout\n            android:id=\"@+id/collapsingToolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"250dp\"\n            android:background=\"?colorSurface\"\n            android:fitsSystemWindows=\"true\"\n            app:contentScrim=\"?colorSurface\"\n            app:expandedTitleMarginBottom=\"?actionBarSize\"\n            app:expandedTitleMarginEnd=\"64dp\"\n            app:expandedTitleMarginStart=\"48dp\"\n            app:expandedTitleTextAppearance=\"@style/ExpandedTextWhite\"\n            app:layout_scrollFlags=\"scroll|exitUntilCollapsed\"\n            app:statusBarScrim=\"?colorSurface\"\n            app:toolbarId=\"@id/toolbar\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:adjustViewBounds=\"true\"\n                android:clickable=\"true\"\n                android:fitsSystemWindows=\"true\"\n                android:foreground=\"?selectableItemBackground\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\"\n                app:layout_collapseMode=\"parallax\"/>\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:alpha=\"0.3\"\n                android:background=\"@android:color/black\"\n                android:fitsSystemWindows=\"true\"/>\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"170dp\"\n                android:layout_gravity=\"top\"\n                android:background=\"@drawable/shadow_gradient\"\n                android:fitsSystemWindows=\"true\" />\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                android:layout_gravity=\"top\"\n                android:layout_marginBottom=\"48dp\"\n                app:layout_collapseMode=\"pin\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n            <com.google.android.material.tabs.TabLayout\n                android:id=\"@+id/tabs\"\n                style=\"@style/Widget.MaterialComponents.TabLayout\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"bottom\"\n                android:background=\"@android:color/transparent\"\n                app:layout_scrollFlags=\"scroll|enterAlways\"\n                app:tabBackground=\"@android:color/transparent\"\n                app:tabIndicator=\"@drawable/material_tab_indicator\"\n                app:tabIndicatorColor=\"?colorSecondary\"\n                app:tabMode=\"scrollable\">\n\n                <com.google.android.material.tabs.TabItem\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"INFO\" />\n\n                <com.google.android.material.tabs.TabItem\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"EPISODIOS\" />\n            </com.google.android.material.tabs.TabLayout>\n        </com.google.android.material.appbar.CollapsingToolbarLayout>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\"\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\">\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:background=\"@color/separator\"/>\n        <androidx.viewpager.widget.ViewPager\n            android:id=\"@+id/pager\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\n    </LinearLayout>\n\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\n        android:id=\"@+id/fab\"\n        style=\"@style/Widget.MaterialComponents.FloatingActionButton\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"16dp\"\n        android:visibility=\"visible\"\n        app:fabSize=\"normal\"\n        app:layout_anchor=\"@+id/appBar\"\n        app:layout_anchorGravity=\"bottom|end\"\n        tools:srcCompat=\"@drawable/heart_empty\"/>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_anime_info_nwv.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    android:id=\"@+id/coordinator\"\n    android:fitsSystemWindows=\"true\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:id=\"@+id/appBar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\">\n\n        <com.google.android.material.appbar.CollapsingToolbarLayout\n            android:id=\"@+id/collapsingToolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"250dp\"\n            android:fitsSystemWindows=\"true\"\n            android:background=\"@color/colorPrimary\"\n            app:contentScrim=\"@color/colorPrimary\"\n            app:expandedTitleMarginBottom=\"?actionBarSize\"\n            app:expandedTitleMarginEnd=\"64dp\"\n            app:expandedTitleMarginStart=\"48dp\"\n            app:expandedTitleTextAppearance=\"@style/ExpandedTextWhite\"\n            app:layout_scrollFlags=\"scroll|exitUntilCollapsed\"\n            app:toolbarId=\"@id/toolbar\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:adjustViewBounds=\"true\"\n                android:clickable=\"true\"\n                android:fitsSystemWindows=\"true\"\n                android:foreground=\"?selectableItemBackground\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\"\n                app:layout_collapseMode=\"parallax\"/>\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:alpha=\"0.3\"\n                android:background=\"@android:color/black\"\n                android:fitsSystemWindows=\"true\"/>\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"120dp\"\n                android:layout_gravity=\"top\"\n                android:background=\"@drawable/shadow_gradient\"\n                android:fitsSystemWindows=\"true\" />\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                android:layout_gravity=\"top\"\n                android:layout_marginBottom=\"48dp\"\n                app:layout_collapseMode=\"pin\"\n                android:background=\"@android:color/transparent\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n            <com.google.android.material.tabs.TabLayout\n                android:id=\"@+id/tabs\"\n                style=\"@style/Widget.MaterialComponents.TabLayout\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"bottom\"\n                android:background=\"@android:color/transparent\"\n                app:layout_scrollFlags=\"scroll|enterAlways\"\n                app:tabBackground=\"@android:color/transparent\"\n                app:tabMode=\"scrollable\">\n\n                <com.google.android.material.tabs.TabItem\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"INFO\"/>\n\n                <com.google.android.material.tabs.TabItem\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"EPISODIOS\"/>\n            </com.google.android.material.tabs.TabLayout>\n        </com.google.android.material.appbar.CollapsingToolbarLayout>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.viewpager.widget.ViewPager\n        android:id=\"@+id/pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\n\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\n        android:id=\"@+id/fab\"\n        style=\"@style/Widget.MaterialComponents.FloatingActionButton\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"16dp\"\n        android:visibility=\"visible\"\n        app:fabSize=\"normal\"\n        app:layout_anchor=\"@+id/appBar\"\n        app:layout_anchorGravity=\"bottom|end\"\n        tools:srcCompat=\"@drawable/heart_empty\"/>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_blank.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\">\r\n\r\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_browser.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:keepScreenOn=\"true\">\r\n\r\n    <com.google.android.material.progressindicator.CircularProgressIndicator\r\n        android:id=\"@+id/loading\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:indeterminate=\"true\"\r\n        android:layout_centerInParent=\"true\"/>\r\n\r\n    <WebView\r\n        android:id=\"@+id/webview\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"/>\r\n\r\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_ea.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:fitsSystemWindows=\"true\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\r\n\r\n        <androidx.appcompat.widget.Toolbar\r\n            android:id=\"@+id/toolbar\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"?actionBarSize\"\r\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <RelativeLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\">\r\n\r\n        <moe.feng.common.stepperview.VerticalStepperView\r\n            android:id=\"@+id/vertical_stepper_view\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"match_parent\"\r\n            app:step_activated_color=\"?colorAccent\"\r\n            app:step_enable_animation=\"true\"/>\r\n\r\n        <ProgressBar\r\n            android:id=\"@+id/progress\"\r\n            style=\"@android:style/Widget.Material.ProgressBar.Large\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_centerInParent=\"true\"/>\r\n\r\n        <RelativeLayout\r\n            android:id=\"@+id/block_view\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"match_parent\"\r\n            android:clickable=\"true\"\r\n            android:focusable=\"true\"\r\n            android:visibility=\"gone\">\r\n\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"match_parent\"\r\n                android:alpha=\".20\"\r\n                android:background=\"#000\"/>\r\n\r\n            <ProgressBar\r\n                style=\"@android:style/Widget.Material.ProgressBar.Large\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_centerInParent=\"true\"/>\r\n        </RelativeLayout>\r\n    </RelativeLayout>\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_eamap.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RelativeLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\">\r\n\r\n    <fragment\r\n        android:id=\"@+id/map\"\r\n        android:name=\"com.google.android.gms.maps.SupportMapFragment\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        tools:context=\".commons.EAMapActivity\"/>\r\n\r\n    <nl.dionsegijn.konfetti.KonfettiView\r\n        android:id=\"@+id/konfetti\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"/>\r\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_emision.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:backgroundTint=\"?colorSurface\"\n        android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n        <com.google.android.material.tabs.TabLayout\n            android:id=\"@+id/tabs\"\n            style=\"@style/Widget.MaterialComponents.TabLayout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"@android:color/transparent\"\n            app:tabBackground=\"@android:color/transparent\"\n            app:tabMode=\"scrollable\" />\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.viewpager.widget.ViewPager\n        android:id=\"@+id/pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_emision_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:backgroundTint=\"?colorSurface\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        app:elevation=\"0dp\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n            <com.google.android.material.tabs.TabLayout\n                android:id=\"@+id/tabs\"\n                style=\"@style/Widget.MaterialComponents.TabLayout\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"@android:color/transparent\"\n                app:tabBackground=\"@android:color/transparent\"\n                app:tabIndicator=\"@drawable/material_tab_indicator\"\n                app:tabMode=\"scrollable\" />\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"@dimen/separator_size\"\n                android:background=\"@color/separator\"/>\n        </LinearLayout>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.viewpager.widget.ViewPager\n        android:id=\"@+id/pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_explorer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:backgroundTint=\"?colorSurface\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n        <com.google.android.material.tabs.TabLayout\n            android:id=\"@+id/tabs\"\n            style=\"@style/Widget.MaterialComponents.TabLayout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"@android:color/transparent\"\n            app:tabBackground=\"@android:color/transparent\"\n            app:tabMode=\"auto\">\n\n            <com.google.android.material.tabs.TabItem\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"Archivos\" />\n\n            <com.google.android.material.tabs.TabItem\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"Descargas\" />\n        </com.google.android.material.tabs.TabLayout>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.viewpager.widget.ViewPager\n        android:id=\"@+id/pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_explorer_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:backgroundTint=\"?colorSurface\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\"\n        app:elevation=\"0dp\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n            <com.google.android.material.tabs.TabLayout\n                android:id=\"@+id/tabs\"\n                style=\"@style/Widget.MaterialComponents.TabLayout\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:background=\"@android:color/transparent\"\n                app:tabBackground=\"@android:color/transparent\"\n                app:tabIndicator=\"@drawable/material_tab_indicator\"\n                app:tabMode=\"auto\">\n\n                <com.google.android.material.tabs.TabItem\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"Archivos\" />\n\n                <com.google.android.material.tabs.TabItem\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"Descargas\" />\n            </com.google.android.material.tabs.TabLayout>\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"@dimen/separator_size\"\n                android:background=\"@color/separator\"/>\n        </LinearLayout>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.viewpager.widget.ViewPager\n        android:id=\"@+id/pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:fitsSystemWindows=\"true\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\r\n\r\n        <androidx.appcompat.widget.Toolbar\r\n            android:id=\"@+id/toolbar\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <FrameLayout\r\n        android:id=\"@+id/fragment_container\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"/>\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_fragment_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:fitsSystemWindows=\"true\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\r\n        app:elevation=\"0dp\">\r\n\r\n        <androidx.appcompat.widget.Toolbar\r\n            android:id=\"@+id/toolbar\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <View\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"@dimen/separator_size\"\r\n        android:background=\"@color/separator\" />\r\n\r\n    <FrameLayout\r\n        android:id=\"@+id/fragment_container\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"/>\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_login.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <View\n        android:id=\"@+id/colorChanger\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:background=\"@android:color/transparent\"\n        android:visibility=\"invisible\"/>\n\n    <com.google.android.material.card.MaterialCardView\n        style=\"@style/AppTheme.Cardview\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_marginStart=\"10dp\"\n        android:layout_marginEnd=\"10dp\"\n        android:animateLayoutChanges=\"true\"\n        android:clipToPadding=\"false\"\n        app:contentPadding=\"8dp\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:animateLayoutChanges=\"true\">\n\n            <include\n                android:id=\"@+id/lay_main\"\n                layout=\"@layout/activity_login_main\"/>\n\n            <include\n                android:id=\"@+id/lay_buttons\"\n                layout=\"@layout/activity_login_buttons\"/>\n\n            <include\n                android:id=\"@+id/lay_firestore\"\n                layout=\"@layout/activity_login_firestore\" />\n\n        </RelativeLayout>\n\n    </com.google.android.material.card.MaterialCardView>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_login_buttons.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/lay_buttons\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:animateLayoutChanges=\"true\"\n    android:orientation=\"vertical\"\n    android:visibility=\"visible\">\n\n    <knf.kuma.custom.SyncItemView\n        android:id=\"@+id/sync_favs\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:si_actionId=\"favs\"\n        app:si_showDivider=\"true\"\n        app:si_title=\"Favoritos\" />\n\n    <knf.kuma.custom.SyncItemView\n        android:id=\"@+id/sync_history\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:si_actionId=\"history\"\n        app:si_showDivider=\"true\"\n        app:si_title=\"Historial\"/>\n\n    <knf.kuma.custom.SyncItemView\n        android:id=\"@+id/sync_following\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:si_actionId=\"following\"\n        app:si_showDivider=\"true\"\n        app:si_title=\"Seguidos\"/>\n\n    <knf.kuma.custom.SyncItemView\n        android:id=\"@+id/sync_seen\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:visibility=\"gone\"\n        app:si_actionId=\"seen\"\n        app:si_hideBackup=\"true\"\n        app:si_showDivider=\"true\"\n        app:si_title=\"Vistos\" />\n\n    <knf.kuma.custom.SyncItemView\n        android:id=\"@+id/sync_seen_new\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:si_actionId=\"seencompact\"\n        app:si_showDivider=\"false\"\n        app:si_title=\"Vistos\" />\n\n    <com.google.android.material.button.MaterialButton\n        android:id=\"@+id/logOut\"\n        style=\"@style/Widget.MaterialComponents.Button\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"6dp\"\n        android:padding=\"20dp\"\n        android:text=\"Cerrar sesion\"\n        android:textColor=\"@android:color/primary_text_dark\"/>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_login_firestore.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    android:id=\"@+id/lay_firestore\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:animateLayoutChanges=\"true\"\n    android:orientation=\"vertical\"\n    android:visibility=\"visible\">\n\n    <knf.kuma.custom.SyncStaticItemView\n        android:id=\"@+id/staticSyncFavs\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:ssi_prefId=\"ls_favs\"\n        app:ssi_title=\"Favoritos\" />\n\n    <knf.kuma.custom.SyncStaticItemView\n        android:id=\"@+id/staticSyncSeen\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:ssi_prefId=\"ls_seen\"\n        app:ssi_title=\"Vistos\" />\n\n    <knf.kuma.custom.SyncStaticItemView\n        android:id=\"@+id/staticSyncAchievements\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:ssi_prefId=\"ls_achievements\"\n        app:ssi_title=\"Logros\" />\n\n    <knf.kuma.custom.SyncStaticItemView\n        android:id=\"@+id/staticSyncEA\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:ssi_prefId=\"ls_ea\"\n        app:ssi_title=\"Easter egg\" />\n\n    <knf.kuma.custom.SyncStaticItemView\n        android:id=\"@+id/staticSyncGenres\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:ssi_prefId=\"ls_genres\"\n        app:ssi_title=\"Datos de uso\" />\n\n    <knf.kuma.custom.SyncStaticItemView\n        android:id=\"@+id/staticSyncHistory\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:ssi_prefId=\"ls_history\"\n        app:ssi_title=\"Historial\" />\n\n    <knf.kuma.custom.SyncStaticItemView\n        android:id=\"@+id/staticSyncQueue\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:ssi_prefId=\"ls_queue\"\n        app:ssi_title=\"Pendientes\" />\n\n    <knf.kuma.custom.SyncStaticItemView\n        android:id=\"@+id/staticSyncSeeing\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:ssi_prefId=\"ls_seeing\"\n        app:ssi_showDivider=\"false\"\n        app:ssi_title=\"Seguidos\" />\n\n    <com.google.android.material.button.MaterialButton\n        android:id=\"@+id/logOutFirestore\"\n        style=\"@style/Widget.MaterialComponents.Button\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"6dp\"\n        android:padding=\"20dp\"\n        android:text=\"Cerrar sesion\"\n        android:textColor=\"@android:color/primary_text_dark\" />\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_login_main.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:id=\"@+id/lay_main\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:animateLayoutChanges=\"true\"\n    android:orientation=\"vertical\"\n    android:visibility=\"gone\"\n    tools:visibility=\"visible\">\n\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center_horizontal\"\n        android:text=\"Iniciar sesión\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Large\" />\n\n    <com.google.android.material.button.MaterialButton\n        android:id=\"@+id/login_dropbox\"\n        style=\"@style/Widget.MaterialComponents.Button.Icon\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:backgroundTint=\"@color/dropbox\"\n        android:padding=\"20dp\"\n        android:text=\"Dropbox\"\n        android:textColor=\"#fff\"\n        android:theme=\"@style/AppTheme.Button.Dropbox\"\n        app:icon=\"@drawable/ic_dropbox\"\n        app:iconTint=\"#fff\" />\n\n    <com.google.android.material.button.MaterialButton\n        android:id=\"@+id/login_firestore\"\n        style=\"@style/Widget.MaterialComponents.Button.Icon\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:padding=\"20dp\"\n        android:text=\"Firestore\"\n        android:textColor=\"@color/raised_button_text_state\"\n        app:backgroundTint=\"@color/firebase_selector\"\n        app:icon=\"@drawable/ic_cloud_firestore\"\n        app:iconTint=\"@color/raised_button_text_state\" />\n\n    <TextView\n        android:id=\"@+id/ads_required\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center\"\n        android:text=\"Requiere anuncios\"\n        android:textColor=\"?colorSecondary\"\n        android:textSize=\"12sp\"\n        android:visibility=\"gone\"\n        tools:visibility=\"visible\" />\n\n    <com.google.android.material.button.MaterialButton\n        android:id=\"@+id/login_local\"\n        style=\"@style/Widget.MaterialComponents.Button.Icon\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:backgroundTint=\"?colorAccentLight\"\n        android:padding=\"20dp\"\n        android:text=\"Local\"\n        android:textColor=\"#fff\"\n        android:theme=\"@style/AppTheme.Button.Local\"\n        app:icon=\"@drawable/ic_save_w\"\n        app:iconTint=\"#fff\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_main_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.drawerlayout.widget.DrawerLayout\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:id=\"@+id/drawer_layout\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\"\n    tools:openDrawer=\"start\">\n\n    <include\n        layout=\"@layout/app_bar_main\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n    <com.google.android.material.navigation.NavigationView\n        android:id=\"@+id/nav_view\"\n        style=\"@style/Widget.MaterialComponents.NavigationView\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:layout_gravity=\"start\"\n        android:fitsSystemWindows=\"true\"\n        app:headerLayout=\"@layout/nav_header_main\"\n        app:menu=\"@menu/activity_main_drawer_drawer\"/>\n\n</androidx.drawerlayout.widget.DrawerLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_main_drawer_nwv.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.drawerlayout.widget.DrawerLayout\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:id=\"@+id/drawer_layout\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:fitsSystemWindows=\"true\"\n    tools:openDrawer=\"start\">\n\n    <include\n        layout=\"@layout/app_bar_main_nwv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\" />\n\n    <com.google.android.material.navigation.NavigationView\n        android:id=\"@+id/nav_view\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:layout_gravity=\"start\"\n        android:fitsSystemWindows=\"true\"\n        app:headerLayout=\"@layout/nav_header_main\"\n        app:menu=\"@menu/activity_main_drawer_drawer\"/>\n\n</androidx.drawerlayout.widget.DrawerLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_main_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.drawerlayout.widget.DrawerLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:id=\"@+id/drawer_layout\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:fitsSystemWindows=\"true\"\r\n    tools:openDrawer=\"start\">\r\n\r\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\r\n        android:id=\"@+id/coordinator\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:background=\"?colorSurface\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"match_parent\"\r\n            android:orientation=\"vertical\">\r\n\r\n            <com.google.android.material.appbar.AppBarLayout\r\n                android:id=\"@+id/appbar\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:background=\"?colorSurface\"\r\n                android:clipToPadding=\"false\"\r\n                android:theme=\"@style/AppTheme.AppBarOverlay\"\r\n                app:elevation=\"0dp\">\r\n\r\n                <com.google.android.material.card.MaterialCardView\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginStart=\"16dp\"\r\n                    android:layout_marginTop=\"4dp\"\r\n                    android:layout_marginEnd=\"16dp\"\r\n                    android:layout_marginBottom=\"16dp\"\r\n                    app:cardCornerRadius=\"8dp\"\r\n                    app:cardElevation=\"4dp\">\r\n\r\n                    <androidx.appcompat.widget.Toolbar\r\n                        android:id=\"@+id/toolbar\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"48dp\"\r\n                        android:clickable=\"true\"\r\n                        android:focusable=\"true\"\r\n                        app:contentInsetStartWithNavigation=\"0dp\"\r\n                        app:navigationIcon=\"@drawable/ic_menu_ham\"\r\n                        app:popupTheme=\"@style/AppTheme.PopupOverlay\"\r\n                        app:titleTextAppearance=\"@style/titleTextAppearance\"\r\n                        app:titleTextColor=\"@color/textSecondaryTitle\" />\r\n                </com.google.android.material.card.MaterialCardView>\r\n            </com.google.android.material.appbar.AppBarLayout>\r\n\r\n            <FrameLayout\r\n                android:id=\"@+id/root\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"0dp\"\r\n                android:layout_weight=\"1\"\r\n                app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\r\n\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:background=\"@color/separator\" />\r\n\r\n            <knf.kuma.custom.ConnectionState\r\n                android:id=\"@+id/connectionState\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:visibility=\"gone\"\r\n                app:cs_bg_color=\"?colorSurface\"/>\r\n\r\n            <com.google.android.material.bottomnavigation.BottomNavigationView\r\n                android:id=\"@+id/bottomNavigation\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:elevation=\"0dp\"\r\n                app:menu=\"@menu/bottom_menu\" />\r\n\r\n        </LinearLayout>\r\n\r\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\r\n\r\n    <com.google.android.material.navigation.NavigationView\r\n        android:id=\"@+id/nav_view\"\r\n        style=\"@style/Widget.MaterialComponents.NavigationView\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"match_parent\"\r\n        android:layout_gravity=\"start\"\r\n        android:fitsSystemWindows=\"true\"\r\n        app:headerLayout=\"@layout/nav_header_main_material\"\r\n        app:menu=\"@menu/activity_main_drawer_drawer\"/>\r\n\r\n</androidx.drawerlayout.widget.DrawerLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_migrate.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@android:color/holo_orange_dark\">\n\n    <FrameLayout\n        android:id=\"@+id/root\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_news.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_height=\"match_parent\"\r\n    android:layout_width=\"match_parent\"\r\n    android:background=\"?colorSurface\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\r\n        android:fitsSystemWindows=\"true\"\r\n        app:elevation=\"0dp\">\r\n\r\n        <androidx.appcompat.widget.Toolbar\r\n            android:id=\"@+id/toolbar\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:layout_scrollFlags=\"scroll|enterAlways\"\r\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <RelativeLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\">\r\n\r\n        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout\r\n            android:id=\"@+id/refresh\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"match_parent\">\r\n\r\n            <androidx.recyclerview.widget.RecyclerView\r\n                android:id=\"@+id/recycler\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layoutAnimation=\"@anim/layout_fall_down\"\r\n                android:clipToPadding=\"false\"\r\n                android:paddingTop=\"16dp\"\r\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\r\n                app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\r\n                tools:listitem=\"@layout/item_news_material\" />\r\n        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>\r\n\r\n        <LinearLayout\r\n            android:id=\"@+id/error\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_centerInParent=\"true\"\r\n            android:orientation=\"vertical\"\r\n            android:visibility=\"gone\"\r\n            tools:visibility=\"visible\">\r\n\r\n            <ImageView\r\n                android:layout_width=\"150dp\"\r\n                android:layout_height=\"150dp\"\r\n                android:layout_gravity=\"center_horizontal\"\r\n                android:adjustViewBounds=\"false\"\r\n                android:tint=\"?android:textColorSecondary\"\r\n                app:srcCompat=\"@drawable/ic_news\"/>\r\n\r\n            <TextView\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_gravity=\"center_horizontal\"\r\n                android:text=\"No hay noticias\"\r\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\r\n                android:textColor=\"?android:textColorSecondary\"\r\n                android:textSize=\"22sp\" />\r\n        </LinearLayout>\r\n    </RelativeLayout>\r\n\r\n    <knf.kuma.custom.BannerContainerView\r\n        android:id=\"@+id/adContainer\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_gravity=\"bottom\"\r\n        app:showBottomSpace=\"true\" />\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_news_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:background=\"?colorSurface\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:fitsSystemWindows=\"true\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\r\n        app:elevation=\"0dp\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:orientation=\"vertical\">\r\n            <androidx.appcompat.widget.Toolbar\r\n                android:id=\"@+id/toolbar\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:layout_scrollFlags=\"scroll|enterAlways\"\r\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:background=\"@color/separator\"/>\r\n        </LinearLayout>\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <RelativeLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\">\r\n\r\n        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout\r\n            android:id=\"@+id/refresh\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"match_parent\">\r\n\r\n            <androidx.recyclerview.widget.RecyclerView\r\n                android:id=\"@+id/recycler\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:clipToPadding=\"false\"\r\n                android:layoutAnimation=\"@anim/layout_fall_down\"\r\n                android:paddingTop=\"16dp\"\r\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\r\n                app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\r\n                tools:listitem=\"@layout/item_news_material\" />\r\n        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>\r\n\r\n        <LinearLayout\r\n            android:id=\"@+id/error\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_centerInParent=\"true\"\r\n            android:orientation=\"vertical\"\r\n            android:visibility=\"gone\"\r\n            tools:visibility=\"visible\">\r\n\r\n            <ImageView\r\n                android:layout_width=\"150dp\"\r\n                android:layout_height=\"150dp\"\r\n                android:layout_gravity=\"center_horizontal\"\r\n                android:adjustViewBounds=\"false\"\r\n                android:tint=\"?android:textColorSecondary\"\r\n                app:srcCompat=\"@drawable/ic_news\"/>\r\n\r\n            <TextView\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_gravity=\"center_horizontal\"\r\n                android:text=\"No hay noticias\"\r\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\r\n                android:textColor=\"?android:textColorSecondary\"\r\n                android:textSize=\"22sp\" />\r\n        </LinearLayout>\r\n    </RelativeLayout>\r\n\r\n    <knf.kuma.custom.BannerContainerView\r\n        android:id=\"@+id/adContainer\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_gravity=\"bottom\"\r\n        app:showBottomSpace=\"true\" />\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_queue.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?android:actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <knf.kuma.custom.GridRecyclerView\n                android:id=\"@+id/recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"0dp\"\n                android:layout_weight=\"1\"\n                android:clipToPadding=\"false\"\n                android:layoutAnimation=\"@anim/layout_fall_down\"\n                android:paddingStart=\"10dp\"\n                android:paddingTop=\"10dp\"\n                android:paddingEnd=\"10dp\"\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\n                app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n                tools:listitem=\"@layout/item_fav\" />\n\n            <knf.kuma.custom.BannerContainerView\n                android:id=\"@+id/adContainer\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                app:showBottomSpace=\"true\" />\n        </LinearLayout>\n\n        <LinearLayout\n            android:id=\"@+id/error\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"\n            android:orientation=\"vertical\"\n            android:visibility=\"gone\">\n\n            <ImageView\n                android:layout_width=\"200dp\"\n                android:layout_height=\"200dp\"\n                android:layout_gravity=\"center_horizontal\"\n                android:adjustViewBounds=\"false\"\n                app:srcCompat=\"@drawable/ic_no_recents\"/>\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center_horizontal\"\n                android:text=\"No hay episodios pendientes\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textColor=\"?android:textColorSecondary\"\n                android:textSize=\"24sp\"/>\n        </LinearLayout>\n    </RelativeLayout>\n\n    <com.google.android.material.card.MaterialCardView\n        android:id=\"@+id/bottom_card\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"350dp\"\n        android:theme=\"@style/AppTheme.Cardview\"\n        app:behavior_hideable=\"true\"\n        app:behavior_peekHeight=\"auto\"\n        app:behavior_skipCollapsed=\"true\"\n        app:cardCornerRadius=\"0dp\"\n        app:cardElevation=\"16dp\"\n        app:layout_behavior=\"@string/bottom_sheet_behavior\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/list_toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                android:background=\"?colorAccent\"\n                android:tag=\":aesthetic_ignore\"\n                android:theme=\"@style/ThemeOverlay.MaterialComponents.Dark\"\n                app:title=\"Title\"\n                app:titleTextAppearance=\"@style/TextAppearance.AppCompat.Subhead\"/>\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/list_recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\n                tools:listitem=\"@layout/item_queue\"/>\n        </LinearLayout>\n    </com.google.android.material.card.MaterialCardView>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_queue_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?android:actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <knf.kuma.custom.GridRecyclerView\n                android:id=\"@+id/recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"0dp\"\n                android:layout_weight=\"1\"\n                android:clipToPadding=\"false\"\n                android:layoutAnimation=\"@anim/grid_fall_down\"\n                android:padding=\"5dp\"\n                app:layoutManager=\".custom.VariantGridLayoutManager\"\n                app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n                app:spanCount=\"@integer/span_count\"\n                tools:listitem=\"@layout/item_fav_grid\" />\n\n            <knf.kuma.custom.BannerContainerView\n                android:id=\"@+id/adContainer\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                app:showBottomSpace=\"true\" />\n        </LinearLayout>\n\n        <LinearLayout\n            android:id=\"@+id/error\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"\n            android:orientation=\"vertical\"\n            android:visibility=\"gone\">\n\n            <ImageView\n                android:layout_width=\"200dp\"\n                android:layout_height=\"200dp\"\n                android:layout_gravity=\"center_horizontal\"\n                android:adjustViewBounds=\"false\"\n                app:srcCompat=\"@drawable/ic_no_recents\"/>\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center_horizontal\"\n                android:text=\"No hay episodios pendientes\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textColor=\"?android:textColorSecondary\"\n                android:textSize=\"24sp\"/>\n        </LinearLayout>\n    </RelativeLayout>\n\n    <com.google.android.material.card.MaterialCardView\n        android:id=\"@+id/bottom_card\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"350dp\"\n        android:theme=\"@style/AppTheme.Cardview\"\n        app:behavior_hideable=\"true\"\n        app:behavior_peekHeight=\"auto\"\n        app:behavior_skipCollapsed=\"true\"\n        app:cardCornerRadius=\"0dp\"\n        app:cardElevation=\"16dp\"\n        app:layout_behavior=\"@string/bottom_sheet_behavior\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/list_toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                android:background=\"?colorAccent\"\n                android:tag=\":aesthetic_ignore\"\n                android:theme=\"@style/ThemeOverlay.MaterialComponents.Dark\"\n                app:title=\"Title\"\n                app:titleTextAppearance=\"@style/TextAppearance.AppCompat.Subhead\"/>\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/list_recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\n                tools:listitem=\"@layout/item_queue\"/>\n        </LinearLayout>\n    </com.google.android.material.card.MaterialCardView>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_queue_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        app:elevation=\"0dp\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?android:actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"@dimen/separator_size\"\n                android:background=\"@color/separator\"/>\n        </LinearLayout>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <knf.kuma.custom.GridRecyclerView\n                android:id=\"@+id/recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"0dp\"\n                android:layout_weight=\"1\"\n                android:clipToPadding=\"false\"\n                android:layoutAnimation=\"@anim/grid_fall_down\"\n                android:padding=\"5dp\"\n                app:layoutManager=\".custom.VariantGridLayoutManager\"\n                app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n                app:spanCount=\"@integer/span_count\"\n                tools:listitem=\"@layout/item_fav_grid\" />\n\n            <knf.kuma.custom.BannerContainerView\n                android:id=\"@+id/adContainer\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                app:showBottomSpace=\"true\" />\n        </LinearLayout>\n\n        <LinearLayout\n            android:id=\"@+id/error\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"\n            android:orientation=\"vertical\"\n            android:visibility=\"gone\">\n\n            <ImageView\n                android:layout_width=\"200dp\"\n                android:layout_height=\"200dp\"\n                android:layout_gravity=\"center_horizontal\"\n                android:adjustViewBounds=\"false\"\n                app:srcCompat=\"@drawable/ic_no_recents\"/>\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center_horizontal\"\n                android:text=\"No hay episodios pendientes\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textColor=\"?android:textColorSecondary\"\n                android:textSize=\"24sp\"/>\n        </LinearLayout>\n    </RelativeLayout>\n\n    <com.google.android.material.card.MaterialCardView\n        android:id=\"@+id/bottom_card\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"350dp\"\n        android:theme=\"@style/AppTheme.Cardview\"\n        app:behavior_hideable=\"true\"\n        app:behavior_peekHeight=\"auto\"\n        app:behavior_skipCollapsed=\"true\"\n        app:cardCornerRadius=\"0dp\"\n        app:cardElevation=\"16dp\"\n        app:layout_behavior=\"@string/bottom_sheet_behavior\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/list_toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                android:background=\"?colorAccent\"\n                android:tag=\":aesthetic_ignore\"\n                android:theme=\"@style/ThemeOverlay.MaterialComponents.Dark\"\n                app:title=\"Title\"\n                app:titleTextAppearance=\"@style/TextAppearance.AppCompat.Subhead\"/>\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/list_recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\n                tools:listitem=\"@layout/item_queue\"/>\n        </LinearLayout>\n    </com.google.android.material.card.MaterialCardView>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_queue_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        app:elevation=\"0dp\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?android:actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"@dimen/separator_size\"\n                android:background=\"@color/separator\"/>\n        </LinearLayout>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <knf.kuma.custom.GridRecyclerView\n                android:id=\"@+id/recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"0dp\"\n                android:layout_weight=\"1\"\n                android:clipToPadding=\"false\"\n                android:layoutAnimation=\"@anim/layout_fall_down\"\n                android:paddingStart=\"10dp\"\n                android:paddingTop=\"10dp\"\n                android:paddingEnd=\"10dp\"\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\n                app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n                tools:listitem=\"@layout/item_fav\" />\n\n            <knf.kuma.custom.BannerContainerView\n                android:id=\"@+id/adContainer\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                app:showBottomSpace=\"true\" />\n        </LinearLayout>\n\n        <LinearLayout\n            android:id=\"@+id/error\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"\n            android:orientation=\"vertical\"\n            android:visibility=\"gone\">\n\n            <ImageView\n                android:layout_width=\"200dp\"\n                android:layout_height=\"200dp\"\n                android:layout_gravity=\"center_horizontal\"\n                android:adjustViewBounds=\"false\"\n                app:srcCompat=\"@drawable/ic_no_recents\"/>\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center_horizontal\"\n                android:text=\"No hay episodios pendientes\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textColor=\"?android:textColorSecondary\"\n                android:textSize=\"24sp\"/>\n        </LinearLayout>\n    </RelativeLayout>\n\n    <com.google.android.material.card.MaterialCardView\n        android:id=\"@+id/bottom_card\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"350dp\"\n        android:theme=\"@style/AppTheme.Cardview\"\n        app:behavior_hideable=\"true\"\n        app:behavior_peekHeight=\"auto\"\n        app:behavior_skipCollapsed=\"true\"\n        app:cardCornerRadius=\"0dp\"\n        app:cardElevation=\"16dp\"\n        app:layout_behavior=\"@string/bottom_sheet_behavior\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/list_toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                android:background=\"?colorAccent\"\n                android:tag=\":aesthetic_ignore\"\n                android:theme=\"@style/ThemeOverlay.MaterialComponents.Dark\"\n                app:title=\"Title\"\n                app:titleTextAppearance=\"@style/TextAppearance.AppCompat.Subhead\"/>\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/list_recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\n                tools:listitem=\"@layout/item_queue\"/>\n        </LinearLayout>\n    </com.google.android.material.card.MaterialCardView>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_search.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:fitsSystemWindows=\"true\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\r\n        app:elevation=\"0dp\">\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:orientation=\"vertical\">\r\n\r\n            <androidx.appcompat.widget.Toolbar\r\n                android:id=\"@+id/toolbar\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"?attr/actionBarSize\"\r\n                app:contentInsetStart=\"24dp\">\r\n\r\n                <androidx.appcompat.widget.AppCompatEditText\r\n                    android:id=\"@+id/etSearch\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"match_parent\"\r\n                    android:background=\"@null\"\r\n                    android:hint=\"Buscar animes\"\r\n                    android:lines=\"1\"\r\n                    android:maxLines=\"1\"\r\n                    android:singleLine=\"true\" />\r\n            </androidx.appcompat.widget.Toolbar>\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:background=\"@color/separator\"/>\r\n        </LinearLayout>\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <androidx.fragment.app.FragmentContainerView\r\n        android:id=\"@+id/frame\"\r\n        android:name=\"knf.kuma.search.SearchFragmentMaterial\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\"/>\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_seening.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:backgroundTint=\"?colorSurface\"\n        android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n        <com.google.android.material.tabs.TabLayout\n            android:id=\"@+id/tabs\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"@android:color/transparent\"\n            app:tabBackground=\"@android:color/transparent\"\n            style=\"@style/Widget.MaterialComponents.TabLayout\"\n            app:tabMode=\"scrollable\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.viewpager.widget.ViewPager\n        android:id=\"@+id/pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_seening_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:backgroundTint=\"?colorSurface\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        app:elevation=\"0dp\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n        <com.google.android.material.tabs.TabLayout\n            android:id=\"@+id/tabs\"\n            style=\"@style/Widget.MaterialComponents.TabLayout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"@android:color/transparent\"\n            app:tabBackground=\"@android:color/transparent\"\n            app:tabIndicator=\"@drawable/material_tab_indicator\"\n            app:tabMode=\"scrollable\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/separator_size\"\n        android:background=\"@color/separator\"/>\n\n    <androidx.viewpager.widget.ViewPager\n        android:id=\"@+id/pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_updater.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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:id=\"@+id/rel_back\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@drawable/updater_background\"\n    android:fitsSystemWindows=\"true\">\n\n    <com.google.android.material.card.MaterialCardView\n        android:id=\"@+id/card\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_marginStart=\"@dimen/margin_login_card\"\n        android:layout_marginEnd=\"@dimen/margin_login_card\"\n        app:cardElevation=\"8dp\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_margin=\"8dp\"\n                android:gravity=\"center_horizontal\"\n                android:text=\"Descargando actualización\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textSize=\"18sp\" />\n\n            <ProgressBar\n                android:id=\"@+id/progress\"\n                style=\"@style/Widget.AppCompat.ProgressBar.Horizontal\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_margin=\"8dp\" />\n\n            <RelativeLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <TextView\n                    android:id=\"@+id/progress_text\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_centerVertical=\"true\"\n                    android:layout_marginStart=\"8dp\"\n                    android:layout_marginEnd=\"8dp\"\n                    android:layout_marginBottom=\"8dp\"\n                    android:text=\"0%\"\n                    android:textAlignment=\"center\"\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n                    android:textSize=\"20sp\" />\n\n                <com.google.android.material.button.MaterialButton\n                    android:id=\"@+id/download\"\n                    style=\"@style/Widget.MaterialComponents.Button.TextButton\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"INSTALAR\"\n                    android:textColor=\"?colorSecondary\"\n                    android:visibility=\"invisible\"\n                    tools:visibility=\"visible\" />\n\n                <com.google.android.material.button.MaterialButton\n                    android:id=\"@+id/retry\"\n                    style=\"@style/Widget.MaterialComponents.Button.TextButton\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"REINTENTAR\"\n                    android:textColor=\"?colorSecondary\"\n                    android:visibility=\"invisible\"\n                    tools:visibility=\"visible\" />\n            </RelativeLayout>\n        </LinearLayout>\n    </com.google.android.material.card.MaterialCardView>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_webview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:id=\"@+id/coordinator\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\">\r\n\r\n    <knf.kuma.custom.WrapWebView\r\n        android:id=\"@+id/webview\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"/>\r\n\r\n    <View\r\n        android:id=\"@+id/overlay\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:alpha=\"0.4\"\r\n        android:background=\"#000\"\r\n        android:visibility=\"gone\"/>\r\n\r\n    <TextView\r\n        android:id=\"@+id/logText\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:gravity=\"bottom\"\r\n        android:lineSpacingExtra=\"8sp\"\r\n        android:padding=\"16dp\"\r\n        android:scrollbars=\"vertical\"\r\n        android:textColor=\"#fff\"\r\n        android:textSize=\"16sp\"\r\n        android:visibility=\"gone\"/>\r\n\r\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\r\n        android:id=\"@+id/fab\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_gravity=\"bottom|end\"\r\n        android:layout_margin=\"16dp\"\r\n        android:src=\"@drawable/ic_terminal\"/>\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_webview_nwv.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:id=\"@+id/coordinator\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\">\r\n\r\n    <LinearLayout\r\n        android:id=\"@+id/error\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_centerInParent=\"true\"\r\n        android:layout_gravity=\"center\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <ImageView\r\n            android:layout_width=\"200dp\"\r\n            android:layout_height=\"200dp\"\r\n            android:layout_gravity=\"center_horizontal\"\r\n            android:adjustViewBounds=\"false\"\r\n            android:tint=\"?android:textColorSecondary\"\r\n            app:srcCompat=\"@drawable/ic_hide_pref\"/>\r\n\r\n        <TextView\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_gravity=\"center_horizontal\"\r\n            android:layout_marginStart=\"25dp\"\r\n            android:layout_marginEnd=\"25dp\"\r\n            android:gravity=\"center\"\r\n            android:text=\"WebView no disponible, intentando en segundo plano\"\r\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\r\n            android:textColor=\"?android:textColorSecondary\"\r\n            android:textSize=\"22sp\"/>\r\n    </LinearLayout>\r\n\r\n    <View\r\n        android:id=\"@+id/overlay\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:alpha=\"0.4\"\r\n        android:background=\"#000\"\r\n        android:visibility=\"gone\"/>\r\n\r\n    <TextView\r\n        android:id=\"@+id/logText\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:gravity=\"bottom\"\r\n        android:lineSpacingExtra=\"8sp\"\r\n        android:padding=\"16dp\"\r\n        android:scrollbars=\"vertical\"\r\n        android:textColor=\"#fff\"\r\n        android:textSize=\"16sp\"\r\n        android:visibility=\"gone\"/>\r\n\r\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\r\n        android:id=\"@+id/fab\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_gravity=\"bottom|end\"\r\n        android:layout_margin=\"16dp\"\r\n        android:src=\"@drawable/ic_terminal\"/>\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/admob_ad_alone.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<knf.kuma.widgets.AdTemplateView xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:id=\"@+id/admobAd\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\" />\r\n"
  },
  {
    "path": "app/src/main/res/layout/admob_ad_card.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<com.google.android.material.card.MaterialCardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:id=\"@+id/card\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:layout_marginStart=\"10dp\"\r\n    android:layout_marginTop=\"10dp\"\r\n    android:layout_marginEnd=\"10dp\"\r\n    android:clickable=\"true\"\r\n    android:focusable=\"true\"\r\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\r\n    android:theme=\"@style/AppTheme.Cardview\"\r\n    app:cardCornerRadius=\"2dp\"\r\n    app:cardElevation=\"2dp\">\r\n\r\n    <knf.kuma.widgets.AdTemplateView\r\n        android:id=\"@+id/admobAd\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\" />\r\n\r\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/admob_ad_news.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<com.google.android.material.card.MaterialCardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:id=\"@+id/card\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:layout_marginStart=\"8dp\"\r\n    android:layout_marginEnd=\"8dp\"\r\n    android:foreground=\"?selectableItemBackground\"\r\n    android:transitionName=\"background\"\r\n    app:cardCornerRadius=\"2dp\"\r\n    app:cardElevation=\"2dp\"\r\n    app:contentPadding=\"8dp\">\r\n\r\n    <knf.kuma.widgets.AdTemplateView\r\n        android:id=\"@+id/admobAd\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\" />\r\n\r\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/admob_ad_plain.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<knf.kuma.widgets.AdTemplateView xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:id=\"@+id/admobAd\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    app:at_layout=\"@layout/item_native_reduced\"\r\n    tools:visibility=\"visible\" />"
  },
  {
    "path": "app/src/main/res/layout/app_bar_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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    android:orientation=\"vertical\"\n    android:background=\"?android:windowBackground\"\n    android:animateLayoutChanges=\"true\"\n    tools:activity=\"knf.kuma.Main\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:id=\"@+id/coordinator\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:id=\"@+id/appBar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <org.cryse.widget.persistentsearch.PersistentSearchView\n            android:id=\"@+id/searchview\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\"\n            android:elevation=\"8dp\"\n            android:tag=\":aesthetic_ignore\"\n            android:visibility=\"gone\"\n            app:layout_anchor=\"@+id/appBar\"\n            app:layout_anchorGravity=\"center\"\n            app:persistentSV_displayMode=\"menuItem\"\n            app:persistentSV_editHintText=\"Buscar\"\n            app:persistentSV_editHintTextColor=\"@android:color/darker_gray\"\n            app:persistentSV_editTextColor=\"@android:color/black\"\n            app:persistentSV_homeButtonMode=\"arrow\"\n            app:persistentSV_searchCardElevation=\"2dp\"\n            app:persistentSV_searchTextColor=\"@android:color/black\"/>\n\n        <FrameLayout\n            android:id=\"@+id/root\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_weight=\"1\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n    <knf.kuma.custom.ConnectionState\n        android:id=\"@+id/connectionState\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:visibility=\"gone\"/>\n\n    <com.google.android.material.bottomnavigation.BottomNavigationView\n        android:id=\"@+id/bottomNavigation\"\n        style=\"@style/Widget.MaterialComponents.BottomNavigationView\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:itemIconTint=\"@drawable/bottom_state\"\n        app:itemTextColor=\"@drawable/bottom_state\"\n        app:menu=\"@menu/bottom_menu\"/>\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/app_bar_main_nwv.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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    android:orientation=\"vertical\"\n    android:animateLayoutChanges=\"true\"\n    tools:activity=\"knf.kuma.Main\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:id=\"@+id/coordinator\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:id=\"@+id/appBar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <org.cryse.widget.persistentsearch.PersistentSearchView\n            android:id=\"@+id/searchview\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\"\n            android:elevation=\"8dp\"\n            android:tag=\":aesthetic_ignore\"\n            android:visibility=\"gone\"\n            app:layout_anchor=\"@+id/appBar\"\n            app:layout_anchorGravity=\"center\"\n            app:persistentSV_displayMode=\"menuItem\"\n            app:persistentSV_editHintText=\"Buscar\"\n            app:persistentSV_editHintTextColor=\"@android:color/darker_gray\"\n            app:persistentSV_editTextColor=\"@android:color/black\"\n            app:persistentSV_homeButtonMode=\"arrow\"\n            app:persistentSV_searchCardElevation=\"2dp\"\n            app:persistentSV_searchTextColor=\"@android:color/black\"/>\n\n        <FrameLayout\n            android:id=\"@+id/root\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_weight=\"1\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"/>\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n    <knf.kuma.custom.ConnectionState\n        android:id=\"@+id/connectionState\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:visibility=\"gone\"/>\n\n    <com.google.android.material.bottomnavigation.BottomNavigationView\n        android:id=\"@+id/bottomNavigation\"\n        style=\"@style/Widget.MaterialComponents.BottomNavigationView\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:itemIconTint=\"@drawable/bottom_state\"\n        app:itemTextColor=\"@drawable/bottom_state\"\n        app:menu=\"@menu/bottom_menu\"/>\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/dialog_ff_enable.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:clipToPadding=\"false\"\r\n    android:orientation=\"vertical\"\r\n    android:padding=\"8dp\">\r\n\r\n    <com.google.android.material.textfield.TextInputLayout\r\n        style=\"@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginBottom=\"4dp\"\r\n        android:hint=\"Contraseña\">\r\n\r\n        <com.google.android.material.textfield.TextInputEditText\r\n            style=\"@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:hint=\"Contraseña\"\r\n            android:inputType=\"textPassword\" />\r\n    </com.google.android.material.textfield.TextInputLayout>\r\n\r\n    <com.google.android.material.textfield.TextInputLayout\r\n        style=\"@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginTop=\"4dp\"\r\n        android:layout_marginBottom=\"4dp\"\r\n        android:hint=\"Repetir contraseña\">\r\n\r\n        <com.google.android.material.textfield.TextInputEditText\r\n            style=\"@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:hint=\"Repetir contraseña\"\r\n            android:inputType=\"textPassword\" />\r\n    </com.google.android.material.textfield.TextInputLayout>\r\n\r\n    <com.google.android.material.textfield.TextInputLayout\r\n        style=\"@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginTop=\"4dp\"\r\n        android:hint=\"Correo de recuperación\">\r\n\r\n        <com.google.android.material.textfield.TextInputEditText\r\n            style=\"@style/Widget.MaterialComponents.TextInputEditText.OutlinedBox\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:hint=\"Correo de recuperación\"\r\n            android:inputType=\"textEmailAddress\" />\r\n    </com.google.android.material.textfield.TextInputLayout>\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/dialog_random_picker.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"180dp\"\r\n    android:orientation=\"vertical\">\r\n\r\n\r\n    <biz.kasual.materialnumberpicker.MaterialNumberPicker\r\n        android:id=\"@+id/picker\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"164dp\"\r\n        android:layout_marginTop=\"8dp\"\r\n        android:layout_marginBottom=\"8dp\"\r\n        android:minHeight=\"164dp\"\r\n        app:npBackgroundColor=\"@android:color/transparent\"\r\n        app:npMaxValue=\"100\"\r\n        app:npMinValue=\"5\"\r\n        app:npTextColor=\"@color/textPrimary\"\r\n        app:npTextSize=\"18sp\" />\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/dialog_wallet.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <RelativeLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"80dp\">\r\n\r\n        <View\r\n            android:id=\"@+id/backgroundTop\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"80dp\"\r\n            android:background=\"?colorSecondaryVariant\" />\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_centerInParent=\"true\"\r\n            android:orientation=\"horizontal\">\r\n\r\n            <ImageView\r\n                android:layout_width=\"36dp\"\r\n                android:layout_height=\"36dp\"\r\n                android:tint=\"#FFFFFF\"\r\n                app:srcCompat=\"@drawable/ic_coin_ach\" />\r\n\r\n            <TextView\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_gravity=\"center_vertical\"\r\n                android:layout_marginStart=\"8dp\"\r\n                android:gravity=\"center\"\r\n                android:text=\"Loli-coins\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                android:textColor=\"#fff\" />\r\n\r\n        </LinearLayout>\r\n    </RelativeLayout>\r\n\r\n    <TextView\r\n        android:id=\"@+id/coinsCount\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginTop=\"44dp\"\r\n        android:layout_marginBottom=\"44dp\"\r\n        android:gravity=\"center\"\r\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n        android:textColor=\"?colorSecondaryVariant\"\r\n        android:textSize=\"36sp\"\r\n        tools:text=\"5000\" />\r\n\r\n    <RelativeLayout\r\n        android:id=\"@+id/showAdButton\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"60dp\"\r\n        android:clickable=\"true\"\r\n        android:focusable=\"true\"\r\n        android:foreground=\"?attr/selectableItemBackground\">\r\n\r\n        <View\r\n            android:id=\"@+id/backgroundBottom\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"60dp\"\r\n            android:background=\"?colorSecondary\" />\r\n\r\n        <TextView\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_centerInParent=\"true\"\r\n            android:fontFamily=\"sans-serif\"\r\n            android:text=\"CONSEGUIR MAS\"\r\n            android:textAppearance=\"@style/Base.TextAppearance.MaterialComponents.Button\"\r\n            android:textColor=\"#fff\"\r\n            android:textSize=\"18sp\" />\r\n    </RelativeLayout>\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/exo_playback_control_view.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    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <RelativeLayout\n        android:id=\"@+id/lay_top\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:layout_gravity=\"top|center_horizontal\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:alpha=\"0.5\"\n            android:background=\"@android:color/black\"/>\n\n        <TextView\n            android:id=\"@+id/video_title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerVertical=\"true\"\n            android:ellipsize=\"end\"\n            android:lines=\"1\"\n            android:padding=\"8dp\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Widget.PopupMenu.Large\"\n            android:textColor=\"#b3ffffff\"\n            android:textSize=\"14sp\"/>\n\n        <!--<ImageButton\n            android:id=\"@+id/c_pip\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_width=\"60dp\"\n            android:layout_height=\"60dp\"\n            android:layout_marginEnd=\"5dp\"\n            app:srcCompat=\"@drawable/ic_pip_exit\"/>-->\n    </RelativeLayout>\n\n    <FrameLayout\n        android:id=\"@+id/previewFrameLayout\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"0dp\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:layout_marginBottom=\"16dp\"\n        android:background=\"#50323232\"\n        android:padding=\"2dp\"\n        android:visibility=\"invisible\"\n        app:layout_constraintBottom_toTopOf=\"@id/lay_bottom\"\n        app:layout_constraintDimensionRatio=\"16:9\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintHorizontal_bias=\"0.0\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintWidth_default=\"percent\"\n        app:layout_constraintWidth_percent=\"0.25\">\n\n        <ImageView\n            android:id=\"@+id/preview\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:scaleType=\"fitXY\"/>\n\n    </FrameLayout>\n\n    <RelativeLayout\n        android:id=\"@+id/lay_bottom\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"70dp\"\n        android:layout_gravity=\"bottom|center_horizontal\"\n        app:layout_constraintBottom_toBottomOf=\"parent\">\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:alpha=\"0.5\"\n            android:background=\"@android:color/black\"/>\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <com.google.android.exoplayer2.ui.DefaultTimeBar\n                android:id=\"@id/exo_progress\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"8dp\"\n                android:layout_marginTop=\"5dp\"\n                android:layout_marginEnd=\"8dp\"\n                app:buffered_color=\"?colorSecondaryVariant\"\n                app:played_color=\"?colorAccent\"\n                app:scrubber_color=\"?colorSecondary\" />\n\n            <RelativeLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\">\n\n                <LinearLayout\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:gravity=\"center_vertical|center_horizontal\"\n                    android:orientation=\"horizontal\">\n\n                    <ImageButton\n                        android:id=\"@+id/pip\"\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                        android:layout_width=\"60dp\"\n                        android:layout_height=\"60dp\"\n                        android:layout_marginStart=\"5dp\"\n                        android:visibility=\"invisible\"\n                        app:srcCompat=\"@drawable/ic_pip\"/>\n\n                    <ImageButton\n                        android:id=\"@id/exo_prev\"\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                        android:layout_width=\"60dp\"\n                        android:layout_height=\"60dp\"\n                        android:layout_marginEnd=\"5dp\"\n                        app:srcCompat=\"@drawable/ic_previous\" />\n\n                    <ImageButton\n                        android:id=\"@id/exo_rew\"\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                        android:layout_width=\"60dp\"\n                        android:layout_height=\"60dp\"\n                        android:layout_marginEnd=\"10dp\"\n                        app:srcCompat=\"@drawable/ic_rewind\" />\n\n                    <ImageButton\n                        android:id=\"@id/exo_play_pause\"\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                        android:layout_width=\"60dp\"\n                        android:layout_height=\"60dp\"\n                        app:srcCompat=\"@drawable/ic_play\"\n                        app:tint=\"?colorAccent\" />\n\n                    <ImageButton\n                        android:id=\"@id/exo_ffwd\"\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                        android:layout_width=\"60dp\"\n                        android:layout_height=\"60dp\"\n                        android:layout_marginStart=\"10dp\"\n                        app:srcCompat=\"@drawable/ic_ffwd\" />\n\n                    <ImageButton\n                        android:id=\"@id/exo_next\"\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                        android:layout_width=\"60dp\"\n                        android:layout_height=\"60dp\"\n                        android:layout_marginStart=\"5dp\"\n                        app:srcCompat=\"@drawable/ic_next\"/>\n\n                    <ImageButton\n                        android:id=\"@+id/skip\"\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                        android:layout_width=\"60dp\"\n                        android:layout_height=\"60dp\"\n                        android:layout_marginStart=\"5dp\"\n                        app:srcCompat=\"@drawable/ic_skip\"/>\n                </LinearLayout>\n\n                <TextView\n                    android:id=\"@id/exo_position\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentStart=\"true\"\n                    android:layout_centerVertical=\"true\"\n                    android:padding=\"8dp\"\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Medium.Inverse\"\n                    android:textColor=\"#b3ffffff\"\n                    android:textSize=\"14sp\"/>\n\n                <TextView\n                    android:id=\"@id/exo_duration\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_alignParentEnd=\"true\"\n                    android:layout_centerVertical=\"true\"\n                    android:padding=\"8dp\"\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Medium.Inverse\"\n                    android:textColor=\"#b3ffffff\"\n                    android:textSize=\"14sp\"/>\n\n            </RelativeLayout>\n        </LinearLayout>\n\n    </RelativeLayout>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintLeft_toLeftOf=\"parent\"\n        app:layout_constraintRight_toRightOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\"/>\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/exo_playback_youtube_control_view.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: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    android:background=\"#77000000\">\n\n    <LinearLayout\n        android:id=\"@+id/linearLayout\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <ImageButton\n            android:id=\"@+id/exit\"\n            android:layout_width=\"48dp\"\n            android:layout_height=\"48dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:src=\"@drawable/ic_arrow_left\" />\n\n        <TextView\n            android:id=\"@+id/video_title\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            android:layout_gravity=\"center\"\n            android:layout_marginStart=\"4dp\"\n            android:textColor=\"@android:color/white\"\n            android:textSize=\"18sp\"\n            tools:text=\"Video title\" />\n\n        <ImageButton\n            android:id=\"@+id/lock\"\n            android:layout_width=\"48dp\"\n            android:layout_height=\"48dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:src=\"@drawable/ic_locked_solid\" />\n\n    </LinearLayout>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            android:layout_width=\"80dp\"\n            android:layout_height=\"80dp\"\n            android:layout_centerInParent=\"true\"\n            android:gravity=\"center\"\n            android:indeterminate=\"true\"\n            android:indeterminateOnly=\"true\"\n            android:indeterminateTint=\"#59FFFFFF\" />\n    </RelativeLayout>\n\n    <LinearLayout\n        android:id=\"@+id/exo_ll_controls\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:gravity=\"center\"\n        android:orientation=\"horizontal\"\n        android:paddingTop=\"4dp\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <RelativeLayout\n            android:id=\"@+id/lay_prev\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\">\n\n            <ImageButton\n                android:id=\"@id/exo_prev\"\n                style=\"@style/ExoMediaButton.Previous\"\n                android:layout_marginEnd=\"48dp\"\n                android:scaleType=\"fitCenter\"\n                tools:ignore=\"ContentDescription\" />\n        </RelativeLayout>\n\n        <ImageButton\n            android:id=\"@id/exo_play\"\n            style=\"@style/ExoMediaButton.Play\"\n            android:scaleType=\"fitCenter\"\n            tools:ignore=\"ContentDescription\" />\n\n        <ImageButton\n            android:id=\"@id/exo_pause\"\n            style=\"@style/ExoMediaButton.Pause\"\n            android:scaleType=\"fitCenter\"\n            tools:ignore=\"ContentDescription\" />\n\n        <RelativeLayout\n            android:id=\"@+id/lay_next\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\">\n\n            <ImageButton\n                android:id=\"@id/exo_next\"\n                style=\"@style/ExoMediaButton.Next\"\n                android:layout_marginStart=\"48dp\"\n                android:scaleType=\"fitCenter\"\n                tools:ignore=\"ContentDescription\" />\n        </RelativeLayout>\n\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/exo_ll_timebar\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center_vertical\"\n        android:orientation=\"horizontal\"\n        android:paddingStart=\"4dp\"\n        android:paddingEnd=\"0dp\"\n        android:paddingBottom=\"12dp\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toStartOf=\"@id/skip\"\n        app:layout_constraintStart_toStartOf=\"parent\">\n\n        <TextView\n            android:id=\"@id/exo_position\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:includeFontPadding=\"false\"\n            android:paddingStart=\"8dp\"\n            android:paddingEnd=\"8dp\"\n            android:textColor=\"@android:color/white\"\n            android:textSize=\"12sp\"\n            tools:text=\"12:30\" />\n\n        <com.google.android.exoplayer2.ui.DefaultTimeBar\n            android:id=\"@id/exo_progress\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"16dp\"\n            android:layout_weight=\"1\"\n            app:bar_height=\"2dp\"\n            app:buffered_color=\"#CBFFFFFF\"\n            app:played_color=\"?colorSecondary\"\n            app:scrubber_color=\"?colorSecondary\"\n            app:scrubber_dragged_size=\"2dp\"\n            app:unplayed_color=\"#CD888888\" />\n\n        <TextView\n            android:id=\"@id/exo_duration\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:includeFontPadding=\"false\"\n            android:paddingStart=\"8dp\"\n            android:paddingEnd=\"8dp\"\n            android:textColor=\"@android:color/white\"\n            android:textSize=\"12sp\"\n            tools:text=\"24:13\" />\n\n    </LinearLayout>\n\n    <ImageView\n        android:id=\"@+id/skip\"\n        android:layout_width=\"36dp\"\n        android:layout_height=\"36dp\"\n        android:layout_marginBottom=\"2dp\"\n        android:background=\"@drawable/background_ripple\"\n        android:clickable=\"true\"\n        android:focusable=\"true\"\n        android:padding=\"8dp\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:srcCompat=\"@drawable/ic_skip\"\n        app:tint=\"#FFFFFF\" />\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/exo_player.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    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <com.google.android.exoplayer2.ui.StyledPlayerView\n        android:id=\"@+id/player\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:keepScreenOn=\"true\"\n        app:controller_layout_id=\"@layout/exo_playback_control_view\"\n        app:resize_mode=\"fit\" />\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_achievements.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RelativeLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\">\r\n\r\n    <androidx.recyclerview.widget.RecyclerView\r\n        android:id=\"@+id/recycler\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:layoutAnimation=\"@anim/layout_fall_down\"\r\n        app:layoutManager=\".custom.VariantLinearLayoutManager\"\r\n        tools:listitem=\"@layout/item_achievements\"/>\r\n\r\n    <LinearLayout\r\n        android:id=\"@+id/error\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_centerInParent=\"true\"\r\n        android:orientation=\"vertical\"\r\n        android:visibility=\"gone\">\r\n\r\n        <ImageView\r\n            android:layout_width=\"150dp\"\r\n            android:layout_height=\"150dp\"\r\n            android:layout_gravity=\"center_horizontal\"\r\n            android:adjustViewBounds=\"false\"\r\n            android:tint=\"?android:textColorSecondary\"\r\n            app:srcCompat=\"@drawable/ic_trophy_normal\"/>\r\n\r\n        <TextView\r\n            android:id=\"@+id/error_text\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_gravity=\"center_horizontal\"\r\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\r\n            android:textColor=\"?android:textColorSecondary\"\r\n            android:textSize=\"20sp\"\r\n            tools:text=\"Sin logros\"/>\r\n    </LinearLayout>\r\n\r\n    <nl.dionsegijn.konfetti.KonfettiView\r\n        android:id=\"@+id/konfetti\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\" />\r\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_anime_details.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.core.widget.NestedScrollView\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    android:descendantFocusability=\"blocksDescendants\"\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:clipToPadding=\"false\"\n        android:orientation=\"vertical\"\n        android:paddingTop=\"25dp\"\n        android:paddingBottom=\"10dp\">\n\n        <com.google.android.material.card.MaterialCardView\n            android:id=\"@+id/card_title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"10dp\"\n            android:layout_marginTop=\"10dp\"\n            android:layout_marginEnd=\"10dp\"\n            android:clickable=\"true\"\n            android:focusable=\"true\"\n            android:theme=\"@style/AppTheme.Cardview\"\n            android:visibility=\"gone\"\n            app:contentPadding=\"8dp\">\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:orientation=\"vertical\">\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"Título\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                    android:textColor=\"?colorAccent\"/>\n\n                <TextView\n                    android:id=\"@+id/title\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginTop=\"5dp\"\n                    android:text=\"TITULO COMPLETO\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\n                    android:textSize=\"16sp\"/>\n            </LinearLayout>\n        </com.google.android.material.card.MaterialCardView>\n\n        <com.google.android.material.card.MaterialCardView\n            android:id=\"@+id/card_desc\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"10dp\"\n            android:layout_marginTop=\"10dp\"\n            android:layout_marginEnd=\"10dp\"\n            android:theme=\"@style/AppTheme.Cardview\"\n            android:visibility=\"gone\"\n            app:cardCornerRadius=\"2dp\"\n            app:cardElevation=\"2dp\"\n            app:contentPadding=\"8dp\"\n            >\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:orientation=\"vertical\">\n\n                <LinearLayout\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:orientation=\"horizontal\">\n\n                    <TextView\n                        android:layout_width=\"0dp\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_weight=\"1\"\n                        android:text=\"Descripción\"\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                        android:textColor=\"?colorAccent\"/>\n\n                    <ImageButton\n                        android:id=\"@+id/expand_icon\"\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                        android:layout_width=\"36dp\"\n                        android:layout_height=\"36dp\"\n                        android:layout_gravity=\"center_vertical\"\n                        android:background=\"@drawable/background_ripple\"\n                        android:tint=\"?colorControlNormal\"\n                        app:srcCompat=\"@drawable/action_expand\"/>\n                </LinearLayout>\n\n                <knf.kuma.custom.ExpandableTV\n                    android:id=\"@+id/expandable_desc\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:clickable=\"true\"\n                    android:ellipsize=\"end\"\n                    android:text=\"TEST\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\n                    android:textSize=\"16sp\"/>\n            </LinearLayout>\n        </com.google.android.material.card.MaterialCardView>\n\n        <FrameLayout\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginTop=\"10dp\"\n            android:visibility=\"gone\" />\n\n        <com.google.android.material.card.MaterialCardView\n            android:id=\"@+id/card_details\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"10dp\"\n            android:layout_marginTop=\"10dp\"\n            android:layout_marginEnd=\"10dp\"\n            android:theme=\"@style/AppTheme.Cardview\"\n            android:visibility=\"gone\">\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:orientation=\"vertical\">\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:padding=\"8dp\"\n                    android:text=\"Detalles\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                    android:textColor=\"?colorAccent\" />\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"8dp\"\n                    android:text=\"Tipo\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\n\n                <TextView\n                    android:id=\"@+id/type\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"8dp\"\n                    android:paddingBottom=\"2dp\"\n                    android:text=\"TIPO\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"8dp\"\n                    android:text=\"Estado\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\n\n                <TextView\n                    android:id=\"@+id/state\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"8dp\"\n                    android:paddingBottom=\"2dp\"\n                    android:text=\"ESTADO\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"8dp\"\n                    android:text=\"ID\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\n\n                <TextView\n                    android:id=\"@+id/aid\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"8dp\"\n                    android:paddingBottom=\"2dp\"\n                    android:text=\"####\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"8dp\"\n                    android:text=\"Seguidores\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\n\n                <TextView\n                    android:id=\"@+id/followers\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"8dp\"\n                    android:paddingBottom=\"2dp\"\n                    android:text=\"0\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\n\n                <LinearLayout\n                    android:id=\"@+id/lay_score\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:orientation=\"vertical\">\n\n                    <LinearLayout\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_gravity=\"center_vertical\"\n                        android:gravity=\"center_vertical\"\n                        android:orientation=\"horizontal\"\n                        android:paddingStart=\"8dp\"\n                        android:paddingEnd=\"8dp\">\n\n                        <TextView\n                            android:layout_width=\"wrap_content\"\n                            android:layout_height=\"wrap_content\"\n                            android:text=\"Votos\"\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\n\n                        <TextView\n                            android:id=\"@+id/rating_count\"\n                            android:layout_width=\"wrap_content\"\n                            android:layout_height=\"wrap_content\"\n                            android:layout_marginStart=\"10dp\"\n                            android:layout_marginTop=\"1dp\"\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\"\n                            tools:text=\"-0000\" />\n                    </LinearLayout>\n\n                    <RelativeLayout\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        android:padding=\"8dp\">\n\n                        <uz.jamshid.library.ExactRatingBar\n                            android:id=\"@+id/ratingBar\"\n                            android:layout_width=\"wrap_content\"\n                            android:layout_height=\"wrap_content\"\n                            android:layout_centerHorizontal=\"true\"\n                            app:isIndicator=\"true\"\n                            app:starCount=\"5\"\n                            app:starFillColor=\"?colorSecondary\"\n                            app:starSize=\"60\" />\n                    </RelativeLayout>\n                </LinearLayout>\n            </LinearLayout>\n        </com.google.android.material.card.MaterialCardView>\n\n        <com.google.android.material.card.MaterialCardView\n            android:id=\"@+id/card_genres\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"10dp\"\n            android:layout_marginTop=\"10dp\"\n            android:layout_marginEnd=\"10dp\"\n            android:theme=\"@style/AppTheme.Cardview\"\n            android:visibility=\"gone\"\n            app:contentPadding=\"8dp\">\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:orientation=\"vertical\">\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"Géneros\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                    android:textColor=\"?colorAccent\"/>\n\n                <androidx.recyclerview.widget.RecyclerView\n                    android:id=\"@+id/recycler_genres\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginTop=\"5dp\"\n                    android:nestedScrollingEnabled=\"false\"\n                    tools:listitem=\"@layout/item_chip\"/>\n            </LinearLayout>\n        </com.google.android.material.card.MaterialCardView>\n\n        <com.google.android.material.card.MaterialCardView\n            android:id=\"@+id/card_list\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"10dp\"\n            android:layout_marginTop=\"10dp\"\n            android:layout_marginEnd=\"10dp\"\n            android:theme=\"@style/AppTheme.Cardview\"\n            android:visibility=\"gone\">\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:orientation=\"vertical\">\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_margin=\"8dp\"\n                    android:text=\"Seguir\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                    android:textColor=\"?colorAccent\"/>\n\n                <Spinner\n                    android:id=\"@+id/spinner_list\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginBottom=\"8dp\"\n                    android:entries=\"@array/list_states\"/>\n\n            </LinearLayout>\n        </com.google.android.material.card.MaterialCardView>\n\n        <com.google.android.material.card.MaterialCardView\n            android:id=\"@+id/card_related\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"10dp\"\n            android:layout_marginTop=\"10dp\"\n            android:layout_marginEnd=\"10dp\"\n            android:theme=\"@style/AppTheme.Cardview\"\n            android:visibility=\"gone\">\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:orientation=\"vertical\">\n\n                <TextView\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_margin=\"8dp\"\n                    android:text=\"Relacionados\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                    android:textColor=\"?colorAccent\"/>\n\n                <androidx.recyclerview.widget.RecyclerView\n                    android:id=\"@+id/recycler_related\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:nestedScrollingEnabled=\"false\"\n                    tools:listitem=\"@layout/item_related\"/>\n            </LinearLayout>\n        </com.google.android.material.card.MaterialCardView>\n    </LinearLayout>\n</androidx.core.widget.NestedScrollView>"
  },
  {
    "path": "app/src/main/res/layout/fragment_anime_details_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.core.widget.NestedScrollView 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    android:descendantFocusability=\"blocksDescendants\"\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:clipToPadding=\"false\"\n        android:orientation=\"vertical\"\n        android:paddingTop=\"25dp\"\n        android:paddingBottom=\"10dp\">\n\n        <LinearLayout\n            android:id=\"@+id/lay_title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:clickable=\"true\"\n            android:focusable=\"true\"\n            android:foreground=\"?selectableItemBackground\"\n            android:orientation=\"vertical\"\n            android:paddingStart=\"16dp\"\n            android:paddingEnd=\"16dp\"\n            android:visibility=\"invisible\"\n            tools:visibility=\"visible\">\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"Título\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\n                android:textSize=\"18sp\" />\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginTop=\"5dp\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\"\n                android:textColor=\"@color/textSecondaryAlpha\"\n                tools:text=\"TITULO COMPLETO\" />\n        </LinearLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:layout_marginTop=\"16dp\"\n            android:layout_marginBottom=\"16dp\"\n            android:background=\"@color/separator\" />\n\n        <LinearLayout\n            android:id=\"@+id/lay_description_separator\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n            <LinearLayout\n                android:id=\"@+id/lay_description\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"16dp\"\n                android:layout_marginEnd=\"16dp\"\n                android:orientation=\"vertical\"\n                android:visibility=\"invisible\"\n                tools:visibility=\"visible\">\n\n                <LinearLayout\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:orientation=\"horizontal\">\n\n                    <TextView\n                        android:layout_width=\"0dp\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_weight=\"1\"\n                        android:text=\"Descripción\"\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\n                        android:textSize=\"18sp\" />\n\n                    <ImageButton\n                        android:id=\"@+id/expand_icon\"\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                        android:layout_width=\"36dp\"\n                        android:layout_height=\"36dp\"\n                        android:layout_gravity=\"center_vertical\"\n                        android:background=\"@drawable/background_ripple\"\n                        android:tint=\"?colorControlNormal\"\n                        app:srcCompat=\"@drawable/action_expand\" />\n                </LinearLayout>\n\n                <knf.kuma.custom.ExpandableTV\n                    android:id=\"@+id/expandable_desc\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:clickable=\"true\"\n                    android:ellipsize=\"end\"\n                    android:text=\"TEST\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\"\n                    android:textColor=\"@color/textSecondaryAlpha\" />\n            </LinearLayout>\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"@dimen/separator_size\"\n                android:layout_marginTop=\"16dp\"\n                android:layout_marginBottom=\"16dp\"\n                android:background=\"@color/separator\" />\n        </LinearLayout>\n\n        <LinearLayout\n            android:id=\"@+id/lay_ad\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\"\n            android:visibility=\"gone\"\n            tools:visibility=\"visible\">\n            <knf.kuma.widgets.AdTemplateView\n                android:id=\"@+id/adContainer\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"16dp\"\n                android:visibility=\"invisible\"\n                app:at_layout=\"@layout/item_native_small_rounded\"\n                tools:visibility=\"visible\" />\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"@dimen/separator_size\"\n                android:layout_marginTop=\"16dp\"\n                android:layout_marginBottom=\"16dp\"\n                android:background=\"@color/separator\" />\n        </LinearLayout>\n\n        <LinearLayout\n            android:id=\"@+id/lay_details\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"16dp\"\n            android:layout_marginEnd=\"16dp\"\n            android:orientation=\"vertical\"\n            android:visibility=\"invisible\"\n            tools:visibility=\"visible\">\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:padding=\"8dp\"\n                android:text=\"Detalles\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:paddingStart=\"8dp\"\n                android:paddingEnd=\"8dp\"\n                android:text=\"Tipo\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\" />\n\n            <TextView\n                android:id=\"@+id/type\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:paddingStart=\"8dp\"\n                android:paddingEnd=\"8dp\"\n                android:paddingBottom=\"2dp\"\n                android:text=\"TIPO\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:paddingStart=\"8dp\"\n                android:paddingEnd=\"8dp\"\n                android:text=\"Estado\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\" />\n\n            <TextView\n                android:id=\"@+id/state\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:paddingStart=\"8dp\"\n                android:paddingEnd=\"8dp\"\n                android:paddingBottom=\"2dp\"\n                android:text=\"ESTADO\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:paddingStart=\"8dp\"\n                android:paddingEnd=\"8dp\"\n                android:text=\"ID\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\" />\n\n            <TextView\n                android:id=\"@+id/aid\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:paddingStart=\"8dp\"\n                android:paddingEnd=\"8dp\"\n                android:paddingBottom=\"2dp\"\n                android:text=\"####\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:paddingStart=\"8dp\"\n                android:paddingEnd=\"8dp\"\n                android:text=\"Seguidores\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\" />\n\n            <TextView\n                android:id=\"@+id/followers\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:paddingStart=\"8dp\"\n                android:paddingEnd=\"8dp\"\n                android:paddingBottom=\"2dp\"\n                android:text=\"0\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\n\n            <LinearLayout\n                android:id=\"@+id/lay_score\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:orientation=\"vertical\">\n\n                <LinearLayout\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center_vertical\"\n                    android:gravity=\"center_vertical\"\n                    android:orientation=\"horizontal\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"8dp\">\n\n                    <TextView\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:text=\"Votos\"\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\" />\n\n                    <TextView\n                        android:id=\"@+id/rating_count\"\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_marginStart=\"10dp\"\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\"\n                        tools:text=\"-0000\" />\n                </LinearLayout>\n\n                <RelativeLayout\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:padding=\"8dp\">\n\n                    <uz.jamshid.library.ExactRatingBar\n                        android:id=\"@+id/ratingBar\"\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_centerHorizontal=\"true\"\n                        app:isIndicator=\"true\"\n                        app:starCount=\"5\"\n                        app:starFillColor=\"?colorSecondary\"\n                        app:starSize=\"60\" />\n                </RelativeLayout>\n            </LinearLayout>\n        </LinearLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:layout_marginTop=\"16dp\"\n            android:layout_marginBottom=\"16dp\"\n            android:background=\"@color/separator\" />\n\n        <LinearLayout\n            android:id=\"@+id/lay_genres\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"16dp\"\n            android:layout_marginEnd=\"16dp\"\n            android:orientation=\"vertical\"\n            android:visibility=\"invisible\"\n            tools:visibility=\"visible\">\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"Géneros\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/recycler_genres\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginTop=\"5dp\"\n                android:nestedScrollingEnabled=\"false\"\n                tools:listitem=\"@layout/item_chip\" />\n        </LinearLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:layout_marginTop=\"16dp\"\n            android:layout_marginBottom=\"8dp\"\n            android:background=\"@color/separator\" />\n\n        <LinearLayout\n            android:id=\"@+id/lay_follow\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"8dp\"\n            android:layout_marginEnd=\"16dp\"\n            android:orientation=\"vertical\"\n            android:visibility=\"invisible\"\n            tools:visibility=\"visible\">\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_margin=\"8dp\"\n                android:text=\"Seguir\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\n\n            <Spinner\n                android:id=\"@+id/spinner_list\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:entries=\"@array/list_states\" />\n\n        </LinearLayout>\n\n        <LinearLayout\n            android:id=\"@+id/lay_related\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\"\n            android:visibility=\"invisible\"\n            tools:visibility=\"visible\">\n\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"@dimen/separator_size\"\n                android:layout_marginTop=\"16dp\"\n                android:layout_marginBottom=\"16dp\"\n                android:background=\"@color/separator\" />\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"16dp\"\n                android:layout_marginEnd=\"16dp\"\n                android:layout_marginBottom=\"8dp\"\n                android:text=\"Relacionados\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/recycler_related\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"16dp\"\n                android:layout_marginEnd=\"16dp\"\n                android:nestedScrollingEnabled=\"false\"\n                tools:listitem=\"@layout/item_related\" />\n        </LinearLayout>\n    </LinearLayout>\n</androidx.core.widget.NestedScrollView>"
  },
  {
    "path": "app/src/main/res/layout/fragment_directory.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:layout_height=\"match_parent\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:orientation=\"vertical\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n\n        <LinearLayout\n            android:id=\"@+id/root\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <com.google.android.material.appbar.AppBarLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:backgroundTint=\"?colorSurface\"\n                android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\">\n\n                <com.google.android.material.tabs.TabLayout\n                    android:id=\"@+id/tabs\"\n                    style=\"@style/Widget.MaterialComponents.TabLayout\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:background=\"@android:color/transparent\"\n                    app:tabBackground=\"@android:color/transparent\">\n\n                    <com.google.android.material.tabs.TabItem\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:text=\"ANIME\" />\n\n                    <com.google.android.material.tabs.TabItem\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:text=\"OVA\" />\n\n                    <com.google.android.material.tabs.TabItem\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:text=\"PELICULA\" />\n                </com.google.android.material.tabs.TabLayout>\n            </com.google.android.material.appbar.AppBarLayout>\n\n            <androidx.viewpager.widget.ViewPager\n                android:id=\"@+id/pager\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n        </LinearLayout>\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n    <knf.kuma.custom.BannerContainerView\n        android:id=\"@+id/adContainer\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:showBottomSpace=\"true\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_directory_material.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    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <androidx.coordinatorlayout.widget.CoordinatorLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n\n        <LinearLayout\n            android:id=\"@+id/root\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <com.google.android.material.appbar.AppBarLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:backgroundTint=\"?colorSurface\"\n                android:theme=\"@style/AppTheme.AppBarOverlay.Simple.NoBackground\"\n                app:elevation=\"0dp\">\n\n                <LinearLayout\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:orientation=\"vertical\">\n\n                    <com.google.android.material.tabs.TabLayout\n                        android:id=\"@+id/tabs\"\n                        style=\"@style/Widget.MaterialComponents.TabLayout\"\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        android:background=\"@android:color/transparent\"\n                        app:tabBackground=\"@android:color/transparent\"\n                        app:tabIndicator=\"@drawable/material_tab_indicator\">\n\n                        <com.google.android.material.tabs.TabItem\n                            android:layout_width=\"wrap_content\"\n                            android:layout_height=\"wrap_content\"\n                            android:text=\"ANIME\" />\n\n                        <com.google.android.material.tabs.TabItem\n                            android:layout_width=\"wrap_content\"\n                            android:layout_height=\"wrap_content\"\n                            android:text=\"OVA\" />\n\n                        <com.google.android.material.tabs.TabItem\n                            android:layout_width=\"wrap_content\"\n                            android:layout_height=\"wrap_content\"\n                            android:text=\"PELICULA\" />\n                    </com.google.android.material.tabs.TabLayout>\n\n                    <View\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"@dimen/separator_size\"\n                        android:background=\"@color/separator\" />\n                </LinearLayout>\n            </com.google.android.material.appbar.AppBarLayout>\n\n            <androidx.viewpager.widget.ViewPager\n                android:id=\"@+id/pager\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\" />\n        </LinearLayout>\n    </androidx.coordinatorlayout.widget.CoordinatorLayout>\n\n    <knf.kuma.custom.BannerContainerView\n        android:id=\"@+id/adContainer\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:showBottomSpace=\"true\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_explorer_files.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    android:id=\"@+id/root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_explorer_permission_pending.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\">\r\n\r\n    <LinearLayout\r\n        android:id=\"@+id/error\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_centerInParent=\"true\"\r\n        android:layout_marginStart=\"32dp\"\r\n        android:layout_marginEnd=\"32dp\"\r\n        android:gravity=\"center\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <ImageView\r\n            android:layout_width=\"200dp\"\r\n            android:layout_height=\"200dp\"\r\n            android:layout_gravity=\"center_horizontal\"\r\n            android:adjustViewBounds=\"false\"\r\n            app:srcCompat=\"@drawable/ic_faq\"\r\n            app:tint=\"?android:textColorSecondary\" />\r\n\r\n        <TextView\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_gravity=\"center_horizontal\"\r\n            android:text=\"Permiso de almacenamiento requerido\"\r\n            android:textAlignment=\"center\"\r\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\r\n            android:textColor=\"?android:textColorSecondary\"\r\n            android:textSize=\"24sp\" />\r\n\r\n        <com.google.android.material.button.MaterialButton\r\n            android:id=\"@+id/permission\"\r\n            style=\"@style/Widget.MaterialComponents.Button.OutlinedButton\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_marginTop=\"16dp\"\r\n            android:text=\"Conceder\" />\r\n    </LinearLayout>\r\n\r\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_home.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.core.widget.NestedScrollView\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:clipToPadding=\"false\"\r\n    android:paddingBottom=\"16dp\">\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:animateLayoutChanges=\"true\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <knf.kuma.custom.HomeList\r\n            android:id=\"@+id/listNew\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:hm_isLarge=\"false\"\r\n            app:hm_showViewAll=\"true\"\r\n            app:hm_viewAllText=\"Ocultar\"\r\n            app:hm_startHidden=\"true\"\r\n            app:hm_subheader=\"Nuevos animes\"/>\r\n\r\n        <knf.kuma.custom.HomeList\r\n            android:id=\"@+id/listFavUpdated\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:hm_errorText=\"Ningun favorito recientemente actualizado\"\r\n            app:hm_isLarge=\"true\"\r\n            app:hm_showViewAll=\"true\"\r\n            app:hm_subheader=\"Favoritos actualizados\"/>\r\n\r\n        <FrameLayout\r\n            android:id=\"@+id/adContainer\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\" />\r\n\r\n        <knf.kuma.custom.HomeList\r\n            android:id=\"@+id/listBestEmission\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:hm_isLarge=\"true\"\r\n            app:hm_subheader=\"Los mejores de la temporada\"/>\r\n\r\n        <knf.kuma.custom.HomeList\r\n            android:id=\"@+id/listPending\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:hm_isLarge=\"true\"\r\n            app:hm_showViewAll=\"true\"\r\n            app:hm_startHidden=\"true\"\r\n            app:hm_subheader=\"Sigue viendo\"/>\r\n\r\n        <knf.kuma.custom.HomeList\r\n            android:id=\"@+id/listWaiting\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:hm_showViewAll=\"true\"\r\n            app:hm_startHidden=\"true\"\r\n            app:hm_subheader=\"Animes en espera\"/>\r\n\r\n        <FrameLayout\r\n            android:id=\"@+id/adContainer2\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\" />\r\n\r\n        <knf.kuma.custom.HomeList\r\n            android:id=\"@+id/listRecommended\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:hm_isLarge=\"true\"\r\n            app:hm_showViewAll=\"true\"\r\n            app:hm_subheader=\"Recomendados para ti\"/>\r\n\r\n        <knf.kuma.custom.HomeList\r\n            android:id=\"@+id/listRecommendedStaff\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:hm_isLarge=\"true\"\r\n            app:hm_subheader=\"Recomendados por el staff\"/>\r\n\r\n    </LinearLayout>\r\n\r\n</androidx.core.widget.NestedScrollView>"
  },
  {
    "path": "app/src/main/res/layout/fragment_home_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <View\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"@dimen/separator_size\"\r\n        android:background=\"@color/separator\" />\r\n\r\n    <androidx.core.widget.NestedScrollView\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:clipToPadding=\"false\"\r\n        android:paddingBottom=\"16dp\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:animateLayoutChanges=\"true\"\r\n            android:orientation=\"vertical\">\r\n\r\n            <knf.kuma.custom.HomeList\r\n                android:id=\"@+id/listNew\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:hm_isLarge=\"false\"\r\n                app:hm_showViewAll=\"true\"\r\n                app:hm_startHidden=\"true\"\r\n                app:hm_subheader=\"Nuevos animes\"\r\n                app:hm_viewAllText=\"Ocultar\" />\r\n\r\n            <knf.kuma.custom.HomeList\r\n                android:id=\"@+id/listFavUpdated\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:hm_errorText=\"Ningun favorito recientemente actualizado\"\r\n                app:hm_isLarge=\"true\"\r\n                app:hm_showViewAll=\"true\"\r\n                app:hm_subheader=\"Favoritos actualizados\" />\r\n\r\n            <knf.kuma.custom.BannerContainerView\r\n                android:id=\"@+id/adContainer\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\" />\r\n\r\n            <knf.kuma.custom.HomeList\r\n                android:id=\"@+id/listBestEmission\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:hm_isLarge=\"true\"\r\n                app:hm_subheader=\"Los mejores de la temporada\" />\r\n\r\n            <knf.kuma.custom.HomeList\r\n                android:id=\"@+id/listPending\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:hm_isLarge=\"true\"\r\n                app:hm_showViewAll=\"true\"\r\n                app:hm_startHidden=\"true\"\r\n                app:hm_subheader=\"Sigue viendo\" />\r\n\r\n            <knf.kuma.custom.HomeList\r\n                android:id=\"@+id/listWaiting\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:hm_isLarge=\"true\"\r\n                app:hm_showViewAll=\"true\"\r\n                app:hm_startHidden=\"true\"\r\n                app:hm_subheader=\"Animes en espera\" />\r\n\r\n            <knf.kuma.custom.BannerContainerView\r\n                android:id=\"@+id/adContainer2\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\" />\r\n\r\n            <knf.kuma.custom.HomeList\r\n                android:id=\"@+id/listRecommended\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:hm_isLarge=\"true\"\r\n                app:hm_showViewAll=\"true\"\r\n                app:hm_subheader=\"Recomendados para ti\" />\r\n\r\n            <knf.kuma.custom.HomeList\r\n                android:id=\"@+id/listRecommendedStaff\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:hm_isLarge=\"true\"\r\n                app:hm_subheader=\"Recomendados por el staff\" />\r\n\r\n        </LinearLayout>\r\n\r\n    </androidx.core.widget.NestedScrollView>\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_preferences.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    android:id=\"@+id/root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n    <fragment\n        android:tag=\"fragment_preferences\"\n        android:name=\"knf.kuma.preferences.ConfigurationFragment\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"/>\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_preferences_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/separator_size\"\n        android:background=\"@color/separator\" />\n\n    <androidx.fragment.app.FragmentContainerView\n        android:id=\"@+id/frame\"\n        android:name=\"knf.kuma.preferences.ConfigurationFragmentMaterial\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:tag=\"fragment_preferences\"/>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_recent_material.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    android:orientation=\"vertical\"\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/separator_size\"\n        android:background=\"@color/separator\" />\n\n    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout\n        android:id=\"@+id/refresh\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:layout_above=\"@+id/adContainer\"\n                android:clipToPadding=\"false\"\n                android:paddingBottom=\"10dp\"\n                tools:listitem=\"@layout/item_recents_material\" />\n\n            <LinearLayout\n                android:id=\"@+id/error\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerInParent=\"true\"\n                android:orientation=\"vertical\"\n                android:visibility=\"gone\">\n\n                <ImageView\n                    android:layout_width=\"200dp\"\n                    android:layout_height=\"200dp\"\n                    android:layout_gravity=\"center_horizontal\"\n                    android:adjustViewBounds=\"false\"\n                    android:tint=\"?android:textColorSecondary\"\n                    app:srcCompat=\"@drawable/ic_no_recents\" />\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_gravity=\"center_horizontal\"\n                    android:text=\"Sin recientes\"\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                    android:textColor=\"?android:textColorSecondary\"\n                    android:textSize=\"24sp\" />\n            </LinearLayout>\n\n            <knf.kuma.custom.BannerContainerView\n                android:id=\"@+id/adContainer\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentBottom=\"true\" />\n        </RelativeLayout>\n\n    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_search.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recycler\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clipToPadding=\"false\"\n        android:layoutAnimation=\"@anim/layout_fall_down\"\n        android:nestedScrollingEnabled=\"false\"\n        android:paddingStart=\"10dp\"\n        android:paddingTop=\"10dp\"\n        android:paddingEnd=\"10dp\"\n        android:paddingBottom=\"140dp\"\n        app:layoutManager=\".custom.VariantLinearLayoutManager\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n        tools:listitem=\"@layout/item_dir\"/>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:indeterminate=\"true\"/>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\"\n        android:paddingBottom=\"64dp\"\n        android:visibility=\"gone\"\n        tools:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_not_found\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Sin resultados\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton\n        android:id=\"@+id/fab\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Géneros\"\n        app:icon=\"@drawable/ic_genres_0\"\n        android:layout_marginStart=\"16dp\"\n        android:layout_marginTop=\"16dp\"\n        android:layout_marginEnd=\"16dp\"\n        android:layout_marginBottom=\"16dp\"\n        app:layout_anchor=\"@id/recycler\"\n        app:fabSize=\"normal\"\n        app:layout_anchorGravity=\"bottom|end\"/>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_search_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <knf.kuma.custom.GridRecyclerView\n        android:id=\"@+id/recycler\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clipToPadding=\"false\"\n        android:layoutAnimation=\"@anim/grid_fall_down\"\n        android:nestedScrollingEnabled=\"false\"\n        android:paddingStart=\"10dp\"\n        android:paddingTop=\"10dp\"\n        android:paddingEnd=\"10dp\"\n        android:paddingBottom=\"140dp\"\n        app:layoutManager=\".custom.VariantGridLayoutManager\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n        app:spanCount=\"@integer/span_count_large\"\n        tools:listitem=\"@layout/item_dir_grid\"/>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:indeterminate=\"true\"/>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\"\n        android:paddingBottom=\"64dp\"\n        android:visibility=\"gone\"\n        tools:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_not_found\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Sin resultados\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton\n        android:id=\"@+id/fab\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Géneros\"\n        app:icon=\"@drawable/ic_genres_0\"\n        android:layout_marginStart=\"16dp\"\n        android:layout_marginTop=\"16dp\"\n        android:layout_marginEnd=\"16dp\"\n        android:layout_marginBottom=\"16dp\"\n        app:layout_anchor=\"@id/recycler\"\n        app:fabSize=\"normal\"\n        app:layout_anchorGravity=\"bottom|end\"/>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_seeing.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.Material.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"/>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:id=\"@+id/error_img\"\n            android:layout_width=\"150dp\"\n            android:layout_height=\"150dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_not_seeing\"/>\n\n        <TextView\n            android:id=\"@+id/error_text\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"No sigues ningún anime\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"20sp\"/>\n    </LinearLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <knf.kuma.custom.FSGridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"5dp\"\n            app:fastScrollPopupBgColor=\"?colorSecondary\"\n            app:fastScrollPopupTextColor=\"@android:color/white\"\n            app:fastScrollThumbColor=\"?colorSecondary\"\n            app:fastScrollThumbInactiveColor=\"?colorSecondaryVariant\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:spanCount=\"@integer/span_count\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_achievements.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:id=\"@+id/root\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"72dp\"\r\n    android:foreground=\"?selectableItemBackground\"\r\n    android:gravity=\"center_vertical\"\r\n    android:orientation=\"horizontal\">\r\n\r\n    <ImageView\r\n        android:id=\"@+id/icon\"\r\n        android:layout_width=\"40dp\"\r\n        android:layout_height=\"40dp\"\r\n        android:layout_margin=\"16dp\"\r\n        android:background=\"@drawable/shape_circle\"\r\n        android:padding=\"8dp\"\r\n        android:tint=\"@android:color/white\"\r\n        tools:srcCompat=\"@drawable/ic_achievement_start\"/>\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"0dp\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_weight=\"1\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <TextView\r\n            android:id=\"@+id/name\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:gravity=\"center_vertical\"\r\n            android:lines=\"2\"\r\n            android:minHeight=\"32dp\"\r\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Large\"\r\n            android:textSize=\"16sp\"\r\n            tools:text=\"Name\"/>\r\n\r\n        <TextView\r\n            android:id=\"@+id/state\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"20dp\"\r\n            tools:text=\"State\"/>\r\n    </LinearLayout>\r\n\r\n    <TextView\r\n        android:id=\"@+id/exp\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginStart=\"16dp\"\r\n        android:layout_marginEnd=\"16dp\"\r\n        android:textColor=\"?colorAccent\"\r\n        tools:text=\"100 XP\"/>\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_ad.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/container\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginTop=\"10dp\"\n    android:paddingStart=\"10dp\"\n    android:paddingEnd=\"10dp\"\n    android:orientation=\"vertical\">\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_ad_achievements.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <FrameLayout\r\n        android:id=\"@+id/container\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\" />\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_ad_fav.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/container\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:paddingStart=\"10dp\"\n    android:paddingEnd=\"10dp\"\n    android:orientation=\"vertical\">\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_ad_news.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/container\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\"\n    android:paddingStart=\"8dp\"\n    android:paddingEnd=\"8dp\">\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_ad_recents_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<View xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:layout_width=\"0dp\"\r\n    android:layout_height=\"0dp\"></View><!--\r\n<com.google.android.gms.ads.nativead.NativeAdView xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:id=\"@+id/nativeAdView\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"101dp\">\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"101dp\"\r\n        android:baselineAligned=\"false\"\r\n        android:clipToPadding=\"false\"\r\n        android:orientation=\"horizontal\"\r\n        android:paddingStart=\"16dp\"\r\n        android:paddingTop=\"8dp\"\r\n        android:paddingEnd=\"16dp\"\r\n        android:paddingBottom=\"8dp\">\r\n        <RelativeLayout\r\n            android:layout_width=\"85dp\"\r\n            android:layout_height=\"85dp\">\r\n\r\n            <com.google.android.material.imageview.ShapeableImageView\r\n                android:id=\"@+id/icon\"\r\n                android:layout_width=\"85dp\"\r\n                android:layout_height=\"85dp\"\r\n                android:scaleType=\"centerCrop\"\r\n                app:shapeAppearanceOverlay=\"@style/roundedCorners\"\r\n                tools:srcCompat=\"@tools:sample/backgrounds/scenic\" />\r\n\r\n        </RelativeLayout>\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"85dp\"\r\n            android:layout_marginStart=\"16dp\"\r\n            android:orientation=\"vertical\">\r\n\r\n            <TextView\r\n                android:id=\"@+id/primary\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:ellipsize=\"end\"\r\n                android:gravity=\"top|center_vertical\"\r\n                android:lines=\"1\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\r\n                tools:text=\"Anime long long long long long long long title\" />\r\n\r\n            <TextView\r\n                android:id=\"@+id/secondary\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"0dp\"\r\n                android:layout_weight=\"1\"\r\n                android:ellipsize=\"end\"\r\n                android:lines=\"2\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\r\n                android:textSize=\"11sp\"\r\n                tools:text=\"@tools:sample/lorem/random\" />\r\n\r\n            <FrameLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\">\r\n\r\n                <com.google.android.material.chip.Chip\r\n                    android:id=\"@+id/cta\"\r\n                    style=\"@style/Widget.MaterialComponents.Chip.Action\"\r\n                    android:layout_width=\"wrap_content\"\r\n                    android:layout_height=\"24dp\"\r\n                    android:layout_gravity=\"bottom\"\r\n                    android:minWidth=\"100dp\"\r\n                    android:textAlignment=\"center\"\r\n                    android:textColor=\"@android:color/white\"\r\n                    app:chipBackgroundColor=\"?colorAccent\"\r\n                    app:chipMinTouchTargetSize=\"0dp\"\r\n                    tools:text=\"Instalar\" />\r\n\r\n                <TextView\r\n                    android:id=\"@+id/ad_notification_view\"\r\n                    android:layout_width=\"wrap_content\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_gravity=\"center_vertical|end\"\r\n                    android:text=\"Ad\"\r\n                    android:textColor=\"#FFCA28\"\r\n                    android:textSize=\"@dimen/gnt_ad_indicator_text_size\"\r\n                    android:textStyle=\"bold\" />\r\n            </FrameLayout>\r\n        </LinearLayout>\r\n    </LinearLayout>\r\n\r\n</com.google.android.gms.ads.nativead.NativeAdView>-->\r\n"
  },
  {
    "path": "app/src/main/res/layout/item_anim_queue.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\">\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"60dp\"\n            android:layout_height=\"85dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"/>\n\n        <RelativeLayout\n            android:layout_width=\"0dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginStart=\"8dp\"\n            android:layout_marginEnd=\"2dp\"\n            android:layout_weight=\"1\">\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentTop=\"true\"\n                android:layout_centerHorizontal=\"true\"\n                android:layout_marginTop=\"4dp\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:lines=\"2\"\n                android:text=\"Title\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textSize=\"18sp\"/>\n\n            <TextView\n                android:id=\"@+id/type\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentBottom=\"true\"\n                android:layout_marginBottom=\"12dp\"\n                android:lines=\"1\"\n                android:text=\"Type\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n                android:textColor=\"?colorAccent\"\n                android:textSize=\"16sp\"/>\n\n        </RelativeLayout>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_anim_queue_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"149dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"/>\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginTop=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"14sp\"/>\n\n        <TextView\n            android:id=\"@+id/type\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"20dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_marginBottom=\"4dp\"\n            android:gravity=\"center_vertical\"\n            android:text=\"Type\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"12sp\"/>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_anim_queue_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:clickable=\"true\"\n    android:clipToPadding=\"false\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:padding=\"8dp\">\n\n    <com.google.android.material.imageview.ShapeableImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"149dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"img\"\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginTop=\"4dp\"\n        android:layout_marginEnd=\"4dp\"\n        android:ellipsize=\"end\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:text=\"Title\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n        android:textSize=\"14sp\"/>\n\n    <TextView\n        android:id=\"@+id/type\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"20dp\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginEnd=\"4dp\"\n        android:layout_marginBottom=\"4dp\"\n        android:gravity=\"center_vertical\"\n        android:text=\"Type\"\n        android:textColor=\"?colorAccent\"\n        android:textSize=\"12sp\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_anim_queue_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"horizontal\">\n\n    <com.google.android.material.imageview.ShapeableImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"60dp\"\n        android:layout_height=\"85dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"img\"\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n    <RelativeLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"2dp\"\n        android:layout_weight=\"1\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_centerHorizontal=\"true\"\n            android:layout_marginTop=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"18sp\"/>\n\n        <TextView\n            android:id=\"@+id/type\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginBottom=\"12dp\"\n            android:lines=\"1\"\n            android:text=\"Type\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"16sp\"/>\n\n    </RelativeLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_changelog.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\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    style=\"@style/AppTheme.Cardview\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"8dp\"\n            android:gravity=\"center_vertical\"\n            android:orientation=\"horizontal\">\n\n            <TextView\n                android:id=\"@+id/version\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"Version\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textColor=\"?colorAccent\"/>\n\n            <TextView\n                android:id=\"@+id/code\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"end\"\n                android:layout_weight=\"1\"\n                android:gravity=\"end\"\n                android:text=\"#\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"/>\n        </LinearLayout>\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:nestedScrollingEnabled=\"false\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            tools:listitem=\"@layout/item_release\"/>\n    </LinearLayout>\n\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_changelog_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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=\"wrap_content\"\n    android:layout_marginTop=\"16dp\"\n    android:layout_marginBottom=\"24dp\"\n    android:orientation=\"vertical\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"16dp\"\n        android:layout_marginEnd=\"16dp\"\n        android:gravity=\"center_vertical\"\n        android:orientation=\"horizontal\">\n\n        <TextView\n            android:id=\"@+id/version\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"Version\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\n            android:textColor=\"?colorAccent\"/>\n\n        <TextView\n            android:id=\"@+id/code\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"end\"\n            android:layout_weight=\"1\"\n            android:gravity=\"end\"\n            android:text=\"#\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\"/>\n    </LinearLayout>\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recycler\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:nestedScrollingEnabled=\"false\"\n        app:layoutManager=\".custom.VariantLinearLayoutManager\"\n        tools:listitem=\"@layout/item_release_material\"/>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_chap.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:baselineAligned=\"false\"\n        android:orientation=\"horizontal\">\n\n        <RelativeLayout\n            android:layout_width=\"145dp\"\n            android:layout_height=\"85dp\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"imgRel\"/>\n\n            <knf.kuma.custom.SeenAnimeOverlay\n                android:id=\"@+id/seen\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"/>\n        </RelativeLayout>\n\n        <RelativeLayout\n            android:layout_width=\"0dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginStart=\"8dp\"\n            android:layout_marginEnd=\"2dp\"\n            android:layout_weight=\"1\">\n\n            <TextView\n                android:id=\"@+id/chapter\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentTop=\"true\"\n                android:layout_centerHorizontal=\"true\"\n                android:layout_marginTop=\"4dp\"\n                android:layout_toStartOf=\"@+id/action\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:lines=\"2\"\n                android:text=\"Chapter\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textSize=\"18sp\"/>\n\n            <TextView\n                android:id=\"@+id/time\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentBottom=\"true\"\n                android:layout_marginBottom=\"12dp\"\n                android:layout_toStartOf=\"@+id/action\"\n                android:lines=\"1\"\n                android:text=\"00:00:00\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n                android:textColor=\"?colorAccent\"\n                android:textSize=\"16sp\"/>\n\n            <ImageButton\n                android:id=\"@+id/action\"\n                style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                android:layout_width=\"36dp\"\n                android:layout_height=\"36dp\"\n                android:layout_alignParentEnd=\"true\"\n                android:layout_centerVertical=\"true\"\n                android:layout_gravity=\"center\"\n                android:layout_marginEnd=\"8dp\"\n                android:background=\"@drawable/background_ripple\"\n                app:srcCompat=\"@drawable/ic_delete\"/>\n\n        </RelativeLayout>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_chap_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"96dp\"\n                android:baselineAligned=\"false\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\"\n                />\n\n            <knf.kuma.custom.SeenAnimeOverlay\n                android:id=\"@+id/seen\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"96dp\"\n                />\n        </RelativeLayout>\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"horizontal\">\n\n            <LinearLayout\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:orientation=\"vertical\">\n\n                <TextView\n                    android:id=\"@+id/chapter\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginStart=\"4dp\"\n                    android:layout_marginTop=\"4dp\"\n                    android:layout_marginEnd=\"4dp\"\n                    android:gravity=\"center_vertical\"\n                    android:lines=\"1\"\n                    android:text=\"Chapter\"\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                    android:textSize=\"16sp\"/>\n\n                <TextView\n                    android:id=\"@+id/time\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"20dp\"\n                    android:layout_marginStart=\"4dp\"\n                    android:layout_marginEnd=\"4dp\"\n                    android:layout_marginBottom=\"4dp\"\n                    android:gravity=\"center_vertical\"\n                    android:text=\"00:00:00\"\n                    android:textColor=\"?colorAccent\"\n                    android:textSize=\"14sp\"/>\n            </LinearLayout>\n\n            <ImageButton\n                android:id=\"@+id/action\"\n                style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                android:layout_width=\"24dp\"\n                android:layout_height=\"24dp\"\n                android:layout_gravity=\"center\"\n                android:layout_margin=\"8dp\"\n                android:background=\"@drawable/background_ripple\"\n                android:cropToPadding=\"false\"\n                app:srcCompat=\"@drawable/ic_delete\"/>\n        </LinearLayout>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_chap_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:clickable=\"true\"\n    android:clipToPadding=\"false\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:padding=\"8dp\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\">\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"96dp\"\n            android:baselineAligned=\"false\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"\n            app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n        <knf.kuma.custom.SeenAnimeOverlay\n            android:id=\"@+id/seen\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"96dp\" />\n    </RelativeLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\">\n\n        <LinearLayout\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            android:orientation=\"vertical\">\n\n            <TextView\n                android:id=\"@+id/chapter\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"4dp\"\n                android:layout_marginTop=\"4dp\"\n                android:layout_marginEnd=\"4dp\"\n                android:gravity=\"center_vertical\"\n                android:lines=\"1\"\n                android:text=\"Chapter\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textSize=\"16sp\"/>\n\n            <TextView\n                android:id=\"@+id/time\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"20dp\"\n                android:layout_marginStart=\"4dp\"\n                android:layout_marginEnd=\"4dp\"\n                android:layout_marginBottom=\"4dp\"\n                android:gravity=\"center_vertical\"\n                android:text=\"00:00:00\"\n                android:textColor=\"?colorAccent\"\n                android:textSize=\"14sp\"/>\n        </LinearLayout>\n\n        <ImageButton\n            android:id=\"@+id/action\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"24dp\"\n            android:layout_height=\"24dp\"\n            android:layout_gravity=\"center\"\n            android:layout_margin=\"8dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:cropToPadding=\"false\"\n            app:srcCompat=\"@drawable/ic_delete\"/>\n    </LinearLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_chap_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:baselineAligned=\"false\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"horizontal\">\n\n    <RelativeLayout\n        android:layout_width=\"145dp\"\n        android:layout_height=\"85dp\">\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"imgRel\"\n            app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n        <knf.kuma.custom.SeenAnimeOverlay\n            android:id=\"@+id/seen\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"/>\n    </RelativeLayout>\n\n    <RelativeLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"2dp\"\n        android:layout_weight=\"1\">\n\n        <TextView\n            android:id=\"@+id/chapter\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_centerHorizontal=\"true\"\n            android:layout_marginTop=\"4dp\"\n            android:layout_toStartOf=\"@+id/action\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Chapter\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"18sp\"/>\n\n        <TextView\n            android:id=\"@+id/time\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginBottom=\"12dp\"\n            android:layout_toStartOf=\"@+id/action\"\n            android:lines=\"1\"\n            android:text=\"00:00:00\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"16sp\"/>\n\n        <ImageButton\n            android:id=\"@+id/action\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"36dp\"\n            android:layout_height=\"36dp\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_centerVertical=\"true\"\n            android:layout_gravity=\"center\"\n            android:layout_marginEnd=\"8dp\"\n            android:background=\"@drawable/background_ripple\"\n            app:srcCompat=\"@drawable/ic_delete\"/>\n\n    </RelativeLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_chapter_preview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"60dp\"\n    android:clickable=\"true\"\n    android:foreground=\"?android:selectableItemBackgroundBorderless\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"0dp\"\n    app:cardElevation=\"2dp\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <View\n                android:id=\"@+id/separator\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"1dp\"\n                android:alpha=\"0.12\"\n                android:background=\"@color/divider\"/>\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:gravity=\"center_vertical\">\n\n                <ImageView\n                    android:id=\"@+id/img\"\n                    android:layout_width=\"100dp\"\n                    android:layout_height=\"60dp\"\n                    android:scaleType=\"centerCrop\"\n                    android:visibility=\"visible\"/>\n\n                <TextView\n                    android:id=\"@+id/chapter\"\n                    android:layout_width=\"0dp\"\n                    android:layout_height=\"match_parent\"\n                    android:layout_gravity=\"center_vertical\"\n                    android:layout_weight=\"1\"\n                    android:gravity=\"center_vertical\"\n                    android:paddingStart=\"8dp\"\n                    android:paddingEnd=\"0dp\"\n                    android:textAppearance=\"@android:style/TextAppearance.Material.Title\"\n                    android:textColor=\"?android:textColorPrimary\"\n                    android:textSize=\"18sp\"\n                    tools:text=\"Episodio #\"/>\n\n                <ImageView\n                    android:id=\"@+id/in_down\"\n                    android:layout_width=\"24dp\"\n                    android:layout_height=\"24dp\"\n                    android:visibility=\"gone\"\n                    app:srcCompat=\"@drawable/ic_chap_down\"/>\n\n                <ImageButton\n                    android:id=\"@+id/actions\"\n                    style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                    android:layout_width=\"36dp\"\n                    android:layout_height=\"36dp\"\n                    android:layout_gravity=\"center_vertical\"\n                    android:layout_marginEnd=\"10dp\"\n                    android:background=\"@drawable/background_ripple\"\n                    app:srcCompat=\"@drawable/action_chapter\"/>\n            </LinearLayout>\n        </LinearLayout>\n\n        <FrameLayout\n            android:id=\"@+id/progress_root\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"3dp\"\n            android:layout_alignParentBottom=\"true\">\n\n            <ProgressBar\n                android:id=\"@+id/progress\"\n                style=\"@style/Widget.AppCompat.ProgressBar.Horizontal\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"20dp\"\n                android:layout_gravity=\"center\"\n                />\n        </FrameLayout>\n    </RelativeLayout>\n\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_chapter_preview_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"60dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?android:selectableItemBackgroundBorderless\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <View\n            android:id=\"@+id/separator\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:alpha=\"0.12\"\n            android:background=\"@color/divider\"/>\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:gravity=\"center_vertical\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"100dp\"\n                android:layout_height=\"60dp\"\n                android:scaleType=\"centerCrop\"\n                android:visibility=\"visible\"/>\n\n            <TextView\n                android:id=\"@+id/chapter\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"match_parent\"\n                android:layout_gravity=\"center_vertical\"\n                android:layout_weight=\"1\"\n                android:gravity=\"center_vertical\"\n                android:paddingStart=\"8dp\"\n                android:paddingEnd=\"0dp\"\n                android:textAppearance=\"@android:style/TextAppearance.Material.Title\"\n                android:textColor=\"?android:textColorPrimary\"\n                android:textSize=\"18sp\"\n                tools:text=\"Episodio #\"/>\n\n            <ImageView\n                android:id=\"@+id/in_down\"\n                android:layout_width=\"24dp\"\n                android:layout_height=\"24dp\"\n                android:visibility=\"gone\"\n                app:srcCompat=\"@drawable/ic_chap_down\"/>\n\n            <ImageButton\n                android:id=\"@+id/actions\"\n                style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n                android:layout_width=\"36dp\"\n                android:layout_height=\"36dp\"\n                android:layout_gravity=\"center_vertical\"\n                android:layout_marginEnd=\"10dp\"\n                android:background=\"@drawable/background_ripple\"\n                app:srcCompat=\"@drawable/action_chapter\"/>\n        </LinearLayout>\n    </LinearLayout>\n\n    <FrameLayout\n        android:id=\"@+id/progress_root\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"3dp\"\n        android:layout_alignParentBottom=\"true\">\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            style=\"@style/Widget.AppCompat.ProgressBar.Horizontal\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"20dp\"\n            android:layout_gravity=\"center\"\n            />\n    </FrameLayout>\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_chip.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/chip\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@drawable/chip_ripple\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:text=\"Label\"\n    android:textColor=\"@android:color/white\"/>"
  },
  {
    "path": "app/src/main/res/layout/item_dir.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginTop=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"60dp\"\n        android:orientation=\"horizontal\">\n\n        <RelativeLayout\n            android:layout_width=\"60dp\"\n            android:layout_height=\"match_parent\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"60dp\"\n                android:layout_height=\"match_parent\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\" />\n\n            <ProgressBar\n                android:id=\"@+id/progress\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerInParent=\"true\"\n                android:visibility=\"gone\" />\n        </RelativeLayout>\n\n        <RelativeLayout\n            android:layout_width=\"0dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_margin=\"8dp\"\n            android:layout_weight=\"1\">\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentTop=\"false\"\n                android:layout_centerInParent=\"true\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:lines=\"2\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textSize=\"16sp\"\n                tools:text=\"Title\"/>\n        </RelativeLayout>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_dir_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"149dp\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"149dp\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\" />\n\n            <ProgressBar\n                android:id=\"@+id/progress\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerInParent=\"true\" />\n\n        </RelativeLayout>\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginTop=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_marginBottom=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"14sp\"\n            tools:text=\"Title\"/>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_dir_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"149dp\">\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"149dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"\n            app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\" />\n\n    </RelativeLayout>\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginTop=\"4dp\"\n        android:layout_marginEnd=\"4dp\"\n        android:layout_marginBottom=\"4dp\"\n        android:ellipsize=\"end\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n        android:textSize=\"14sp\"\n        tools:text=\"Title\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_dir_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"76dp\"\n    android:clickable=\"true\"\n    android:clipToPadding=\"false\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"horizontal\"\n    android:paddingTop=\"8dp\"\n    android:paddingBottom=\"8dp\">\n\n    <RelativeLayout\n        android:layout_width=\"60dp\"\n        android:layout_height=\"match_parent\">\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"60dp\"\n            android:layout_height=\"match_parent\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"\n            app:shapeAppearanceOverlay=\"@style/roundedCorners\" />\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"\n            android:visibility=\"gone\" />\n    </RelativeLayout>\n\n    <RelativeLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_margin=\"8dp\"\n        android:layout_weight=\"1\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"false\"\n            android:layout_centerInParent=\"true\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"16sp\"\n            tools:text=\"Title\"/>\n    </RelativeLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_downloading_extra.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"16dp\"\n            android:orientation=\"vertical\">\n\n            <TextView\n                android:id=\"@+id/server\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Overline\"\n                tools:text=\"Server\" />\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:maxLines=\"2\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                android:textColor=\"?android:attr/textColorPrimary\"\n                android:textSize=\"18sp\"\n                tools:text=\"Title\" />\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"25dp\"\n                android:orientation=\"horizontal\">\n\n                <TextView\n                    android:id=\"@+id/chapter\"\n                    android:layout_width=\"0dp\"\n                    android:layout_height=\"25dp\"\n                    android:layout_weight=\"1\"\n                    android:gravity=\"bottom\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n                    android:textColor=\"?colorAccent\"\n                    android:textSize=\"16sp\"\n                    tools:text=\"Chapter\"/>\n\n                <TextView\n                    android:id=\"@+id/eta\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"25dp\"\n                    android:gravity=\"bottom\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n                    android:textSize=\"14sp\"\n                    tools:text=\"ETA\"/>\n            </LinearLayout>\n\n        </LinearLayout>\n\n        <FrameLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"3dp\">\n\n            <ProgressBar\n                android:id=\"@+id/progress\"\n                style=\"@style/Widget.AppCompat.ProgressBar.Horizontal\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"20dp\"\n                android:layout_gravity=\"center\"\n                android:indeterminate=\"true\"/>\n        </FrameLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:alpha=\"0.12\"\n            android:background=\"@color/divider\"/>\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"horizontal\"\n            android:weightSum=\"2\">\n\n            <com.google.android.material.button.MaterialButton\n                android:id=\"@+id/action\"\n                style=\"@style/Widget.MaterialComponents.Button.TextButton\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:textColor=\"?colorSecondary\"\n                android:text=\"PAUSAR\"/>\n\n            <com.google.android.material.button.MaterialButton\n                android:id=\"@+id/cancel\"\n                style=\"@style/Widget.MaterialComponents.Button.TextButton\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:textColor=\"?colorSecondary\"\n                android:text=\"CANCELAR\"/>\n        </LinearLayout>\n    </LinearLayout>\n\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_downloading_extra_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"16dp\">\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n\n            <TextView\n                android:id=\"@+id/server\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginEnd=\"32dp\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Overline\"\n                tools:text=\"Server\" />\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginEnd=\"32dp\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:maxLines=\"2\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                android:textColor=\"?android:attr/textColorPrimary\"\n                android:textSize=\"18sp\"\n                tools:text=\"Title\" />\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"25dp\"\n                android:orientation=\"horizontal\">\n\n                <TextView\n                    android:id=\"@+id/chapter\"\n                    android:layout_width=\"0dp\"\n                    android:layout_height=\"25dp\"\n                    android:layout_weight=\"1\"\n                    android:gravity=\"bottom\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n                    android:textColor=\"?colorAccent\"\n                    android:textSize=\"16sp\"\n                    tools:text=\"Chapter\"/>\n\n                <TextView\n                    android:id=\"@+id/eta\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"25dp\"\n                    android:gravity=\"bottom\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n                    android:textSize=\"14sp\"\n                    tools:text=\"ETA\"/>\n            </LinearLayout>\n        </LinearLayout>\n        <ImageView\n            android:id=\"@+id/actionMenu\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_alignParentEnd=\"true\"\n            android:background=\"@drawable/background_ripple\"\n            android:clickable=\"true\"\n            android:focusable=\"true\"\n            android:padding=\"4dp\"\n            app:srcCompat=\"@drawable/action_chapter\" />\n    </RelativeLayout>\n\n    <FrameLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"3dp\"\n        android:layout_marginStart=\"16dp\"\n        android:layout_marginEnd=\"16dp\"\n        android:layout_marginBottom=\"16dp\">\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            style=\"@style/Widget.AppCompat.ProgressBar.Horizontal\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"20dp\"\n            android:layout_gravity=\"center\"\n            android:indeterminate=\"true\"/>\n    </FrameLayout>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_ea_step.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:layout_marginTop=\"16dp\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <TextView\r\n        android:id=\"@+id/hint\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"0dp\"\r\n        android:layout_weight=\"1\"\r\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n        tools:text=\"Hints\"/>\r\n\r\n    <LinearLayout\r\n        android:id=\"@+id/layBuy\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <TextView\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:text=\"Comprar\"\r\n            android:textAppearance=\"@style/Base.TextAppearance.MaterialComponents.Headline6\" />\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:gravity=\"center|end\"\r\n            android:orientation=\"horizontal\"\r\n            android:weightSum=\"2\">\r\n\r\n            <com.google.android.material.button.MaterialButton\r\n                android:id=\"@+id/unlockCoins\"\r\n                style=\"@style/Widget.MaterialComponents.Button.OutlinedButton.Icon\"\r\n                android:layout_width=\"0dp\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"4dp\"\r\n                android:layout_marginEnd=\"8dp\"\r\n                android:layout_weight=\"1\"\r\n                android:textColor=\"@color/accent_button_state\"\r\n                app:icon=\"@drawable/ic_coin_ach\"\r\n                app:iconGravity=\"textStart\"\r\n                app:strokeColor=\"@color/accent_button_state\"\r\n                tools:text=\"1000\" />\r\n        </LinearLayout>\r\n    </LinearLayout>\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_emision.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"149dp\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\"/>\n\n            <knf.kuma.custom.HiddenOverlay\n                android:id=\"@+id/hidden\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"149dp\"\n                android:visibility=\"gone\"/>\n\n            <ImageView\n                android:id=\"@+id/heart\"\n                android:layout_width=\"18dp\"\n                android:layout_height=\"18dp\"\n                android:layout_alignParentTop=\"true\"\n                android:layout_alignParentEnd=\"true\"\n                android:layout_marginStart=\"4dp\"\n                android:layout_marginTop=\"4dp\"\n                android:layout_marginEnd=\"4dp\"\n                android:layout_marginBottom=\"4dp\"\n                android:visibility=\"gone\"\n                app:srcCompat=\"@drawable/heart_full\"\n                app:tint=\"?colorAccent\" />\n        </RelativeLayout>\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_margin=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"14sp\"/>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_emision_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:clickable=\"true\"\n    android:clipToPadding=\"false\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:padding=\"8dp\">\n\n    <com.google.android.material.card.MaterialCardView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:clickable=\"false\"\n        android:focusable=\"false\"\n        app:cardElevation=\"0dp\"\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"149dp\">\n\n            <com.google.android.material.imageview.ShapeableImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"149dp\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\"\n                app:shapeAppearanceOverlay=\"@style/roundedCorners\" />\n\n            <knf.kuma.custom.HiddenOverlay\n                android:id=\"@+id/hidden\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"149dp\"\n                android:visibility=\"gone\" />\n\n            <RelativeLayout\n                android:id=\"@+id/heart\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"149dp\"\n                android:background=\"@drawable/circular_shade\"\n                android:visibility=\"gone\"\n                tools:visibility=\"visible\">\n\n                <ImageView\n                    android:layout_width=\"18dp\"\n                    android:layout_height=\"18dp\"\n                    android:layout_alignParentTop=\"true\"\n                    android:layout_alignParentEnd=\"true\"\n                    android:layout_marginStart=\"4dp\"\n                    android:layout_marginTop=\"4dp\"\n                    android:layout_marginEnd=\"4dp\"\n                    android:layout_marginBottom=\"4dp\"\n                    app:srcCompat=\"@drawable/heart_full\"\n                    app:tint=\"?colorAccent\" />\n            </RelativeLayout>\n        </RelativeLayout>\n    </com.google.android.material.card.MaterialCardView>\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:layout_margin=\"4dp\"\n        android:ellipsize=\"end\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:text=\"Title\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n        android:textSize=\"14sp\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_explorer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\">\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"60dp\"\n            android:layout_height=\"85dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"imgRel\"/>\n\n        <RelativeLayout\n            android:layout_width=\"0dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginStart=\"8dp\"\n            android:layout_marginEnd=\"2dp\"\n            android:layout_weight=\"1\">\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentTop=\"true\"\n                android:layout_centerHorizontal=\"true\"\n                android:layout_marginTop=\"4dp\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:lines=\"2\"\n                android:text=\"Title\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textSize=\"18sp\"/>\n\n            <TextView\n                android:id=\"@+id/chapter\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentBottom=\"true\"\n                android:layout_marginBottom=\"12dp\"\n                android:lines=\"1\"\n                android:text=\"Chapter #\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n                android:textColor=\"?colorAccent\"\n                android:textSize=\"16sp\"/>\n\n        </RelativeLayout>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_explorer_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"149dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"/>\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginTop=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"14sp\"/>\n\n        <TextView\n            android:id=\"@+id/chapter\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"20dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_marginBottom=\"4dp\"\n            android:gravity=\"center_vertical\"\n            android:text=\"Chapter #\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"12sp\"/>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_explorer_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:clickable=\"true\"\n    android:clipToPadding=\"false\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:padding=\"8dp\">\n\n    <com.google.android.material.imageview.ShapeableImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"149dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"img\"\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginTop=\"4dp\"\n        android:layout_marginEnd=\"4dp\"\n        android:ellipsize=\"end\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:text=\"Title\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n        android:textSize=\"14sp\"/>\n\n    <TextView\n        android:id=\"@+id/chapter\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"20dp\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginEnd=\"4dp\"\n        android:layout_marginBottom=\"4dp\"\n        android:gravity=\"center_vertical\"\n        android:text=\"Chapter #\"\n        android:textColor=\"?colorAccent\"\n        android:textSize=\"12sp\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_explorer_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"horizontal\">\n\n    <com.google.android.material.imageview.ShapeableImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"60dp\"\n        android:layout_height=\"85dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"imgRel\"\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n    <RelativeLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"2dp\"\n        android:layout_weight=\"1\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_centerHorizontal=\"true\"\n            android:layout_marginTop=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"18sp\"/>\n\n        <TextView\n            android:id=\"@+id/chapter\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginBottom=\"12dp\"\n            android:lines=\"1\"\n            android:text=\"Chapter #\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"16sp\"/>\n\n    </RelativeLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_faq.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <com.github.florent37.expansionpanel.ExpansionHeader\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        app:expansion_headerIndicator=\"@id/headerIndicator\"\r\n        app:expansion_layout=\"@id/expansionLayout\"\r\n        app:expansion_toggleOnClick=\"true\">\r\n\r\n        <TextView\r\n            android:id=\"@+id/question\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_marginStart=\"8dp\"\r\n            android:layout_marginTop=\"8dp\"\r\n            android:layout_marginEnd=\"40dp\"\r\n            android:layout_marginBottom=\"8dp\"\r\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\r\n            tools:text=\"FAQ Question\" />\r\n\r\n        <ImageView\r\n            android:id=\"@+id/headerIndicator\"\r\n            android:layout_width=\"24dp\"\r\n            android:layout_height=\"24dp\"\r\n            android:layout_gravity=\"center_vertical|end\"\r\n            android:layout_marginStart=\"16dp\"\r\n            android:adjustViewBounds=\"true\"\r\n            app:srcCompat=\"@drawable/faq_indicator\" />\r\n    </com.github.florent37.expansionpanel.ExpansionHeader>\r\n\r\n    <com.github.florent37.expansionpanel.ExpansionLayout\r\n        android:id=\"@+id/expansionLayout\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\">\r\n\r\n            <TextView\r\n                android:id=\"@+id/answer\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_margin=\"8dp\"\r\n                tools:text=\"This is a question answer\" />\r\n        </LinearLayout>\r\n\r\n    </com.github.florent37.expansionpanel.ExpansionLayout>\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_fav.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:layout_marginStart=\"10dp\"\n    android:layout_marginEnd=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\">\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"60dp\"\n            android:layout_height=\"85dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"/>\n\n        <RelativeLayout\n            android:layout_width=\"0dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginStart=\"8dp\"\n            android:layout_marginEnd=\"2dp\"\n            android:layout_weight=\"1\">\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentTop=\"true\"\n                android:layout_centerHorizontal=\"true\"\n                android:layout_marginTop=\"4dp\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:lines=\"2\"\n                android:text=\"Title\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                android:textSize=\"18sp\"/>\n\n            <TextView\n                android:id=\"@+id/type\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentBottom=\"true\"\n                android:layout_marginBottom=\"12dp\"\n                android:lines=\"1\"\n                android:text=\"Type\"\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n                android:textColor=\"?colorAccent\"/>\n\n        </RelativeLayout>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_fav_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"149dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"/>\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginTop=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n            android:textSize=\"14sp\"\n            tools:text=\"Title\"/>\n\n        <TextView\n            android:id=\"@+id/type\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"20dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_marginBottom=\"4dp\"\n            android:gravity=\"center_vertical\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"12sp\"\n            tools:text=\"Type\"/>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_fav_grid_card.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:id=\"@+id/card\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\">\n\n    <com.google.android.material.card.MaterialCardView\n        android:id=\"@+id/card_img\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"149dp\"\n        app:layout_constraintDimensionRatio=\"26:37\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\"\n                tools:srcCompat=\"@tools:sample/backgrounds/scenic\"/>\n\n            <knf.kuma.custom.SeenAnimeOverlay\n                android:id=\"@+id/seenOverlay\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:visibility=\"gone\"/>\n        </RelativeLayout>\n\n    </com.google.android.material.card.MaterialCardView>\n\n    <LinearLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"0dp\"\n        android:orientation=\"vertical\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintDimensionRatio=\"26:16.9\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintHorizontal_bias=\"0.0\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/card_img\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginTop=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n            android:textSize=\"14sp\"\n            tools:text=\"Title\"/>\n\n        <TextView\n            android:id=\"@+id/type\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"20dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_marginBottom=\"4dp\"\n            android:gravity=\"center_vertical\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"12sp\"\n            tools:text=\"Type\"/>\n\n    </LinearLayout>\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_fav_grid_card_material.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:id=\"@+id/card\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:clickable=\"true\"\n    android:clipToPadding=\"false\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:padding=\"8dp\">\n\n    <RelativeLayout\n        android:id=\"@+id/frame_img\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"149dp\"\n        app:layout_constraintDimensionRatio=\"26:37\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"149dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"\n            app:shapeAppearanceOverlay=\"@style/roundedCorners\"\n            tools:srcCompat=\"@tools:sample/backgrounds/scenic\"/>\n\n        <knf.kuma.custom.SeenAnimeOverlay\n            android:id=\"@+id/seenOverlay\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:visibility=\"gone\"/>\n    </RelativeLayout>\n\n    <LinearLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"0dp\"\n        android:orientation=\"vertical\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintDimensionRatio=\"26:16.9\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintHorizontal_bias=\"0.0\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/frame_img\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginTop=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n            android:textSize=\"14sp\"\n            tools:text=\"Title\"/>\n\n        <TextView\n            android:id=\"@+id/type\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"20dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_marginBottom=\"4dp\"\n            android:gravity=\"center_vertical\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"12sp\"\n            tools:text=\"Type\"/>\n\n    </LinearLayout>\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_fav_grid_card_simple.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:id=\"@+id/card\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\">\n\n    <com.google.android.material.card.MaterialCardView\n        android:id=\"@+id/card_img\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"149dp\"\n        app:layout_constraintDimensionRatio=\"26:37\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <ImageView\n                android:id=\"@+id/img\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:scaleType=\"centerCrop\"\n                android:transitionName=\"img\"\n                tools:srcCompat=\"@tools:sample/backgrounds/scenic\"/>\n\n            <knf.kuma.custom.SeenAnimeOverlay\n                android:id=\"@+id/seenOverlay\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:visibility=\"gone\"/>\n        </RelativeLayout>\n\n    </com.google.android.material.card.MaterialCardView>\n\n    <LinearLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"0dp\"\n        android:orientation=\"vertical\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintDimensionRatio=\"26:12\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintHorizontal_bias=\"0.0\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/card_img\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_margin=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n            android:textSize=\"14sp\"\n            tools:text=\"Title\"/>\n\n    </LinearLayout>\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_fav_grid_card_simple_material.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:id=\"@+id/card\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:clickable=\"true\"\n    android:clipToPadding=\"false\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:padding=\"8dp\">\n\n    <RelativeLayout\n        android:id=\"@+id/frame_image\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"149dp\"\n        app:layout_constraintDimensionRatio=\"26:37\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\">\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"149dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"\n            app:shapeAppearanceOverlay=\"@style/roundedCorners\"\n            tools:srcCompat=\"@tools:sample/backgrounds/scenic\"/>\n\n        <knf.kuma.custom.SeenAnimeOverlay\n            android:id=\"@+id/seenOverlay\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:visibility=\"gone\"/>\n    </RelativeLayout>\n\n    <LinearLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"0dp\"\n        android:orientation=\"vertical\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintDimensionRatio=\"26:12\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintHorizontal_bias=\"0.0\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/frame_image\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_margin=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n            android:textSize=\"14sp\"\n            tools:text=\"Title\"/>\n\n    </LinearLayout>\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_fav_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\">\n\n    <com.google.android.material.imageview.ShapeableImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"149dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"img\"\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginTop=\"4dp\"\n        android:layout_marginEnd=\"4dp\"\n        android:ellipsize=\"end\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n        android:textSize=\"14sp\"\n        tools:text=\"Title\"/>\n\n    <TextView\n        android:id=\"@+id/type\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"20dp\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginEnd=\"4dp\"\n        android:layout_marginBottom=\"4dp\"\n        android:gravity=\"center_vertical\"\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n        android:textColor=\"?colorAccent\"\n        android:textSize=\"12sp\"\n        tools:text=\"Type\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_fav_header.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:gravity=\"center_vertical\"\n    android:paddingStart=\"16dp\"\n    android:paddingEnd=\"16dp\"\n    android:orientation=\"horizontal\">\n\n    <TextView\n        android:id=\"@+id/header\"\n              android:layout_width=\"0dp\"\n              android:layout_height=\"wrap_content\"\n              android:layout_marginTop=\"10dp\"\n              android:layout_marginBottom=\"5dp\"\n              android:layout_weight=\"1\"\n              android:text=\"Header\"\n              android:textAppearance=\"@style/TextAppearance.AppCompat.Headline\"/>\n\n    <ImageButton\n        android:id=\"@+id/action\"\n        style=\"@style/Widget.AppCompat.Button.Borderless\"\n        android:layout_width=\"24dp\"\n        android:layout_height=\"24dp\"\n        android:layout_marginStart=\"10dp\"\n        android:layout_marginTop=\"10dp\"\n        android:layout_marginBottom=\"5dp\"\n        android:background=\"@drawable/background_ripple\"\n        android:src=\"@drawable/ic_edit\"/>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_fav_material.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:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:clickable=\"true\"\n    android:clipToPadding=\"false\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"horizontal\"\n    android:paddingStart=\"16dp\"\n    android:paddingTop=\"8dp\"\n    android:paddingEnd=\"16dp\"\n    android:paddingBottom=\"8dp\">\n\n    <com.google.android.material.imageview.ShapeableImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"60dp\"\n        android:layout_height=\"85dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"img\"\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n    <RelativeLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginStart=\"16dp\"\n        android:layout_marginEnd=\"2dp\"\n        android:layout_weight=\"1\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_centerHorizontal=\"true\"\n            android:layout_marginTop=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n            android:textSize=\"18sp\"\n            tools:text=\"Title\"/>\n\n        <TextView\n            android:id=\"@+id/type\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginBottom=\"12dp\"\n            android:lines=\"1\"\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n            android:textColor=\"?colorAccent\"\n            tools:text=\"Type\"/>\n\n    </RelativeLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_native_reduced.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<merge>\r\n\r\n    <!--<com.google.android.gms.ads.nativead.NativeAdView\r\n        android:id=\"@+id/native_ad_view\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_centerInParent=\"true\">\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_centerInParent=\"true\">\r\n\r\n            <LinearLayout\r\n                android:id=\"@+id/background\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:gravity=\"center\"\r\n                android:orientation=\"horizontal\">\r\n\r\n                <ImageView\r\n                    android:id=\"@+id/icon\"\r\n                    android:layout_width=\"48dp\"\r\n                    android:layout_height=\"48dp\"\r\n                    android:layout_gravity=\"center\"\r\n                    android:layout_marginStart=\"16dp\"\r\n                    android:adjustViewBounds=\"true\"\r\n                    android:scaleType=\"centerCrop\"\r\n                    tools:srcCompat=\"@tools:sample/backgrounds/scenic\" />\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"48dp\"\r\n                    android:layout_gravity=\"center_vertical\"\r\n                    android:layout_marginStart=\"16dp\"\r\n                    android:orientation=\"horizontal\">\r\n                    <LinearLayout\r\n                        android:id=\"@+id/headline\"\r\n                        android:layout_width=\"0dp\"\r\n                        android:layout_height=\"match_parent\"\r\n                        android:layout_marginEnd=\"8dp\"\r\n                        android:layout_weight=\"1\"\r\n                        android:gravity=\"center\"\r\n                        android:orientation=\"vertical\">\r\n\r\n                        <TextView\r\n                            android:id=\"@+id/primary\"\r\n                            android:layout_width=\"match_parent\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:lines=\"1\"\r\n                            android:textSize=\"@dimen/gnt_text_size_large\"\r\n                            android:textStyle=\"bold\"\r\n                            tools:text=\"Primary\" />\r\n\r\n                        <TextView\r\n                            android:id=\"@+id/secondary\"\r\n                            android:layout_width=\"match_parent\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:gravity=\"top\"\r\n                            android:lines=\"1\"\r\n                            android:textSize=\"@dimen/gnt_text_size_small\"\r\n                            tools:text=\"Secondary\" />\r\n                    </LinearLayout>\r\n\r\n                    <RelativeLayout\r\n                        android:layout_width=\"90dp\"\r\n                        android:layout_height=\"match_parent\">\r\n                        <Button\r\n                            android:id=\"@+id/cta\"\r\n                            style=\"@style/Widget.MaterialComponents.Button.TextButton\"\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:lines=\"1\"\r\n                            tools:text=\"Abrir\" />\r\n                        <TextView\r\n                            android:id=\"@+id/ad_notification_view\"\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_alignParentEnd=\"true\"\r\n                            android:layout_alignParentBottom=\"true\"\r\n                            android:layout_gravity=\"center_vertical\"\r\n                            android:layout_marginTop=\"@dimen/gnt_ad_indicator_top_margin\"\r\n                            android:layout_marginEnd=\"4dp\"\r\n                            android:text=\"Ad\"\r\n                            android:textColor=\"#FFCA28\"\r\n                            android:textSize=\"@dimen/gnt_ad_indicator_text_size\"\r\n                            android:textStyle=\"bold\" />\r\n                    </RelativeLayout>\r\n                </LinearLayout>\r\n\r\n\r\n            </LinearLayout>\r\n\r\n        </RelativeLayout>\r\n\r\n    </com.google.android.gms.ads.nativead.NativeAdView>-->\r\n\r\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/item_native_small.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<merge>\r\n\r\n    <!--<com.google.android.gms.ads.nativead.NativeAdView\r\n        android:id=\"@+id/native_ad_view\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_centerInParent=\"true\">\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_centerInParent=\"true\">\r\n\r\n            <LinearLayout\r\n                android:id=\"@+id/background\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:orientation=\"horizontal\">\r\n\r\n                <ImageView\r\n                    android:id=\"@+id/icon\"\r\n                    android:layout_width=\"95dp\"\r\n                    android:layout_height=\"95dp\"\r\n                    android:layout_gravity=\"center\"\r\n                    android:adjustViewBounds=\"true\"\r\n                    android:scaleType=\"centerCrop\"\r\n                    tools:srcCompat=\"@tools:sample/backgrounds/scenic\" />\r\n\r\n                <LinearLayout\r\n                    android:id=\"@+id/content\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"85dp\"\r\n                    android:layout_marginStart=\"10dp\"\r\n                    android:layout_marginTop=\"10dp\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <LinearLayout\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_gravity=\"center_vertical\"\r\n                        android:orientation=\"horizontal\">\r\n                        <LinearLayout\r\n                            android:id=\"@+id/headline\"\r\n                            android:layout_width=\"0dp\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_marginEnd=\"8dp\"\r\n                            android:layout_weight=\"1\"\r\n                            android:orientation=\"vertical\">\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/primary\"\r\n                                android:layout_width=\"match_parent\"\r\n                                android:layout_height=\"match_parent\"\r\n                                android:lines=\"1\"\r\n                                android:textSize=\"@dimen/gnt_text_size_large\"\r\n                                android:textStyle=\"bold\"\r\n                                app:layout_constraintBottom_toBottomOf=\"parent\"\r\n                                app:layout_constraintEnd_toEndOf=\"parent\"\r\n                                app:layout_constraintStart_toEndOf=\"parent\"\r\n                                app:layout_constraintTop_toTopOf=\"parent\"\r\n                                tools:text=\"Primary\" />\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/secondary\"\r\n                                android:layout_width=\"match_parent\"\r\n                                android:layout_height=\"wrap_content\"\r\n                                android:gravity=\"top\"\r\n                                android:lines=\"1\"\r\n                                android:textSize=\"@dimen/gnt_text_size_small\"\r\n                                tools:text=\"Secondary\" />\r\n                        </LinearLayout>\r\n\r\n                        <TextView\r\n                            android:id=\"@+id/ad_notification_view\"\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_gravity=\"center_vertical\"\r\n                            android:layout_marginTop=\"@dimen/gnt_ad_indicator_top_margin\"\r\n                            android:layout_marginEnd=\"16dp\"\r\n                            android:gravity=\"center\"\r\n                            android:text=\"Ad\"\r\n                            android:textColor=\"#FFCA28\"\r\n                            android:textSize=\"@dimen/gnt_ad_indicator_text_size\"\r\n                            android:textStyle=\"bold\"\r\n                            app:layout_constraintBottom_toBottomOf=\"parent\"\r\n                            app:layout_constraintStart_toStartOf=\"parent\"\r\n                            app:layout_constraintTop_toTopOf=\"parent\" />\r\n                    </LinearLayout>\r\n\r\n                    <Button\r\n                        android:id=\"@+id/cta\"\r\n                        style=\"@style/Widget.MaterialComponents.Button.TextButton\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:lines=\"1\"\r\n                        tools:text=\"Abrir\" />\r\n\r\n\r\n                </LinearLayout>\r\n\r\n\r\n            </LinearLayout>\r\n\r\n        </RelativeLayout>\r\n\r\n    </com.google.android.gms.ads.nativead.NativeAdView>-->\r\n\r\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/item_native_small_rounded.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<merge>\r\n\r\n    <!--<com.google.android.gms.ads.nativead.NativeAdView\r\n        android:id=\"@+id/native_ad_view\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_centerInParent=\"true\">\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_centerInParent=\"true\">\r\n\r\n            <LinearLayout\r\n                android:id=\"@+id/background\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:orientation=\"horizontal\">\r\n\r\n                <com.google.android.material.imageview.ShapeableImageView\r\n                    android:id=\"@+id/icon\"\r\n                    android:layout_width=\"95dp\"\r\n                    android:layout_height=\"95dp\"\r\n                    android:layout_gravity=\"center\"\r\n                    android:layout_marginEnd=\"16dp\"\r\n                    android:adjustViewBounds=\"true\"\r\n                    android:scaleType=\"centerCrop\"\r\n                    app:shapeAppearanceOverlay=\"@style/roundedCorners\"\r\n                    tools:srcCompat=\"@tools:sample/backgrounds/scenic\" />\r\n\r\n                <LinearLayout\r\n                    android:id=\"@+id/content\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"85dp\"\r\n                    android:layout_marginTop=\"10dp\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <LinearLayout\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_gravity=\"center_vertical\"\r\n                        android:orientation=\"horizontal\">\r\n                        <LinearLayout\r\n                            android:id=\"@+id/headline\"\r\n                            android:layout_width=\"0dp\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_marginEnd=\"8dp\"\r\n                            android:layout_weight=\"1\"\r\n                            android:orientation=\"vertical\">\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/primary\"\r\n                                android:layout_width=\"match_parent\"\r\n                                android:layout_height=\"match_parent\"\r\n                                android:lines=\"1\"\r\n                                android:textSize=\"@dimen/gnt_text_size_large\"\r\n                                android:textStyle=\"bold\"\r\n                                app:layout_constraintBottom_toBottomOf=\"parent\"\r\n                                app:layout_constraintEnd_toEndOf=\"parent\"\r\n                                app:layout_constraintStart_toEndOf=\"parent\"\r\n                                app:layout_constraintTop_toTopOf=\"parent\"\r\n                                tools:text=\"Primary\" />\r\n\r\n                            <TextView\r\n                                android:id=\"@+id/secondary\"\r\n                                android:layout_width=\"match_parent\"\r\n                                android:layout_height=\"wrap_content\"\r\n                                android:gravity=\"top\"\r\n                                android:lines=\"1\"\r\n                                android:textSize=\"@dimen/gnt_text_size_small\"\r\n                                tools:text=\"Secondary\" />\r\n                        </LinearLayout>\r\n\r\n                        <TextView\r\n                            android:id=\"@+id/ad_notification_view\"\r\n                            android:layout_width=\"wrap_content\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_gravity=\"center_vertical\"\r\n                            android:layout_marginTop=\"@dimen/gnt_ad_indicator_top_margin\"\r\n                            android:layout_marginEnd=\"16dp\"\r\n                            android:gravity=\"center\"\r\n                            android:text=\"Ad\"\r\n                            android:textColor=\"#FFCA28\"\r\n                            android:textSize=\"@dimen/gnt_ad_indicator_text_size\"\r\n                            android:textStyle=\"bold\"\r\n                            app:layout_constraintBottom_toBottomOf=\"parent\"\r\n                            app:layout_constraintStart_toStartOf=\"parent\"\r\n                            app:layout_constraintTop_toTopOf=\"parent\" />\r\n                    </LinearLayout>\r\n\r\n                    <Button\r\n                        android:id=\"@+id/cta\"\r\n                        style=\"@style/Widget.MaterialComponents.Button.TextButton\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:lines=\"1\"\r\n                        tools:text=\"Abrir\" />\r\n\r\n\r\n                </LinearLayout>\r\n\r\n\r\n            </LinearLayout>\r\n\r\n        </RelativeLayout>\r\n\r\n    </com.google.android.gms.ads.nativead.NativeAdView>-->\r\n\r\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/item_news.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<com.google.android.material.card.MaterialCardView\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:id=\"@+id/card\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:foreground=\"?selectableItemBackground\"\r\n    android:transitionName=\"background\"\r\n    android:layout_marginStart=\"8dp\"\r\n    android:layout_marginEnd=\"8dp\"\r\n    app:cardCornerRadius=\"2dp\"\r\n    app:cardElevation=\"2dp\"\r\n    app:contentPadding=\"8dp\">\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <TextView\r\n            android:id=\"@+id/metadata\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:textColor=\"?colorAccent\"\r\n            android:textSize=\"15sp\"\r\n            tools:text=\"Author — Date in text\"/>\r\n\r\n        <TextView\r\n            android:id=\"@+id/title\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:ellipsize=\"end\"\r\n            android:gravity=\"center_vertical\"\r\n            android:lines=\"2\"\r\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\r\n            android:textSize=\"21sp\"\r\n            android:textStyle=\"bold\"\r\n            android:transitionName=\"title\"\r\n            tools:text=\"Title\"/>\r\n\r\n        <TextView\r\n            android:id=\"@+id/description\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:ellipsize=\"end\"\r\n            android:lines=\"4\"\r\n            android:textSize=\"17sp\"\r\n            android:transitionName=\"content\"\r\n            tools:text=\"Cu error laoreet his. Usu ancillae noluisse an. Ad hendrerit elaboraret vis, sea salutandi salutatus ut. Vis ad errem epicurei tacimates, mei ut paulo exerci admodum. Choro tollit epicuri et ius, qui dolore eligendi te, ad errem philosophia cum.\"/>\r\n    </LinearLayout>\r\n\r\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_news_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:id=\"@+id/root\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:layout_marginBottom=\"12dp\"\r\n    android:clickable=\"true\"\r\n    android:focusable=\"true\"\r\n    android:foreground=\"?selectableItemBackground\"\r\n    android:orientation=\"vertical\"\r\n    android:paddingStart=\"16dp\"\r\n    android:paddingEnd=\"16dp\">\r\n\r\n    <RelativeLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\">\r\n\r\n        <com.google.android.material.imageview.ShapeableImageView\r\n            android:id=\"@+id/image\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"180dp\"\r\n            android:scaleType=\"centerCrop\"\r\n            app:shapeAppearanceOverlay=\"@style/roundedCorners\"\r\n            tools:srcCompat=\"@tools:sample/backgrounds/scenic\" />\r\n\r\n        <ProgressBar\r\n            android:id=\"@+id/progress\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_centerInParent=\"true\" />\r\n    </RelativeLayout>\r\n\r\n    <TextView\r\n        android:id=\"@+id/type\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginTop=\"12dp\"\r\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Overline\"\r\n        android:textColor=\"?colorAccentLight\"\r\n        tools:text=\"Article type\" />\r\n\r\n    <TextView\r\n        android:id=\"@+id/title\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:layout_marginTop=\"4dp\"\r\n        android:ellipsize=\"end\"\r\n        android:lines=\"2\"\r\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\r\n        tools:text=\"Article\\ntitle\" />\r\n\r\n    <TextView\r\n        android:id=\"@+id/date\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginTop=\"8dp\"\r\n        android:layout_marginBottom=\"8dp\"\r\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\"\r\n        tools:text=\"99/99/99\" />\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_queue.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"horizontal\"\n    android:padding=\"8dp\">\n\n    <ImageView\n        android:id=\"@+id/icon\"\n        android:layout_width=\"24dp\"\n        android:layout_height=\"24dp\"\n        android:layout_gravity=\"center\"\n        app:srcCompat=\"@drawable/bottom_settings\"/>\n\n    <TextView\n        android:id=\"@+id/chapter\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginTop=\"4dp\"\n        android:layout_marginBottom=\"4dp\"\n        android:layout_weight=\"1\"\n        android:text=\"Chapter #\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n        android:textSize=\"16sp\"/>\n\n    <ImageButton\n        android:id=\"@+id/action_delete\"\n        style=\"?borderlessButtonStyle\"\n        android:layout_width=\"24dp\"\n        android:layout_height=\"24dp\"\n        android:layout_gravity=\"center\"\n        android:src=\"@drawable/ic_action_close\"/>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_queue_full.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"1dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"0dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\">\n\n        <ImageView\n            android:id=\"@+id/drag\"\n            android:layout_width=\"30dp\"\n            android:layout_height=\"71dp\"\n            android:clickable=\"true\"\n            android:padding=\"12dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"\n            app:srcCompat=\"@drawable/ic_drag\"/>\n\n        <RelativeLayout\n            android:layout_width=\"0dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginStart=\"8dp\"\n            android:layout_marginEnd=\"2dp\"\n            android:layout_weight=\"1\">\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentTop=\"true\"\n                android:layout_centerHorizontal=\"true\"\n                android:layout_marginTop=\"4dp\"\n                android:layout_marginEnd=\"4dp\"\n                android:layout_toLeftOf=\"@+id/state\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:lines=\"2\"\n                android:text=\"Title\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textSize=\"16sp\"/>\n\n            <TextView\n                android:id=\"@+id/chapter\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentBottom=\"true\"\n                android:layout_marginEnd=\"4dp\"\n                android:layout_marginBottom=\"8dp\"\n                android:layout_toLeftOf=\"@+id/state\"\n                android:lines=\"1\"\n                android:text=\"Chapter\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n                android:textColor=\"?colorAccent\"\n                android:textSize=\"14sp\"/>\n\n            <ImageView\n                android:id=\"@+id/state\"\n                android:layout_width=\"24dp\"\n                android:layout_height=\"24dp\"\n                android:layout_alignParentEnd=\"true\"\n                android:layout_centerVertical=\"true\"\n                android:layout_marginEnd=\"8dp\"/>\n\n        </RelativeLayout>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_queue_full_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"1dp\"\n    android:orientation=\"horizontal\">\n\n    <ImageView\n        android:id=\"@+id/drag\"\n        android:layout_width=\"30dp\"\n        android:layout_height=\"71dp\"\n        android:clickable=\"true\"\n        android:padding=\"12dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"img\"\n        app:srcCompat=\"@drawable/ic_drag\"/>\n\n    <RelativeLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"2dp\"\n        android:layout_weight=\"1\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_centerHorizontal=\"true\"\n            android:layout_marginTop=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_toLeftOf=\"@+id/state\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"16sp\"/>\n\n        <TextView\n            android:id=\"@+id/chapter\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_marginBottom=\"8dp\"\n            android:layout_toLeftOf=\"@+id/state\"\n            android:lines=\"1\"\n            android:text=\"Chapter\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"14sp\"/>\n\n        <ImageView\n            android:id=\"@+id/state\"\n            android:layout_width=\"24dp\"\n            android:layout_height=\"24dp\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_centerVertical=\"true\"\n            android:layout_marginEnd=\"8dp\"/>\n\n    </RelativeLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_ranking.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginTop=\"8dp\"\n    android:theme=\"@style/AppTheme.Cardview\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_vertical\"\n            android:orientation=\"horizontal\">\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_margin=\"4dp\"\n                android:layout_weight=\"1\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:lines=\"2\"\n                android:text=\"Title\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textSize=\"16sp\"/>\n\n            <TextView\n                android:id=\"@+id/count\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center_vertical\"\n                android:layout_marginEnd=\"4dp\"\n                android:gravity=\"center_vertical\"\n                android:text=\"##\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"/>\n        </LinearLayout>\n\n        <ProgressBar\n            android:id=\"@+id/ranking\"\n            style=\"@android:style/Widget.Material.ProgressBar.Horizontal\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginEnd=\"4dp\"/>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_ranking_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginTop=\"8dp\"\n    android:orientation=\"vertical\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center_vertical\"\n        android:orientation=\"horizontal\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_margin=\"4dp\"\n            android:layout_weight=\"1\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"16sp\"/>\n\n        <TextView\n            android:id=\"@+id/count\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_vertical\"\n            android:layout_marginEnd=\"4dp\"\n            android:gravity=\"center_vertical\"\n            android:text=\"##\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"/>\n    </LinearLayout>\n\n    <ProgressBar\n        android:id=\"@+id/ranking\"\n        style=\"@android:style/Widget.Material.ProgressBar.Horizontal\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginEnd=\"4dp\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_recents.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginStart=\"10dp\"\n    android:layout_marginTop=\"10dp\"\n    android:layout_marginEnd=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"142dp\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"horizontal\">\n\n            <RelativeLayout\n                android:layout_width=\"100dp\"\n                android:layout_height=\"142dp\">\n\n                <ImageView\n                    android:id=\"@+id/img\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"\n                    android:scaleType=\"centerCrop\"\n                    android:transitionName=\"img\"/>\n\n                <knf.kuma.custom.SeenAnimeOverlay\n                    android:id=\"@+id/seenOverlay\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"match_parent\"/>\n            </RelativeLayout>\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"142dp\"\n                android:orientation=\"vertical\">\n\n                <LinearLayout\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"0dp\"\n                    android:layout_weight=\"1\"\n                    android:baselineAligned=\"false\"\n                    android:orientation=\"horizontal\">\n\n                    <RelativeLayout\n                        android:layout_width=\"0dp\"\n                        android:layout_height=\"match_parent\"\n                        android:layout_marginStart=\"8dp\"\n                        android:layout_marginEnd=\"2dp\"\n                        android:layout_weight=\"1\">\n\n                        <TextView\n                            android:id=\"@+id/title\"\n                            android:layout_width=\"match_parent\"\n                            android:layout_height=\"wrap_content\"\n                            android:layout_alignParentTop=\"true\"\n                            android:layout_centerHorizontal=\"true\"\n                            android:layout_marginTop=\"8dp\"\n                            android:ellipsize=\"end\"\n                            android:gravity=\"center_vertical\"\n                            android:lines=\"2\"\n                            android:text=\"Title\"\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\n                            android:textSize=\"18sp\"/>\n\n                        <TextView\n                            android:id=\"@+id/chapter\"\n                            android:layout_width=\"match_parent\"\n                            android:layout_height=\"wrap_content\"\n                            android:layout_alignParentBottom=\"true\"\n                            android:layout_marginBottom=\"8dp\"\n                            android:lines=\"1\"\n                            android:text=\"Chapter\"\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\n                            android:textColor=\"?android:attr/textColorSecondary\"/>\n\n                    </RelativeLayout>\n\n                    <LinearLayout\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"match_parent\"\n                        android:layout_marginTop=\"5dp\"\n                        android:layout_marginEnd=\"5dp\"\n                        android:layout_marginBottom=\"5dp\"\n                        android:gravity=\"center_vertical\"\n                        android:orientation=\"vertical\">\n\n                        <ImageView\n                            android:id=\"@+id/new_icon\"\n                            android:layout_width=\"24dp\"\n                            android:layout_height=\"24dp\"\n                            android:tint=\"#FFEB3B\"\n                            android:visibility=\"gone\"\n                            app:srcCompat=\"@drawable/ic_new\"/>\n\n                        <ImageView\n                            android:id=\"@+id/fav_icon\"\n                            android:layout_width=\"24dp\"\n                            android:layout_height=\"24dp\"\n                            android:tint=\"#F44336\"\n                            android:visibility=\"gone\"\n                            app:srcCompat=\"@drawable/heart_full\"/>\n\n                        <ImageView\n                            android:id=\"@+id/down_icon\"\n                            android:layout_width=\"24dp\"\n                            android:layout_height=\"24dp\"\n                            android:visibility=\"gone\"\n                            app:srcCompat=\"@drawable/ic_download\"/>\n\n                    </LinearLayout>\n                </LinearLayout>\n\n                <View\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"1dp\"\n                    android:alpha=\"0.12\"\n                    android:background=\"@color/divider\"/>\n\n                <LinearLayout\n                    android:id=\"@+id/lay_buttons\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\"\n                    android:orientation=\"horizontal\"\n                    android:weightSum=\"2\">\n\n                    <com.google.android.material.button.MaterialButton\n                        android:id=\"@+id/streaming\"\n                        style=\"@style/Widget.MaterialComponents.Button.TextButton\"\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_weight=\"1\"\n                        android:text=\"STREAMING\" />\n\n                    <com.google.android.material.button.MaterialButton\n                        android:id=\"@+id/download\"\n                        style=\"@style/Widget.MaterialComponents.Button.TextButton\"\n                        android:layout_width=\"wrap_content\"\n                        android:layout_height=\"wrap_content\"\n                        android:layout_weight=\"1\"\n                        android:text=\"DESCARGA\" />\n                </LinearLayout>\n            </LinearLayout>\n        </LinearLayout>\n\n        <FrameLayout\n            android:id=\"@+id/progress_root\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"3dp\"\n            android:layout_alignParentBottom=\"true\"\n            android:visibility=\"gone\">\n\n            <ProgressBar\n                android:id=\"@+id/progress\"\n                style=\"@style/Widget.AppCompat.ProgressBar.Horizontal\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"20dp\"\n                android:layout_gravity=\"center\"\n                android:progress=\"50\"/>\n        </FrameLayout>\n    </RelativeLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_recents_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:id=\"@+id/root\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"101dp\"\r\n    android:baselineAligned=\"false\"\r\n    android:clickable=\"true\"\r\n    android:clipToPadding=\"false\"\r\n    android:focusable=\"true\"\r\n    android:foreground=\"?selectableItemBackground\"\r\n    android:orientation=\"horizontal\"\r\n    android:paddingStart=\"16dp\"\r\n    android:paddingTop=\"8dp\"\r\n    android:paddingEnd=\"11dp\"\r\n    android:paddingBottom=\"8dp\">\r\n\r\n    <com.google.android.material.card.MaterialCardView\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:clickable=\"false\"\r\n        android:focusable=\"false\"\r\n        app:cardElevation=\"0dp\"\r\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\">\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"85dp\"\r\n            android:layout_height=\"85dp\">\r\n\r\n            <com.google.android.material.imageview.ShapeableImageView\r\n                android:id=\"@+id/image\"\r\n                android:layout_width=\"85dp\"\r\n                android:layout_height=\"85dp\"\r\n                android:scaleType=\"centerCrop\"\r\n                app:shapeAppearanceOverlay=\"@style/roundedCorners\"\r\n                tools:srcCompat=\"@tools:sample/backgrounds/scenic\" />\r\n\r\n            <RelativeLayout\r\n                android:id=\"@+id/layDownloading\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"match_parent\"\r\n                android:layout_centerInParent=\"true\"\r\n                android:background=\"#59000000\"\r\n                android:visibility=\"gone\"\r\n                tools:visibility=\"visible\">\r\n\r\n                <com.google.android.material.progressindicator.CircularProgressIndicator\r\n                    android:id=\"@+id/progressIndicator\"\r\n                    style=\"@style/Widget.MaterialComponents.CircularProgressIndicator\"\r\n                    android:layout_width=\"77dp\"\r\n                    android:layout_height=\"77dp\"\r\n                    android:layout_centerInParent=\"true\"\r\n                    android:max=\"100\" />\r\n\r\n                <ImageView\r\n                    android:id=\"@+id/actionCancel\"\r\n                    android:layout_width=\"48dp\"\r\n                    android:layout_height=\"48dp\"\r\n                    android:layout_centerInParent=\"true\"\r\n                    android:background=\"@drawable/background_ripple\"\r\n                    android:clickable=\"true\"\r\n                    android:focusable=\"true\"\r\n                    android:padding=\"11dp\"\r\n                    android:scaleType=\"fitCenter\"\r\n                    app:srcCompat=\"@drawable/ic_close\" />\r\n            </RelativeLayout>\r\n\r\n            <RelativeLayout\r\n                android:id=\"@+id/seenIndicator\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"match_parent\"\r\n                android:layout_alignParentEnd=\"true\"\r\n                android:background=\"@drawable/circular_shade\"\r\n                android:visibility=\"gone\"\r\n                tools:visibility=\"visible\">\r\n\r\n                <ImageView\r\n                    android:layout_width=\"18dp\"\r\n                    android:layout_height=\"18dp\"\r\n                    android:layout_alignParentEnd=\"true\"\r\n                    android:layout_margin=\"4dp\"\r\n                    app:srcCompat=\"@drawable/ic_seen\"\r\n                    app:tint=\"?colorSecondaryVariant\" />\r\n            </RelativeLayout>\r\n        </RelativeLayout>\r\n    </com.google.android.material.card.MaterialCardView>\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"0dp\"\r\n        android:layout_height=\"85dp\"\r\n        android:layout_marginStart=\"16dp\"\r\n        android:layout_weight=\"1\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:orientation=\"horizontal\">\r\n\r\n            <TextView\r\n                android:id=\"@+id/chapter\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:lines=\"1\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Overline\"\r\n                android:textColor=\"?colorSecondaryVariant\"\r\n                tools:text=\"Episodio ##\" />\r\n\r\n            <ImageView\r\n                android:id=\"@+id/newIndicator\"\r\n                android:layout_width=\"14dp\"\r\n                android:layout_height=\"14dp\"\r\n                android:layout_marginStart=\"4dp\"\r\n                android:visibility=\"gone\"\r\n                app:srcCompat=\"@drawable/ic_error\"\r\n                app:tint=\"#FDD835\"\r\n                tools:visibility=\"visible\" />\r\n            <ImageView\r\n                android:id=\"@+id/favIndicator\"\r\n                android:layout_width=\"14dp\"\r\n                android:layout_height=\"14dp\"\r\n                android:layout_gravity=\"center_vertical|end\"\r\n                android:layout_marginStart=\"4dp\"\r\n                android:layout_marginEnd=\"3dp\"\r\n                android:visibility=\"gone\"\r\n                app:srcCompat=\"@drawable/heart_full\"\r\n                app:tint=\"@color/material_red_500\"\r\n                tools:visibility=\"visible\" />\r\n        </LinearLayout>\r\n\r\n        <TextView\r\n            android:id=\"@+id/name\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:ellipsize=\"end\"\r\n            android:gravity=\"top|center_vertical\"\r\n            android:maxLines=\"2\"\r\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\r\n            tools:text=\"Anime long long long long long long long title\" />\r\n\r\n        <FrameLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"match_parent\">\r\n\r\n            <com.google.android.material.chip.Chip\r\n                android:id=\"@+id/downloadedChip\"\r\n                style=\"@style/Widget.MaterialComponents.Chip.Action\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"24dp\"\r\n                android:minWidth=\"100dp\"\r\n                android:layout_gravity=\"bottom\"\r\n                android:clickable=\"false\"\r\n                android:text=\"Descargado\"\r\n                android:textColor=\"@android:color/white\"\r\n                android:visibility=\"gone\"\r\n                app:chipBackgroundColor=\"?colorAccent\"\r\n                app:chipMinTouchTargetSize=\"0dp\"\r\n                tools:visibility=\"visible\" />\r\n        </FrameLayout>\r\n    </LinearLayout>\r\n\r\n    <FrameLayout\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"match_parent\">\r\n\r\n        <ImageView\r\n            android:id=\"@+id/actionMenu\"\r\n            android:layout_width=\"32dp\"\r\n            android:layout_height=\"32dp\"\r\n            android:background=\"@drawable/background_ripple\"\r\n            android:clickable=\"true\"\r\n            android:focusable=\"true\"\r\n            android:padding=\"4dp\"\r\n            app:srcCompat=\"@drawable/action_chapter\" />\r\n    </FrameLayout>\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_recommend_header.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          android:id=\"@+id/title\"\n          android:layout_width=\"match_parent\"\n          android:layout_height=\"wrap_content\"\n          android:padding=\"8dp\"\n          android:text=\"Genre Names\"\n          android:textAppearance=\"@style/TextAppearance.AppCompat.Title\">\n\n</TextView>"
  },
  {
    "path": "app/src/main/res/layout/item_record.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\">\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"60dp\"\n            android:layout_height=\"85dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"/>\n\n        <RelativeLayout\n            android:layout_width=\"0dp\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginStart=\"8dp\"\n            android:layout_marginEnd=\"2dp\"\n            android:layout_weight=\"1\">\n\n            <TextView\n                android:id=\"@+id/title\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentTop=\"true\"\n                android:layout_centerHorizontal=\"true\"\n                android:layout_marginTop=\"4dp\"\n                android:ellipsize=\"end\"\n                android:gravity=\"center_vertical\"\n                android:lines=\"2\"\n                android:text=\"Title\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textSize=\"18sp\"/>\n\n            <TextView\n                android:id=\"@+id/chapter\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_alignParentBottom=\"true\"\n                android:layout_marginBottom=\"12dp\"\n                android:lines=\"1\"\n                android:text=\"Chapter\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n                android:textColor=\"?colorAccent\"\n                android:textSize=\"16sp\"/>\n\n        </RelativeLayout>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_record_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.card.MaterialCardView\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:layout_margin=\"5dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.Cardview\"\n    app:cardCornerRadius=\"2dp\"\n    app:cardElevation=\"2dp\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"149dp\"\n            android:scaleType=\"centerCrop\"\n            android:transitionName=\"img\"/>\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"40dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginTop=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"14sp\"/>\n\n        <TextView\n            android:id=\"@+id/chapter\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"20dp\"\n            android:layout_marginStart=\"4dp\"\n            android:layout_marginEnd=\"4dp\"\n            android:layout_marginBottom=\"4dp\"\n            android:gravity=\"center_vertical\"\n            android:text=\"Chapter\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"12sp\"/>\n\n    </LinearLayout>\n</com.google.android.material.card.MaterialCardView>"
  },
  {
    "path": "app/src/main/res/layout/item_record_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center_horizontal\"\n    android:clickable=\"true\"\n    android:clipToPadding=\"false\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"vertical\"\n    android:padding=\"8dp\">\n\n    <com.google.android.material.imageview.ShapeableImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"149dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"img\"\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"40dp\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginTop=\"4dp\"\n        android:layout_marginEnd=\"4dp\"\n        android:ellipsize=\"end\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:text=\"Title\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n        android:textSize=\"14sp\"/>\n\n    <TextView\n        android:id=\"@+id/chapter\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"20dp\"\n        android:layout_marginStart=\"4dp\"\n        android:layout_marginEnd=\"4dp\"\n        android:layout_marginBottom=\"4dp\"\n        android:gravity=\"center_vertical\"\n        android:text=\"Chapter\"\n        android:textColor=\"?colorAccent\"\n        android:textSize=\"12sp\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_record_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginBottom=\"10dp\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:orientation=\"horizontal\">\n\n    <com.google.android.material.imageview.ShapeableImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"60dp\"\n        android:layout_height=\"85dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"img\"\n        app:shapeAppearanceOverlay=\"@style/roundedCorners\"/>\n\n    <RelativeLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"match_parent\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"2dp\"\n        android:layout_weight=\"1\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_centerHorizontal=\"true\"\n            android:layout_marginTop=\"4dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"18sp\"/>\n\n        <TextView\n            android:id=\"@+id/chapter\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginBottom=\"12dp\"\n            android:lines=\"1\"\n            android:text=\"Chapter\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n            android:textColor=\"?colorAccent\"\n            android:textSize=\"16sp\"/>\n\n    </RelativeLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_related.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/card\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:clickable=\"true\"\n    android:focusable=\"true\"\n    android:foreground=\"?selectableItemBackground\"\n    android:orientation=\"horizontal\">\n\n    <ImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"60dp\"\n        android:layout_height=\"85dp\"\n        android:scaleType=\"centerCrop\"\n        android:transitionName=\"imgRel\"\n        android:visibility=\"visible\"/>\n\n    <RelativeLayout\n        android:layout_width=\"0dp\"\n        android:layout_height=\"85dp\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"2dp\"\n        android:layout_weight=\"1\">\n\n        <TextView\n            android:id=\"@+id/title\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_centerHorizontal=\"true\"\n            android:layout_marginTop=\"8dp\"\n            android:ellipsize=\"end\"\n            android:gravity=\"center_vertical\"\n            android:lines=\"2\"\n            android:text=\"Title\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textSize=\"18sp\"/>\n\n        <TextView\n            android:id=\"@+id/relation\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            android:layout_marginBottom=\"8dp\"\n            android:lines=\"1\"\n            android:text=\"Relation\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n            android:textSize=\"16sp\"/>\n\n    </RelativeLayout>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_release.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:orientation=\"vertical\">\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:alpha=\"0.12\"\n        android:background=\"@color/divider\"/>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginTop=\"4dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:layout_marginBottom=\"4dp\"\n        android:gravity=\"center_vertical\"\n        android:orientation=\"horizontal\">\n\n        <TextView\n            android:id=\"@+id/type\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginEnd=\"5dp\"\n            android:background=\"@drawable/chip_shape\"\n            android:elevation=\"2dp\"\n            android:gravity=\"center_horizontal\"\n            android:minWidth=\"75dp\"\n            android:text=\"Type\"\n            android:textColor=\"@android:color/white\"/>\n\n        <TextView\n            android:id=\"@+id/description\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center_vertical\"\n            android:text=\"Description\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"/>\n    </LinearLayout>\n\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_release_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_marginStart=\"16dp\"\n    android:layout_marginTop=\"8dp\"\n    android:layout_marginEnd=\"16dp\"\n    android:gravity=\"center_vertical\"\n    android:orientation=\"horizontal\">\n\n    <com.google.android.material.chip.Chip\n        android:id=\"@+id/type\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"26dp\"\n        android:layout_marginEnd=\"5dp\"\n        android:clickable=\"false\"\n        android:elevation=\"2dp\"\n        android:minWidth=\"75dp\"\n        android:text=\"Type\"\n        android:textAlignment=\"center\"\n        android:textColor=\"@android:color/white\"\n        android:textSize=\"12sp\"\n        app:chipMinTouchTargetSize=\"0dp\" />\n\n    <TextView\n        android:id=\"@+id/description\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center_vertical\"\n        android:text=\"Description\"\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\"/>\n\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_simple_spinner.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<TextView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n          xmlns:tools=\"http://schemas.android.com/tools\"\n          android:id=\"@android:id/text1\"\n          android:layout_width=\"match_parent\"\n          android:layout_height=\"wrap_content\"\n          android:gravity=\"center_vertical\"\n          android:minHeight=\"?android:attr/listPreferredItemHeightSmall\"\n          android:paddingStart=\"?android:attr/listPreferredItemPaddingStart\"\n          android:paddingEnd=\"?android:attr/listPreferredItemPaddingEnd\"\n          android:textAppearance=\"@style/TextAppearance.AppCompat.Widget.DropDownItem\"\n          android:textColor=\"@color/textPrimary\"\n          tools:text=\"jajdna\"/>"
  },
  {
    "path": "app/src/main/res/layout/item_top.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:gravity=\"center_vertical\"\r\n    android:orientation=\"horizontal\"\r\n    android:paddingStart=\"8dp\"\r\n    android:paddingTop=\"4dp\"\r\n    android:paddingEnd=\"8dp\"\r\n    android:paddingBottom=\"4dp\">\r\n\r\n    <ImageView\r\n        android:id=\"@+id/trophy\"\r\n        android:layout_width=\"24dp\"\r\n        android:layout_height=\"24dp\"\r\n        tools:srcCompat=\"@drawable/ic_trophy_gold\"\r\n        tools:visibility=\"invisible\" />\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"0dp\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginStart=\"8dp\"\r\n        android:layout_marginEnd=\"8dp\"\r\n        android:layout_weight=\"1\"\r\n        android:orientation=\"vertical\">\r\n        <TextView\r\n            android:id=\"@+id/ranking\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Overline\"\r\n            tools:text=\"#999999\" />\r\n\r\n        <TextView\r\n            android:id=\"@+id/name\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:ellipsize=\"end\"\r\n            android:lines=\"1\"\r\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\r\n            tools:text=\"Top name\" />\r\n    </LinearLayout>\r\n\r\n    <TextView\r\n        android:id=\"@+id/counter\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\"\r\n        android:textColor=\"?colorSecondary\"\r\n        android:textSize=\"16sp\"\r\n        tools:text=\"9999999\" />\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_top_current.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:background=\"?colorSecondaryVariant\"\r\n    android:gravity=\"center_vertical\"\r\n    android:orientation=\"horizontal\"\r\n    android:paddingStart=\"8dp\"\r\n    android:paddingTop=\"4dp\"\r\n    android:paddingEnd=\"8dp\"\r\n    android:paddingBottom=\"4dp\">\r\n\r\n    <ImageView\r\n        android:id=\"@+id/trophy\"\r\n        android:layout_width=\"24dp\"\r\n        android:layout_height=\"24dp\"\r\n        tools:srcCompat=\"@drawable/ic_trophy_gold\"\r\n        tools:visibility=\"visible\" />\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"0dp\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginStart=\"8dp\"\r\n        android:layout_marginEnd=\"8dp\"\r\n        android:layout_weight=\"1\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <TextView\r\n            android:id=\"@+id/ranking\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Overline\"\r\n            android:textColor=\"?colorOnSecondary\"\r\n            tools:text=\"#999999\" />\r\n\r\n        <TextView\r\n            android:id=\"@+id/name\"\r\n            android:layout_width=\"wrap_content\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:ellipsize=\"end\"\r\n            android:lines=\"1\"\r\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle1\"\r\n            android:textColor=\"?colorOnSecondary\"\r\n            tools:text=\"Top name\" />\r\n    </LinearLayout>\r\n\r\n    <TextView\r\n        android:id=\"@+id/counter\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\"\r\n        android:textColor=\"?colorOnSecondary\"\r\n        android:textSize=\"16sp\"\r\n        tools:text=\"9999999\" />\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_tv_card.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"180dp\"\n    android:layout_height=\"280dp\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        android:scaleType=\"centerCrop\"\n        tools:srcCompat=\"@tools:sample/backgrounds/scenic\" />\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:paddingTop=\"8dp\"\n        android:paddingBottom=\"8dp\"\n        android:textSize=\"14sp\"\n        tools:text=\"Title\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_tv_card_adv.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=\"180dp\"\n    android:layout_height=\"280dp\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        android:scaleType=\"centerCrop\"\n        tools:srcCompat=\"@tools:sample/backgrounds/scenic\" />\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:paddingTop=\"8dp\"\n        android:paddingBottom=\"4dp\"\n        android:textSize=\"14sp\"\n        tools:text=\"Title\" />\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center_vertical\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:orientation=\"horizontal\"\n        android:paddingBottom=\"4dp\">\n\n        <TextView\n            android:id=\"@+id/rating\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            android:textColor=\"@color/colorAccent\"\n            android:textSize=\"12sp\"\n            android:textStyle=\"bold\"\n            tools:text=\"★?.?\" />\n\n        <TextView\n            android:id=\"@+id/type\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:textSize=\"12sp\"\n            tools:text=\"Anime?\" />\n    </LinearLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_tv_card_chapter.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"180dp\"\n    android:layout_height=\"280dp\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        android:scaleType=\"centerCrop\"/>\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:paddingStart=\"8dp\"\n        android:paddingTop=\"8dp\"\n        android:paddingEnd=\"8dp\"\n        android:textSize=\"14sp\"\n        tools:text=\"Title\"/>\n\n    <TextView\n        android:id=\"@+id/chapter\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:paddingStart=\"8dp\"\n        android:paddingEnd=\"8dp\"\n        android:paddingBottom=\"8dp\"\n        android:text=\"Chapter\"\n        android:textColor=\"@color/colorAccent\"\n        android:textSize=\"12sp\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_tv_card_chapter_preview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"280dp\"\n    android:layout_height=\"200dp\"\n    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\">\n\n        <ImageView\n            android:id=\"@+id/img\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:scaleType=\"centerCrop\"/>\n\n        <ImageView\n            android:id=\"@+id/indicator\"\n            android:layout_width=\"36dp\"\n            android:layout_height=\"36dp\"\n            android:layout_alignParentTop=\"true\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_margin=\"8dp\"\n            android:background=\"@drawable/ic_check_tv\"/>\n    </RelativeLayout>\n\n    <TextView\n        android:id=\"@+id/chapter\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"1\"\n        android:padding=\"8dp\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n        tools:text=\"Title\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_tv_card_rate.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=\"180dp\"\n    android:layout_height=\"280dp\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        android:scaleType=\"centerCrop\"\n        tools:srcCompat=\"@tools:sample/backgrounds/scenic\" />\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:paddingTop=\"8dp\"\n        android:paddingBottom=\"4dp\"\n        android:textSize=\"14sp\"\n        tools:text=\"Title\" />\n\n    <TextView\n        android:id=\"@+id/rating\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:paddingBottom=\"4dp\"\n        android:textColor=\"@color/colorAccent\"\n        android:textSize=\"12sp\"\n        android:textStyle=\"bold\"\n        tools:text=\"★?.?\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_tv_card_section.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=\"180dp\"\n    android:layout_height=\"165dp\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"130dp\"\n        android:padding=\"24dp\"\n        tools:srcCompat=\"@drawable/ic_directory_not\" />\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"35dp\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"1\"\n        android:paddingTop=\"8dp\"\n        android:paddingBottom=\"8dp\"\n        android:textSize=\"14sp\"\n        tools:text=\"Title\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_tv_card_sync.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"280dp\"\n    android:layout_height=\"250dp\"\n    android:orientation=\"vertical\">\n\n    <ImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_weight=\"1\"\n        android:scaleType=\"centerCrop\"/>\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"1\"\n        android:padding=\"8dp\"\n        android:textSize=\"14sp\"\n        tools:text=\"Title\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_tv_tag.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:gravity=\"center_vertical\"\n    android:orientation=\"horizontal\"\n    android:padding=\"8dp\">\n\n    <ImageView\n        android:layout_width=\"24dp\"\n        android:layout_height=\"24dp\"\n        android:scaleType=\"centerCrop\"\n        android:src=\"@drawable/ic_tag\"\n        app:srcCompat=\"@drawable/ic_tag\"/>\n\n    <TextView\n        android:id=\"@+id/title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:gravity=\"center_vertical\"\n        android:lines=\"2\"\n        android:textSize=\"14sp\"\n        tools:text=\"Tag name\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_widget_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@android:color/white\">\n\n    <LinearLayout\n        android:id=\"@+id/linear\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:background=\"@color/cardview_background\"\n        android:clickable=\"true\"\n        android:foreground=\"?android:attr/selectableItemBackground\"\n        android:orientation=\"vertical\"\n        android:padding=\"15dp\">\n\n        <TextView\n            android:id=\"@+id/heading\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:singleLine=\"true\"\n            android:text=\"Heading\"\n            android:textColor=\"@color/textSecondary\"\n            android:textSize=\"16sp\"\n            android:textStyle=\"bold\"/>\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/lay_banner_container.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <View\r\n        android:id=\"@+id/spaceTop\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"8dp\"\r\n        android:visibility=\"gone\" />\r\n\r\n    <FrameLayout\r\n        android:id=\"@+id/container\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\" />\r\n\r\n    <View\r\n        android:id=\"@+id/spaceBottom\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"0dp\"\r\n        android:visibility=\"gone\" />\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/lay_bottom_actions.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@color/cardview_background\"\n    android:orientation=\"vertical\"\n    android:theme=\"@style/AppTheme.DayNight\">\n\n    <TextView\n        android:id=\"@+id/action_seen\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"56dp\"\n        android:clickable=\"true\"\n        android:drawableStart=\"@drawable/ic_option_seen\"\n        android:drawablePadding=\"32dp\"\n        android:drawableTint=\"?colorControlNormal\"\n        android:focusable=\"true\"\n        android:foreground=\"?selectableItemBackground\"\n        android:gravity=\"start|center_vertical\"\n        android:paddingStart=\"16dp\"\n        android:paddingEnd=\"16dp\"\n        android:text=\"Marcar como vistos\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Large\"\n        android:textSize=\"16sp\"/>\n\n    <TextView\n        android:id=\"@+id/action_unseen\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"56dp\"\n        android:background=\"?selectableItemBackground\"\n        android:clickable=\"true\"\n        android:drawableStart=\"@drawable/ic_option_not_seen\"\n        android:drawablePadding=\"32dp\"\n        android:drawableTint=\"?colorControlNormal\"\n        android:focusable=\"true\"\n        android:gravity=\"start|center_vertical\"\n        android:paddingStart=\"16dp\"\n        android:paddingEnd=\"16dp\"\n        android:text=\"Marcar como no vistos\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Large\"\n        android:textSize=\"16sp\"/>\n\n    <TextView\n        android:id=\"@+id/action_import_all\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"56dp\"\n        android:background=\"?selectableItemBackground\"\n        android:clickable=\"true\"\n        android:drawableStart=\"@drawable/ic_import\"\n        android:drawablePadding=\"32dp\"\n        android:drawableTint=\"?colorControlNormal\"\n        android:focusable=\"true\"\n        android:gravity=\"start|center_vertical\"\n        android:paddingStart=\"16dp\"\n        android:paddingEnd=\"16dp\"\n        android:text=\"Importar archivos\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Large\"\n        android:textSize=\"16sp\"/>\n\n    <TextView\n        android:id=\"@+id/action_download_all\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"56dp\"\n        android:background=\"?selectableItemBackground\"\n        android:clickable=\"true\"\n        android:drawableStart=\"@drawable/ic_download_multiple\"\n        android:drawablePadding=\"32dp\"\n        android:drawableTint=\"?colorControlNormal\"\n        android:focusable=\"true\"\n        android:gravity=\"start|center_vertical\"\n        android:paddingStart=\"16dp\"\n        android:paddingEnd=\"16dp\"\n        android:text=\"Descargar todos\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Large\"\n        android:textSize=\"16sp\"/>\n\n    <TextView\n        android:id=\"@+id/action_queue_all\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"56dp\"\n        android:background=\"?selectableItemBackground\"\n        android:clickable=\"true\"\n        android:drawableStart=\"@drawable/ic_add_list\"\n        android:drawablePadding=\"32dp\"\n        android:drawableTint=\"?colorControlNormal\"\n        android:focusable=\"true\"\n        android:gravity=\"start|center_vertical\"\n        android:paddingStart=\"16dp\"\n        android:paddingEnd=\"16dp\"\n        android:text=\"Añadir a cola\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Large\"\n        android:textSize=\"16sp\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/lay_comments.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"450dp\"\r\n    android:background=\"@color/cardview_background\"\r\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\r\n\r\n    <androidx.core.widget.NestedScrollView\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"450dp\">\r\n\r\n        <knf.kuma.custom.AppWebView\r\n            android:id=\"@+id/webview\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\" />\r\n    </androidx.core.widget.NestedScrollView>\r\n\r\n    <ProgressBar\r\n        android:id=\"@+id/loading\"\r\n        style=\"@android:style/Widget.Material.ProgressBar.Large\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_gravity=\"center\" />\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/lay_migrate_directory.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@android:color/holo_orange_dark\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:gravity=\"center_horizontal\"\n        android:orientation=\"vertical\">\n\n        <TextView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginBottom=\"25dp\"\n            android:gravity=\"center_horizontal\"\n            android:text=\"Creando directorio\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Large\"\n            android:textColor=\"@color/cardview_light_background\"\n            android:textSize=\"24sp\"/>\n\n        <LinearLayout\n            android:id=\"@+id/loading\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center_horizontal\"\n            android:orientation=\"vertical\"\n            >\n\n            <ProgressBar\n                android:layout_width=\"100dp\"\n                android:layout_height=\"100dp\"/>\n\n            <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginTop=\"10dp\"\n                android:gravity=\"center_horizontal\"\n                android:orientation=\"horizontal\">\n\n                <TextView\n                    android:id=\"@+id/tv_directory_count\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:minWidth=\"50dp\"\n                    android:text=\"####\"\n                    android:textAlignment=\"textEnd\"\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Medium.Inverse\"\n                    android:textColor=\"@color/textSecondaryDark\"/>\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_marginStart=\"10dp\"\n                    android:layout_marginEnd=\"10dp\"\n                    android:text=\"/\"\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Medium.Inverse\"\n                    android:textColor=\"@android:color/background_light\"/>\n\n                <TextView\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"~3000\"\n                    android:textAppearance=\"@style/TextAppearance.AppCompat.Medium.Inverse\"\n                    android:textColor=\"@android:color/background_light\"/>\n            </LinearLayout>\n        </LinearLayout>\n\n        <TextView\n            android:id=\"@+id/tv_error\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"25dp\"\n            android:layout_marginEnd=\"25dp\"\n            android:gravity=\"center_horizontal\"\n            android:text=\"Error\"\n            android:textColor=\"@color/colorAccent\"\n            android:textSize=\"24sp\"\n            android:visibility=\"gone\"/>\n\n        <TextView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"25dp\"\n            android:layout_marginTop=\"20dp\"\n            android:layout_marginEnd=\"25dp\"\n            android:text=\"Antes de migrar datos la app necesita generar todo el directorio de animes, por favor espera... \"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"\n            android:textColor=\"@color/textSecondaryDark\"/>\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/lay_migrate_success.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@android:color/holo_orange_dark\">\n\n    <com.google.android.material.card.MaterialCardView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_margin=\"10dp\"\n        android:clipToPadding=\"false\"\n        android:theme=\"@style/AppTheme.Cardview\"\n        app:cardCornerRadius=\"2dp\"\n        app:cardElevation=\"2dp\"\n        app:contentPadding=\"8dp\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"Migración de datos\"\n                android:textAlignment=\"center\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Large\"/>\n\n            <TextView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"Se intentará migrar la mayor cantidad de datos desde Animeflv App, puede haber perdidas en el proceso.\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"/>\n\n            <com.google.android.material.button.MaterialButton\n                android:id=\"@+id/migrate_favs\"\n                style=\"@style/Widget.AppCompat.Button.Colored\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:backgroundTint=\"?colorSecondary\"\n                android:text=\"favoritos\"\n                android:textColor=\"@android:color/primary_text_dark\"/>\n\n            <com.google.android.material.button.MaterialButton\n                android:id=\"@+id/migrate_seen\"\n                style=\"@style/Widget.AppCompat.Button.Colored\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:backgroundTint=\"?colorSecondary\"\n                android:text=\"capitulos vistos\"\n                android:textColor=\"@android:color/primary_text_dark\"/>\n        </LinearLayout>\n    </com.google.android.material.card.MaterialCardView>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/lay_migrate_version.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@android:color/holo_orange_dark\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:gravity=\"center_horizontal\"\n        android:orientation=\"vertical\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:src=\"@drawable/ic_umaru\"/>\n\n        <TextView\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"25dp\"\n            android:layout_marginEnd=\"25dp\"\n            android:text=\"Parece que tienes una versión no compatible de Animeflv App, actualiza para continuar con la migracion de datos\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium.Inverse\"\n            android:textColor=\"@color/textSecondaryDark\"/>\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"25dp\"\n            android:layout_marginTop=\"25dp\"\n            android:layout_marginEnd=\"25dp\"\n            android:gravity=\"center_vertical\"\n            android:orientation=\"horizontal\">\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"Versión compatible:\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Small.Inverse\"\n                android:textColor=\"@android:color/background_light\"\n                android:textSize=\"16sp\"\n                android:textStyle=\"bold\"/>\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"10dp\"\n                android:text=\">=252\"\n                android:textColor=\"@color/colorAccentGreen\"\n                android:textSize=\"18sp\"\n                android:textStyle=\"bold\"/>\n        </LinearLayout>\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginStart=\"25dp\"\n            android:layout_marginTop=\"25dp\"\n            android:layout_marginEnd=\"25dp\"\n            android:gravity=\"center_vertical\"\n            android:orientation=\"horizontal\">\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"Versión instalada:\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Small.Inverse\"\n                android:textColor=\"@android:color/background_light\"\n                android:textSize=\"16sp\"\n                android:textStyle=\"bold\"/>\n\n            <TextView\n                android:id=\"@+id/tv_version_bad\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"10dp\"\n                android:text=\"########\"\n                android:textColor=\"@color/colorAccent\"\n                android:textSize=\"18sp\"\n                android:textStyle=\"bold\"/>\n        </LinearLayout>\n    </LinearLayout>\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/lay_news.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.core.widget.NestedScrollView xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"450dp\"\r\n    android:background=\"@color/cardview_background\"\r\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\r\n\r\n    <knf.kuma.custom.AppWebView\r\n        android:id=\"@+id/webview\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\" />\r\n\r\n\r\n</androidx.core.widget.NestedScrollView>"
  },
  {
    "path": "app/src/main/res/layout/lay_status_bar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:id=\"@+id/container\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"24dp\"\r\n    android:clickable=\"true\"\r\n    android:focusable=\"true\"\r\n    android:gravity=\"center_vertical|center_horizontal\"\r\n    android:orientation=\"horizontal\">\r\n\r\n    <ProgressBar\r\n        android:id=\"@+id/progress\"\r\n        style=\"@android:style/Widget.Material.Light.ProgressBar.Small\"\r\n        android:layout_width=\"18dp\"\r\n        android:layout_height=\"18dp\"/>\r\n\r\n    <ImageView\r\n        android:id=\"@+id/icon\"\r\n        android:layout_width=\"18dp\"\r\n        android:layout_height=\"18dp\"\r\n        android:visibility=\"gone\"\r\n        tools:srcCompat=\"@drawable/ic_warning\"/>\r\n\r\n    <TextView\r\n        android:id=\"@+id/message\"\r\n        android:layout_width=\"wrap_content\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginStart=\"4dp\"\r\n        android:textSize=\"12sp\"\r\n        tools:text=\"Comprobando...\"/>\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_comments_dialog.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <Spinner\n        android:id=\"@+id/spinner\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"/>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <ScrollView\n            android:id=\"@+id/scroll\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\">\n\n            <WebView\n                android:id=\"@+id/webview\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:visibility=\"invisible\"/>\n        </ScrollView>\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"/>\n\n    </RelativeLayout>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_diagnostic.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:fitsSystemWindows=\"true\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\r\n\r\n        <androidx.appcompat.widget.Toolbar\r\n            android:id=\"@+id/toolbar\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <androidx.core.widget.NestedScrollView\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:orientation=\"vertical\">\r\n\r\n            <com.google.android.material.card.MaterialCardView\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"8dp\"\r\n                android:layout_marginTop=\"8dp\"\r\n                android:layout_marginEnd=\"8dp\"\r\n                android:layout_marginBottom=\"4dp\"\r\n                app:contentPadding=\"16dp\">\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <LinearLayout\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:gravity=\"center_vertical\"\r\n                        android:layout_marginBottom=\"8dp\"\r\n                        android:orientation=\"horizontal\">\r\n\r\n                        <TextView\r\n                            android:layout_width=\"0dp\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_weight=\"1\"\r\n                            android:text=\"Animeflv.net\"\r\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                            android:textColor=\"?colorAccent\"/>\r\n\r\n                        <ImageButton\r\n                            android:id=\"@+id/info\"\r\n                            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\r\n                            android:layout_width=\"24dp\"\r\n                            android:layout_height=\"24dp\"\r\n                            android:background=\"@drawable/background_ripple\"\r\n                            android:padding=\"5dp\"\r\n                            android:src=\"@drawable/ic_info\"\r\n                            android:visibility=\"gone\"/>\r\n                    </LinearLayout>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/generalState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Estado general\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/codeState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Código http\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/timeoutState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Tiempo de respuesta\"/>\r\n                </LinearLayout>\r\n            </com.google.android.material.card.MaterialCardView>\r\n\r\n            <com.google.android.material.card.MaterialCardView\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"8dp\"\r\n                android:layout_marginTop=\"4dp\"\r\n                android:layout_marginEnd=\"8dp\"\r\n                android:layout_marginBottom=\"4dp\"\r\n                app:contentPadding=\"16dp\">\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <LinearLayout\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:gravity=\"center_vertical\"\r\n                        android:layout_marginBottom=\"8dp\"\r\n                        android:orientation=\"horizontal\">\r\n\r\n                        <TextView\r\n                            android:layout_width=\"0dp\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:layout_weight=\"1\"\r\n                            android:text=\"Bypass\"\r\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                            android:textColor=\"?colorAccent\"/>\r\n\r\n                        <ImageButton\r\n                            android:id=\"@+id/bypassRecreate\"\r\n                            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\r\n                            android:layout_width=\"24dp\"\r\n                            android:layout_height=\"24dp\"\r\n                            android:background=\"@drawable/background_ripple\"\r\n                            android:padding=\"5dp\"\r\n                            android:src=\"@drawable/ic_settings_reload\"\r\n                            android:visibility=\"gone\"/>\r\n                    </LinearLayout>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/bypassState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Estado general\" />\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/ipState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:visibility=\"gone\"\r\n                        app:sv_title=\"IP\" />\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/countryState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:visibility=\"gone\"\r\n                        app:sv_title=\"País\" />\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/clearanceState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:visibility=\"gone\"\r\n                        app:sv_title=\"cf_clearance\" />\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/cfduidState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:visibility=\"gone\"\r\n                        app:sv_title=\"__cfduid\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/userAgentState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:visibility=\"gone\"\r\n                        app:sv_title=\"User agent\"/>\r\n                </LinearLayout>\r\n            </com.google.android.material.card.MaterialCardView>\r\n\r\n            <com.google.android.material.card.MaterialCardView\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"8dp\"\r\n                android:layout_marginTop=\"4dp\"\r\n                android:layout_marginEnd=\"8dp\"\r\n                android:layout_marginBottom=\"4dp\"\r\n                android:visibility=\"gone\"\r\n                app:contentPadding=\"16dp\">\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <TextView\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginBottom=\"8dp\"\r\n                        android:text=\"Internet\"\r\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                        android:textColor=\"?colorAccent\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/downState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Bajada\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/upState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Subida\"/>\r\n                </LinearLayout>\r\n            </com.google.android.material.card.MaterialCardView>\r\n\r\n            <com.google.android.material.card.MaterialCardView\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"8dp\"\r\n                android:layout_marginTop=\"4dp\"\r\n                android:layout_marginEnd=\"8dp\"\r\n                android:layout_marginBottom=\"4dp\"\r\n                app:contentPadding=\"16dp\">\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <TextView\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginBottom=\"8dp\"\r\n                        android:text=\"Directorio\"\r\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                        android:textColor=\"?colorAccent\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/dirState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Estado general\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/dirTotalState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Animes en directorio\"/>\r\n                </LinearLayout>\r\n            </com.google.android.material.card.MaterialCardView>\r\n\r\n            <com.google.android.material.card.MaterialCardView\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"8dp\"\r\n                android:layout_marginTop=\"4dp\"\r\n                android:layout_marginEnd=\"8dp\"\r\n                android:layout_marginBottom=\"4dp\"\r\n                app:contentPadding=\"16dp\">\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <TextView\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginBottom=\"8dp\"\r\n                        android:text=\"Memoria libre\"\r\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                        android:textColor=\"?colorAccent\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/internalState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Interna\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/externalState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:visibility=\"gone\"\r\n                        app:sv_title=\"Tarjeta SD\"/>\r\n                </LinearLayout>\r\n            </com.google.android.material.card.MaterialCardView>\r\n\r\n            <com.google.android.material.card.MaterialCardView\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"8dp\"\r\n                android:layout_marginTop=\"4dp\"\r\n                android:layout_marginEnd=\"8dp\"\r\n                android:layout_marginBottom=\"8dp\"\r\n                app:contentPadding=\"16dp\">\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <TextView\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginBottom=\"8dp\"\r\n                        android:text=\"Respaldos\"\r\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                        android:textColor=\"?colorAccent\"/>\r\n\r\n                    <LinearLayout\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_marginBottom=\"2dp\"\r\n                        android:orientation=\"vertical\">\r\n\r\n                        <TextView\r\n                            android:layout_width=\"match_parent\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:text=\"UUID\"\r\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\" />\r\n\r\n                        <TextView\r\n                            android:id=\"@+id/uuid\"\r\n                            android:layout_width=\"match_parent\"\r\n                            android:layout_height=\"wrap_content\"\r\n                            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\r\n                    </LinearLayout>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/subscriptionState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Suscripción\" />\r\n\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/backupState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        app:sv_title=\"Configurado\"/>\r\n\r\n                    <knf.kuma.custom.StateView\r\n                        android:id=\"@+id/lastBackupState\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:visibility=\"gone\"\r\n                        app:sv_title=\"Último respaldo\"/>\r\n                </LinearLayout>\r\n            </com.google.android.material.card.MaterialCardView>\r\n        </LinearLayout>\r\n\r\n    </androidx.core.widget.NestedScrollView>\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_diagnostic_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\r\n        android:fitsSystemWindows=\"true\"\r\n        app:elevation=\"0dp\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:orientation=\"vertical\">\r\n            <androidx.appcompat.widget.Toolbar\r\n                android:id=\"@+id/toolbar\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:background=\"@color/separator\"/>\r\n        </LinearLayout>\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <androidx.core.widget.NestedScrollView\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:clipToPadding=\"false\"\r\n        android:paddingTop=\"8dp\"\r\n        android:paddingBottom=\"16dp\"\r\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:orientation=\"vertical\">\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"16dp\"\r\n                android:layout_marginEnd=\"16dp\"\r\n                android:orientation=\"vertical\">\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:gravity=\"center_vertical\"\r\n                    android:orientation=\"horizontal\">\r\n\r\n                    <TextView\r\n                        android:layout_width=\"0dp\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_weight=\"1\"\r\n                        android:text=\"Animeflv.net\"\r\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n                        android:textColor=\"?colorAccent\"/>\r\n\r\n                    <ImageButton\r\n                        android:id=\"@+id/info\"\r\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\r\n                        android:layout_width=\"48dp\"\r\n                        android:layout_height=\"48dp\"\r\n                        android:background=\"@drawable/background_ripple\"\r\n                        android:padding=\"10dp\"\r\n                        android:src=\"@drawable/ic_info\"\r\n                        android:visibility=\"gone\"\r\n                        tools:visibility=\"visible\" />\r\n                </LinearLayout>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/generalState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Estado general\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/codeState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Código http\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/timeoutState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Tiempo de respuesta\"/>\r\n            </LinearLayout>\r\n\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:layout_marginTop=\"16dp\"\r\n                android:layout_marginBottom=\"8dp\"\r\n                android:background=\"@color/separator\"/>\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"16dp\"\r\n                android:layout_marginEnd=\"16dp\"\r\n                android:orientation=\"vertical\">\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    android:gravity=\"center_vertical\"\r\n                    android:orientation=\"horizontal\">\r\n\r\n                    <TextView\r\n                        android:layout_width=\"0dp\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:layout_weight=\"1\"\r\n                        android:text=\"Bypass\"\r\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n                        android:textColor=\"?colorAccent\"/>\r\n\r\n                    <ImageButton\r\n                        android:id=\"@+id/bypassRecreate\"\r\n                        style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\r\n                        android:layout_width=\"48dp\"\r\n                        android:layout_height=\"48dp\"\r\n                        android:background=\"@drawable/background_ripple\"\r\n                        android:padding=\"10dp\"\r\n                        android:src=\"@drawable/ic_settings_reload\"\r\n                        android:visibility=\"gone\"\r\n                        tools:visibility=\"visible\" />\r\n                </LinearLayout>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/bypassState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Estado general\" />\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/ipState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:visibility=\"gone\"\r\n                    app:svm_title=\"IP\" />\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/countryState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:visibility=\"gone\"\r\n                    app:svm_title=\"País\" />\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/clearanceState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:visibility=\"gone\"\r\n                    app:svm_title=\"cf_clearance\" />\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/cfduidState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:visibility=\"gone\"\r\n                    app:svm_title=\"__cfduid\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/userAgentState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:visibility=\"gone\"\r\n                    app:svm_title=\"User agent\"/>\r\n            </LinearLayout>\r\n\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:layout_marginTop=\"16dp\"\r\n                android:layout_marginBottom=\"16dp\"\r\n                android:visibility=\"gone\"\r\n                android:background=\"@color/separator\"/>\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"16dp\"\r\n                android:layout_marginEnd=\"16dp\"\r\n                android:visibility=\"gone\"\r\n                android:orientation=\"vertical\">\r\n\r\n                <TextView\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    android:text=\"Internet\"\r\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n                    android:textColor=\"?colorAccent\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/downState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Bajada\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/upState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Subida\"/>\r\n            </LinearLayout>\r\n\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:layout_marginTop=\"16dp\"\r\n                android:layout_marginBottom=\"16dp\"\r\n                android:background=\"@color/separator\"/>\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"16dp\"\r\n                android:layout_marginEnd=\"16dp\"\r\n                android:orientation=\"vertical\">\r\n\r\n                <TextView\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    android:text=\"Directorio\"\r\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n                    android:textColor=\"?colorAccent\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/dirState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Estado general\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/dirTotalState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Animes en directorio\"/>\r\n            </LinearLayout>\r\n\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:layout_marginTop=\"16dp\"\r\n                android:layout_marginBottom=\"16dp\"\r\n                android:background=\"@color/separator\"/>\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"16dp\"\r\n                android:layout_marginEnd=\"16dp\"\r\n                android:orientation=\"vertical\">\r\n\r\n                <TextView\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    android:text=\"Memoria libre\"\r\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n                    android:textColor=\"?colorAccent\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/internalState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Interna\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/externalState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:visibility=\"gone\"\r\n                    app:svm_title=\"Tarjeta SD\"/>\r\n            </LinearLayout>\r\n\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:layout_marginTop=\"16dp\"\r\n                android:layout_marginBottom=\"16dp\"\r\n                android:background=\"@color/separator\"/>\r\n\r\n            <LinearLayout\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_marginStart=\"16dp\"\r\n                android:layout_marginEnd=\"16dp\"\r\n                android:orientation=\"vertical\">\r\n\r\n                <TextView\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginBottom=\"8dp\"\r\n                    android:text=\"Respaldos\"\r\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"\r\n                    android:textColor=\"?colorAccent\"/>\r\n\r\n                <LinearLayout\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:layout_marginBottom=\"2dp\"\r\n                    android:orientation=\"vertical\">\r\n\r\n                    <TextView\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:text=\"UUID\"\r\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\" />\r\n\r\n                    <TextView\r\n                        android:id=\"@+id/uuid\"\r\n                        android:layout_width=\"match_parent\"\r\n                        android:layout_height=\"wrap_content\"\r\n                        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\r\n                </LinearLayout>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/subscriptionState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Suscripción\" />\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/backupState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    app:svm_title=\"Configurado\"/>\r\n\r\n                <knf.kuma.custom.StateViewMaterial\r\n                    android:id=\"@+id/lastBackupState\"\r\n                    android:layout_width=\"match_parent\"\r\n                    android:layout_height=\"wrap_content\"\r\n                    android:visibility=\"gone\"\r\n                    app:svm_title=\"Último respaldo\"/>\r\n            </LinearLayout>\r\n        </LinearLayout>\r\n\r\n    </androidx.core.widget.NestedScrollView>\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_expandable_textview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/tv_expand_text_view_animation\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:maxLines=\"4\"\n        android:text=\"TEST\"\n        android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"/>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_img_big.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_height=\"match_parent\">\n\n    <ImageView\n        android:id=\"@+id/img\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clickable=\"true\"\n        android:scaleType=\"fitCenter\"\n        android:transitionName=\"img\"/>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:paddingBottom=\"64dp\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_not_found\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Error al cargar imagen\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <View\n        android:id=\"@+id/anchor\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"0dp\"\n        android:layout_centerInParent=\"true\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_img_big_base.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <androidx.viewpager.widget.ViewPager\n        android:id=\"@+id/pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n    <com.tbuonomo.viewpagerdotsindicator.WormDotsIndicator\n        android:id=\"@+id/indicator\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerHorizontal=\"true\"\n        android:layout_marginTop=\"16dp\"\n        app:dotsColor=\"?colorAccent\"\n        app:dotsCornerRadius=\"8dp\"\n        app:dotsSize=\"16dp\"\n        app:dotsSpacing=\"4dp\"\n        app:dotsStrokeColor=\"?colorAccent\"\n        app:dotsStrokeWidth=\"2dp\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_loading_text.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <TextView\r\n            android:id=\"@+id/title\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body1\"/>\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_marginBottom=\"2dp\">\r\n\r\n            <TextView\r\n                android:id=\"@+id/text\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_centerVertical=\"true\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\"\r\n                android:visibility=\"gone\"/>\r\n\r\n            <ProgressBar\r\n                android:id=\"@+id/loading\"\r\n                style=\"@android:style/Widget.Material.Light.ProgressBar.Small\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_centerVertical=\"true\"/>\r\n        </RelativeLayout>\r\n    </LinearLayout>\r\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/layout_loading_text_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\">\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <TextView\r\n            android:id=\"@+id/title\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:textAppearance=\"@style/TextAppearance.MaterialComponents.Subtitle2\"\r\n            tools:text=\"State title\" />\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_marginBottom=\"2dp\">\r\n\r\n            <TextView\r\n                android:id=\"@+id/text\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_centerVertical=\"true\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\"\r\n                android:visibility=\"gone\"\r\n                tools:text=\"Status\"\r\n                tools:visibility=\"visible\" />\r\n\r\n            <ProgressBar\r\n                android:id=\"@+id/loading\"\r\n                style=\"@android:style/Widget.Material.Light.ProgressBar.Small\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_centerVertical=\"true\"/>\r\n        </RelativeLayout>\r\n    </LinearLayout>\r\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/nav_header_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/img\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@drawable/side_nav_bar\"\n    android:fitsSystemWindows=\"false\"\n    android:gravity=\"top\"\n    android:orientation=\"vertical\"\n    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"24dp\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    android:theme=\"@style/ThemeOverlay.AppCompat.Dark\">\n\n    <LinearLayout\n        android:id=\"@+id/optionsBar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"32dp\"\n        android:gravity=\"bottom|end\"\n        android:orientation=\"horizontal\">\n\n        <ImageButton\n            android:id=\"@+id/action_migrate\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginEnd=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            android:visibility=\"gone\"\n            app:srcCompat=\"@drawable/ic_umaru\"/>\n\n        <ImageButton\n            android:id=\"@+id/action_share\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginEnd=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            android:tint=\"@android:color/white\"\n            app:srcCompat=\"@drawable/ic_achievement_share\" />\n\n        <ImageButton\n            android:id=\"@+id/action_info\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginEnd=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            app:srcCompat=\"@drawable/ic_info_white\"/>\n\n        <ImageButton\n            android:id=\"@+id/action_trophy\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginEnd=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            app:srcCompat=\"@drawable/ic_trophy\"/>\n\n        <ImageButton\n            android:id=\"@+id/action_login\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            app:srcCompat=\"@drawable/ic_sync\"/>\n\n        <ImageButton\n            android:id=\"@+id/action_map\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginStart=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            android:visibility=\"visible\"\n            app:srcCompat=\"@drawable/ic_map\"/>\n    </LinearLayout>\n\n    <ImageView\n        android:layout_width=\"80dp\"\n        android:layout_height=\"80dp\"\n        android:paddingTop=\"4dp\"\n        android:paddingBottom=\"4dp\"\n        app:srcCompat=\"@mipmap/ic_launcher\"/>\n\n    <TextView\n        android:id=\"@+id/backupLocation\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:paddingStart=\"4dp\"\n        android:tag=\":aesthetic_ignore\"\n        android:text=\"Almacenamiento local\"\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n        android:textColor=\"@android:color/white\"\n        android:textSize=\"18sp\"\n        android:textStyle=\"bold\"/>\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/nav_header_main_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/img\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"@drawable/side_nav_bar\"\n    android:clipToPadding=\"false\"\n    android:fitsSystemWindows=\"false\"\n    android:gravity=\"top\"\n    android:orientation=\"vertical\"\n    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"40dp\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    android:theme=\"@style/ThemeOverlay.AppCompat.Dark\">\n\n    <LinearLayout\n        android:id=\"@+id/optionsBar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"32dp\"\n        android:layout_marginTop=\"12dp\"\n        android:gravity=\"bottom|end\"\n        android:orientation=\"horizontal\">\n\n        <ImageButton\n            android:id=\"@+id/action_migrate\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginEnd=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            android:visibility=\"gone\"\n            app:srcCompat=\"@drawable/ic_umaru\"/>\n\n        <ImageButton\n            android:id=\"@+id/action_share\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginEnd=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            android:tint=\"@android:color/white\"\n            app:srcCompat=\"@drawable/ic_achievement_share\" />\n\n        <ImageButton\n            android:id=\"@+id/action_info\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginEnd=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            app:srcCompat=\"@drawable/ic_info_white\"/>\n\n        <ImageButton\n            android:id=\"@+id/action_trophy\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginEnd=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            app:srcCompat=\"@drawable/ic_trophy\"/>\n\n        <ImageButton\n            android:id=\"@+id/action_login\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            app:srcCompat=\"@drawable/ic_sync\"/>\n\n        <ImageButton\n            android:id=\"@+id/action_map\"\n            style=\"@style/Base.Widget.AppCompat.Button.Borderless\"\n            android:layout_width=\"32dp\"\n            android:layout_height=\"32dp\"\n            android:layout_marginStart=\"5dp\"\n            android:background=\"@drawable/background_ripple\"\n            android:padding=\"5dp\"\n            android:visibility=\"visible\"\n            app:srcCompat=\"@drawable/ic_map\"/>\n    </LinearLayout>\n\n    <ImageView\n        android:layout_width=\"80dp\"\n        android:layout_height=\"80dp\"\n        android:paddingTop=\"4dp\"\n        android:paddingBottom=\"4dp\"\n        app:srcCompat=\"@mipmap/ic_launcher\"/>\n\n    <TextView\n        android:id=\"@+id/backupLocation\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:paddingStart=\"4dp\"\n        android:tag=\":aesthetic_ignore\"\n        android:text=\"Almacenamiento local\"\n        android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n        android:textColor=\"@android:color/white\"\n        android:textSize=\"18sp\"\n        android:textStyle=\"bold\"/>\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/overlay.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n             android:layout_width=\"match_parent\"\r\n             android:layout_height=\"match_parent\"\r\n             android:alpha=\"0.4\"\r\n             android:background=\"@android:color/black\"\r\n             android:clickable=\"true\"\r\n             android:longClickable=\"true\"\r\n             android:visibility=\"gone\"/>"
  },
  {
    "path": "app/src/main/res/layout/player_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    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <!--<com.google.android.exoplayer2.ui.PlayerView\n        android:id=\"@+id/player\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:keepScreenOn=\"true\"\n        app:controller_layout_id=\"@layout/exo_playback_control_view\"\n        app:resize_mode=\"fit\"/>-->\n\n    <com.github.vkay94.dtpv.DoubleTapPlayerView\n        android:id=\"@+id/player\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:keepScreenOn=\"true\"\n        android:animateLayoutChanges=\"true\"\n        app:controller_layout_id=\"@layout/exo_playback_youtube_control_view\"\n        app:resize_mode=\"fit\"\n        app:dtpv_controller=\"@+id/youtubeOverlay\" />\n\n    <com.github.vkay94.dtpv.youtube.YouTubeOverlay\n        android:id=\"@+id/youtubeOverlay\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:visibility=\"invisible\"\n        app:yt_playerView=\"@+id/player\" />\n\n    <RelativeLayout\n        android:id=\"@+id/lay_locked\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clickable=\"true\"\n        android:focusable=\"true\"\n        android:visibility=\"gone\">\n        <ImageButton\n            android:id=\"@+id/unlock\"\n            android:layout_width=\"48dp\"\n            android:layout_height=\"48dp\"\n            android:background=\"#4D000000\"\n            android:layout_alignParentEnd=\"true\"\n            android:src=\"@drawable/ic_unlocked\" />\n    </RelativeLayout>\n\n\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/preference_recyclerview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.recyclerview.widget.RecyclerView\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    android:id=\"@+id/recycler_view\"\r\n    style=\"?attr/preferenceFragmentListStyle\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:clipToPadding=\"false\"\r\n    android:paddingTop=\"0dp\"\r\n    android:paddingBottom=\"0dp\"/>"
  },
  {
    "path": "app/src/main/res/layout/recycler_changelog.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:layout_scrollFlags=\"scroll|exitUntilCollapsed\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_changelog\"/>\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"/>\n\n    </RelativeLayout>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_changelog_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        android:fitsSystemWindows=\"true\"\n        app:elevation=\"0dp\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:layout_scrollFlags=\"scroll|exitUntilCollapsed\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/separator_size\"\n        android:background=\"@color/separator\"\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\"/>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_changelog_material\"/>\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"/>\n\n    </RelativeLayout>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_chapters.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <knf.kuma.custom.FSRecyclerView\n        android:id=\"@+id/recycler\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clipToPadding=\"false\"\n        android:paddingStart=\"10dp\"\n        android:paddingTop=\"35dp\"\n        android:paddingEnd=\"10dp\"\n        android:paddingBottom=\"10dp\"\n        android:nestedScrollingEnabled=\"false\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n        app:fastScrollPopupBgColor=\"?colorSecondary\"\n        app:fastScrollPopupTextColor=\"@android:color/white\"\n        app:fastScrollThumbColor=\"?colorSecondary\"\n        app:fastScrollThumbInactiveColor=\"?colorSecondaryVariant\"\n        tools:listitem=\"@layout/item_chapter_preview\"/>\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_dir.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView\n        android:id=\"@+id/recycler\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clipToPadding=\"false\"\n        android:layoutAnimation=\"@anim/layout_fall_down\"\n        android:paddingStart=\"10dp\"\n        android:paddingEnd=\"10dp\"\n        android:paddingBottom=\"10dp\"\n        app:fastScrollPopupBgColor=\"?colorSecondary\"\n        app:fastScrollPopupTextColor=\"@android:color/white\"\n        app:fastScrollThumbColor=\"?colorSecondary\"\n        app:fastScrollThumbInactiveColor=\"?colorSecondaryVariant\"\n        app:layoutManager=\".custom.VariantLinearLayoutManager\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n        tools:listitem=\"@layout/item_dir\" />\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"/>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_dir_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <knf.kuma.custom.FSGridRecyclerView\n        android:id=\"@+id/recycler\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clipToPadding=\"false\"\n        android:layoutAnimation=\"@anim/grid_fall_down\"\n        android:padding=\"5dp\"\n        app:layoutManager=\".custom.VariantGridLayoutManager\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n        app:spanCount=\"@integer/span_count\"\n        app:fastScrollPopupBgColor=\"?colorSecondary\"\n        app:fastScrollPopupTextColor=\"@android:color/white\"\n        app:fastScrollThumbColor=\"?colorSecondary\"\n        app:fastScrollThumbInactiveColor=\"?colorSecondaryVariant\"\n        tools:listitem=\"@layout/item_dir_grid\"/>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"/>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_downloading.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_no_downloading\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"No hay descargas activas\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"/>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            android:paddingBottom=\"56dp\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            android:layout_above=\"@+id/adContainer\"\n            tools:listitem=\"@layout/item_explorer\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\"\n            app:showBottomSpace=\"true\" />\n\n        <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton\n            android:id=\"@+id/clear\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_above=\"@+id/adContainer\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_marginStart=\"16dp\"\n            android:layout_marginTop=\"16dp\"\n            android:layout_marginEnd=\"16dp\"\n            android:layout_marginBottom=\"16dp\"\n            android:text=\"Limpiar\"\n            app:icon=\"@drawable/ic_clear_white\"\n            tools:visibility=\"visible\" />\n    </RelativeLayout>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_emision.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <knf.kuma.custom.GridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"5dp\"\n            app:layoutManager=\"knf.kuma.custom.FixedGridLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_emision\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            app:srcCompat=\"@drawable/ic_no_emision\"\n            app:tint=\"?android:textColorSecondary\" />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"No hay animes para este dia\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_explorer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_explorer\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:gravity=\"center_horizontal\"\n        android:orientation=\"vertical\">\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"/>\n\n        <TextView\n            android:id=\"@+id/state\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"Cargando...\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"/>\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_no_downloads\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Ningún anime descargado\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_explorer_chaps.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            android:paddingBottom=\"80dp\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_explorer\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n    </LinearLayout>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"/>\n\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\n        android:id=\"@+id/fab\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentEnd=\"true\"\n        android:layout_alignParentBottom=\"true\"\n        android:layout_marginStart=\"16dp\"\n        android:layout_marginTop=\"16dp\"\n        android:layout_marginEnd=\"16dp\"\n        android:layout_marginBottom=\"16dp\"\n        android:src=\"@drawable/ic_play_all\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_explorer_chaps_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <knf.kuma.custom.GridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            android:paddingBottom=\"80dp\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            app:spanCount=\"@integer/span_count_large\"\n            tools:listitem=\"@layout/item_chap_grid\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n    </LinearLayout>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"/>\n\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\n        android:id=\"@+id/fab\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentEnd=\"true\"\n        android:layout_alignParentBottom=\"true\"\n        android:layout_marginStart=\"16dp\"\n        android:layout_marginTop=\"16dp\"\n        android:layout_marginEnd=\"16dp\"\n        android:layout_marginBottom=\"16dp\"\n        android:src=\"@drawable/ic_play_all\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_explorer_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <knf.kuma.custom.GridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"5dp\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_explorer_grid\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n    <LinearLayout\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:gravity=\"center_horizontal\"\n        android:orientation=\"vertical\">\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"/>\n\n        <TextView\n            android:id=\"@+id/state\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"Cargando...\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Medium\"/>\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            app:srcCompat=\"@drawable/ic_no_downloads\"\n            app:tint=\"?android:textColorSecondary\" />\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Ningún anime descargado\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_faq.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:fitsSystemWindows=\"true\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\r\n\r\n        <androidx.appcompat.widget.Toolbar\r\n            android:id=\"@+id/toolbar\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"?actionBarSize\"\r\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <androidx.recyclerview.widget.RecyclerView\r\n        android:id=\"@+id/recycler\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:clipToPadding=\"false\"\r\n        android:padding=\"8dp\"\r\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\"\r\n        tools:listitem=\"@layout/item_faq\" />\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_faq_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <com.google.android.material.appbar.AppBarLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:fitsSystemWindows=\"true\"\r\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\r\n        app:elevation=\"0dp\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:orientation=\"vertical\">\r\n            <androidx.appcompat.widget.Toolbar\r\n                android:id=\"@+id/toolbar\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"?actionBarSize\"\r\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\r\n            <View\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"@dimen/separator_size\"\r\n                android:background=\"@color/separator\"/>\r\n        </LinearLayout>\r\n    </com.google.android.material.appbar.AppBarLayout>\r\n\r\n    <androidx.recyclerview.widget.RecyclerView\r\n        android:id=\"@+id/recycler\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"match_parent\"\r\n        android:clipToPadding=\"false\"\r\n        android:padding=\"8dp\"\r\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\"\r\n        tools:listitem=\"@layout/item_faq\" />\r\n\r\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_favs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <knf.kuma.custom.FSRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingTop=\"10dp\"\n            app:fastScrollPopupBgColor=\"?colorSecondary\"\n            app:fastScrollPopupTextColor=\"@android:color/white\"\n            app:fastScrollThumbColor=\"?colorSecondary\"\n            app:fastScrollThumbInactiveColor=\"?colorSecondaryVariant\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_fav\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/heart_broken\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Aún no tienes favoritos\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_favs_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <knf.kuma.custom.FSGridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"5dp\"\n            app:fastScrollPopupBgColor=\"?colorSecondary\"\n            app:fastScrollPopupTextColor=\"@android:color/white\"\n            app:fastScrollThumbColor=\"?colorSecondary\"\n            app:fastScrollThumbInactiveColor=\"?colorSecondaryVariant\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_fav_grid\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/heart_broken\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Aún no tienes favoritos\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_favs_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:background=\"@color/separator\"/>\n\n        <knf.kuma.custom.FSGridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"8dp\"\n            app:fastScrollPopupBgColor=\"?colorSecondary\"\n            app:fastScrollPopupTextColor=\"@android:color/white\"\n            app:fastScrollThumbColor=\"?colorSecondary\"\n            app:fastScrollThumbInactiveColor=\"?colorSecondaryVariant\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_fav_grid\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/heart_broken\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Aún no tienes favoritos\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_favs_matertial.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:background=\"@color/separator\"/>\n\n        <knf.kuma.custom.FSRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingTop=\"10dp\"\n            app:fastScrollPopupBgColor=\"?colorSecondary\"\n            app:fastScrollPopupTextColor=\"@android:color/white\"\n            app:fastScrollThumbColor=\"?colorSecondary\"\n            app:fastScrollThumbInactiveColor=\"?colorSecondaryVariant\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_fav\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/heart_broken\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Aún no tienes favoritos\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_genre.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            android:paddingBottom=\"10dp\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_ranking\">\n\n        </androidx.recyclerview.widget.RecyclerView>\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            style=\"@android:style/Widget.Material.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"/>\n    </RelativeLayout>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_genre_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        android:fitsSystemWindows=\"true\"\n        app:elevation=\"0dp\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <View\n            android:id=\"@+id/separator\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:background=\"@color/separator\"/>\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_below=\"@+id/separator\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            android:paddingBottom=\"10dp\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_ranking\">\n\n        </androidx.recyclerview.widget.RecyclerView>\n\n        <ProgressBar\n            android:id=\"@+id/progress\"\n            style=\"@android:style/Widget.Material.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"/>\n    </RelativeLayout>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_loader.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.coordinatorlayout.widget.CoordinatorLayout 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    android:orientation=\"vertical\">\n\n    <androidx.appcompat.widget.LinearLayoutCompat\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\">\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:clipToPadding=\"false\"\n                android:layoutAnimation=\"@anim/layout_fall_down\"\n                android:paddingTop=\"4dp\"\n                android:paddingBottom=\"4dp\"\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\n                tools:listitem=\"@layout/item_top\" />\n\n            <androidx.core.widget.ContentLoadingProgressBar\n                android:id=\"@+id/loading\"\n                style=\"?android:attr/progressBarStyleLarge\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerInParent=\"true\" />\n        </RelativeLayout>\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n    </androidx.appcompat.widget.LinearLayoutCompat>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_loader_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.coordinatorlayout.widget.CoordinatorLayout 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    android:orientation=\"vertical\">\n\n    <androidx.appcompat.widget.LinearLayoutCompat\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\"\n            app:elevation=\"0dp\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\" />\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:background=\"@color/separator\"/>\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\">\n\n            <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/recycler\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:clipToPadding=\"false\"\n                android:layoutAnimation=\"@anim/layout_fall_down\"\n                android:paddingTop=\"4dp\"\n                android:paddingBottom=\"4dp\"\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\n                tools:listitem=\"@layout/item_top\" />\n\n            <androidx.core.widget.ContentLoadingProgressBar\n                android:id=\"@+id/loading\"\n                style=\"?android:attr/progressBarStyleLarge\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_centerInParent=\"true\" />\n        </RelativeLayout>\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n    </androidx.appcompat.widget.LinearLayoutCompat>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_ranking.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recycler\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clipToPadding=\"false\"\n        android:layoutAnimation=\"@anim/layout_fall_down\"\n        android:paddingStart=\"8dp\"\n        android:paddingEnd=\"8dp\"\n        android:paddingBottom=\"8dp\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n        tools:listitem=\"@layout/item_ranking\">\n    </androidx.recyclerview.widget.RecyclerView>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_ranking_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        android:fitsSystemWindows=\"true\"\n        app:elevation=\"0dp\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:orientation=\"vertical\">\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n            <View\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"@dimen/separator_size\"\n                android:background=\"@color/separator\"/>\n        </LinearLayout>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recycler\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:clipToPadding=\"false\"\n        android:layoutAnimation=\"@anim/layout_fall_down\"\n        android:paddingStart=\"8dp\"\n        android:paddingEnd=\"8dp\"\n        android:paddingBottom=\"8dp\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n        tools:listitem=\"@layout/item_ranking\">\n    </androidx.recyclerview.widget.RecyclerView>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_recommends.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_fav\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_no_genres\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"No hay suficiente información\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/loading\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\">\n\n        <ProgressBar\n            style=\"@android:style/Widget.Material.Light.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"/>\n\n        <TextView\n            android:id=\"@+id/state\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Iniciando búsqueda\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_recommends_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <knf.kuma.custom.GridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"5dp\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_fav_grid\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/heart_broken\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Aún no tienes favoritos\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/loading\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\">\n\n        <ProgressBar\n            style=\"@android:style/Widget.Material.Light.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"/>\n\n        <TextView\n            android:id=\"@+id/state\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Iniciando búsqueda\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_recommends_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        app:elevation=\"0dp\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\"\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\">\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:background=\"@color/separator\"/>\n\n        <knf.kuma.custom.GridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"8dp\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_fav_grid\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/heart_broken\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Aún no tienes favoritos\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/loading\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\">\n\n        <ProgressBar\n            style=\"@android:style/Widget.Material.Light.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"/>\n\n        <TextView\n            android:id=\"@+id/state\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Iniciando búsqueda\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_recommends_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\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    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        app:elevation=\"0dp\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\"\n        app:layout_behavior=\"com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior\">\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:background=\"@color/separator\"/>\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            app:layout_behavior=\"@string/appbar_scrolling_view_behavior\"\n            tools:listitem=\"@layout/item_fav\" />\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_no_genres\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"No hay suficiente información\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/loading\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:layout_gravity=\"center\"\n        android:orientation=\"vertical\">\n\n        <ProgressBar\n            style=\"@android:style/Widget.Material.Light.ProgressBar.Large\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"/>\n\n        <TextView\n            android:id=\"@+id/state\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"Iniciando búsqueda\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_records.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:fitsSystemWindows=\"true\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            tools:listitem=\"@layout/item_record\">\n        </androidx.recyclerview.widget.RecyclerView>\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_no_records\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"No has visto nigún episodio\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_records_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:fitsSystemWindows=\"true\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <knf.kuma.custom.GridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"5dp\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_record_grid\">\n        </knf.kuma.custom.GridRecyclerView>\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_no_records\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"No has visto nigún episodio\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_records_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\"\n            android:fitsSystemWindows=\"true\"\n            app:elevation=\"0dp\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:background=\"@color/separator\"/>\n\n        <knf.kuma.custom.GridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"5dp\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_record_grid\">\n        </knf.kuma.custom.GridRecyclerView>\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_no_records\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"No has visto nigún episodio\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_records_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\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    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:orientation=\"vertical\">\n\n        <com.google.android.material.appbar.AppBarLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:theme=\"@style/AppTheme.AppBarOverlay\"\n            android:fitsSystemWindows=\"true\"\n            app:elevation=\"0dp\">\n\n            <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?actionBarSize\"\n                app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n        </com.google.android.material.appbar.AppBarLayout>\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"@dimen/separator_size\"\n            android:background=\"@color/separator\"/>\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"0dp\"\n            android:layout_weight=\"1\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            tools:listitem=\"@layout/item_record\">\n        </androidx.recyclerview.widget.RecyclerView>\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            app:showBottomSpace=\"true\" />\n    </LinearLayout>\n\n    <LinearLayout\n        android:id=\"@+id/error\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:orientation=\"vertical\"\n        android:visibility=\"gone\">\n\n        <ImageView\n            android:layout_width=\"200dp\"\n            android:layout_height=\"200dp\"\n            android:layout_gravity=\"center_horizontal\"\n            android:adjustViewBounds=\"false\"\n            android:tint=\"?android:textColorSecondary\"\n            app:srcCompat=\"@drawable/ic_no_records\"/>\n\n        <TextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"center_horizontal\"\n            android:text=\"No has visto nigún episodio\"\n            android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n            android:textColor=\"?android:textColorSecondary\"\n            android:textSize=\"24sp\"/>\n    </LinearLayout>\n\n    <ProgressBar\n        android:id=\"@+id/progress\"\n        style=\"@android:style/Widget.DeviceDefault.Light.ProgressBar.Large\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_refresh.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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    android:orientation=\"vertical\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout\n        android:id=\"@+id/refresh\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            tools:listitem=\"@layout/item_fav\"/>\n\n    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>\n\n    <knf.kuma.custom.BannerContainerView\n        android:id=\"@+id/adContainer\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_refresh_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.swiperefreshlayout.widget.SwipeRefreshLayout\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:id=\"@+id/refresh\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:paddingBottom=\"10dp\"\n            android:layout_above=\"@+id/adContainer\"\n            tools:listitem=\"@layout/item_recents\"/>\n\n        <LinearLayout\n            android:id=\"@+id/error\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_centerInParent=\"true\"\n            android:orientation=\"vertical\"\n            android:visibility=\"gone\">\n\n            <ImageView\n                android:layout_width=\"200dp\"\n                android:layout_height=\"200dp\"\n                android:layout_gravity=\"center_horizontal\"\n                android:adjustViewBounds=\"false\"\n                android:tint=\"?android:textColorSecondary\"\n                app:srcCompat=\"@drawable/ic_no_recents\"/>\n\n            <TextView\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:layout_gravity=\"center_horizontal\"\n                android:text=\"Sin recientes\"\n                android:textAppearance=\"@style/TextAppearance.AppCompat.Title\"\n                android:textColor=\"?android:textColorSecondary\"\n                android:textSize=\"24sp\" />\n        </LinearLayout>\n\n        <knf.kuma.custom.BannerContainerView\n            android:id=\"@+id/adContainer\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentBottom=\"true\" />\n    </RelativeLayout>\n\n</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_refresh_grid.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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    android:orientation=\"vertical\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout\n        android:id=\"@+id/refresh\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <knf.kuma.custom.GridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"5dp\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_fav_grid\"/>\n\n    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>\n\n    <knf.kuma.custom.BannerContainerView\n        android:id=\"@+id/adContainer\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_refresh_grid_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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    android:orientation=\"vertical\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        app:elevation=\"0dp\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/separator_size\"\n        android:background=\"@color/separator\"/>\n\n    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout\n        android:id=\"@+id/refresh\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <knf.kuma.custom.GridRecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/grid_fall_down\"\n            android:padding=\"5dp\"\n            app:layoutManager=\".custom.VariantGridLayoutManager\"\n            app:spanCount=\"@integer/span_count\"\n            tools:listitem=\"@layout/item_fav_grid\"/>\n\n    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>\n\n    <knf.kuma.custom.BannerContainerView\n        android:id=\"@+id/adContainer\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/recycler_refresh_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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    android:orientation=\"vertical\">\n\n    <com.google.android.material.appbar.AppBarLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:fitsSystemWindows=\"true\"\n        android:theme=\"@style/AppTheme.AppBarOverlay\"\n        app:elevation=\"0dp\">\n\n        <androidx.appcompat.widget.Toolbar\n            android:id=\"@+id/toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"?actionBarSize\"\n            app:popupTheme=\"@style/AppTheme.PopupOverlay\"/>\n    </com.google.android.material.appbar.AppBarLayout>\n\n    <View\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"@dimen/separator_size\"\n        android:background=\"@color/separator\"/>\n\n    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout\n        android:id=\"@+id/refresh\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:layout_behavior=\"@string/appbar_scrolling_view_behavior\">\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/recycler\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:clipToPadding=\"false\"\n            android:layoutAnimation=\"@anim/layout_fall_down\"\n            android:paddingStart=\"10dp\"\n            android:paddingTop=\"10dp\"\n            android:paddingEnd=\"10dp\"\n            app:layoutManager=\".custom.VariantLinearLayoutManager\"\n            tools:listitem=\"@layout/item_fav\"/>\n\n    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>\n\n    <knf.kuma.custom.BannerContainerView\n        android:id=\"@+id/adContainer\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/snackprogressbar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<knf.kuma.custom.snackbar.SnackProgressBarLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n                                                 android:layout_width=\"match_parent\"\r\n                                                 android:layout_height=\"wrap_content\"\r\n                                                 android:clickable=\"true\"\r\n                                                 android:focusable=\"false\"\r\n                                                 android:focusableInTouchMode=\"false\"\r\n                                                 android:gravity=\"bottom\"\r\n                                                 android:orientation=\"vertical\"\r\n                                                 android:visibility=\"visible\">\r\n\r\n    <ProgressBar\r\n        android:id=\"@+id/snackProgressBar_progressbar_horizontal\"\r\n        style=\"@style/Widget.AppCompat.ProgressBar.Horizontal\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:layout_marginTop=\"-7dp\"\r\n        android:layout_marginBottom=\"-7dp\"\r\n        android:clickable=\"true\"\r\n        android:indeterminate=\"false\"\r\n        android:max=\"100\"\r\n        android:progress=\"0\"\r\n        android:visibility=\"gone\"/>\r\n\r\n    <LinearLayout\r\n        android:id=\"@+id/snackProgressBar_layout_background\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:background=\"@color/background\"\r\n        android:clickable=\"true\"\r\n        android:longClickable=\"true\"\r\n        android:orientation=\"vertical\"\r\n        android:visibility=\"visible\">\r\n\r\n        <LinearLayout\r\n            android:id=\"@+id/snackProgressBar_layout_main\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"@dimen/snackProgressBar_height_single\"\r\n            android:orientation=\"horizontal\">\r\n\r\n            <ImageView\r\n                android:id=\"@+id/snackProgressBar_img_icon\"\r\n                android:layout_width=\"@dimen/snackProgressBar_size_icon\"\r\n                android:layout_height=\"match_parent\"\r\n                android:layout_gravity=\"center\"\r\n                android:layout_marginLeft=\"@dimen/snackProgressBar_padding_left_right\"\r\n                android:clickable=\"false\"\r\n                android:longClickable=\"false\"\r\n                android:scaleType=\"fitCenter\"\r\n                android:visibility=\"gone\"/>\r\n\r\n            <TextView\r\n                android:id=\"@+id/snackProgressBar_txt_message\"\r\n                android:layout_width=\"0dp\"\r\n                android:layout_height=\"match_parent\"\r\n                android:layout_gravity=\"center\"\r\n                android:layout_weight=\"100\"\r\n                android:clickable=\"false\"\r\n                android:ellipsize=\"end\"\r\n                android:gravity=\"center_vertical|left|start\"\r\n                android:longClickable=\"false\"\r\n                android:maxLines=\"2\"\r\n                android:paddingLeft=\"@dimen/snackProgressBar_padding_left_right\"\r\n                android:paddingRight=\"@dimen/snackProgressBar_padding_left_right\"\r\n                android:text=\"\"\r\n                android:textAlignment=\"viewStart\"\r\n                android:textColor=\"@color/textWhitePrimary\"\r\n                android:textSize=\"@dimen/text_body\"\r\n                android:visibility=\"visible\"/>\r\n\r\n            <ProgressBar\r\n                android:id=\"@+id/snackProgressBar_progressbar_circular_indeterminate\"\r\n                style=\"@style/Widget.AppCompat.ProgressBar\"\r\n                android:layout_width=\"@dimen/snackProgressBar_size_progressbar_circular\"\r\n                android:layout_height=\"match_parent\"\r\n                android:layout_gravity=\"center\"\r\n                android:layout_marginRight=\"@dimen/snackProgressBar_padding_left_right\"\r\n                android:clickable=\"false\"\r\n                android:indeterminate=\"true\"\r\n                android:longClickable=\"false\"\r\n                android:visibility=\"gone\"/>\r\n\r\n            <RelativeLayout\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"match_parent\">\r\n\r\n                <ProgressBar\r\n                    android:id=\"@+id/snackProgressBar_progressbar_circular_determinate\"\r\n                    style=\"?android:progressBarStyleHorizontal\"\r\n                    android:layout_width=\"@dimen/snackProgressBar_size_progressbar_circular\"\r\n                    android:layout_height=\"match_parent\"\r\n                    android:layout_gravity=\"center\"\r\n                    android:layout_marginRight=\"@dimen/snackProgressBar_padding_left_right\"\r\n                    android:clickable=\"false\"\r\n                    android:indeterminate=\"false\"\r\n                    android:longClickable=\"false\"\r\n                    android:max=\"100\"\r\n                    android:progress=\"0\"\r\n                    android:progressDrawable=\"@drawable/progressbar_circle\"\r\n                    android:rotation=\"-90\"\r\n                    android:visibility=\"gone\"/>\r\n\r\n                <TextView\r\n                    android:id=\"@+id/snackProgressBar_txt_progress_circular\"\r\n                    android:layout_width=\"@dimen/snackProgressBar_size_progressbar_circular\"\r\n                    android:layout_height=\"match_parent\"\r\n                    android:layout_gravity=\"center\"\r\n                    android:layout_marginRight=\"@dimen/snackProgressBar_padding_left_right\"\r\n                    android:clickable=\"false\"\r\n                    android:gravity=\"center\"\r\n                    android:longClickable=\"false\"\r\n                    android:text=\"0\"\r\n                    android:textColor=\"@color/textWhitePrimary\"\r\n                    android:textSize=\"@dimen/text_body\"\r\n                    android:visibility=\"gone\"/>\r\n\r\n            </RelativeLayout>\r\n\r\n            <TextView\r\n                android:id=\"@+id/snackProgressBar_txt_progress\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"match_parent\"\r\n                android:layout_gravity=\"center\"\r\n                android:layout_marginRight=\"@dimen/snackProgressBar_padding_left_right\"\r\n                android:clickable=\"false\"\r\n                android:gravity=\"center\"\r\n                android:longClickable=\"false\"\r\n                android:text=\"0%\"\r\n                android:textColor=\"@color/textWhitePrimary\"\r\n                android:textSize=\"@dimen/text_body\"\r\n                android:visibility=\"gone\"/>\r\n\r\n            <TextView\r\n                android:id=\"@+id/snackProgressBar_txt_action\"\r\n                style=\"@style/FontMediumStyle\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"match_parent\"\r\n                android:layout_gravity=\"center\"\r\n                android:layout_marginRight=\"@dimen/snackProgressBar_padding_left_right\"\r\n                android:clickable=\"true\"\r\n                android:gravity=\"center_vertical\"\r\n                android:longClickable=\"false\"\r\n                android:textColor=\"@color/colorAccent\"\r\n                android:textSize=\"@dimen/text_body\"\r\n                android:visibility=\"gone\"/>\r\n\r\n        </LinearLayout>\r\n\r\n        <LinearLayout\r\n            android:id=\"@+id/snackProgressBar_layout_actionNextLine\"\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"@dimen/snackProgressBar_height_actionNextLine\"\r\n            android:clickable=\"false\"\r\n            android:gravity=\"right|top\"\r\n            android:longClickable=\"false\"\r\n            android:visibility=\"gone\">\r\n\r\n            <TextView\r\n                android:id=\"@+id/snackProgressBar_txt_actionNextLine\"\r\n                style=\"@style/FontMediumStyle\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"match_parent\"\r\n                android:layout_marginRight=\"@dimen/snackProgressBar_padding_left_right\"\r\n                android:clickable=\"true\"\r\n                android:gravity=\"top\"\r\n                android:longClickable=\"false\"\r\n                android:textColor=\"@color/colorAccent\"\r\n                android:textSize=\"@dimen/text_body\"/>\r\n\r\n        </LinearLayout>\r\n\r\n    </LinearLayout>\r\n\r\n</knf.kuma.custom.snackbar.SnackProgressBarLayout>\r\n"
  },
  {
    "path": "app/src/main/res/layout/sync_item_layout.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginStart=\"8dp\"\n        android:layout_marginEnd=\"8dp\"\n        android:layout_marginBottom=\"5dp\"\n        android:orientation=\"vertical\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center_vertical\"\n            android:orientation=\"horizontal\">\n\n            <LinearLayout\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_weight=\"1\"\n                android:gravity=\"center_vertical\"\n                android:orientation=\"vertical\">\n\n                <TextView\n                    android:id=\"@+id/title\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"Sync title\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\n                    android:textSize=\"18sp\" />\n\n                <TextView\n                    android:id=\"@+id/date\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"wrap_content\"\n                    android:text=\"Cargando...\"\n                    android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\" />\n            </LinearLayout>\n\n            <LinearLayout\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:gravity=\"center|center_vertical\"\n                android:orientation=\"horizontal\">\n\n                <androidx.appcompat.widget.AppCompatImageButton\n                    android:id=\"@+id/backup\"\n                    style=\"@style/Widget.AppCompat.Button.Borderless\"\n                    android:layout_width=\"36dp\"\n                    android:layout_height=\"36dp\"\n                    android:layout_marginStart=\"8dp\"\n                    android:layout_marginEnd=\"8dp\"\n                    android:background=\"@drawable/background_ripple\"\n                    android:enabled=\"false\"\n                    android:src=\"@drawable/ic_backup\" />\n\n\n                <androidx.appcompat.widget.AppCompatImageButton\n                    android:id=\"@+id/restore\"\n                    style=\"@style/Widget.AppCompat.Button.Borderless\"\n                    android:layout_width=\"36dp\"\n                    android:layout_height=\"36dp\"\n                    android:background=\"@drawable/background_ripple\"\n                    android:enabled=\"false\"\n                    android:src=\"@drawable/ic_restore\" />\n            </LinearLayout>\n\n        </LinearLayout>\n\n        <View\n            android:id=\"@+id/separator\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"1dp\"\n            android:alpha=\"0.12\"\n            android:background=\"@color/divider\"/>\n    </LinearLayout>\n\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/tv_activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\">\n\n    <FrameLayout\n        android:id=\"@+id/tv_frame_content\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</RelativeLayout>"
  },
  {
    "path": "app/src/main/res/layout/view_hidden_overlay.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n       android:layout_width=\"match_parent\"\n       android:layout_height=\"match_parent\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:alpha=\"0.3\"\n            android:background=\"@android:color/black\"/>\n\n        <ImageView\n            android:layout_width=\"36dp\"\n            android:layout_height=\"36dp\"\n            android:layout_centerInParent=\"true\"\n            app:srcCompat=\"@drawable/ic_hide\"/>\n    </RelativeLayout>\n\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/view_home_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<merge\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\">\r\n\r\n    <LinearLayout\r\n        android:id=\"@+id/rootLayout\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_gravity=\"center_vertical\"\r\n            android:clipToPadding=\"false\"\r\n            android:orientation=\"horizontal\"\r\n            android:paddingStart=\"10dp\"\r\n            android:paddingEnd=\"8dp\">\r\n\r\n            <TextView\r\n                android:id=\"@+id/subheader\"\r\n                android:layout_width=\"0dp\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_weight=\"1\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body2\"\r\n                android:textColor=\"?android:textColorSecondary\"\r\n                tools:text=\"Subheader\"/>\r\n\r\n            <com.google.android.material.button.MaterialButton\r\n                android:id=\"@+id/viewAll\"\r\n                style=\"@style/Widget.MaterialComponents.Button.TextButton\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:text=\" VER TODOS\"\r\n                android:visibility=\"invisible\"/>\r\n        </LinearLayout>\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"207dp\">\r\n\r\n            <androidx.recyclerview.widget.RecyclerView\r\n                android:id=\"@+id/recycler\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:clipToPadding=\"false\"\r\n                android:nestedScrollingEnabled=\"false\"\r\n                android:orientation=\"horizontal\"\r\n                android:paddingStart=\"6dp\"\r\n                android:paddingEnd=\"0dp\"\r\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\r\n                tools:listitem=\"@layout/item_fav_grid_card_simple\"/>\r\n\r\n            <TextView\r\n                android:id=\"@+id/errorTV\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_centerInParent=\"true\"\r\n                android:layout_marginStart=\"32dp\"\r\n                android:layout_marginTop=\"32dp\"\r\n                android:layout_marginEnd=\"32dp\"\r\n                android:layout_marginBottom=\"32dp\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                android:visibility=\"gone\"\r\n                tools:text=\"Error text\"/>\r\n\r\n            <ProgressBar\r\n                android:id=\"@+id/progress\"\r\n                style=\"@android:style/Widget.Material.ProgressBar.Large\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_centerInParent=\"true\"/>\r\n        </RelativeLayout>\r\n    </LinearLayout>\r\n\r\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/view_home_list_large.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<merge\r\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\">\r\n\r\n    <LinearLayout\r\n        android:id=\"@+id/rootLayout\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:orientation=\"vertical\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_gravity=\"center_vertical\"\r\n            android:clipToPadding=\"false\"\r\n            android:orientation=\"horizontal\"\r\n            android:paddingStart=\"16dp\"\r\n            android:paddingEnd=\"8dp\">\r\n\r\n            <TextView\r\n                android:id=\"@+id/subheader\"\r\n                android:layout_width=\"0dp\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_weight=\"1\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Body2\"\r\n                android:textColor=\"?android:textColorSecondary\"\r\n                tools:text=\"Subheader\"/>\r\n\r\n            <com.google.android.material.button.MaterialButton\r\n                android:id=\"@+id/viewAll\"\r\n                style=\"@style/Widget.MaterialComponents.Button.TextButton\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:text=\" VER TODOS\"\r\n                android:visibility=\"invisible\"/>\r\n        </LinearLayout>\r\n\r\n        <RelativeLayout\r\n            android:layout_width=\"match_parent\"\r\n            android:layout_height=\"wrap_content\">\r\n\r\n            <androidx.recyclerview.widget.RecyclerView\r\n                android:id=\"@+id/recycler\"\r\n                android:layout_width=\"match_parent\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:clipToPadding=\"false\"\r\n                android:nestedScrollingEnabled=\"false\"\r\n                android:orientation=\"horizontal\"\r\n                android:paddingStart=\"8dp\"\r\n                android:paddingEnd=\"0dp\"\r\n                app:layoutManager=\".custom.VariantLinearLayoutManager\"\r\n                tools:listitem=\"@layout/item_fav_grid_card\"/>\r\n\r\n            <TextView\r\n                android:id=\"@+id/errorTV\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_centerInParent=\"true\"\r\n                android:layout_marginStart=\"32dp\"\r\n                android:layout_marginTop=\"32dp\"\r\n                android:layout_marginEnd=\"32dp\"\r\n                android:layout_marginBottom=\"32dp\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                android:visibility=\"gone\"\r\n                tools:text=\"Error text\"/>\r\n\r\n            <ProgressBar\r\n                android:id=\"@+id/progress\"\r\n                style=\"@android:style/Widget.Material.ProgressBar.Large\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:layout_centerInParent=\"true\"/>\r\n        </RelativeLayout>\r\n    </LinearLayout>\r\n\r\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/view_seen_overlay.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n       xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n       android:layout_width=\"match_parent\"\n       android:layout_height=\"match_parent\">\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <View\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:alpha=\"0.3\"\n            android:background=\"@android:color/black\"/>\n\n        <ImageView\n            android:layout_width=\"36dp\"\n            android:layout_height=\"36dp\"\n            android:layout_centerInParent=\"true\"\n            app:srcCompat=\"@drawable/ic_seen\"/>\n    </RelativeLayout>\n\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/view_sync_firestore.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:tools=\"http://schemas.android.com/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"wrap_content\"\r\n    android:orientation=\"vertical\">\r\n\r\n    <LinearLayout\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"wrap_content\"\r\n        android:gravity=\"center_vertical\"\r\n        android:orientation=\"horizontal\"\r\n        android:paddingTop=\"4dp\"\r\n        android:paddingBottom=\"4dp\">\r\n\r\n        <LinearLayout\r\n            android:layout_width=\"0dp\"\r\n            android:layout_height=\"wrap_content\"\r\n            android:layout_weight=\"1\"\r\n            android:orientation=\"vertical\">\r\n\r\n            <TextView\r\n                android:id=\"@+id/title\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Headline6\"\r\n                android:textSize=\"18sp\"\r\n                tools:text=\"Title\" />\r\n\r\n            <TextView\r\n                android:id=\"@+id/stateText\"\r\n                android:layout_width=\"wrap_content\"\r\n                android:layout_height=\"wrap_content\"\r\n                android:textAppearance=\"@style/TextAppearance.MaterialComponents.Caption\"\r\n                tools:text=\"Last sync: ....\" />\r\n        </LinearLayout>\r\n\r\n        <ImageView\r\n            android:id=\"@+id/indicator\"\r\n            android:layout_width=\"24dp\"\r\n            android:layout_height=\"24dp\"\r\n            android:src=\"@drawable/ic_check_bold\" />\r\n    </LinearLayout>\r\n\r\n    <View\r\n        android:id=\"@+id/separator\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"1dp\"\r\n        android:alpha=\"0.12\"\r\n        android:background=\"?colorOnSurface\" />\r\n\r\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/widget_emision.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout\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    android:orientation=\"vertical\">\n\n    <RelativeLayout\n        android:id=\"@+id/back_layout\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"60dp\"\n        android:layout_marginBottom=\"5dp\"\n        android:background=\"@color/colorPrimary\"\n        android:clickable=\"true\"\n        android:padding=\"10dp\">\n\n        <TextView\n            android:id=\"@+id/title_day\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentStart=\"true\"\n            android:layout_centerVertical=\"true\"\n            android:text=\"Day\"\n            android:textColor=\"@color/textPrimary\"\n            android:textSize=\"20sp\"/>\n\n        <TextView\n            android:id=\"@+id/title_count\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:layout_alignParentEnd=\"true\"\n            android:layout_centerVertical=\"true\"\n            android:text=\"##\"\n            android:textColor=\"@color/textPrimary\"\n            android:textSize=\"20sp\"/>\n\n    </RelativeLayout>\n\n    <RelativeLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\">\n\n        <ListView\n            android:id=\"@+id/words\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            tools:listitem=\"@layout/item_widget_list\"/>\n\n        <ImageView\n            android:id=\"@+id/empty\"\n            android:layout_width=\"150dp\"\n            android:layout_height=\"150dp\"\n            android:layout_centerInParent=\"true\"\n            android:visibility=\"gone\"\n            app:srcCompat=\"@drawable/ic_no_emision\"/>\n    </RelativeLayout>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/menu/activity_main_drawer_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:tools=\"http://schemas.android.com/tools\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n      tools:showIn=\"navigation_view\">\n    <item\n        android:id=\"@+id/drawer_explorer\"\n        android:icon=\"@drawable/ic_files\"\n        android:visible=\"@bool/showUncensored\"\n        android:title=\"Explorador\"/>\n    <item\n        android:id=\"@+id/drawer_emision\"\n        android:icon=\"@drawable/ic_emision\"\n        android:title=\"Emisión\"\n        app:actionViewClass=\"android.widget.TextView\"/>\n    <item\n        android:id=\"@+id/drawer_seeing\"\n        android:icon=\"@drawable/ic_seeing_drawer\"\n        android:title=\"Siguiendo\"\n        app:actionViewClass=\"android.widget.TextView\"/>\n    <item\n        android:id=\"@+id/drawer_queue\"\n        android:icon=\"@drawable/ic_clock\"\n        android:title=\"Pendientes\"\n        android:visible=\"@bool/showUncensored\"\n        app:actionViewClass=\"android.widget.TextView\"/>\n    <item\n        android:id=\"@+id/drawer_suggestions\"\n        android:icon=\"@drawable/ic_suggestions\"\n        android:title=\"Sugerencias\"/>\n    <item\n        android:id=\"@+id/drawer_news\"\n        android:icon=\"@drawable/ic_news\"\n        android:title=\"Noticias\"/>\n    <item\n        android:id=\"@+id/drawer_records\"\n        android:icon=\"@drawable/ic_record\"\n        android:visible=\"@bool/showUncensored\"\n        android:title=\"Historial\"/>\n    <item\n        android:id=\"@+id/drawer_random\"\n        android:icon=\"@drawable/ic_random\"\n        android:title=\"Random\"/>\n    <item\n        android:id=\"@+id/drawer_faq\"\n        android:icon=\"@drawable/ic_faq\"\n        android:title=\"FAQ\" />\n</menu>\n"
  },
  {
    "path": "app/src/main/res/menu/bottom_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/action_bottom_recents\"\n        android:enabled=\"true\"\n        android:icon=\"@drawable/bottom_recents\"\n        android:title=\"Recientes\"\n        app:showAsAction=\"ifRoom\"/>\n    <item\n        android:id=\"@+id/action_bottom_favorites\"\n        android:enabled=\"true\"\n        android:icon=\"@drawable/heart_full\"\n        android:title=\"Favoritos\"\n        app:showAsAction=\"ifRoom\"/>\n    <item\n        android:id=\"@+id/action_bottom_directory\"\n        android:enabled=\"true\"\n        android:icon=\"@drawable/bottom_directory\"\n        android:title=\"Directorio\"\n        app:showAsAction=\"ifRoom\"/>\n    <item\n        android:id=\"@+id/action_bottom_settings\"\n        android:enabled=\"true\"\n        android:icon=\"@drawable/bottom_settings\"\n        android:title=\"Configuración\"\n        app:showAsAction=\"ifRoom\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/chapter_casting_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item\n        android:id=\"@+id/download\"\n        android:title=\"DESCARGA\"/>\n    <item\n        android:id=\"@+id/casting\"\n        android:title=\"CAST\"/>\n    <item\n        android:id=\"@+id/queue\"\n        android:title=\"AÑADIR A COLA\"/>\n    <item\n        android:id=\"@+id/share\"\n        android:title=\"COMPARTIR\"/>\n    <item\n        android:id=\"@+id/import_file\"\n        android:title=\"IMPORTAR\"/>\n    <item\n        android:id=\"@+id/commentaries\"\n        android:title=\"COMENTARIOS\"\n        android:visible=\"false\" />\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/chapter_downloaded_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item\n        android:id=\"@+id/play\"\n        android:title=\"REPRODUCIR\"/>\n    <item\n        android:id=\"@+id/cast\"\n        android:title=\"CAST\"/>\n    <item\n        android:id=\"@+id/delete\"\n        android:title=\"ELIMINAR\"/>\n    <item\n        android:id=\"@+id/queue\"\n        android:title=\"AÑADIR A COLA\"/>\n    <item\n        android:id=\"@+id/share\"\n        android:title=\"COMPARTIR\"/>\n    <item\n        android:id=\"@+id/import_file\"\n        android:title=\"IMPORTAR\"\n        android:visible=\"false\"/>\n    <item\n        android:id=\"@+id/commentaries\"\n        android:title=\"COMENTARIOS\"\n        android:visible=\"false\" />\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/chapter_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item\n        android:id=\"@+id/download\"\n        android:title=\"DESCARGA\"/>\n    <item\n        android:id=\"@+id/streaming\"\n        android:title=\"STREAMING\"/>\n    <item\n        android:id=\"@+id/queue\"\n        android:title=\"AÑADIR A COLA\"/>\n    <item\n        android:id=\"@+id/share\"\n        android:title=\"COMPARTIR\"/>\n    <item\n        android:id=\"@+id/import_file\"\n        android:title=\"IMPORTAR\"/>\n    <item\n        android:id=\"@+id/commentaries\"\n        android:title=\"COMENTARIOS\"\n        android:visible=\"false\" />\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/chapter_menu_offline.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item\n        android:id=\"@+id/share\"\n        android:title=\"COMPARTIR\"/>\n    <item\n        android:id=\"@+id/import_file\"\n        android:title=\"IMPORTAR\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/dir_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/action_search\"\n        android:icon=\"@drawable/action_search\"\n        android:orderInCategory=\"900\"\n        android:title=\"Buscar\"\n        app:showAsAction=\"always\"/>\n    <item\n        android:icon=\"@drawable/ic_filter\"\n        android:orderInCategory=\"100\"\n        android:title=\"Item\"\n        app:showAsAction=\"always\">\n        <menu>\n            <group\n                android:checkableBehavior=\"single\">\n                <item\n                    android:id=\"@+id/by_name_dir\"\n                    android:title=\"Nombre\"/>\n                <item\n                    android:id=\"@+id/by_votes\"\n                    android:title=\"Puntuación\"/>\n                <item\n                    android:id=\"@+id/by_followers\"\n                    android:title=\"Seguidores\"/>\n                <item\n                    android:id=\"@+id/by_id_dir\"\n                    android:title=\"ID\"/>\n                <item\n                    android:id=\"@+id/by_added_dir\"\n                    android:title=\"Ú. añadidos\"/>\n            </group>\n        </menu>\n    </item>\n\n    <item\n        android:id=\"@+id/castMenu\"\n        android:orderInCategory=\"2\"\n        android:title=\"Connect\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/dir_menu_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:icon=\"@drawable/ic_filter\"\n        android:orderInCategory=\"100\"\n        android:title=\"Item\"\n        app:showAsAction=\"always\">\n        <menu>\n            <group\n                android:checkableBehavior=\"single\">\n                <item\n                    android:id=\"@+id/by_name_dir\"\n                    android:title=\"Nombre\"/>\n                <item\n                    android:id=\"@+id/by_votes\"\n                    android:title=\"Puntuación\"/>\n                <item\n                    android:id=\"@+id/by_followers\"\n                    android:title=\"Seguidores\"/>\n                <item\n                    android:id=\"@+id/by_id_dir\"\n                    android:title=\"ID\"/>\n                <item\n                    android:id=\"@+id/by_added_dir\"\n                    android:title=\"Ú. añadidos\"/>\n            </group>\n        </menu>\n    </item>\n\n    <item\n        android:id=\"@+id/castMenu\"\n        android:orderInCategory=\"2\"\n        android:title=\"Connect\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/fav_menu.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <item\n        android:id=\"@+id/action_search\"\n        android:icon=\"@drawable/action_search\"\n        android:orderInCategory=\"900\"\n        android:title=\"Buscar\"\n        app:showAsAction=\"always\"/>\n    <item\n        android:icon=\"@drawable/ic_filter\"\n        android:orderInCategory=\"800\"\n        android:title=\"Item\"\n        app:showAsAction=\"always\">\n        <menu>\n            <group\n                android:checkableBehavior=\"single\">\n                <item\n                    android:id=\"@+id/by_name\"\n                    android:title=\"Nombre\"/>\n                <item\n                    android:id=\"@+id/by_id\"\n                    android:title=\"ID\"/>\n            </group>\n        </menu>\n    </item>\n\n    <item\n        android:id=\"@+id/action_new_category\"\n        android:icon=\"@drawable/ic_add_category\"\n        android:orderInCategory=\"700\"\n        android:title=\"Nueva categoria\"\n        app:showAsAction=\"always\"/>\n    <item\n        android:id=\"@+id/castMenu\"\n        android:orderInCategory=\"2\"\n        android:title=\"Connect\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/fav_menu_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <item\n        android:icon=\"@drawable/ic_filter\"\n        android:orderInCategory=\"800\"\n        android:title=\"Item\"\n        app:showAsAction=\"always\">\n        <menu>\n            <group\n                android:checkableBehavior=\"single\">\n                <item\n                    android:id=\"@+id/by_name\"\n                    android:title=\"Nombre\"/>\n                <item\n                    android:id=\"@+id/by_id\"\n                    android:title=\"ID\"/>\n            </group>\n        </menu>\n    </item>\n\n    <item\n        android:id=\"@+id/action_new_category\"\n        android:icon=\"@drawable/ic_add_category\"\n        android:orderInCategory=\"700\"\n        android:title=\"Nueva categoria\"\n        app:showAsAction=\"always\"/>\n    <item\n        android:id=\"@+id/castMenu\"\n        android:orderInCategory=\"2\"\n        android:title=\"Connect\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <item\n        android:id=\"@+id/castMenu\"\n        android:orderInCategory=\"2\"\n        android:title=\"Connect\"\n        app:showAsAction=\"always\"/>\n\n    <item\n        android:id=\"@+id/action_search\"\n        android:icon=\"@drawable/action_search\"\n        android:orderInCategory=\"900\"\n        android:title=\"Buscar\"\n        app:showAsAction=\"always\"/>\n</menu>\n"
  },
  {
    "path": "app/src/main/res/menu/main_material.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <item\n        android:id=\"@+id/castMenu\"\n        android:orderInCategory=\"2\"\n        android:title=\"Connect\"\n        app:showAsAction=\"always\"/>\n</menu>\n"
  },
  {
    "path": "app/src/main/res/menu/menu_achievements.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\r\n\r\n    <item\r\n        android:id=\"@+id/coins\"\r\n        android:icon=\"@drawable/ic_coin\"\r\n        android:title=\"Conseguir monedas\"\r\n        app:showAsAction=\"always\" />\r\n\r\n    <item\r\n        android:id=\"@+id/sync\"\r\n        android:icon=\"@drawable/ic_sync_menu\"\r\n        android:title=\"Sincronizar\"\r\n        app:showAsAction=\"always\">\r\n        <menu>\r\n            <item\r\n                android:id=\"@+id/backup\"\r\n                android:icon=\"@drawable/ic_backup\"\r\n                android:title=\"Respaldar\"\r\n                app:showAsAction=\"always|withText\"/>\r\n            <item\r\n                android:id=\"@+id/restore\"\r\n                android:icon=\"@drawable/ic_restore\"\r\n                android:title=\"Restaurar\"\r\n                app:showAsAction=\"always|withText\"/>\r\n        </menu>\r\n    </item>\r\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_anime_info.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n    <item\n        android:id=\"@+id/castMenu\"\n        android:title=\"Connect\"\n        app:showAsAction=\"always\"/>\n    <item\n        android:id=\"@+id/action_share\"\n        android:icon=\"@drawable/ic_share\"\n        android:title=\"Compartir\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_bug.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\r\n    <item\r\n        android:id=\"@+id/report\"\r\n        android:icon=\"@drawable/ic_bug\"\r\n        android:title=\"Reportar bug\"\r\n        app:showAsAction=\"always\" />\r\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_download_info.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n\r\n    <item\r\n        android:id=\"@+id/download\"\r\n        android:icon=\"@drawable/ic_download\"\r\n        android:title=\"Descargar\"/>\r\n    <item\r\n        android:id=\"@+id/streaming\"\r\n        android:icon=\"@drawable/ic_play_queue\"\r\n        android:title=\"Streaming\"/>\r\n    <item\r\n        android:id=\"@+id/delete\"\r\n        android:icon=\"@drawable/ic_delete\"\r\n        android:title=\"Eliminar\" />\r\n    <item\r\n        android:id=\"@+id/info\"\r\n        android:icon=\"@drawable/ic_info\"\r\n        android:title=\"Información de anime\" />\r\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_download_options.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n\r\n    <item\r\n        android:id=\"@+id/resume\"\r\n        android:icon=\"@drawable/ic_play_queue\"\r\n        android:title=\"Reanudar\" />\r\n    <item\r\n        android:id=\"@+id/pause\"\r\n        android:icon=\"@drawable/ic_pause_normal\"\r\n        android:title=\"Pausar\" />\r\n    <item\r\n        android:id=\"@+id/cancel\"\r\n        android:icon=\"@drawable/ic_action_close\"\r\n        android:title=\"Cancelar\" />\r\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_ea.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\r\n\r\n    <item\r\n        android:id=\"@+id/coins\"\r\n        android:icon=\"@drawable/ic_coin\"\r\n        android:title=\"Conseguir monedas\"\r\n        app:showAsAction=\"always\" />\r\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_emision.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <!--<item\n        android:id=\"@+id/action_favs\"\n        android:icon=\"@drawable/ic_heart_off\"\n        android:title=\"Cambiar favoritos\"\n        app:showAsAction=\"always\"/>-->\n    <item\n        android:id=\"@+id/action_hideshow\"\n        android:icon=\"@drawable/ic_show\"\n        android:title=\"Cambiar ocultos\"\n        app:showAsAction=\"always|always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_explorer_connected.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/castMenu\"\n        android:orderInCategory=\"2\"\n        android:title=\"Connect\"\n        app:showAsAction=\"always\"/>\n\n    <item\n        android:id=\"@+id/delete_all\"\n        android:icon=\"@drawable/ic_delete_all\"\n        android:title=\"Delete all\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_img.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/download\"\n        android:title=\"Descargar\"\n        app:showAsAction=\"never\"/>\n    <item\n        android:id=\"@+id/share\"\n        android:title=\"Compartir\"\n        app:showAsAction=\"never\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_news_filters.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\r\n\r\n    <item\r\n        android:id=\"@+id/filters\"\r\n        android:icon=\"@drawable/ic_filter\"\r\n        android:title=\"Filtros\"\r\n        app:showAsAction=\"always\"/>\r\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_play_queue.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/clear\"\n        android:icon=\"@drawable/ic_clear_all\"\n        android:title=\"Clear\"\n        app:showAsAction=\"always\"/>\n    <item\n        android:id=\"@+id/play\"\n        android:icon=\"@drawable/ic_play_queue\"\n        android:title=\"Play\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_queue_group.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/queue_list\"\n        android:icon=\"@drawable/ic_queue_list\"\n        android:title=\"Lista\"\n        app:showAsAction=\"always\"/>\n    <item\n        android:id=\"@+id/info\"\n        android:icon=\"@drawable/ic_info\"\n        android:title=\"Info\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_queue_list.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/play\"\n        android:icon=\"@drawable/ic_play_queue\"\n        android:title=\"Reproducir\"\n        app:showAsAction=\"always\"/>\n    <item\n        android:id=\"@+id/queue_group\"\n        android:icon=\"@drawable/ic_grouped\"\n        android:title=\"Agrupar\"\n        app:showAsAction=\"always\"/>\n    <item\n        android:id=\"@+id/info\"\n        android:icon=\"@drawable/ic_info\"\n        android:title=\"Info\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_random.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/picker\"\n        android:icon=\"@drawable/ic_hash\"\n        android:title=\"Numero\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_rating.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/clear\"\n        android:icon=\"@drawable/ic_clear\"\n        android:title=\"Limpiar\"\n        app:showAsAction=\"always|always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_records.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/action_clear\"\n        android:icon=\"@drawable/ic_clear\"\n        android:title=\"Item\"\n        app:showAsAction=\"always\"/>\n\n    <item\n        android:id=\"@+id/action_status\"\n        android:icon=\"@drawable/ic_info\"\n        android:title=\"Estado\"\n        app:showAsAction=\"always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_seeing.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <item\r\n        android:id=\"@+id/watching\"\r\n        android:title=\"Viendo\"/>\r\n    <item\r\n        android:id=\"@+id/considering\"\r\n        android:title=\"Considerando\"/>\r\n    <item\r\n        android:id=\"@+id/completed\"\r\n        android:title=\"Completado\"/>\r\n    <item\r\n        android:id=\"@+id/droped\"\r\n        android:title=\"Dropeado\"/>\r\n    <item\r\n        android:id=\"@+id/paused\"\r\n        android:title=\"Pausa\"/>\r\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_seeing_auto.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\r\n\r\n    <item\r\n        android:id=\"@+id/auto\"\r\n        android:icon=\"@drawable/ic_magic\"\r\n        android:title=\"Auto\"\r\n        app:showAsAction=\"always\"/>\r\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_suggestions.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n      xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <item\n        android:id=\"@+id/blacklist\"\n        android:icon=\"@drawable/ic_blacklist\"\n        android:title=\"Lista negra\"\n        app:showAsAction=\"always|always\"/>\n    <item\n        android:id=\"@+id/rating\"\n        android:icon=\"@drawable/ic_rating\"\n        android:title=\"Rating\"\n        app:showAsAction=\"always|always\"/>\n</menu>"
  },
  {
    "path": "app/src/main/res/menu/menu_top.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\r\n    <item\r\n        android:id=\"@+id/coins\"\r\n        android:icon=\"@drawable/ic_coin\"\r\n        android:title=\"Conseguir monedas\"\r\n        app:showAsAction=\"always\" />\r\n    <item\r\n        android:id=\"@+id/editName\"\r\n        android:icon=\"@drawable/ic_account_edit\"\r\n        android:title=\"Editar nombre\"\r\n        app:showAsAction=\"always\" />\r\n    <group android:checkableBehavior=\"single\">\r\n        <item\r\n            android:id=\"@+id/top25\"\r\n            android:title=\"Top 25\" />\r\n        <item\r\n            android:id=\"@+id/top50\"\r\n            android:title=\"Top 50\" />\r\n        <item\r\n            android:id=\"@+id/top75\"\r\n            android:title=\"Top 75\" />\r\n        <item\r\n            android:id=\"@+id/top100\"\r\n            android:title=\"Top 100\" />\r\n    </group>\r\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=\"@color/ic_launcher_background\"/>\n    <foreground android:drawable=\"@mipmap/ic_launcher_foreground\"/>\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=\"@color/ic_launcher_background\"/>\n    <foreground android:drawable=\"@mipmap/ic_launcher_foreground\"/>\n</adaptive-icon>"
  },
  {
    "path": "app/src/main/res/values/attr.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <declare-styleable name=\"AdTemplateView\">\n        <attr name=\"at_layout\" format=\"reference\"/>\n    </declare-styleable>\n    <declare-styleable name=\"ExpandableTextView\">\n        <attr name=\"tvea_expandLines\" format=\"integer\"/>\n        <attr name=\"tvea_shrinkBitmap\" format=\"reference\"/>\n        <attr name=\"tvea_expandBitmap\" format=\"reference\"/>\n        <attr name=\"tvea_textStateColor\" format=\"color\"/>\n        <attr name=\"tvea_textContentColor\" format=\"color\"/>\n        <attr name=\"tvea_textContentSize\" format=\"dimension\"/>\n        <attr name=\"tvea_textShrink\" format=\"string\"/>\n        <attr name=\"tvea_textExpand\" format=\"string\"/>\n    </declare-styleable>\n    <declare-styleable name=\"SyncItemView\">\n        <attr name=\"si_title\" format=\"string\"/>\n        <attr name=\"si_showDivider\" format=\"boolean\"/>\n        <attr name=\"si_actionId\" format=\"string\"/>\n        <attr name=\"si_hideBackup\" format=\"boolean\" />\n    </declare-styleable>\n    <declare-styleable name=\"SyncStaticItemView\">\n        <attr name=\"ssi_title\" format=\"string\" />\n        <attr name=\"ssi_showDivider\" format=\"boolean\" />\n        <attr name=\"ssi_prefId\" format=\"string\" />\n    </declare-styleable>\n    <declare-styleable name=\"StateView\">\n        <attr name=\"sv_title\" format=\"string\"/>\n    </declare-styleable>\n    <declare-styleable name=\"StateViewMaterial\">\n        <attr name=\"svm_title\" format=\"string\"/>\n    </declare-styleable>\n    <declare-styleable name=\"ConnectionState\">\n        <attr name=\"cs_bg_color\" format=\"color\"/>\n    </declare-styleable>\n    <declare-styleable name=\"HomeList\">\n        <attr name=\"hm_showViewAll\" format=\"boolean\"/>\n        <attr name=\"hm_viewAllText\" format=\"string\" />\n        <attr name=\"hm_isLarge\" format=\"boolean\"/>\n        <attr name=\"hm_subheader\" format=\"string\"/>\n        <attr name=\"hm_startHidden\" format=\"boolean\"/>\n        <attr name=\"hm_errorText\" format=\"string\"/>\n    </declare-styleable>\n    <declare-styleable name=\"BannerContainerView\">\n        <attr name=\"showBottomSpace\" format=\"boolean\" />\n    </declare-styleable>\n    <attr name=\"colorAccentLight\" format=\"reference\"/>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/bool.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <bool name=\"isLandscape\">false</bool>\n    <bool name=\"isDark\">false</bool>\n    <bool name=\"isNotDark\">true</bool>\n    <bool name=\"isTv\">false</bool>\n    <bool name=\"isTablet\">false</bool>\n    <string name=\"layType\">0</string>\n    <bool name=\"showUncensored\">true</bool>\n    <bool name=\"is_release\">true</bool>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!-- snackbar -->\n    <color name=\"background\">#424242</color>\n    <!-- text color -->\n    <color name=\"textWhitePrimary\">#fff</color>\n\n    <color name=\"screenBackground\">#fff3f3f3</color>\n\n    <color name=\"colorPrimary\">#ffffff</color>\n    <color name=\"colorPrimaryDark\">#c7c7c7</color>\n    <color name=\"colorAccent\">#d32f2f</color>\n\n    <color name=\"stateOk\">#43a047</color>\n    <color name=\"stateWarning\">#fdd835</color>\n    <color name=\"stateError\">#e53935</color>\n\n    <color name=\"release_new\">#d4b621</color>\n    <color name=\"release_change\">#107307</color>\n    <color name=\"release_error\">#ae1315</color>\n\n    <color name=\"colorAccentPink\">#C2185B</color>\n    <color name=\"colorAccentPurple\">#7B1FA2</color>\n    <color name=\"colorAccentDeepPurple\">#512DA8</color>\n    <color name=\"colorAccentIndigo\">#303F9F</color>\n    <color name=\"colorAccentBlue\">#1976D2</color>\n    <color name=\"colorAccentLightBlue\">#0288D1</color>\n    <color name=\"colorAccentCyan\">#0097A7</color>\n    <color name=\"colorAccentTeal\">#00796B</color>\n    <color name=\"colorAccentGreen\">#388e3c</color>\n    <color name=\"colorAccentLightGreen\">#689F38</color>\n    <color name=\"colorAccentLime\">#AFB42B</color>\n    <color name=\"colorAccentYellow\">#FBC02D</color>\n    <color name=\"colorAccentAmber\">#FFA000</color>\n    <color name=\"colorAccentOrange\">#F57C00</color>\n    <color name=\"colorAccentDeepOrange\">#E64A19</color>\n    <color name=\"colorAccentBrown\">#5D4037</color>\n    <color name=\"colorAccentGray\">#616161</color>\n    <color name=\"colorAccentBlueGrey\">#455A64</color>\n\n    <color name=\"colorAccentLight\">#ff6f60</color>\n\n    <color name=\"colorAccentPinkLight\">#fa5788</color>\n    <color name=\"colorAccentPurpleLight\">#ae52d4</color>\n    <color name=\"colorAccentDeepPurpleLight\">#8559da</color>\n    <color name=\"colorAccentIndigoLight\">#666ad1</color>\n    <color name=\"colorAccentBlueLight\">#63a4ff</color>\n    <color name=\"colorAccentLightBlueLight\">#5eb8ff</color>\n    <color name=\"colorAccentCyanLight\">#56c8d8</color>\n    <color name=\"colorAccentTealLight\">#48a999</color>\n    <color name=\"colorAccentGreenLight\">#6abf69</color>\n    <color name=\"colorAccentLightGreenLight\">#99d066</color>\n    <color name=\"colorAccentLimeLight\">#e4e65e</color>\n    <color name=\"colorAccentYellowLight\">#fff263</color>\n    <color name=\"colorAccentAmberLight\">#ffd149</color>\n    <color name=\"colorAccentOrangeLight\">#ffad42</color>\n    <color name=\"colorAccentDeepOrangeLight\">#ff7d47</color>\n    <color name=\"colorAccentBrownLight\">#8b6b61</color>\n    <color name=\"colorAccentGrayLight\">#8e8e8e</color>\n    <color name=\"colorAccentBlueGreyLight\">#718792</color>\n\n    <color name=\"cardview_background\">#FFFFFF</color>\n\n    <color name=\"divider\">#000000</color>\n    <color name=\"separator\">#26000000</color>\n    <color name=\"textPrimary\">#000</color>\n    <color name=\"textSecondaryAlpha\">#8A000000</color>\n    <color name=\"textSecondaryTitle\">#80000000</color>\n    <color name=\"textSecondary\">#323232</color>\n    <color name=\"textSecondaryDark\">#DAFFFFFF</color>\n\n    <color name=\"colorSplash\">#333333</color>\n\n    <color name=\"dropbox\">#007EE5</color>\n    <color name=\"firestore\">#FFA000</color>\n    <color name=\"drive\">#ffbb00</color>\n    <color name=\"text_disable\">#42000000</color>\n\n    <color name=\"color_bottom_line_disabled\">#AAAAAA</color>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">20dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n    <dimen name=\"nav_header_height\">176dp</dimen>\n    <dimen name=\"lb_details_v2_card_height\">430dp</dimen>\n\n    <!-- general -->\n\n    <dimen name=\"separator_size\">1.5dp</dimen>\n\n    <!-- snackProgressBar -->\n    <dimen name=\"snackProgressBar_height_single\">48dp</dimen>\n    <dimen name=\"snackProgressBar_height_multi\">80dp</dimen>\n    <dimen name=\"snackProgressBar_height_actionNextLine\">32dp</dimen>\n    <dimen name=\"snackProgressBar_padding_left_right\">24dp</dimen>\n    <dimen name=\"snackProgressBar_size_progressbar_circular\">32dp</dimen>\n    <dimen name=\"snackProgressBar_size_icon\">32dp</dimen>\n\n    <!-- text -->\n    <dimen name=\"text_body\">14sp</dimen>\n    <dimen name=\"text_body_dp\">14dp</dimen>\n\n    <!--ads dimens-->\n    <item name=\"gnt_medium_template_bottom_weight\" format=\"float\" type=\"dimen\">0.4</item>\n    <item name=\"gnt_text_row_weight\" format=\"float\" type=\"dimen\">0.25</item>\n    <item name=\"gnt_media_view_weight\" format=\"float\" type=\"dimen\">1.0</item>\n    <item name=\"gnt_medium_template_top_weight\" format=\"float\" type=\"dimen\">0.2</item>\n    <dimen name=\"gnt_default_margin\">10dp</dimen>\n    <dimen name=\"gnt_text_size_small\">12sp</dimen>\n    <dimen name=\"gnt_text_size_large\">15sp</dimen>\n    <dimen name=\"gnt_ad_indicator_width\">25dp</dimen>\n    <dimen name=\"gnt_ad_indicator_height\">20dp</dimen>\n    <dimen name=\"gnt_ad_indicator_bar_height\">30dp</dimen>\n    <dimen name=\"gnt_ad_indicator_top_margin\">0dp</dimen>\n    <dimen name=\"gnt_ad_indicator_bottom_margin\">10dp</dimen>\n    <dimen name=\"gnt_ad_indicator_text_size\">10sp</dimen>\n    <dimen name=\"gnt_small_cta_button_height\">30dp</dimen>\n    <dimen name=\"gnt_medium_cta_button_height\">50dp</dimen>\n    <dimen name=\"gnt_no_margin\">0dp</dimen>\n    <dimen name=\"gnt_no_size\">0dp</dimen>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/font_certs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <array name=\"com_google_android_gms_fonts_certs\">\r\n        <item>@array/com_google_android_gms_fonts_certs_dev</item>\r\n        <item>@array/com_google_android_gms_fonts_certs_prod</item>\r\n    </array>\r\n    <string-array name=\"com_google_android_gms_fonts_certs_dev\">\r\n        <item>\r\n            MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=\r\n        </item>\r\n    </string-array>\r\n    <string-array name=\"com_google_android_gms_fonts_certs_prod\">\r\n        <item>\r\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\r\n        </item>\r\n    </string-array>\r\n</resources>\r\n"
  },
  {
    "path": "app/src/main/res/values/google_maps_api.xml",
    "content": "<resources>\n    <string name=\"google_maps_key\" templateMergeStrategy=\"preserve\" translatable=\"false\">AIzaSyBHDfuuG_yI5okc3vUVC6Wk_MJ4mlS4RB0</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"ic_launcher_background\">#FFB74D</color>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/ints.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <integer name=\"span_count\">3</integer>\n    <integer name=\"span_count_large\">2</integer>\n    <dimen name=\"num_picker\">22sp</dimen>\n    <dimen name=\"margin_login_card\">20dp</dimen>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/preloaded_fonts.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <array name=\"preloaded_fonts\" translatable=\"false\">\r\n    </array>\r\n</resources>\r\n"
  },
  {
    "path": "app/src/main/res/values/shapes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n\r\n    <style name=\"roundedCorners\" parent=\"\">\r\n        <item name=\"cornerFamily\">rounded</item>\r\n        <item name=\"cornerSize\">10dp</item>\r\n    </style>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">UKIKU</string>\n    <string name=\"title_activity_main\">UKIKU</string>\n\n    <string name=\"navigation_drawer_open\">Open navigation drawer</string>\n    <string name=\"navigation_drawer_close\">Close navigation drawer</string>\n\n    <string name=\"directory_channel_title\">Actualizacion de directorio</string>\n\n    <string name=\"theme_default\">3</string>\n\n    <string-array name=\"theme_options\">\n        <item>Automático</item>\n        <item>Dia</item>\n        <item>Noche</item>\n    </string-array>\n    <string-array name=\"theme_values\">\n        <item>3</item>\n        <item>1</item>\n        <item>2</item>\n    </string-array>\n    <string-array name=\"storage_type\">\n        <item>Memoria interna</item>\n        <item>Tarjeta SD</item>\n    </string-array>\n    <string-array name=\"storage_values\">\n        <item>0</item>\n        <item>1</item>\n    </string-array>\n    <string-array name=\"recents_type\">\n        <item>Lista</item>\n        <item>Home</item>\n    </string-array>\n    <string-array name=\"recents_type_values\">\n        <item>0</item>\n        <item>1</item>\n    </string-array>\n    <string-array name=\"recents_options\">\n        <item>Nunca</item>\n        <item>15 minutos</item>\n        <item>30 minutos</item>\n        <item>45 minutos</item>\n        <item>60 minutos</item>\n    </string-array>\n    <string-array name=\"recents_values\">\n        <item>0</item>\n        <item>1</item>\n        <item>2</item>\n        <item>3</item>\n        <item>4</item>\n    </string-array>\n    <string-array name=\"timeout_options\">\n        <item>10 segundos</item>\n        <item>20 segundos</item>\n        <item>30 segundos</item>\n        <item>Ilimitado</item>\n    </string-array>\n    <string-array name=\"timeout_values\">\n        <item>10</item>\n        <item>20</item>\n        <item>30</item>\n        <item>0</item>\n    </string-array>\n    <string-array name=\"dir_options\">\n        <item>Nunca</item>\n        <item>Diario</item>\n        <item>2 dias</item>\n        <item>3 dias</item>\n        <item>4 dias</item>\n        <item>5 dias</item>\n        <item>6 dias</item>\n        <item>Semanalmente</item>\n    </string-array>\n    <string-array name=\"dir_values\">\n        <item>0</item>\n        <item>1</item>\n        <item>2</item>\n        <item>3</item>\n        <item>4</item>\n        <item>5</item>\n        <item>6</item>\n        <item>7</item>\n    </string-array>\n    <string-array name=\"player_options\">\n        <item>Interno</item>\n        <item>Externo</item>\n    </string-array>\n    <string-array name=\"player_values\">\n        <item>0</item>\n        <item>1</item>\n    </string-array>\n    <string-array name=\"layType_options\">\n        <item>Lista</item>\n        <item>Cuadrícula</item>\n    </string-array>\n    <string-array name=\"layType_values\">\n        <item>0</item>\n        <item>1</item>\n    </string-array>\n    <string-array name=\"player_resize_options\">\n        <item>Ajustar video</item>\n        <item>Llenar pantalla</item>\n        <item>Llenar ancho</item>\n        <item>Llenar largo</item>\n    </string-array>\n    <string-array name=\"player_resize_values\">\n        <item>0</item>\n        <item>1</item>\n        <item>2</item>\n        <item>3</item>\n    </string-array>\n    <string-array name=\"buffer_size\">\n        <item>1kb</item>\n        <item>2kb</item>\n        <item>4kb</item>\n        <item>8kb</item>\n        <item>16kb</item>\n        <item>32kb</item>\n        <item>64kb</item>\n    </string-array>\n    <string-array name=\"buffer_size_values\">\n        <item>1</item>\n        <item>2</item>\n        <item>4</item>\n        <item>8</item>\n        <item>16</item>\n        <item>32</item>\n        <item>64</item>\n    </string-array>\n    <string-array name=\"parallel_count\">\n        <item>1</item>\n        <item>2</item>\n        <item>3</item>\n        <item>4</item>\n        <item>5</item>\n    </string-array>\n    <string-array name=\"downloader_type\">\n        <item>Clásico</item>\n        <item>Multiple</item>\n    </string-array>\n    <string-array name=\"downloader_type_values\">\n        <item>0</item>\n        <item>1</item>\n    </string-array>\n    <string-array name=\"autobackup\">\n        <item>Nunca</item>\n        <item>Diariamente</item>\n        <item>Cada 3 días</item>\n        <item>Cada 5 días</item>\n        <item>Semanalmente</item>\n    </string-array>\n    <string-array name=\"autobackup_values\">\n        <item>0</item>\n        <item>1</item>\n        <item>3</item>\n        <item>5</item>\n        <item>7</item>\n    </string-array>\n    <string-array name=\"savetype_values\">\n        <item>0</item>\n        <item>1</item>\n    </string-array>\n    <string-array name=\"savetype\">\n        <item>Nombre</item>\n        <item>ID</item>\n    </string-array>\n    <string-array name=\"list_states\">\n        <item>Ninguno</item>\n        <item>Viendo</item>\n        <item>Considerando</item>\n        <item>Completado</item>\n        <item>Dropeado</item>\n        <item>Pausado</item>\n    </string-array>\n    <string name=\"shortcut_fav_short\">Favoritos</string>\n    <string name=\"shortcut_fav_long\">Animes favoritos</string>\n    <string name=\"shortcut_dir_short\">Directorio</string>\n    <string name=\"shortcut_dir_long\">Animes en directorio</string>\n    <string name=\"shortcut_explorer_short\">Explorador</string>\n    <string name=\"shortcut_explorer_long\">Explorador</string>\n    <string name=\"shortcut_emision_short\">Emisión</string>\n    <string name=\"shortcut_emision_long\">Animes en emisión</string>\n    <string name=\"shortcut_disable_flat\">Flat design</string>\n    <string name=\"shortcut_disable_classic\">Classic design</string>\n\n    <string-array name=\"theme_colors\">\n        <item>Rojo</item>\n        <item>Rosa</item>\n        <item>Morado</item>\n        <item>Morado obscuro</item>\n        <item>Indigo</item>\n        <item>Azul</item>\n        <item>Azul claro</item>\n        <item>Cyan</item>\n        <item>Verde azulado</item>\n        <item>Verde</item>\n        <item>Verde claro</item>\n        <item>Lima</item>\n        <item>Amarillo</item>\n        <item>Ambar</item>\n        <item>Naranja</item>\n        <item>Naranja obscuro</item>\n        <item>Café</item>\n        <item>Gris</item>\n        <item>Gris azulado</item>\n    </string-array>\n\n    <string-array name=\"theme_colors_values\">\n        <item>0</item>\n        <item>1</item>\n        <item>2</item>\n        <item>3</item>\n        <item>4</item>\n        <item>5</item>\n        <item>6</item>\n        <item>7</item>\n        <item>8</item>\n        <item>9</item>\n        <item>10</item>\n        <item>11</item>\n        <item>12</item>\n        <item>13</item>\n        <item>14</item>\n        <item>15</item>\n        <item>16</item>\n        <item>17</item>\n        <item>18</item>\n    </string-array>\n\n    <string-array name=\"design_options\">\n        <item>Flat</item>\n        <item>Clasico</item>\n    </string-array>\n    <string-array name=\"recents_action_options\">\n        <item>Streaming</item>\n        <item>Descarga</item>\n    </string-array>\n    <string-array name=\"design_values\">\n        <item>0</item>\n        <item>1</item>\n    </string-array>\n    <string name=\"title_activity_eam\">Mapa</string>\n    <string name=\"title_activity_eamap\">Map</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.DayNight.NoActionBar\">\n        <item name=\"colorSecondary\">@color/colorAccent</item>\n        <item name=\"colorSecondaryVariant\">@color/colorAccentLight</item>\n        <item name=\"colorPrimary\">?attr/colorSecondary</item>\n        <item name=\"colorPrimaryVariant\">@color/colorPrimaryDark</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorOnSecondary\">#fff</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n        <item name=\"colorAccentLight\">@color/colorAccentLight</item>\n        <item name=\"colorOnSurface\">@color/textPrimary</item>\n        <item name=\"android:statusBarColor\">?attr/colorSurface</item>\n        <item name=\"android:navigationBarColor\">?attr/colorSurface</item>\n        <item name=\"android:windowContentTransitions\">true</item>\n    </style>\n\n    <style name=\"AppTheme.DayNight\" parent=\"AppTheme\"/>\n\n    <style name=\"AppTheme.TV.Browser\" parent=\"Theme.Leanback.Browse\">\n        <item name=\"android:colorPrimary\">#424242</item>\n        <item name=\"android:colorPrimaryDark\">#1b1b1b</item>\n        <item name=\"android:colorAccent\">@color/colorAccent</item>\n        <item name=\"defaultBrandColor\">#424242</item>\n        <item name=\"defaultBrandColorDark\">#1b1b1b</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowActionBar\">false</item>\n        <item name=\"android:windowFullscreen\">true</item>\n        <item name=\"android:windowContentOverlay\">@null</item>\n    </style>\n\n    <style name=\"AppTheme.TV.Guided\" parent=\"Theme.Leanback.GuidedStep\">\n        <item name=\"android:colorPrimary\">#424242</item>\n        <item name=\"android:colorPrimaryDark\">#1b1b1b</item>\n        <item name=\"android:colorAccent\">@color/colorAccent</item>\n        <item name=\"defaultBrandColor\">#424242</item>\n        <item name=\"defaultBrandColorDark\">#1b1b1b</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowActionBar\">false</item>\n        <item name=\"android:windowFullscreen\">true</item>\n        <item name=\"android:windowContentOverlay\">@null</item>\n    </style>\n\n    <style name=\"AppTheme.TV.Base\" parent=\"Theme.Leanback\">\n        <item name=\"android:colorPrimary\">#424242</item>\n        <item name=\"android:colorPrimaryDark\">#1b1b1b</item>\n        <item name=\"android:colorAccent\">@color/colorAccent</item>\n        <item name=\"defaultBrandColor\">#424242</item>\n        <item name=\"defaultBrandColorDark\">#1b1b1b</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowActionBar\">false</item>\n        <item name=\"android:windowFullscreen\">true</item>\n        <item name=\"android:windowContentOverlay\">@null</item>\n    </style>\n\n    <style name=\"AppTheme.TV.Details\" parent=\"Theme.Leanback.Details\">\n        <item name=\"android:colorPrimary\">#424242</item>\n        <item name=\"android:colorPrimaryDark\">#1b1b1b</item>\n        <item name=\"android:colorAccent\">@color/colorAccent</item>\n        <item name=\"defaultBrandColor\">#424242</item>\n        <item name=\"defaultBrandColorDark\">#1b1b1b</item>\n    </style>\n\n    <style name=\"AppTheme.TV.Grid\" parent=\"Theme.Leanback.VerticalGrid\">\n        <item name=\"android:colorPrimary\">#424242</item>\n        <item name=\"android:colorPrimaryDark\">#1b1b1b</item>\n        <item name=\"android:colorAccent\">@color/colorAccent</item>\n        <item name=\"defaultBrandColor\">#424242</item>\n        <item name=\"defaultBrandColorDark\">#1b1b1b</item>\n    </style>\n\n    <style name=\"AppTheme.NoActionBar\" parent=\"AppTheme.DayNight\">\n        <item name=\"windowActionBar\">false</item>\n        <item name=\"windowNoTitle\">true</item>\n        <item name=\"android:windowContentTransitions\">true</item>\n    </style>\n\n    <style name=\"AppTheme.FullScreen\" parent=\"AppTheme.DayNight\">\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowActionBar\">false</item>\n        <item name=\"android:windowFullscreen\">true</item>\n        <item name=\"android:windowContentOverlay\">@null</item>\n    </style>\n\n    <style name=\"AppTheme.Translucent\" parent=\"AppTheme.DayNight\">\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowActionBar\">false</item>\n        <item name=\"android:windowTranslucentStatus\">true</item>\n        <item name=\"android:windowTranslucentNavigation\">true</item>\n    </style>\n\n    <style name=\"AppTheme.Dialog.Base\" parent=\"Theme.MaterialComponents.Dialog.Alert\">\n        <item name=\"colorSecondary\">@color/colorAccent</item>\n        <item name=\"colorPrimary\">?attr/colorSecondary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n        <item name=\"android:windowTranslucentNavigation\">true</item>\n        <item name=\"android:windowNoTitle\">true</item>\n    </style>\n\n    <style name=\"AppTheme.Dialog.Base.Light\" parent=\"Theme.MaterialComponents.Light.Dialog.Alert\">\n        <item name=\"colorSecondary\">@color/colorAccent</item>\n        <item name=\"colorPrimary\">?attr/colorSecondary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n        <item name=\"android:windowTranslucentNavigation\">true</item>\n    </style>\n\n    <style name=\"AppTheme.Dialog.Base.DayNight\" parent=\"Theme.MaterialComponents.Light.Dialog\">\n        <item name=\"android:windowNoTitle\">true</item>\n    </style>\n\n    <style name=\"AppTheme.Button.Dropbox\" parent=\"Widget.AppCompat.Button.Colored\">\n        <item name=\"android:colorButtonNormal\">@color/dropbox</item>\n        <item name=\"android:textColor\">@android:color/white</item>\n    </style>\n\n    <style name=\"AppTheme.Button.Firestore\" parent=\"Widget.AppCompat.Button.Colored\">\n        <item name=\"android:colorButtonNormal\">@color/firestore</item>\n        <item name=\"android:textColor\">@android:color/white</item>\n    </style>\n\n    <style name=\"AppTheme.Button.Drive\" parent=\"Widget.AppCompat.Button.Colored\">\n        <item name=\"android:colorButtonNormal\">@color/drive</item>\n        <item name=\"android:textColor\">@android:color/white</item>\n    </style>\n\n    <style name=\"AppTheme.Button.Local\" parent=\"Widget.AppCompat.Button.Colored\">\n        <item name=\"android:colorButtonNormal\">?colorAccentLight</item>\n        <item name=\"android:textColor\">@android:color/white</item>\n    </style>\n\n    <style name=\"AppTheme.AppInfo\" parent=\"Theme.MaterialComponents.Light\">\n        <item name=\"colorPrimary\">?attr/colorSurface</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorSecondary\">@color/colorAccent</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n        <item name=\"md_color_button_text\">?attr/colorSecondary</item>\n        <item name=\"android:navigationBarColor\">@color/colorPrimaryDark</item>\n    </style>\n\n    <style name=\"AppTheme.Toolbar\">\n        <item name=\"android:background\">?attr/colorSurface</item>\n    </style>\n\n    <style name=\"AppTheme.AppBarOverlay\" parent=\"ThemeOverlay.MaterialComponents.Light\">\n        <item name=\"android:background\">?attr/colorSurface</item>\n        <item name=\"android:backgroundTint\">?colorSurface</item>\n    </style>\n\n    <style name=\"AppTheme.AppBarOverlay.Simple\" parent=\"ThemeOverlay.MaterialComponents.Light\">\n        <item name=\"android:background\">?attr/colorSurface</item>\n    </style>\n\n    <style name=\"AppTheme.AppBarOverlay.Simple.NoBackground\" parent=\"ThemeOverlay.MaterialComponents.Light\" />\n\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.MaterialComponents.Light\"/>\n\n    <style name=\"AppTheme.Cardview\" parent=\"Widget.MaterialComponents.CardView\"/>\n\n    <style name=\"FontMediumStyle\">\n        <item name=\"android:fontFamily\">sans-serif-medium</item>\n        <item name=\"android:textStyle\">normal</item>\n    </style>\n\n    <style name=\"AppTheme.Splash\" parent=\"Theme.AppCompat.NoActionBar\">\n        <item name=\"colorPrimary\">@color/colorAccent</item>\n        <item name=\"android:windowBackground\">@drawable/drawable_splash</item>\n        <item name=\"android:windowNoTitle\">true</item>\n        <item name=\"android:windowActionBar\">false</item>\n        <item name=\"android:windowTranslucentStatus\">true</item>\n        <item name=\"android:windowTranslucentNavigation\">true</item>\n    </style>\n\n    <style name=\"NoTitleStyle\" parent=\"AppTheme.DayNight\">\n        <item name=\"android:textColor\">@android:color/transparent</item>\n        <item name=\"android:textSize\">0sp</item>\n    </style>\n\n    <style name=\"ExpandedTextWhite\" parent=\"TextAppearance.AppCompat.Widget.ActionBar.Title\">\n        <item name=\"android:textColor\">#fff</item>\n        <item name=\"android:textSize\">30sp</item>\n    </style>\n\n    <style name=\"titleTextAppearance\" parent=\"TextAppearance.AppCompat.Body1\">\n        <item name=\"android:textColor\">@color/textSecondaryTitle</item>\n        <item name=\"android:textSize\">17sp</item>\n        <item name=\"fontFamily\">@font/open_sans</item>\n    </style>\n\n    <style name=\"ToolTipAltStyle\" parent=\"ToolTipLayoutDefaultStyle\">\n        <item name=\"ttlm_backgroundColor\">?colorSecondaryVariant</item>\n        <item name=\"ttlm_cornerRadius\">6dp</item>\n        <item name=\"ttlm_arrowRatio\">1.2</item>\n        <item name=\"ttlm_textStyle\">@style/ToolTipAltTextStyle</item>\n    </style>\n\n    <style name=\"ToolTipAltTextStyle\" parent=\"ToolTipTextStyle\">\n        <item name=\"android:textColor\">@android:color/white</item>\n    </style>\n\n    <style name=\"AppTheme.FirebaseUI\" parent=\"Theme.Material3.Dark.NoActionBar\">\n        <item name=\"colorPrimary\">@color/colorAccent</item>\n        <item name=\"colorPrimaryDark\">@color/colorAccent</item>\n        <item name=\"colorOnPrimary\">#fff</item>\n        <item name=\"colorAccent\">@color/colorPrimary</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-land/bool.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <bool name=\"isLandscape\">true</bool>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/values-land/ints.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <integer name=\"span_count\">5</integer>\n    <integer name=\"span_count_large\">3</integer>\n    <dimen name=\"num_picker\">22sp</dimen>\n    <dimen name=\"margin_login_card\">160dp</dimen>\n</resources>"
  },
  {
    "path": "app/src/main/res/values-large/bool.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <bool name=\"isTablet\">true</bool>\r\n    <string name=\"layType\">1</string>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/values-night/bool.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <bool name=\"isDark\">true</bool>\n    <bool name=\"isNotDark\">false</bool>\n</resources>"
  },
  {
    "path": "app/src/main/res/values-night/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"background\">#fff</color>\n    <color name=\"textWhitePrimary\">#000</color>\n\n    <color name=\"colorPrimary\">#282828</color>\n    <color name=\"colorPrimaryDark\">#1b1b1b</color>\n    <color name=\"divider\">#fff</color>\n    <color name=\"separator\">#26FFFFFF</color>\n    <color name=\"textPrimary\">#fff</color>\n    <color name=\"textSecondaryAlpha\">#B2FFFFFF</color>\n    <color name=\"textSecondaryTitle\">#80FFFFFF</color>\n    <color name=\"textSecondary\">#BEBEBE</color>\n\n    <color name=\"cardview_background\">#222222</color>\n    <color name=\"text_disable\">#42ffffff</color>\n\n    <color name=\"screenBackground\">#ff303030</color>\n\n    <color name=\"color_bottom_line_disabled\">#EEEEEE</color>\n</resources>"
  },
  {
    "path": "app/src/main/res/values-night/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <style name=\"AppTheme.DayNight\" parent=\"AppTheme\"/>\n\n    <style name=\"AppTheme.Dialog.Base.DayNight\" parent=\"Theme.MaterialComponents.Dialog\">\n        <item name=\"android:windowNoTitle\">true</item>\n    </style>\n\n    <style name=\"AppTheme.Toolbar\" />\n\n    <style name=\"AppTheme.AppBarOverlay\" parent=\"ThemeOverlay.MaterialComponents.Dark\" />\n\n    <style name=\"AppTheme.AppBarOverlay.Simple\" parent=\"ThemeOverlay.MaterialComponents.Dark\"/>\n\n    <style name=\"AppTheme.AppBarOverlay.Simple.NoBackground\" parent=\"ThemeOverlay.MaterialComponents.Dark\" />\n\n    <style name=\"AppTheme.PopupOverlay\" parent=\"ThemeOverlay.MaterialComponents.Dark\"/>\n\n    <style name=\"AppTheme.AppInfo\" parent=\"Theme.MaterialComponents\">\n        <item name=\"colorPrimary\">?attr/colorSurface</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n        <item name=\"md_color_button_text\">?attr/colorSecondary</item>\n        <item name=\"android:navigationBarColor\">@color/colorPrimaryDark</item>\n    </style>\n\n</resources>"
  },
  {
    "path": "app/src/main/res/values-night-v27/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n\r\n    <style name=\"AppTheme.AppInfo\" parent=\"Theme.MaterialComponents\">\r\n        <item name=\"colorPrimary\">?attr/colorSurface</item>\r\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\r\n        <item name=\"colorAccent\">@color/colorAccent</item>\r\n        <item name=\"md_color_button_text\">?attr/colorSecondary</item>\r\n        <item name=\"android:navigationBarColor\">?attr/colorSurface</item>\r\n        <item name=\"android:windowLightStatusBar\">@bool/isNotDark</item>\r\n        <item name=\"android:windowLightNavigationBar\">@bool/isNotDark</item>\r\n    </style>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/values-night-v28/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n\r\n    <style name=\"AppTheme.AppInfo\" parent=\"Theme.MaterialComponents\">\r\n        <item name=\"colorPrimary\">?attr/colorSurface</item>\r\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\r\n        <item name=\"colorAccent\">@color/colorAccent</item>\r\n        <item name=\"md_color_button_text\">?attr/colorSecondary</item>\r\n        <item name=\"android:navigationBarColor\">?attr/colorSurface</item>\r\n        <item name=\"android:windowLightStatusBar\">@bool/isNotDark</item>\r\n        <item name=\"android:windowLightNavigationBar\">@bool/isNotDark</item>\r\n        <item name=\"android:windowLayoutInDisplayCutoutMode\">shortEdges</item>\r\n    </style>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/values-television/bool.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <bool name=\"isTv\">true</bool>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/values-v27/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n\r\n    <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.DayNight.NoActionBar\">\r\n        <item name=\"colorSecondary\">@color/colorAccent</item>\r\n        <item name=\"colorSecondaryVariant\">@color/colorAccentLight</item>\r\n        <item name=\"colorPrimary\">?attr/colorSecondary</item>\r\n        <item name=\"colorPrimaryVariant\">@color/colorPrimaryDark</item>\r\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\r\n        <item name=\"colorOnSecondary\">#fff</item>\r\n        <item name=\"colorAccent\">@color/colorAccent</item>\r\n        <item name=\"colorAccentLight\">@color/colorAccentLight</item>\r\n        <item name=\"android:statusBarColor\">?attr/colorSurface</item>\r\n        <item name=\"android:navigationBarColor\">?attr/colorSurface</item>\r\n        <item name=\"android:windowContentTransitions\">true</item>\r\n        <item name=\"android:windowLightStatusBar\">@bool/isNotDark</item>\r\n        <item name=\"android:windowLightNavigationBar\">@bool/isNotDark</item>\r\n    </style>\r\n\r\n    <style name=\"AppTheme.AppInfo\" parent=\"Theme.MaterialComponents.Light\">\r\n        <item name=\"colorPrimary\">?attr/colorSurface</item>\r\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\r\n        <item name=\"colorAccent\">@color/colorAccent</item>\r\n        <item name=\"md_color_button_text\">?attr/colorSecondary</item>\r\n        <item name=\"android:navigationBarColor\">?attr/colorSurface</item>\r\n        <item name=\"android:windowLightNavigationBar\">@bool/isNotDark</item>\r\n    </style>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/values-v28/styles.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n\r\n    <style name=\"AppTheme\" parent=\"Theme.MaterialComponents.DayNight.NoActionBar\">\r\n        <item name=\"colorSecondary\">@color/colorAccent</item>\r\n        <item name=\"colorSecondaryVariant\">@color/colorAccentLight</item>\r\n        <item name=\"colorPrimary\">?attr/colorSecondary</item>\r\n        <item name=\"colorPrimaryVariant\">@color/colorPrimaryDark</item>\r\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\r\n        <item name=\"colorOnSecondary\">#fff</item>\r\n        <item name=\"colorAccent\">@color/colorAccent</item>\r\n        <item name=\"colorAccentLight\">@color/colorAccentLight</item>\r\n        <item name=\"android:statusBarColor\">?attr/colorSurface</item>\r\n        <item name=\"android:navigationBarColor\">?attr/colorSurface</item>\r\n        <item name=\"android:windowContentTransitions\">true</item>\r\n        <item name=\"android:windowLightStatusBar\">@bool/isNotDark</item>\r\n        <item name=\"android:windowLightNavigationBar\">@bool/isNotDark</item>\r\n        <item name=\"android:windowLayoutInDisplayCutoutMode\">shortEdges</item>\r\n    </style>\r\n\r\n    <style name=\"AppTheme.AppInfo\" parent=\"Theme.MaterialComponents.Light\">\r\n        <item name=\"colorPrimary\">?attr/colorSurface</item>\r\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\r\n        <item name=\"colorAccent\">@color/colorAccent</item>\r\n        <item name=\"android:colorBackground\">@color/screenBackground</item>\r\n        <item name=\"md_color_button_text\">?attr/colorSecondary</item>\r\n        <item name=\"android:navigationBarColor\">?attr/colorSurface</item>\r\n        <item name=\"android:windowLightNavigationBar\">@bool/isNotDark</item>\r\n        <item name=\"android:windowLayoutInDisplayCutoutMode\">shortEdges</item>\r\n    </style>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/values-v29/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <string name=\"theme_default\">-1</string>\r\n    <string-array name=\"theme_values\">\r\n        <item>-1</item>\r\n        <item>1</item>\r\n        <item>2</item>\r\n    </string-array>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/values-xlarge/bool.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <bool name=\"isTablet\">true</bool>\r\n    <string name=\"layType\">1</string>\r\n</resources>"
  },
  {
    "path": "app/src/main/res/xml/backup_descriptor.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<full-backup-content>\n    <!-- Exclude specific shared preferences that contain GCM registration Id -->\n</full-backup-content>\n"
  },
  {
    "path": "app/src/main/res/xml/network_security.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<network-security-config>\r\n    <base-config cleartextTrafficPermitted=\"true\">\r\n        <trust-anchors>\r\n            <certificates src=\"system\" />\r\n        </trust-anchors>\r\n    </base-config>\r\n    <domain-config cleartextTrafficPermitted=\"true\">\r\n        <domain includeSubdomains=\"true\">127.0.0.1</domain>\r\n    </domain-config>\r\n</network-security-config>"
  },
  {
    "path": "app/src/main/res/xml/path_providers.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<paths>\n    <external-path\n        name=\"internal\"\n        path=\".\"/>\n    <external-path\n        name=\"downloads\"\n        path=\"UKIKU/downloads/\"/>\n    <external-path\n        name=\"backups\"\n        path=\"UKIKU/backups/\"/>\n    <files-path\n        name=\"files\"\n        path=\".\"/>\n    <external-files-path\n        name=\"external_files\"\n        path=\".\"/>\n</paths>"
  },
  {
    "path": "app/src/main/res/xml/preferences.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<PreferenceScreen xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <PreferenceCategory android:title=\"Actualizaciones\">\n\n        <ListPreference\n            android:defaultValue=\"1\"\n            android:entries=\"@array/recents_options\"\n            android:entryValues=\"@array/recents_values\"\n            android:icon=\"@drawable/ic_recents\"\n            android:key=\"recents_time\"\n            android:summary=\"%s\"\n            android:title=\"Revisar recientes\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_group\"\n            android:key=\"group_notifications\"\n            android:title=\"Agrupar notificaciones\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_heart\"\n            android:key=\"notify_favs\"\n            android:summaryOff=\"Se notificaran todos los capitulos\"\n            android:summaryOn=\"Se notificaran capitulos solo si estan en favoritos\"\n            android:title=\"Solo favoritos\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_img\"\n            android:key=\"recent_image\"\n            android:summary=\"Episodios recientes\"\n            android:title=\"Portada en notificación\"/>\n        <ListPreference\n            android:defaultValue=\"7\"\n            android:entries=\"@array/dir_options\"\n            android:entryValues=\"@array/dir_values\"\n            android:icon=\"@drawable/ic_directory\"\n            android:key=\"dir_update_time\"\n            android:summary=\"%s\"\n            android:title=\"Recrear directorio\"/>\n        <Preference\n            android:icon=\"@drawable/ic_note\"\n            android:key=\"custom_tone\"\n            android:summary=\"Sistema\"\n            android:title=\"Tono de notificación\"/>\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:enabled=\"false\"\n            android:entries=\"@array/autobackup\"\n            android:entryValues=\"@array/autobackup_values\"\n            android:icon=\"@drawable/ic_cloud_upload\"\n            android:key=\"auto_backup\"\n            android:summary=\"%s\"\n            android:title=\"Auto respaldo\"/>\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:key=\"storage_group\"\n        android:title=\"Almacenamiento\">\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/storage_type\"\n            android:entryValues=\"@array/storage_values\"\n            android:icon=\"@drawable/ic_download\"\n            android:key=\"download_type\"\n            android:summary=\"%s\"\n            android:title=\"Descargas\"/>\n        <Preference\n            android:icon=\"@drawable/ic_download\"\n            android:key=\"download_type_q\"\n            android:title=\"Descargas\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_hide_pref\"\n            android:key=\"hide_chaps\"\n            android:title=\"Ocultar de galeria\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_import\"\n            android:key=\"show_import\"\n            android:title=\"Importar archivos\"/>\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/savetype\"\n            android:entryValues=\"@array/savetype_values\"\n            android:icon=\"@drawable/ic_save\"\n            android:key=\"save_type\"\n            android:summary=\"%s\"\n            android:title=\"Formato de guardado\"/>\n        <ListPreference\n            android:defaultValue=\"1\"\n            android:entries=\"@array/downloader_type\"\n            android:entryValues=\"@array/downloader_type_values\"\n            android:icon=\"@drawable/ic_downloader\"\n            android:key=\"downloader_type\"\n            android:summary=\"%s\"\n            android:title=\"Administrador de descarga\"/>\n        <ListPreference\n            android:defaultValue=\"3\"\n            android:entries=\"@array/parallel_count\"\n            android:entryValues=\"@array/parallel_count\"\n            android:icon=\"@drawable/ic_download_multiple\"\n            android:key=\"max_parallel_downloads\"\n            android:summary=\"Máximo %s\"\n            android:title=\"Descargas paralelas\"/>\n        <ListPreference\n            android:defaultValue=\"32\"\n            android:entries=\"@array/buffer_size\"\n            android:entryValues=\"@array/buffer_size_values\"\n            android:icon=\"@drawable/ic_buffer\"\n            android:key=\"buffer_size\"\n            android:summary=\"%s\"\n            android:title=\"Tamaño de buffer\"/>\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Reproducción\">\n\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/player_options\"\n            android:entryValues=\"@array/player_values\"\n            android:icon=\"@drawable/ic_player\"\n            android:key=\"player_type\"\n            android:summary=\"%s\"\n            android:title=\"Tipo de reproductor\"/>\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/player_resize_options\"\n            android:entryValues=\"@array/player_resize_values\"\n            android:icon=\"@drawable/ic_resize\"\n            android:key=\"player_resize\"\n            android:summary=\"%s\"\n            android:title=\"Redimensión de video\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_experimental\"\n            android:key=\"experimental_player\"\n            android:title=\"Reproductor avanzado\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_samsung_tv\"\n            android:key=\"force_local_cast\"\n            android:summary=\"Usar proxy para cast\"\n            android:title=\"Cast local\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_remember\"\n            android:key=\"remember_server\"\n            android:title=\"Recordar último servidor\"/>\n\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Diseño\">\n\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/recents_type\"\n            android:entryValues=\"@array/recents_type_values\"\n            android:icon=\"@drawable/ic_home\"\n            android:key=\"recents_design\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de recientes\"/>\n\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/recents_action_options\"\n            android:entryValues=\"@array/design_values\"\n            android:icon=\"@drawable/ic_cloud_download\"\n            android:key=\"recentActionType\"\n            android:summary=\"%s\"\n            android:title=\"Accion de click en recientes\"\n            app:useSimpleSummaryProvider=\"true\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_setting_asc_list\"\n            android:key=\"asc_chapters\"\n            android:summaryOff=\"Descendente\"\n            android:summaryOn=\"Ascendente\"\n            android:title=\"Orden de capitulos\"/>\n        <ListPreference\n            android:defaultValue=\"@string/layType\"\n            android:entries=\"@array/layType_options\"\n            android:entryValues=\"@array/layType_values\"\n            android:icon=\"@drawable/ic_lay_type\"\n            android:key=\"lay_type\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de listas\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_download_progress\"\n            android:key=\"show_progress\"\n            android:title=\"Progreso de descarga\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_sectioned_favs\"\n            android:key=\"fav_sections\"\n            android:title=\"Favoritos por categoria\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_number\"\n            android:key=\"show_fav_count\"\n            android:title=\"Indicador de favoritos\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_collapse\"\n            android:key=\"collapse_dir_nots\"\n            android:summary=\"Crear y actualizar directorio\"\n            android:title=\"Notificaciones pequeñas\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_scale\"\n            android:key=\"scale_img\"\n            android:summary=\"Portada en pantalla completa\"\n            android:title=\"Mejor calidad de imagen\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_animations\"\n            android:key=\"smooth_animations\"\n            android:title=\"Mejorar animaciones\"/>\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_heart_full_menu\"\n            android:key=\"show_favs\"\n            android:summary=\"Marcar favoritos en emisión\"\n            android:title=\"Indicador de favoritos\"/>\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_list_placeholder\"\n            android:key=\"list_placeholder\"\n            android:title=\"Usar placeholder en listas\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_cash\"\n            android:key=\"ads_enabled_new\"\n            android:summary=\"Mostrar anuncios para ayudar al programador\"\n            android:title=\"Mostrar anuncios\" />\n        <Preference\n            android:icon=\"@drawable/ic_cash\"\n            android:key=\"ads_settings\"\n            android:title=\"Configuracion de anuncios\" />\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:key=\"category_design\"\n        android:title=\"Personalización\">\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/design_options\"\n            android:entryValues=\"@array/design_values\"\n            android:icon=\"@drawable/ic_design_ab\"\n            android:key=\"designStyleType\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de UI\" />\n        <ListPreference\n            android:defaultValue=\"@string/theme_default\"\n            android:entries=\"@array/theme_options\"\n            android:entryValues=\"@array/theme_values\"\n            android:icon=\"@drawable/ic_theme\"\n            android:key=\"theme_option\"\n            android:summary=\"%s\"\n            android:title=\"Estilo de tema\"/>\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/theme_colors\"\n            android:entryValues=\"@array/theme_colors_values\"\n            android:icon=\"@drawable/ic_palette\"\n            android:key=\"theme_color\"\n            android:summary=\"%s\"\n            android:title=\"Color de tema\"/>\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Extras\">\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_ff\"\n            android:key=\"family_friendly_enabled\"\n            android:title=\"Modo family friendly\" />\n        <androidx.preference.ListPreference\n            android:defaultValue=\"10\"\n            android:entries=\"@array/timeout_options\"\n            android:entryValues=\"@array/timeout_values\"\n            android:icon=\"@drawable/ic_timeout\"\n            android:key=\"timeout_time\"\n            android:summary=\"%s\"\n            android:title=\"Espera de conexión\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_incognito\"\n            android:key=\"may_use_random_useragent_1\"\n            android:summaryOn=\"Se usará agente al azar cuando sea posible\"\n            android:summaryOff=\"Se usará la configuracion actual\"\n            android:title=\"Usar agente al azar cuando sea posible\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_bug\"\n            android:key=\"security_blocking_firestore\"\n            android:summaryOff=\"Desactivada\"\n            android:summaryOn=\"Activada\"\n            android:title=\"Protección contra SP \" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_trophy_normal\"\n            android:key=\"achievements_permissions\"\n            android:title=\"Habilitar logros\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_changelog_get\"\n            android:key=\"changelog_load\"\n            android:summaryOff=\"Web\"\n            android:summaryOn=\"Archivo local\"\n            android:title=\"Obtencion de changelog\"/>\n        <Preference\n            android:icon=\"@drawable/ic_settings_reload\"\n            android:key=\"dir_update\"\n            android:title=\"Actualizar directorio\"/>\n        <Preference\n            android:icon=\"@drawable/ic_danger\"\n            android:key=\"dir_destroy\"\n            android:title=\"Recrear directorio\"/>\n    </PreferenceCategory>\n</PreferenceScreen>"
  },
  {
    "path": "app/src/main/res/xml/shortcuts.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shortcuts xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <shortcut\n        android:icon=\"@drawable/ic_shortcut_fav\"\n        android:shortcutId=\"favs\"\n        android:shortcutLongLabel=\"@string/shortcut_fav_long\"\n        android:shortcutShortLabel=\"@string/shortcut_fav_short\">\n        <intent\n            android:action=\"android.intent.action.VIEW\"\n            android:targetClass=\"knf.kuma.shortcuts.DummyMainActivity\"\n            android:targetPackage=\"knf.kuma\">\n            <extra\n                android:name=\"start_position\"\n                android:value=\"1\"/>\n        </intent>\n    </shortcut>\n    <shortcut\n        android:icon=\"@drawable/ic_shortcut_dir\"\n        android:shortcutId=\"dir\"\n        android:shortcutLongLabel=\"@string/shortcut_dir_long\"\n        android:shortcutShortLabel=\"@string/shortcut_dir_short\">\n        <intent\n            android:action=\"android.intent.action.VIEW\"\n            android:targetClass=\"knf.kuma.shortcuts.DummyMainActivity\"\n            android:targetPackage=\"knf.kuma\">\n            <extra\n                android:name=\"start_position\"\n                android:value=\"2\"/>\n        </intent>\n    </shortcut>\n    <shortcut\n        android:icon=\"@drawable/ic_shortcut_explorer\"\n        android:shortcutId=\"explorer\"\n        android:shortcutLongLabel=\"@string/shortcut_explorer_long\"\n        android:shortcutShortLabel=\"@string/shortcut_explorer_short\">\n        <intent\n            android:action=\"android.intent.action.VIEW\"\n            android:targetClass=\"knf.kuma.shortcuts.DummyExplorerActivity\"\n            android:targetPackage=\"knf.kuma\"/>\n    </shortcut>\n    <shortcut\n        android:icon=\"@drawable/ic_shortcut_emision\"\n        android:shortcutId=\"emission\"\n        android:shortcutLongLabel=\"@string/shortcut_emision_long\"\n        android:shortcutShortLabel=\"@string/shortcut_emision_short\">\n        <intent\n            android:action=\"android.intent.action.VIEW\"\n            android:targetClass=\"knf.kuma.shortcuts.DummyEmissionActivity\"\n            android:targetPackage=\"knf.kuma\"/>\n    </shortcut>\n</shortcuts>"
  },
  {
    "path": "app/src/main/res/xml/widget_emision.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<appwidget-provider\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:initialLayout=\"@layout/widget_emision\"\n    android:minWidth=\"250dp\"\n    android:minHeight=\"250dp\"\n    android:previewImage=\"@drawable/widget_emision_preview\"\n    android:resizeMode=\"horizontal|vertical\"\n    android:updatePeriodMillis=\"10800000\"\n    android:widgetCategory=\"home_screen\">\n</appwidget-provider>"
  },
  {
    "path": "app/src/playstore/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-feature\n        android:name=\"android.software.leanback\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.touchscreen\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.microphone\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.faketouch\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.telephony\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.camera\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.nfc\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.location.gps\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.location\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.sensor\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n    <uses-feature\n        android:name=\"android.hardware.wifi\"\n        android:required=\"false\"\n        tools:node=\"remove\"/>\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n    <uses-permission android:name=\"android.permission.CHANGE_WIFI_MULTICAST_STATE\" tools:node=\"remove\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" tools:node=\"remove\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" tools:node=\"remove\" />\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\" />\n    <uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\" tools:node=\"remove\" />\n    <uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\" tools:node=\"remove\"/>\n    <uses-permission\n        android:name=\"android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK\"\n        tools:node=\"remove\" />\n    <uses-permission\n        android:name=\"android.permission.RECORD_AUDIO\"\n        android:requiredFeature=\"android.software.leanback\"\n        tools:node=\"remove\"/>\n\n    <application\n        android:name=\".App\"\n        android:allowBackup=\"true\"\n        android:fullBackupContent=\"@xml/backup_descriptor\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:resizeableActivity=\"true\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:theme=\"@style/AppTheme.DayNight\"\n        android:usesCleartextTraffic=\"true\"\n        tools:replace=\"android:fullBackupContent\">\n\n        <meta-data\n            android:name=\"com.google.android.geo.API_KEY\"\n            android:value=\"@string/google_maps_key\" />\n        <meta-data\n            android:name=\"com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME\"\n            android:value=\"knf.kuma.cast.CastOptionsProvider\" />\n\n\n        <activity\n            android:name=\".commons.EAMapActivity\"\n            android:label=\"@string/title_activity_eamap\" />\n        <activity\n            android:name=\".SplashActivity\"\n            android:label=\"@string/title_activity_main\"\n            android:theme=\"@style/AppTheme.Splash\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"http\" />\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n            <intent-filter>\n                <data\n                    android:host=\"open\"\n                    android:scheme=\"ukiku\" />\n\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n            </intent-filter>\n\n            <meta-data\n                android:name=\"android.app.shortcuts\"\n                android:resource=\"@xml/shortcuts\" />\n        </activity>\n        <activity\n            android:name=\".Main\"\n            android:label=\"@string/title_activity_main\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/search\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".tv.ui.TVMain\"\n            android:banner=\"@drawable/tv_banner\"\n            android:exported=\"true\"\n            android:theme=\"@style/AppTheme.TV.Browser\"\n            tools:node=\"remove\">\n        </activity>\n        <activity\n            android:name=\".animeinfo.ActivityAnime\"\n            android:theme=\"@style/AppTheme.NoActionBar\"\n            android:windowSoftInputMode=\"stateHidden\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/anime/\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".player.CustomExoPlayer\"\n            android:configChanges=\"screenSize|smallestScreenSize|screenLayout|orientation\"\n            android:immersive=\"true\"\n            android:launchMode=\"singleTask\"\n            android:resizeableActivity=\"true\"\n            android:supportsPictureInPicture=\"true\">\n            <intent-filter android:label=\"UKIKU\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"http\" />\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".player.VideoActivity\"\n            android:configChanges=\"screenSize|smallestScreenSize|screenLayout|orientation\"\n            android:immersive=\"true\"\n            android:launchMode=\"singleTask\"\n            android:resizeableActivity=\"true\"\n            android:supportsPictureInPicture=\"true\">\n            <intent-filter android:label=\"UKIKU experimental\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"http\" />\n                <data\n                    android:mimeType=\"video/mp4\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".animeinfo.img.ActivityImgFull\"\n            android:theme=\"@style/AppTheme.FullScreen\" />\n        <activity android:name=\".record.RecordActivity\" />\n        <activity android:name=\".seeing.SeeingActivity\" />\n        <activity android:name=\".emision.EmissionActivity\" />\n        <activity android:name=\".explorer.ExplorerActivity\" />\n        <activity\n            android:name=\".updater.UpdateActivity\"\n            android:excludeFromRecents=\"true\"\n            android:exported=\"true\" />\n        <activity android:name=\".random.RandomActivity\" />\n        <activity android:name=\".changelog.ChangelogActivity\" />\n        <activity\n            android:name=\".backup.BackUpActivity\"\n            android:theme=\"@style/AppTheme.Translucent\" />\n        <activity\n            android:name=\"com.dropbox.core.android.AuthActivity\"\n            android:configChanges=\"orientation|keyboard\"\n            android:launchMode=\"singleTask\">\n            <intent-filter>\n                <data android:scheme=\"db-qtjow4hsk06vt19\" />\n\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".backup.MigrationActivity\"\n            android:theme=\"@style/AppTheme.Translucent\" />\n        <activity android:name=\".recommended.RecommendActivity\" />\n        <activity android:name=\".recommended.RankingActivity\" />\n        <activity android:name=\".search.GenreActivity\" />\n\n        <service android:name=\".directory.DirectoryService\" />\n        <service android:name=\".directory.DirectoryUpdateService\" />\n        <service android:name=\".download.DownloadService\" />\n        <service\n            android:name=\".widgets.emision.WEmissionService\"\n            android:permission=\"android.permission.BIND_REMOTEVIEWS\" />\n        <service android:name=\".download.DownloadManager\" />\n        <service android:name=\".commons.SelfServer\" />\n\n        <receiver\n            android:name=\".widgets.emision.WEmisionProvider\"\n            android:label=\"Emisión\">\n            <intent-filter>\n                <action android:name=\"android.appwidget.action.APPWIDGET_UPDATE\" />\n            </intent-filter>\n\n            <meta-data\n                android:name=\"android.appwidget.provider\"\n                android:resource=\"@xml/widget_emision\" />\n        </receiver>\n        <receiver android:name=\".download.DownloadReceiver\" />\n        <receiver android:name=\".recents.RecentsNotReceiver\" />\n\n        <provider\n            android:name=\"androidx.core.content.FileProvider\"\n            android:authorities=\"${applicationId}.fileprovider\"\n            android:exported=\"false\"\n            android:grantUriPermissions=\"true\">\n            <meta-data\n                android:name=\"android.support.FILE_PROVIDER_PATHS\"\n                android:resource=\"@xml/path_providers\" />\n        </provider>\n\n        <meta-data\n            android:name=\"com.google.android.gms.ads.AD_MANAGER_APP\"\n            android:value=\"true\" />\n\n        <activity android:name=\".queue.QueueActivity\" />\n        <activity\n            android:name=\".download.DownloadDialogActivity\"\n            android:excludeFromRecents=\"true\"\n            android:theme=\"@style/Theme.AppCompat.DayNight.Dialog\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/ver/\"\n                    android:scheme=\"https\" />\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/ver/\"\n                    android:scheme=\"http\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\".custom.ThemedControlsActivity\" />\n        <activity android:name=\".news.NewsActivity\" />\n        <activity android:name=\".achievements.AchievementActivity\" />\n        <activity android:name=\".commons.EAUnlockActivity\" />\n        <activity\n            android:name=\"es.munix.multidisplaycast.CastControlsActivity\"\n            android:screenOrientation=\"sensor\"\n            tools:node=\"merge\"\n            tools:replace=\"android:screenOrientation\" />\n        <activity android:name=\".Diagnostic\" />\n        <activity android:name=\".recents.RecentsActivity\" />\n        <activity android:name=\".Diagnostic$FullBypass\" />\n\n        <uses-library\n            android:name=\"org.apache.http.legacy\"\n            android:required=\"false\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/playstore/res/drawable/ic_launcher_foregound.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        android:width=\"108dp\"\n        android:height=\"108dp\"\n        android:viewportWidth=\"4045.2056\"\n        android:viewportHeight=\"4045.2056\">\n    <group\n        android:translateX=\"546.1027\"\n        android:translateY=\"546.1027\">\n        <path\n            android:name=\"UKIKU\"\n            android:fillColor=\"#fff\"\n            android:pathData=\"m395.4 1256.4v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.2 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3zm533.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm164 0v440.5h79.9v-440.5zm173.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm154.5 0v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.3 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3z\"/>\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/playstore/res/drawable/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"4596.8247\"\n    android:viewportHeight=\"4596.8247\">\n  <group android:translateX=\"275.80948\"\n      android:translateY=\"275.80948\">\n      <group\n          android:translateX=\"546.1027\"\n          android:translateY=\"546.1027\">\n          <path\n              android:name=\"UKIKU\"\n              android:fillColor=\"#fff\"\n              android:pathData=\"m395.4 1256.4v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.2 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3zm533.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm164 0v440.5h79.9v-440.5zm173.9 0v440.5h79.9v-440.5zm347.8 0 -179.7 180h-56.2v80.5h56.2l179.7 180h113.4l-226.4 -220.3l226.4 -220.3zm154.5 0v220.3c0 25.8 3.1 49.2 9.2 70.2c6.1 21 14.6 39.6 25.3 55.9c10.8 16.3 23.3 30.4 37.6 42.2c14.3 11.9 29.6 21.7 45.9 29.3c16.3 7.7 33.1 13.4 50.5 17.1c17.4 3.7 34.6 5.5 51.6 5.5h180c5.5 0 10.8 -1 15.7 -3.1c4.9 -2 9.2 -4.9 12.9 -8.4c3.7 -3.6 6.6 -7.8 8.6 -12.7c2 -4.9 3.1 -10.2 3.1 -16v-400.3h-79.9v360.7h-140.4c-2.5 0 -7.6 -0.4 -15.5 -1.1c-7.9 -0.7 -17 -2.5 -27.3 -5.4c-10.3 -2.9 -21.3 -7.3 -32.7 -13.2c-11.5 -5.9 -22 -14.1 -31.6 -24.6c-9.6 -10.4 -17.6 -23.4 -23.8 -39c-6.3 -15.6 -9.4 -34.6 -9.4 -57.1v-220.3z\"/>\n      </group>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/playstore/res/menu/activity_main_drawer_drawer.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu 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    tools:showIn=\"navigation_view\">\n    <item\n        android:id=\"@+id/drawer_explorer\"\n        android:icon=\"@drawable/ic_files\"\n        android:title=\"Explorador\"\n        android:visible=\"false\" />\n    <item\n        android:id=\"@+id/drawer_emision\"\n        android:icon=\"@drawable/ic_emision\"\n        android:title=\"Emisión\"\n        app:actionViewClass=\"android.widget.TextView\" />\n    <item\n        android:id=\"@+id/drawer_seeing\"\n        android:icon=\"@drawable/ic_seeing_drawer\"\n        android:title=\"Siguiendo\"\n        app:actionViewClass=\"android.widget.TextView\" />\n    <item\n        android:id=\"@+id/drawer_queue\"\n        android:icon=\"@drawable/ic_clock\"\n        android:title=\"Pendientes\"\n        android:visible=\"false\"\n        app:actionViewClass=\"android.widget.TextView\" />\n    <item\n        android:id=\"@+id/drawer_suggestions\"\n        android:icon=\"@drawable/ic_suggestions\"\n        android:title=\"Sugerencias\" />\n    <item\n        android:id=\"@+id/drawer_news\"\n        android:icon=\"@drawable/ic_news\"\n        android:title=\"Noticias\" />\n    <item\n        android:id=\"@+id/drawer_records\"\n        android:icon=\"@drawable/ic_record\"\n        android:title=\"Historial\"\n        android:visible=\"false\" />\n    <item\n        android:id=\"@+id/drawer_random\"\n        android:icon=\"@drawable/ic_random\"\n        android:title=\"Random\" />\n    <item\n        android:id=\"@+id/drawer_faq\"\n        android:icon=\"@drawable/ic_faq\"\n        android:title=\"FAQ\" />\n</menu>\n"
  },
  {
    "path": "app/src/playstore/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <background android:drawable=\"@color/ic_launcher_background\"/>\r\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\r\n</adaptive-icon>"
  },
  {
    "path": "app/src/playstore/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n    <background android:drawable=\"@color/ic_launcher_background\"/>\r\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\r\n</adaptive-icon>"
  },
  {
    "path": "app/src/playstore/res/values/bool.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <bool name=\"isLandscape\">false</bool>\r\n    <bool name=\"isDark\">false</bool>\r\n    <bool name=\"isNotDark\">true</bool>\r\n    <bool name=\"isTv\">false</bool>\r\n    <bool name=\"isTablet\">false</bool>\r\n    <string name=\"layType\">0</string>\r\n    <bool name=\"showUncensored\">false</bool>\r\n    <bool name=\"is_release\">false</bool>\r\n</resources>"
  },
  {
    "path": "app/src/playstore/res/values/google_maps_api.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <string name=\"google_maps_key\" templateMergeStrategy=\"preserve\" translatable=\"false\">AIzaSyD2QS_E66qKxXmJhlXW8eRT7OYNdHphWUY</string>\r\n</resources>"
  },
  {
    "path": "app/src/playstore/res/values/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <color name=\"ic_launcher_background\">#000000</color>\r\n</resources>"
  },
  {
    "path": "app/src/playstore/res/xml/preferences.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<PreferenceScreen xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <PreferenceCategory android:title=\"Actualizaciones\">\n\n        <ListPreference\n            android:defaultValue=\"1\"\n            android:entries=\"@array/recents_options\"\n            android:entryValues=\"@array/recents_values\"\n            android:icon=\"@drawable/ic_recents\"\n            android:key=\"recents_time\"\n            android:summary=\"%s\"\n            android:title=\"Revisar recientes\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_group\"\n            android:key=\"group_notifications\"\n            android:title=\"Agrupar notificaciones\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_heart\"\n            android:key=\"notify_favs\"\n            android:summaryOff=\"Se notificaran todos los capitulos\"\n            android:summaryOn=\"Se notificaran capitulos solo si estan en favoritos\"\n            android:title=\"Solo favoritos\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_img\"\n            android:key=\"recent_image\"\n            android:summary=\"Episodios recientes\"\n            android:title=\"Portada en notificación\" />\n        <ListPreference\n            android:defaultValue=\"7\"\n            android:entries=\"@array/dir_options\"\n            android:entryValues=\"@array/dir_values\"\n            android:icon=\"@drawable/ic_directory\"\n            android:key=\"dir_update_time\"\n            android:summary=\"%s\"\n            android:title=\"Recrear directorio\" />\n        <Preference\n            android:icon=\"@drawable/ic_note\"\n            android:key=\"custom_tone\"\n            android:summary=\"Sistema\"\n            android:title=\"Tono de notificación\" />\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:enabled=\"false\"\n            android:entries=\"@array/autobackup\"\n            android:entryValues=\"@array/autobackup_values\"\n            android:icon=\"@drawable/ic_cloud_upload\"\n            android:key=\"auto_backup\"\n            android:summary=\"%s\"\n            android:title=\"Auto respaldo\" />\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:key=\"storage_group\"\n        android:title=\"Almacenamiento\"\n        app:isPreferenceVisible=\"false\">\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/storage_type\"\n            android:entryValues=\"@array/storage_values\"\n            android:icon=\"@drawable/ic_download\"\n            android:key=\"download_type\"\n            android:summary=\"%s\"\n            android:title=\"Descargas\" />\n        <Preference\n            android:icon=\"@drawable/ic_download\"\n            android:key=\"download_type_q\"\n            android:title=\"Descargas\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_hide_pref\"\n            android:key=\"hide_chaps\"\n            android:title=\"Ocultar de galeria\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_import\"\n            android:key=\"show_import\"\n            android:title=\"Importar archivos\" />\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/savetype\"\n            android:entryValues=\"@array/savetype_values\"\n            android:icon=\"@drawable/ic_save\"\n            android:key=\"save_type\"\n            android:summary=\"%s\"\n            android:title=\"Formato de guardado\" />\n        <ListPreference\n            android:defaultValue=\"1\"\n            android:entries=\"@array/downloader_type\"\n            android:entryValues=\"@array/downloader_type_values\"\n            android:icon=\"@drawable/ic_downloader\"\n            android:key=\"downloader_type\"\n            android:summary=\"%s\"\n            android:title=\"Administrador de descarga\" />\n        <ListPreference\n            android:defaultValue=\"3\"\n            android:entries=\"@array/parallel_count\"\n            android:entryValues=\"@array/parallel_count\"\n            android:icon=\"@drawable/ic_download_multiple\"\n            android:key=\"max_parallel_downloads\"\n            android:summary=\"Máximo %s\"\n            android:title=\"Descargas paralelas\" />\n        <ListPreference\n            android:defaultValue=\"32\"\n            android:entries=\"@array/buffer_size\"\n            android:entryValues=\"@array/buffer_size_values\"\n            android:icon=\"@drawable/ic_buffer\"\n            android:key=\"buffer_size\"\n            android:summary=\"%s\"\n            android:title=\"Tamaño de buffer\" />\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:title=\"Reproducción\"\n        app:isPreferenceVisible=\"false\">\n\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/player_options\"\n            android:entryValues=\"@array/player_values\"\n            android:icon=\"@drawable/ic_player\"\n            android:key=\"player_type\"\n            android:summary=\"%s\"\n            android:title=\"Tipo de reproductor\" />\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/player_resize_options\"\n            android:entryValues=\"@array/player_resize_values\"\n            android:icon=\"@drawable/ic_resize\"\n            android:key=\"player_resize\"\n            android:summary=\"%s\"\n            android:title=\"Redimensión de video\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_experimental\"\n            android:key=\"experimental_player\"\n            android:title=\"Reproductor experimental\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_samsung_tv\"\n            android:key=\"force_local_cast\"\n            android:summary=\"Usar proxy para cast\"\n            android:title=\"Cast local\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_remember\"\n            android:key=\"remember_server\"\n            android:title=\"Recordar último servidor\" />\n\n    </PreferenceCategory>\n    <PreferenceCategory android:title=\"Diseño\">\n\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/recents_type\"\n            android:entryValues=\"@array/recents_type_values\"\n            android:icon=\"@drawable/ic_home\"\n            android:key=\"recents_design\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de recientes\" />\n\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_setting_asc_list\"\n            android:key=\"asc_chapters\"\n            android:summaryOff=\"Descendente\"\n            android:summaryOn=\"Ascendente\"\n            android:title=\"Orden de capitulos\" />\n        <ListPreference\n            android:defaultValue=\"@string/layType\"\n            android:entries=\"@array/layType_options\"\n            android:entryValues=\"@array/layType_values\"\n            android:icon=\"@drawable/ic_lay_type\"\n            android:key=\"lay_type\"\n            android:summary=\"%s\"\n            android:title=\"Diseño de listas\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_download_progress\"\n            android:key=\"show_progress\"\n            android:title=\"Progreso de descarga\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_sectioned_favs\"\n            android:key=\"fav_sections\"\n            android:title=\"Favoritos por categoria\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_number\"\n            android:key=\"show_fav_count\"\n            android:title=\"Indicador de favoritos\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_collapse\"\n            android:key=\"collapse_dir_nots\"\n            android:summary=\"Crear y actualizar directorio\"\n            android:title=\"Notificaciones pequeñas\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_scale\"\n            android:key=\"scale_img\"\n            android:summary=\"Portada en pantalla completa\"\n            android:title=\"Mejor calidad de imagen\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_animations\"\n            android:key=\"smooth_animations\"\n            android:title=\"Mejorar animaciones\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_heart_full_menu\"\n            android:key=\"show_favs\"\n            android:summary=\"Marcar favoritos en emisión\"\n            android:title=\"Indicador de favoritos\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_list_placeholder\"\n            android:key=\"list_placeholder\"\n            android:title=\"Usar placeholder en listas\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_cash\"\n            android:key=\"ads_enabled_new\"\n            android:summary=\"Mostrar anuncios para ayudar al programador\"\n            android:title=\"Mostrar anuncios\" />\n    </PreferenceCategory>\n    <PreferenceCategory\n        android:key=\"category_design\"\n        android:title=\"Personalización\">\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/theme_options\"\n            android:entryValues=\"@array/theme_values\"\n            android:icon=\"@drawable/ic_theme\"\n            android:key=\"theme_option\"\n            android:summary=\"%s\"\n            android:title=\"Estilo de tema\" />\n        <ListPreference\n            android:defaultValue=\"0\"\n            android:entries=\"@array/theme_colors\"\n            android:entryValues=\"@array/theme_colors_values\"\n            android:icon=\"@drawable/ic_palette\"\n            android:key=\"theme_color\"\n            android:summary=\"%s\"\n            android:title=\"Color de tema\" />\n    </PreferenceCategory>\n    <PreferenceCategory android:title=\"Extras\">\n\n        <androidx.preference.ListPreference\n            android:defaultValue=\"10\"\n            android:entries=\"@array/timeout_options\"\n            android:entryValues=\"@array/timeout_values\"\n            android:icon=\"@drawable/ic_timeout\"\n            android:key=\"timeout_time\"\n            android:summary=\"%s\"\n            android:title=\"Espera de conexión\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_incognito\"\n            android:key=\"default_useragent\"\n            android:summaryOff=\"Se usará agente al azar en bypass\"\n            android:summaryOn=\"Se usará agente por defecto en bypass\"\n            android:title=\"Usar agente del dispositivo\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_setting_gps\"\n            android:key=\"daynigth_permission\"\n            android:title=\"Tema dia/noche preciso\" />\n        <SwitchPreference\n            android:defaultValue=\"false\"\n            android:icon=\"@drawable/ic_trophy_normal\"\n            android:key=\"achievements_permissions\"\n            android:title=\"Habilitar logros\" />\n        <SwitchPreference\n            android:defaultValue=\"true\"\n            android:icon=\"@drawable/ic_changelog_get\"\n            android:key=\"changelog_load\"\n            android:summaryOff=\"Web\"\n            android:summaryOn=\"Archivo local\"\n            android:title=\"Obtencion de changelog\" />\n        <Preference\n            android:icon=\"@drawable/ic_settings_reload\"\n            android:key=\"dir_update\"\n            android:title=\"Actualizar directorio\" />\n        <Preference\n            android:icon=\"@drawable/ic_danger\"\n            android:key=\"dir_destroy\"\n            android:title=\"Recrear directorio\" />\n    </PreferenceCategory>\n</PreferenceScreen>"
  },
  {
    "path": "app/src/release/res/values/google_maps_api.xml",
    "content": "<resources>\r\n    <string name=\"google_maps_key\" templateMergeStrategy=\"preserve\" translatable=\"false\">AIzaSyBHDfuuG_yI5okc3vUVC6Wk_MJ4mlS4RB0</string>\r\n</resources>\r\n"
  },
  {
    "path": "app/src/test/java/knf/kuma/ExampleUnitTest.kt",
    "content": "package knf.kuma\n\nimport knf.kuma.achievements.LevelCalculator\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\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    @Throws(Exception::class)\n    fun addition_isCorrect() {\n        assertEquals(4, (2 + 2).toLong())\n    }\n\n    @Test\n    fun testPoints() {\n        val lc = LevelCalculator()\n        var last = 0\n        lc.levels.forEachIndexed { index, i ->\n            print(\"Level ${index + 1}: ${i - last}\\n\")\n            last = i\n        }\n    }\n}"
  },
  {
    "path": "app/src/tv/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-feature\n        android:name=\"android.software.leanback\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.touchscreen\"\n        android:required=\"false\" />\n    <uses-feature\n        android:name=\"android.hardware.microphone\"\n        android:required=\"false\" />\n\n    <uses-permission android:name=\"android.permission.INTERNET\"/>\n    <uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>\n    <uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>\n    <uses-permission\n        android:name=\"android.permission.RECORD_AUDIO\"\n        android:requiredFeature=\"android.software.leanback\" />\n    <uses-permission android:name=\"android.permission.FOREGROUND_SERVICE\"/>\n\n    <application\n        android:name=\".App\"\n        android:allowBackup=\"true\"\n        android:banner=\"@drawable/tv_banner\"\n        android:fullBackupContent=\"@xml/backup_descriptor\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:resizeableActivity=\"true\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme.DayNight\"\n        android:usesCleartextTraffic=\"true\">\n        <activity\n            android:name=\".tv.ui.TVMain\"\n            android:banner=\"@drawable/tv_banner\"\n            android:screenOrientation=\"sensorLandscape\"\n            android:theme=\"@style/AppTheme.TV.Browser\"\n            tools:replace=\"android:screenOrientation\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\"/>\n\n                <category android:name=\"android.intent.category.LAUNCHER\"/>\n                <category android:name=\"android.intent.category.LEANBACK_LAUNCHER\"/>\n            </intent-filter>\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\"/>\n\n                <category android:name=\"android.intent.category.BROWSABLE\"/>\n                <category android:name=\"android.intent.category.DEFAULT\"/>\n\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"http\"/>\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/*\"\n                    android:scheme=\"https\"/>\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/get.php\"\n                    android:scheme=\"http\"/>\n                <data\n                    android:host=\"ukiku.app\"\n                    android:pathPrefix=\"/get.php\"\n                    android:scheme=\"https\" />\n            </intent-filter>\n\n            <meta-data\n                android:name=\"android.app.shortcuts\"\n                android:resource=\"@xml/shortcuts\" />\n        </activity>\n        <activity\n            android:name=\".SplashActivity\"\n            tools:node=\"remove\" />\n        <activity\n            android:name=\".backup.BackUpActivity\"\n            android:theme=\"@style/AppTheme.Translucent\" />\n        <activity\n            android:name=\"com.dropbox.core.android.AuthActivity\"\n            android:configChanges=\"orientation|keyboard\"\n            android:launchMode=\"singleTask\">\n            <intent-filter>\n                <data android:scheme=\"db-qtjow4hsk06vt19\" />\n\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.BROWSABLE\"/>\n                <category android:name=\"android.intent.category.DEFAULT\"/>\n            </intent-filter>\n        </activity>\n\n        <service android:name=\".directory.DirectoryService\"/>\n        <service android:name=\".directory.DirectoryUpdateService\"/>\n        <service android:name=\".download.DownloadService\"/>\n        <service\n            android:name=\".widgets.emision.WEmissionService\"\n            android:permission=\"android.permission.BIND_REMOTEVIEWS\"/>\n        <service android:name=\".download.DownloadManager\"/>\n        <service android:name=\".commons.SelfServer\"/>\n\n        <receiver\n            android:name=\".widgets.emision.WEmisionProvider\"\n            android:label=\"Emisión\">\n            <intent-filter>\n                <action android:name=\"android.appwidget.action.APPWIDGET_UPDATE\"/>\n            </intent-filter>\n\n            <meta-data\n                android:name=\"android.appwidget.provider\"\n                android:resource=\"@xml/widget_emision\"/>\n        </receiver>\n        <receiver android:name=\".download.DownloadReceiver\"/>\n        <receiver android:name=\".recents.RecentsNotReceiver\"/>\n\n        <provider\n            android:name=\"androidx.core.content.FileProvider\"\n            android:authorities=\"${applicationId}.fileprovider\"\n            android:exported=\"false\"\n            android:grantUriPermissions=\"true\">\n            <meta-data\n                android:name=\"android.support.FILE_PROVIDER_PATHS\"\n                android:resource=\"@xml/path_providers\"/>\n        </provider>\n\n        <meta-data\n            android:name=\"io.fabric.ApiKey\"\n            android:value=\"8971b3733a2fd699ebd101e18ce228d80baeab92\"/>\n        <meta-data\n            android:name=\"com.google.android.gms.ads.AD_MANAGER_APP\"\n            android:value=\"true\" />\n\n        <activity\n            android:name=\".tv.streaming.TVServerSelection\"\n            android:theme=\"@style/AppTheme.TV.Guided\"/>\n        <activity\n            android:name=\".tv.exoplayer.TVPlayer\"\n            android:theme=\"@style/AppTheme.TV.Base\"/>\n        <activity\n            android:name=\".tv.details.TVAnimesDetails\"\n            android:theme=\"@style/AppTheme.TV.Details\"/>\n        <activity\n            android:name=\".tv.search.TVSearch\"\n            android:theme=\"@style/AppTheme.TV.Base\"/>\n        <activity\n            android:name=\".tv.directory.TVDir\"\n            android:theme=\"@style/AppTheme.TV.Grid\"/>\n        <activity\n            android:name=\".download.DownloadDialogActivity\"\n            android:excludeFromRecents=\"true\"\n            android:theme=\"@style/Theme.AppCompat.DayNight.Dialog\">\n            <intent-filter android:label=\"@string/app_name\">\n                <action android:name=\"android.intent.action.VIEW\"/>\n\n                <category android:name=\"android.intent.category.BROWSABLE\"/>\n                <category android:name=\"android.intent.category.DEFAULT\"/>\n\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/ver/\"\n                    android:scheme=\"https\"/>\n                <data\n                    android:host=\"animeflv.net\"\n                    android:pathPrefix=\"/ver/\"\n                    android:scheme=\"http\"/>\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".player.VideoActivity\"\n            android:configChanges=\"screenSize|smallestScreenSize|screenLayout|orientation\"\n            android:immersive=\"true\"\n            android:launchMode=\"singleTask\"\n            android:resizeableActivity=\"true\"\n            android:supportsPictureInPicture=\"true\"/>\n        <activity android:name=\".custom.ThemedControlsActivity\"/>\n        <activity android:name=\".news.NewsActivity\"/>\n        <activity android:name=\".achievements.AchievementActivity\"/>\n        <activity android:name=\".commons.EAUnlockActivity\"/>\n        <activity\n            android:name=\"es.munix.multidisplaycast.CastControlsActivity\"\n            android:screenOrientation=\"sensor\"\n            tools:node=\"merge\"\n            tools:replace=\"android:screenOrientation\"/>\n        <activity\n            android:name=\".tv.streaming.TVMultiSelection\"\n            android:theme=\"@style/AppTheme.TV.Guided\"/>\n\n        <uses-library\n            android:name=\"org.apache.http.legacy\"\n            android:required=\"false\"/>\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/tv/res/values/bool.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <bool name=\"isLandscape\">false</bool>\r\n    <bool name=\"isDark\">false</bool>\r\n    <bool name=\"isTv\">true</bool>\r\n</resources>"
  },
  {
    "path": "app/src/tv/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">UKIKU TV</string>\n</resources>\n"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    ext.kotlin_version = '2.1.21'\n    ext.dokka_version = '0.9.16'\n    repositories {\n        google()\n        mavenCentral()\n        maven { url \"https://repo.grails.org/grails/core\" }\n        maven { url 'https://dl.bintray.com/kotlin/kotlin-eap' }\n        maven {\n            url 'https://maven.google.com/'\n            name 'Google'\n        }\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:8.8.0'\n        classpath 'com.google.gms:google-services:4.4.3'\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n        classpath \"org.jetbrains.dokka:dokka-android-gradle-plugin:$dokka_version\"\n        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'\n        classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'\n        classpath 'com.google.firebase:firebase-crashlytics-gradle:3.0.6'\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\n/*subprojects { subproject ->\n    subproject.tasks.whenTaskAdded {\n        if (it.name.contains(\"kapt\")) {\n            it.enabled = false\n        }\n    }\n}*/\n\nallprojects {\n    repositories {\n        mavenLocal()\n        google()\n        mavenCentral()\n        maven { url \"https://artifactory.appodeal.com/appodeal-public/\" }\n        maven { url \"https://jcenter.bintray.com/\" }\n        maven { url \"https://android-sdk.is.com\" }\n        maven { url 'https://jitpack.io' }\n        maven { url 'https://repo.gradle.org/gradle/libs-releases/' }\n        maven { url 'https://maven.scijava.org/content/repositories/public/' }\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "fastlane/.gitignore",
    "content": "installer/\n"
  },
  {
    "path": "fastlane/Appfile",
    "content": "# The Appfile can be used to specify information that's used across all fastlane\n# tools, like your username or the app's bundle identifier.\n#\n# For more details, check out the documentation at:\n# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Appfile.md\n\n# app_identifier \"com.your.app\" # the bundle identifier of your app\n# apple_id \"apple@fastlane.tools\" # Your Apple ID\n"
  },
  {
    "path": "fastlane/Fastfile",
    "content": "# More documentation about how to customize your build\n# can be found here:\n# https://docs.fastlane.tools\nfastlane_version \"2.68.0\"\n\n# This value helps us track success metrics for Fastfiles\n# we automatically generate. Feel free to remove this line\n# once you get things running smoothly!\ngenerated_fastfile_id \"02955c49-e335-4ead-a2af-188273f1639a\"\n\ndefault_platform :android\n\n# Fastfile actions accept additional configuration, but\n# don't worry, fastlane will prompt you for required\n# info which you can add here later\nlane :beta do\n  # build the release variant\n  build_android_app(task: \"assembleRelease\")\n\n  # upload to Beta by Crashlytics\n  crashlytics(\n    api_token: \"8971b3733a2fd699ebd101e18ce228d80baeab92\",\n    build_secret: \"88ba4d6880340c6e16c2690f626c60dcedff2e3a38650f2a8fb206f22f3e62d8\"\n  )\nend\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Mon Jan 13 01:29:03 CST 2025\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.10.2-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx8182m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\norg.gradle.parallel=true\norg.gradle.daemon=true\nandroid.useAndroidX=true\nandroid.enableJetifier=true\nandroid.enableR8.fullMode=false\nandroid.defaults.buildfeatures.buildconfig=true\nandroid.nonTransitiveRClass=false\nandroid.nonFinalResIds=false\n\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"
  },
  {
    "path": "gradlew",
    "content": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original 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 POSIX generated by Gradle.\n#\n#   Important for running:\n#\n#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is\n#       noncompliant, but you have some other compliant shell such as ksh or\n#       bash, then to run this script, type that shell name before the whole\n#       command line, like:\n#\n#           ksh Gradle\n#\n#       Busybox and similar reduced shells will NOT work, because this script\n#       requires all of these POSIX shell features:\n#         * functions;\n#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,\n#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;\n#         * compound commands having a testable exit status, especially «case»;\n#         * various built-in commands including «command», «set», and «ulimit».\n#\n#   Important for patching:\n#\n#   (2) This script targets any POSIX shell, so it avoids extensions provided\n#       by Bash, Ksh, etc; in particular arrays are avoided.\n#\n#       The \"traditional\" practice of packing multiple parameters into a\n#       space-separated string is a well documented source of bugs and security\n#       problems, so this is (mostly) avoided, by progressively accumulating\n#       options in \"$@\", and eventually passing that to Java.\n#\n#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,\n#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;\n#       see the in-line comments for details.\n#\n#       There are tweaks for specific operating systems such as AIX, CygWin,\n#       Darwin, MinGW, and NonStop.\n#\n#   (3) This script is generated from the Groovy template\n#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt\n#       within the Gradle project.\n#\n#       You can find Gradle at https://github.com/gradle/gradle/.\n#\n##############################################################################\n\n# Attempt to set APP_HOME\n\n# Resolve links: $0 may be a link\napp_path=$0\n\n# Need this for daisy-chained symlinks.\nwhile\n    APP_HOME=${app_path%\"${app_path##*/}\"}  # leaves a trailing /; empty if no leading path\n    [ -h \"$app_path\" ]\ndo\n    ls=$( ls -ld \"$app_path\" )\n    link=${ls#*' -> '}\n    case $link in             #(\n      /*)   app_path=$link ;; #(\n      *)    app_path=$APP_HOME$link ;;\n    esac\ndone\n\n# This is normally unused\n# shellcheck disable=SC2034\nAPP_BASE_NAME=${0##*/}\n# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)\nAPP_HOME=$( cd \"${APP_HOME:-./}\" > /dev/null && pwd -P ) || exit\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=maximum\n\nwarn () {\n    echo \"$*\"\n} >&2\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n} >&2\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"$( uname )\" in                #(\n  CYGWIN* )         cygwin=true  ;; #(\n  Darwin* )         darwin=true  ;; #(\n  MSYS* | MINGW* )  msys=true    ;; #(\n  NONSTOP* )        nonstop=true ;;\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    if ! command -v java >/dev/null 2>&1\n    then\n        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.\"\n    fi\nfi\n\n# Increase the maximum file descriptors if we can.\nif ! \"$cygwin\" && ! \"$darwin\" && ! \"$nonstop\" ; then\n    case $MAX_FD in #(\n      max*)\n        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        MAX_FD=$( ulimit -H -n ) ||\n            warn \"Could not query maximum file descriptor limit\"\n    esac\n    case $MAX_FD in  #(\n      '' | soft) :;; #(\n      *)\n        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.\n        # shellcheck disable=SC2039,SC3045\n        ulimit -n \"$MAX_FD\" ||\n            warn \"Could not set maximum file descriptor limit to $MAX_FD\"\n    esac\nfi\n\n# Collect all arguments for the java command, stacking in reverse order:\n#   * args from the command line\n#   * the main class name\n#   * -classpath\n#   * -D...appname settings\n#   * --module-path (only if needed)\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif \"$cygwin\" || \"$msys\" ; then\n    APP_HOME=$( cygpath --path --mixed \"$APP_HOME\" )\n    CLASSPATH=$( cygpath --path --mixed \"$CLASSPATH\" )\n\n    JAVACMD=$( cygpath --unix \"$JAVACMD\" )\n\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    for arg do\n        if\n            case $arg in                                #(\n              -*)   false ;;                            # don't mess with options #(\n              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath\n                    [ -e \"$t\" ] ;;                      #(\n              *)    false ;;\n            esac\n        then\n            arg=$( cygpath --path --ignore --mixed \"$arg\" )\n        fi\n        # Roll the args list around exactly as many times as the number of\n        # args, so each arg winds up back in the position where it started, but\n        # possibly modified.\n        #\n        # NB: a `for` loop captures its iteration list before it begins, so\n        # changing the positional parameters here affects neither the number of\n        # iterations, nor the values presented in `arg`.\n        shift                   # remove old arg\n        set -- \"$@\" \"$arg\"      # push replacement arg\n    done\nfi\n\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# Collect all arguments for the java command:\n#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,\n#     and any embedded shellness will be escaped.\n#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be\n#     treated as '${Hostname}' itself on the command line.\n\nset -- \\\n        \"-Dorg.gradle.appname=$APP_BASE_NAME\" \\\n        -classpath \"$CLASSPATH\" \\\n        org.gradle.wrapper.GradleWrapperMain \\\n        \"$@\"\n\n# Stop when \"xargs\" is not available.\nif ! command -v xargs >/dev/null 2>&1\nthen\n    die \"xargs is not available\"\nfi\n\n# Use \"xargs\" to parse quoted args.\n#\n# With -n1 it outputs one arg per line, with the quotes and backslashes removed.\n#\n# In Bash we could simply go:\n#\n#   readarray ARGS < <( xargs -n1 <<<\"$var\" ) &&\n#   set -- \"${ARGS[@]}\" \"$@\"\n#\n# but POSIX shell has neither arrays nor command substitution, so instead we\n# post-process each arg (as a line of input to sed) to backslash-escape any\n# character that might be a shell metacharacter, then use eval to reverse\n# that process (while maintaining the separation between arguments), and wrap\n# the whole thing up as a single \"set\" statement.\n#\n# This will of course break if any of these variables contains a newline or\n# an unmatched quote.\n#\n\neval \"set -- $(\n        printf '%s\\n' \"$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\" |\n        xargs -n1 |\n        sed ' s~[^-[:alnum:]+,./:=@_]~\\\\&~g; ' |\n        tr '\\n' ' '\n    )\" '\"$@\"'\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=.\n@rem This is normally unused\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% equ 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% equ 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!\nset EXIT_CODE=%ERRORLEVEL%\nif %EXIT_CODE% equ 0 set EXIT_CODE=1\nif not \"\"==\"%GRADLE_EXIT_CONSOLE%\" exit %EXIT_CODE%\nexit /b %EXIT_CODE%\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "persistentsearchview/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "persistentsearchview/bintray.gradle",
    "content": "apply plugin: 'com.jfrog.bintray'\n\nversion = libraryVersion\n\ntask sourcesJar(type: Jar) {\n    from android.sourceSets.main.java.srcDirs\n    classifier = 'sources'\n}\n\ntask javadoc(type: Javadoc) {\n    source = android.sourceSets.main.java.srcDirs\n    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))\n    destinationDir = file(\"../javadoc/\")\n    failOnError false\n}\n\ntask javadocJar(type: Jar, dependsOn: javadoc) {\n    classifier = 'javadoc'\n    from javadoc.destinationDir\n}\nartifacts {\n    archives javadocJar\n    archives sourcesJar\n}\n\n// Bintray\nProperties properties = new Properties()\nproperties.load(project.rootProject.file('local.properties').newDataInputStream())\n\nbintray {\n    user = properties.getProperty(\"bintray.user\")\n    key = properties.getProperty(\"bintray.apikey\")\n\n    configurations = ['archives']\n    pkg {\n        repo = bintrayRepo\n        name = bintrayName\n        desc = libraryDescription\n        websiteUrl = siteUrl\n        vcsUrl = gitUrl\n        licenses = allLicenses\n        publish = true\n        publicDownloadNumbers = true\n        version {\n            desc = libraryDescription\n            gpg {\n                sign = true //Determines whether to GPG sign the files. The default is false\n                passphrase = properties.getProperty(\"bintray.gpg.password\")\n                //Optional. The passphrase for GPG signing'\n            }\n        }\n    }\n}"
  },
  {
    "path": "persistentsearchview/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 28\n\n    defaultConfig {\n        minSdkVersion 21\n        targetSdkVersion 28\n        versionCode 7\n        versionName \"1.0.4\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n    lintOptions {\n        abortOnError false\n    }\n\n}\n\ndependencies {\n    implementation fileTree(dir: 'libs', include: ['*.jar'])\n    implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'\n    implementation 'androidx.cardview:cardview:1.0.0'\n}\n\n\n\next {\n    bintrayRepo = 'maven'\n    bintrayName = 'persistent-searchview'\n\n    publishedGroupId = 'org.cryse.widget'\n    libraryName = 'PersistentSearchView'\n    artifact = 'persistentsearchview'\n\n    libraryDescription = 'A library that implements Google Play like PersistentSearch view.'\n\n    siteUrl = 'https://github.com/crysehillmes/PersistentSearchView'\n    gitUrl = 'https://github.com/crysehillmes/PersistentSearchView.git'\n\n    libraryVersion = \"1.0.4\"\n\n    developerId = 'tyk5555'\n    developerName = 'Cryse Hillmes'\n    developerEmail = 'tikey0328@gmail.com'\n\n    licenseName = 'The Apache Software License, Version 2.0'\n    licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'\n    allLicenses = [\"Apache-2.0\"]\n}\n\napply from: 'install.gradle'\napply from: 'bintray.gradle'"
  },
  {
    "path": "persistentsearchview/gradle.properties",
    "content": "POM_NAME=Persistent Search\nPOM_ARTIFACT_ID=library\nPOM_PACKAGING=aar"
  },
  {
    "path": "persistentsearchview/install.gradle",
    "content": "apply plugin: 'com.github.dcendents.android-maven'\n\ngroup = publishedGroupId                               // Maven Group ID for the artifact\n\ninstall {\n    repositories.mavenInstaller {\n        // This generates POM.xml with proper parameters\n        pom {\n            project {\n                packaging 'aar'\n                groupId publishedGroupId\n                artifactId artifactId\n\n                // Add your description here\n                name libraryName\n                description libraryDescription\n                url siteUrl\n\n                // Set your license\n                licenses {\n                    license {\n                        name licenseName\n                        url licenseUrl\n                    }\n                }\n                developers {\n                    developer {\n                        id developerId\n                        name developerName\n                        email developerEmail\n                    }\n                }\n                scm {\n                    connection gitUrl\n                    developerConnection gitUrl\n                    url siteUrl\n\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "persistentsearchview/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in C:/Users/Kieron/Android/adt-bundle-windows-x86_64-20140702/adt-bundle-windows-x86_64-20140702/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\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"
  },
  {
    "path": "persistentsearchview/src/androidTest/java/org/cryse/widget/persistentsearch/ApplicationTest.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/AndroidManifest.xml",
    "content": "<manifest package=\"org.cryse.widget.persistentsearch\">\n\n    <application />\n\n</manifest>\n"
  },
  {
    "path": "persistentsearchview/src/main/java/androidx/appcompat/graphics/drawable/SupportDrawerArrowDrawable.java",
    "content": "package androidx.appcompat.graphics.drawable;\n\nimport android.content.Context;\n\npublic class SupportDrawerArrowDrawable extends DrawerArrowDrawable {\n\n    public SupportDrawerArrowDrawable(Context themedContext) {\n        super(themedContext);\n    }\n\n    public void setPosition(float position) {\n        if (position == 1f) {\n            setVerticalMirror(true);\n        } else if (position == 0f) {\n            setVerticalMirror(false);\n        }\n        super.setProgress(position);\n    }\n\n    public float getPosition() {\n        return super.getProgress();\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/io/codetail/animation/RevealAnimator.java",
    "content": "package io.codetail.animation;\n\nimport android.animation.Animator;\nimport android.annotation.TargetApi;\nimport android.graphics.Rect;\nimport android.os.Build;\nimport android.util.Property;\nimport android.view.View;\n\nimport java.lang.ref.WeakReference;\n\nimport static io.codetail.animation.ViewAnimationUtils.SimpleAnimationListener;\n\n/**\n * @hide\n */\npublic interface RevealAnimator{\n\n    RevealRadius CLIP_RADIUS = new RevealRadius();\n\n    /**\n     * Listen when animation start/end/cancel\n     * and setup view for it\n     */\n    void onRevealAnimationStart();\n    void onRevealAnimationEnd();\n    void onRevealAnimationCancel();\n\n    /**\n     * Used with animator to animate view clipping\n     *\n     * @param value clip radius\n     */\n    void setRevealRadius(float value);\n\n    /**\n     * Used with animator to animate view clipping\n     *\n     * @return current radius\n     */\n    float getRevealRadius();\n\n    /**\n     * Invalidate certain rectangle\n     *\n     * @param bounds bounds to redraw\n     * @see View#invalidate(Rect)\n     */\n    void invalidate(Rect bounds);\n\n    /**\n     * {@link ViewAnimationUtils#createCircularReveal(View, int, int, float, float)} is\n     * called it creates new {@link io.codetail.animation.RevealAnimator.RevealInfo}\n     * and attaches to parent, here is necessary data about animation\n     *\n     * @param info reveal information\n     *\n     * @see RevealAnimator.RevealInfo\n     */\n    void attachRevealInfo(RevealInfo info);\n\n    /**\n     * Returns new {@link SupportAnimator} that plays\n     * reversed animation of current one\n     *\n     * This method might be temporary, you should call\n     * {@link SupportAnimator#reverse()} instead\n     *\n     * @hide\n     * @return reverse {@link SupportAnimator}\n     *\n     * @see SupportAnimator#reverse()\n     */\n    SupportAnimator startReverseAnimation();\n\n    class RevealInfo{\n        public final int centerX;\n        public final int centerY;\n        public final float startRadius;\n        public final float endRadius;\n        public final WeakReference<View> target;\n\n        public RevealInfo(int centerX, int centerY, float startRadius, float endRadius,\n                          WeakReference<View> target) {\n            this.centerX = centerX;\n            this.centerY = centerY;\n            this.startRadius = startRadius;\n            this.endRadius = endRadius;\n            this.target = target;\n        }\n\n        public View getTarget(){\n            return target.get();\n        }\n\n        public boolean hasTarget(){\n            return getTarget() != null;\n        }\n    }\n\n    class RevealFinishedGingerbread extends SimpleAnimationListener {\n        WeakReference<RevealAnimator> mReference;\n\n        RevealFinishedGingerbread(RevealAnimator target) {\n            mReference = new WeakReference<>(target);\n        }\n\n        @Override\n        public void onAnimationStart(Animator animation) {\n            RevealAnimator target = mReference.get();\n            target.onRevealAnimationStart();\n        }\n\n        @Override\n        public void onAnimationCancel(Animator animation) {\n            RevealAnimator target = mReference.get();\n            target.onRevealAnimationCancel();\n        }\n\n        @Override\n        public void onAnimationEnd(Animator animation) {\n            RevealAnimator target = mReference.get();\n            target.onRevealAnimationEnd();\n        }\n    }\n\n    @TargetApi(Build.VERSION_CODES.HONEYCOMB)\n    class RevealFinishedIceCreamSandwich extends RevealFinishedGingerbread {\n        int mFeaturedLayerType;\n        int mLayerType;\n\n        RevealFinishedIceCreamSandwich(RevealAnimator target) {\n            super(target);\n\n            mLayerType = ((View) target).getLayerType();\n            mFeaturedLayerType = View.LAYER_TYPE_SOFTWARE;\n        }\n\n        @Override\n        public void onAnimationCancel(Animator animation) {\n            ((View) mReference.get()).setLayerType(mLayerType, null);\n            super.onAnimationEnd(animation);\n        }\n\n        @Override\n        public void onAnimationStart(Animator animation) {\n            ((View) mReference.get()).setLayerType(mFeaturedLayerType, null);\n            super.onAnimationStart(animation);\n        }\n\n        @Override\n        public void onAnimationEnd(Animator animation) {\n            ((View) mReference.get()).setLayerType(mLayerType, null);\n            super.onAnimationEnd(animation);\n        }\n    }\n\n    class RevealFinishedJellyBeanMr2 extends RevealFinishedIceCreamSandwich {\n\n        @TargetApi(Build.VERSION_CODES.HONEYCOMB)\n        RevealFinishedJellyBeanMr2(RevealAnimator target) {\n            super(target);\n\n            mFeaturedLayerType = View.LAYER_TYPE_HARDWARE;\n        }\n    }\n\n    class RevealRadius extends Property<RevealAnimator, Float> {\n\n        public RevealRadius() {\n            super(Float.TYPE, \"revealRadius\");\n        }\n\n        @Override\n        public void set(RevealAnimator object, Float value) {\n            object.setRevealRadius(value);\n        }\n\n        @Override\n        public Float get(RevealAnimator object) {\n            return object.getRevealRadius();\n        }\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/io/codetail/animation/SupportAnimator.java",
    "content": "package io.codetail.animation;\n\nimport android.view.animation.Interpolator;\n\nimport java.lang.ref.WeakReference;\n\npublic abstract class SupportAnimator {\n\n    WeakReference<RevealAnimator> mTarget;\n\n    public SupportAnimator(RevealAnimator target) {\n        mTarget = new WeakReference<>(target);\n    }\n\n    /**\n     * @return true if using native android animation framework, otherwise is\n     * nineoldandroids\n     */\n    public abstract boolean isNativeAnimator();\n\n    /**\n     * @return depends from {@link android.os.Build.VERSION} if sdk version\n     * {@link android.os.Build.VERSION_CODES#LOLLIPOP} and greater will return\n     * {@link android.animation.Animator}\n     */\n    public abstract Object get();\n\n    /**\n     * Starts this animation. If the animation has a nonzero startDelay, the animation will start\n     * running after that delay elapses. A non-delayed animation will have its initial\n     * value(s) set immediately, followed by calls to\n     * {@link android.animation.Animator.AnimatorListener#onAnimationStart(android.animation.Animator)}\n     * for any listeners of this animator.\n     *\n     * <p>The animation started by calling this method will be run on the thread that called\n     * this method. This thread should have a Looper on it (a runtime exception will be thrown if\n     * this is not the case). Also, if the animation will animate\n     * properties of objects in the view hierarchy, then the calling thread should be the UI\n     * thread for that view hierarchy.</p>\n     *\n     */\n    public abstract void start();\n\n    /**\n     * Sets the duration of the animation.\n     *\n     * @param duration The length of the animation, in milliseconds.\n     */\n    public abstract void setDuration(int duration);\n\n    /**\n     * The time interpolator used in calculating the elapsed fraction of the\n     * animation. The interpolator determines whether the animation runs with\n     * linear or non-linear motion, such as acceleration and deceleration. The\n     * default value is {@link android.view.animation.AccelerateDecelerateInterpolator}.\n     *\n     * @param value the interpolator to be used by this animation\n     */\n    public abstract void setInterpolator(Interpolator value);\n\n\n    /**\n     * Adds a listener to the set of listeners that are sent events through the life of an\n     * animation, such as start, repeat, and end.\n     *\n     * @param listener the listener to be added to the current set of listeners for this animation.\n     */\n    public abstract void addListener(AnimatorListener listener);\n\n\n    /**\n     * Returns whether this Animator is currently running (having been started and gone past any\n     * initial startDelay period and not yet ended).\n     *\n     * @return Whether the Animator is running.\n     */\n    public abstract boolean isRunning();\n\n\n    /**\n     * Cancels the animation. Unlike {@link #end()}, <code>cancel()</code> causes the animation to\n     * stop in its tracks, sending an\n     * {@link AnimatorListener#onAnimationCancel()} to\n     * its listeners, followed by an\n     * {@link AnimatorListener#onAnimationEnd()} message.\n     *\n     * <p>This method must be called on the thread that is running the animation.</p>\n     */\n    public abstract void cancel();\n\n    /**\n     * Ends the animation. This causes the animation to assign the end value of the property being\n     * animated, then calling the\n     * {@link AnimatorListener#onAnimationEnd()} method on\n     * its listeners.\n     *\n     * <p>This method must be called on the thread that is running the animation.</p>\n     */\n    public void end() {\n    }\n\n    /**\n     * This method tells the object to use appropriate information to extract\n     * starting values for the animation. For example, a AnimatorSet object will pass\n     * this call to its child objects to tell them to set up the values. A\n     * ObjectAnimator object will use the information it has about its target object\n     * and PropertyValuesHolder objects to get the start values for its properties.\n     * A ValueAnimator object will ignore the request since it does not have enough\n     * information (such as a target object) to gather these values.\n     */\n    public void setupStartValues() {\n    }\n\n    /**\n     * This method tells the object to use appropriate information to extract\n     * ending values for the animation. For example, a AnimatorSet object will pass\n     * this call to its child objects to tell them to set up the values. A\n     * ObjectAnimator object will use the information it has about its target object\n     * and PropertyValuesHolder objects to get the start values for its properties.\n     * A ValueAnimator object will ignore the request since it does not have enough\n     * information (such as a target object) to gather these values.\n     */\n    public void setupEndValues() {\n    }\n\n    /**\n     * Experimental feature\n     */\n    public SupportAnimator reverse() {\n        if(isRunning()){\n            return null;\n        }\n\n        RevealAnimator target = mTarget.get();\n        if(target != null){\n            return target.startReverseAnimation();\n        }\n\n        return null;\n    }\n\n    /**\n     * <p>An animation listener receives notifications from an animation.\n     * Notifications indicate animation related events, such as the end or the\n     * repetition of the animation.</p>\n     */\n    public interface AnimatorListener {\n        /**\n         * <p>Notifies the start of the animation.</p>\n         */\n        void onAnimationStart();\n\n        /**\n         * <p>Notifies the end of the animation. This callback is not invoked\n         * for animations with repeat count set to INFINITE.</p>\n         */\n        void onAnimationEnd();\n\n        /**\n         * <p>Notifies the cancellation of the animation. This callback is not invoked\n         * for animations with repeat count set to INFINITE.</p>\n         */\n        void onAnimationCancel();\n\n        /**\n         * <p>Notifies the repetition of the animation.</p>\n         */\n        void onAnimationRepeat();\n    }\n\n    /**\n     * <p>Provides default implementation for AnimatorListener.</p>\n     */\n    public static abstract class SimpleAnimatorListener implements AnimatorListener {\n\n        @Override\n        public void onAnimationStart() {\n\n        }\n\n        @Override\n        public void onAnimationEnd() {\n\n        }\n\n        @Override\n        public void onAnimationCancel() {\n\n        }\n\n        @Override\n        public void onAnimationRepeat() {\n\n        }\n    }\n\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/io/codetail/animation/SupportAnimatorLollipop.java",
    "content": "package io.codetail.animation;\n\nimport android.animation.Animator;\nimport android.annotation.TargetApi;\nimport android.os.Build;\nimport android.view.animation.Interpolator;\n\nimport java.lang.ref.WeakReference;\n\n@TargetApi(Build.VERSION_CODES.HONEYCOMB)\nfinal class SupportAnimatorLollipop extends SupportAnimator{\n\n    WeakReference<Animator> mAnimator;\n\n    SupportAnimatorLollipop(Animator animator, RevealAnimator target) {\n        super(target);\n        mAnimator = new WeakReference<>(animator);\n    }\n\n    @Override\n    public boolean isNativeAnimator() {\n        return true;\n    }\n\n    @Override\n    public Object get() {\n        return mAnimator.get();\n    }\n\n\n    @Override\n    public void start() {\n        Animator a = mAnimator.get();\n        if(a != null) {\n            a.start();\n        }\n    }\n\n    @Override\n    public void setDuration(int duration) {\n        Animator a = mAnimator.get();\n        if(a != null) {\n            a.setDuration(duration);\n        }\n    }\n\n    @Override\n    public void setInterpolator(Interpolator value) {\n        Animator a = mAnimator.get();\n        if(a != null) {\n            a.setInterpolator(value);\n        }\n    }\n\n    @Override\n    public void addListener(final AnimatorListener listener) {\n        Animator a = mAnimator.get();\n        if(a == null) {\n            return;\n        }\n\n        if(listener == null){\n            a.addListener(null);\n            return;\n        }\n\n        a.addListener(new Animator.AnimatorListener() {\n            @Override\n            public void onAnimationStart(Animator animation) {\n                listener.onAnimationStart();\n            }\n\n            @Override\n            public void onAnimationEnd(Animator animation) {\n                listener.onAnimationEnd();\n            }\n\n            @Override\n            public void onAnimationCancel(Animator animation) {\n                listener.onAnimationCancel();\n            }\n\n            @Override\n            public void onAnimationRepeat(Animator animation) {\n                listener.onAnimationRepeat();\n            }\n        });\n    }\n\n    @Override\n    public boolean isRunning() {\n        Animator a = mAnimator.get();\n        return a != null && a.isRunning();\n    }\n\n    @Override\n    public void cancel() {\n        Animator a = mAnimator.get();\n        if(a != null){\n            a.cancel();\n        }\n    }\n\n    @Override\n    public void end() {\n        Animator a = mAnimator.get();\n        if(a != null){\n            a.end();\n        }\n    }\n\n    @Override\n    public void setupStartValues() {\n        Animator a = mAnimator.get();\n        if(a != null){\n            a.setupStartValues();\n        }\n    }\n\n    @Override\n    public void setupEndValues() {\n        Animator a = mAnimator.get();\n        if(a != null){\n            a.setupEndValues();\n        }\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/io/codetail/animation/SupportAnimatorPreL.java",
    "content": "package io.codetail.animation;\n\nimport android.animation.Animator;\nimport android.view.animation.Interpolator;\n\nimport java.lang.ref.WeakReference;\n\nfinal class SupportAnimatorPreL extends SupportAnimator {\n\n    WeakReference<Animator> mAnimator;\n\n    SupportAnimatorPreL(Animator animator, RevealAnimator target) {\n        super(target);\n        mAnimator = new WeakReference<>(animator);\n    }\n\n    @Override\n    public boolean isNativeAnimator() {\n        return false;\n    }\n\n    @Override\n    public Object get() {\n        return mAnimator.get();\n    }\n\n    @Override\n    public void start() {\n        Animator a = mAnimator.get();\n        if(a != null) {\n            a.start();\n        }\n    }\n\n    @Override\n    public void setDuration(int duration) {\n        Animator a = mAnimator.get();\n        if(a != null) {\n            a.setDuration(duration);\n        }\n    }\n\n    @Override\n    public void setInterpolator(Interpolator value) {\n        Animator a = mAnimator.get();\n        if(a != null) {\n            a.setInterpolator(value);\n        }\n    }\n\n    @Override\n    public void addListener(final AnimatorListener listener) {\n        Animator a = mAnimator.get();\n        if(a == null) {\n            return;\n        }\n\n        if(listener == null){\n            a.addListener(null);\n            return;\n        }\n\n        a.addListener(new Animator.AnimatorListener() {\n            @Override\n            public void onAnimationStart(Animator animation) {\n                listener.onAnimationStart();\n            }\n\n            @Override\n            public void onAnimationEnd(Animator animation) {\n                listener.onAnimationEnd();\n            }\n\n            @Override\n            public void onAnimationCancel(Animator animation) {\n                listener.onAnimationCancel();\n            }\n\n            @Override\n            public void onAnimationRepeat(Animator animation) {\n                listener.onAnimationRepeat();\n            }\n        });\n    }\n\n    @Override\n    public boolean isRunning() {\n        Animator a = mAnimator.get();\n        return a != null && a.isRunning();\n    }\n\n    @Override\n    public void cancel() {\n        Animator a = mAnimator.get();\n        if(a != null){\n            a.cancel();\n        }\n    }\n\n    @Override\n    public void end() {\n        Animator a = mAnimator.get();\n        if(a != null){\n            a.end();\n        }\n    }\n\n    @Override\n    public void setupStartValues() {\n        Animator a = mAnimator.get();\n        if(a != null){\n            a.setupStartValues();\n        }\n    }\n\n    @Override\n    public void setupEndValues() {\n        Animator a = mAnimator.get();\n        if(a != null){\n            a.setupEndValues();\n        }\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/io/codetail/animation/ViewAnimationUtils.java",
    "content": "package io.codetail.animation;\n\nimport android.animation.Animator;\nimport android.animation.ObjectAnimator;\nimport android.annotation.TargetApi;\nimport android.os.Build;\nimport android.view.View;\nimport android.view.animation.AccelerateDecelerateInterpolator;\n\nimport java.lang.ref.WeakReference;\n\nimport io.codetail.animation.RevealAnimator.RevealInfo;\n\nimport static android.os.Build.VERSION.SDK_INT;\nimport static android.os.Build.VERSION_CODES.LOLLIPOP;\nimport static io.codetail.animation.RevealAnimator.CLIP_RADIUS;\n\npublic class ViewAnimationUtils {\n\n    private final static boolean LOLLIPOP_PLUS = SDK_INT >= LOLLIPOP;\n\n    public static final int SCALE_UP_DURATION = 500;\n\n    /**\n     * Returns an Animator which can animate a clipping circle.\n     * <p>\n     * Any shadow cast by the View will respect the circular clip from this animator.\n     * <p>\n     * Only a single non-rectangular clip can be applied on a View at any time.\n     * Views clipped by a circular reveal animation take priority over\n     * {@link android.view.View#setClipToOutline(boolean) View Outline clipping}.\n     * <p>\n     * Note that the animation returned here is a one-shot animation. It cannot\n     * be re-used, and once started it cannot be paused or resumed.\n     *\n     * @param view The View will be clipped to the animating circle.\n     * @param centerX The x coordinate of the center of the animating circle.\n     * @param centerY The y coordinate of the center of the animating circle.\n     * @param startRadius The starting radius of the animating circle.\n     * @param endRadius The ending radius of the animating circle.\n     */\n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n    public static SupportAnimator createCircularReveal(View view,\n                                                       int centerX,  int centerY,\n                                                       float startRadius, float endRadius) {\n\n        if(!(view.getParent() instanceof RevealAnimator)){\n            throw new IllegalArgumentException(\"View must be inside RevealFrameLayout or RevealLinearLayout.\");\n        }\n\n        RevealAnimator revealLayout = (RevealAnimator) view.getParent();\n        revealLayout.attachRevealInfo(new RevealInfo(centerX, centerY, startRadius, endRadius,\n                new WeakReference<>(view)));\n\n        if(LOLLIPOP_PLUS){\n            return new SupportAnimatorLollipop(android.view.ViewAnimationUtils\n                    .createCircularReveal(view, centerX, centerY, startRadius, endRadius), revealLayout);\n        }\n\n        ObjectAnimator reveal = ObjectAnimator.ofFloat(revealLayout, CLIP_RADIUS,\n                startRadius, endRadius);\n        reveal.addListener(getRevealFinishListener(revealLayout));\n\n        return new SupportAnimatorPreL(reveal, revealLayout);\n    }\n\n    private static Animator.AnimatorListener getRevealFinishListener(RevealAnimator target){\n        if(SDK_INT >= 18){\n            return new RevealAnimator.RevealFinishedJellyBeanMr2(target);\n        }else if(SDK_INT >= 14){\n            return new RevealAnimator.RevealFinishedIceCreamSandwich(target);\n        }else {\n            return new RevealAnimator.RevealFinishedGingerbread(target);\n        }\n    }\n\n    /**\n     * Lifting view\n     *\n     * @param view The animation target\n     * @param baseRotation initial Rotation X in 3D space\n     * @param fromY initial Y position of view\n     * @param duration aniamtion duration\n     * @param startDelay start delay before animation begin\n     */\n    @Deprecated\n    public static void liftingFromBottom(View view, float baseRotation, float fromY, int duration, int startDelay){\n        view.setRotationX(baseRotation);\n        view.setTranslationY(fromY);\n\n        view\n                .animate()\n                .setInterpolator(new AccelerateDecelerateInterpolator())\n                .setDuration(duration)\n                .setStartDelay(startDelay)\n                .rotationX(0)\n                .translationY(0)\n                .start();\n\n    }\n\n    /**\n     * Lifting view\n     *\n     * @param view The animation target\n     * @param baseRotation initial Rotation X in 3D space\n     * @param duration aniamtion duration\n     * @param startDelay start delay before animation begin\n     */\n    @Deprecated\n    public static void liftingFromBottom(View view, float baseRotation, int duration, int startDelay){\n        view.setRotationX(baseRotation);\n        view.setTranslationY(view.getHeight() / 3);\n\n        view\n                .animate()\n                .setInterpolator(new AccelerateDecelerateInterpolator())\n                .setDuration(duration)\n                .setStartDelay(startDelay)\n                .rotationX(0)\n                .translationY(0)\n                .start();\n\n    }\n\n    /**\n     * Lifting view\n     *\n     * @param view The animation target\n     * @param baseRotation initial Rotation X in 3D space\n     * @param duration aniamtion duration\n     */\n    @Deprecated\n    public static void liftingFromBottom(View view, float baseRotation, int duration){\n        view.setRotationX(baseRotation);\n        view.setTranslationY(view.getHeight() / 3);\n\n        view\n                .animate()\n                .setInterpolator(new AccelerateDecelerateInterpolator())\n                .setDuration(duration)\n                .rotationX(0)\n                .translationY(0)\n                .start();\n\n    }\n\n    static class SimpleAnimationListener implements Animator.AnimatorListener{\n\n        @Override\n        public void onAnimationStart(Animator animation) {\n\n        }\n\n        @Override\n        public void onAnimationEnd(Animator animation) {\n\n        }\n\n        @Override\n        public void onAnimationCancel(Animator animation) {\n\n        }\n\n        @Override\n        public void onAnimationRepeat(Animator animation) {\n\n        }\n    }\n\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/io/codetail/widget/RevealFrameLayout.java",
    "content": "package io.codetail.widget;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Path;\nimport android.graphics.Rect;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.widget.FrameLayout;\n\nimport io.codetail.animation.RevealAnimator;\nimport io.codetail.animation.SupportAnimator;\nimport io.codetail.animation.ViewAnimationUtils;\n\npublic class RevealFrameLayout extends FrameLayout implements RevealAnimator{\n\n    private Path mRevealPath;\n    private final Rect mTargetBounds = new Rect();\n    private RevealInfo mRevealInfo;\n    private boolean mRunning;\n    private float mRadius;\n\n    public RevealFrameLayout(Context context) {\n        this(context, null);\n    }\n\n    public RevealFrameLayout(Context context, AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public RevealFrameLayout(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs, defStyle);\n        mRevealPath = new Path();\n    }\n\n    @Override\n    public void onRevealAnimationStart() {\n        mRunning = true;\n    }\n\n    @Override\n    public void onRevealAnimationEnd() {\n        mRunning = false;\n        invalidate(mTargetBounds);\n    }\n\n    @Override\n    public void onRevealAnimationCancel() {\n        onRevealAnimationEnd();\n    }\n\n    /**\n     * Circle radius size\n     *\n     * @hide\n     */\n    @Override\n    public void setRevealRadius(float radius){\n        mRadius = radius;\n        mRevealInfo.getTarget().getHitRect(mTargetBounds);\n        invalidate(mTargetBounds);\n    }\n\n    /**\n     * Circle radius size\n     *\n     * @hide\n     */\n    @Override\n    public float getRevealRadius(){\n        return mRadius;\n    }\n\n    /**\n     * @hide\n     */\n    @Override\n    public void attachRevealInfo(RevealInfo info) {\n        mRevealInfo = info;\n    }\n\n    /**\n     * @hide\n     */\n    @Override\n    public SupportAnimator startReverseAnimation() {\n        if(mRevealInfo != null && mRevealInfo.hasTarget() && !mRunning) {\n            return ViewAnimationUtils.createCircularReveal(mRevealInfo.getTarget(),\n                    mRevealInfo.centerX, mRevealInfo.centerY,\n                    mRevealInfo.endRadius, mRevealInfo.startRadius);\n        }\n        return null;\n    }\n\n    @Override\n    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {\n        if(mRunning && child == mRevealInfo.getTarget()){\n            final int state = canvas.save();\n\n            mRevealPath.reset();\n            mRevealPath.addCircle(mRevealInfo.centerX, mRevealInfo.centerY, mRadius, Path.Direction.CW);\n\n            canvas.clipPath(mRevealPath);\n\n            boolean isInvalided = super.drawChild(canvas, child, drawingTime);\n\n            canvas.restoreToCount(state);\n\n            return isInvalided;\n        }\n\n        return super.drawChild(canvas, child, drawingTime);\n    }\n\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/io/codetail/widget/RevealLinearLayout.java",
    "content": "package io.codetail.widget;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Path;\nimport android.graphics.Rect;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.widget.LinearLayout;\n\nimport io.codetail.animation.RevealAnimator;\nimport io.codetail.animation.SupportAnimator;\nimport io.codetail.animation.ViewAnimationUtils;\n\npublic class RevealLinearLayout extends LinearLayout implements RevealAnimator{\n\n    private Path mRevealPath;\n    private final Rect mTargetBounds = new Rect();\n    private RevealInfo mRevealInfo;\n    private boolean mRunning;\n    private float mRadius;\n\n    public RevealLinearLayout(Context context) {\n        this(context, null);\n    }\n\n    public RevealLinearLayout(Context context, AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public RevealLinearLayout(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs);\n        mRevealPath = new Path();\n    }\n\n    @Override\n    public void onRevealAnimationStart() {\n        mRunning = true;\n    }\n\n    @Override\n    public void onRevealAnimationEnd() {\n        mRunning = false;\n        invalidate(mTargetBounds);\n    }\n\n    @Override\n    public void onRevealAnimationCancel() {\n        onRevealAnimationEnd();\n    }\n\n    /**\n     * Circle radius size\n     *\n     * @hide\n     */\n    @Override\n    public void setRevealRadius(float radius){\n        mRadius = radius;\n        mRevealInfo.getTarget().getHitRect(mTargetBounds);\n        invalidate(mTargetBounds);\n    }\n\n    /**\n     * Circle radius size\n     *\n     * @hide\n     */\n    @Override\n    public float getRevealRadius(){\n        return mRadius;\n    }\n\n    /**\n     * @hide\n     */\n    @Override\n    public void attachRevealInfo(RevealInfo info) {\n        mRevealInfo = info;\n    }\n\n    /**\n     * @hide\n     */\n    @Override\n    public SupportAnimator startReverseAnimation() {\n        if(mRevealInfo != null && mRevealInfo.hasTarget() && !mRunning) {\n            return ViewAnimationUtils.createCircularReveal(mRevealInfo.getTarget(),\n                    mRevealInfo.centerX, mRevealInfo.centerY,\n                    mRevealInfo.endRadius, mRevealInfo.startRadius);\n        }\n        return null;\n    }\n\n    @Override\n    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {\n        if(mRunning && child == mRevealInfo.getTarget()){\n            final int state = canvas.save();\n\n            mRevealPath.reset();\n            mRevealPath.addCircle(mRevealInfo.centerX, mRevealInfo.centerY, mRadius, Path.Direction.CW);\n\n            canvas.clipPath(mRevealPath);\n\n            boolean isInvalided = super.drawChild(canvas, child, drawingTime);\n\n            canvas.restoreToCount(state);\n\n            return isInvalided;\n        }\n\n        return super.drawChild(canvas, child, drawingTime);\n    }\n\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/DefaultVoiceRecognizerDelegate.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.content.pm.PackageManager;\nimport android.content.pm.ResolveInfo;\nimport android.speech.RecognizerIntent;\n\nimport java.util.List;\n\nimport androidx.fragment.app.Fragment;\n\npublic class DefaultVoiceRecognizerDelegate extends VoiceRecognitionDelegate {\n\n    public DefaultVoiceRecognizerDelegate(Activity activity) {\n        super(activity);\n    }\n\n    public DefaultVoiceRecognizerDelegate(Activity activity, int activityRequestCode) {\n        super(activity, activityRequestCode);\n    }\n\n    public DefaultVoiceRecognizerDelegate(Fragment supportFragment) {\n        super(supportFragment);\n    }\n\n    public DefaultVoiceRecognizerDelegate(Fragment supportFragment, int activityRequestCode) {\n        super(supportFragment, activityRequestCode);\n    }\n\n    @Override\n    public Intent buildVoiceRecognitionIntent() {\n        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);\n        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,\n                RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);\n        intent.putExtra(RecognizerIntent.EXTRA_PROMPT,\n                getContext().getString(R.string.speak_now));\n        return intent;\n    }\n\n    @Override\n    public boolean isVoiceRecognitionAvailable() {\n        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);\n        PackageManager mgr = getContext().getPackageManager();\n        if (mgr != null) {\n            List<ResolveInfo> list = mgr.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);\n            return list.size() > 0;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/HomeButton.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.animation.ObjectAnimator;\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimport android.graphics.Color;\nimport android.graphics.ColorFilter;\nimport android.graphics.PorterDuff;\nimport android.graphics.PorterDuffColorFilter;\nimport android.os.Build;\nimport androidx.appcompat.graphics.drawable.SupportDrawerArrowDrawable;\nimport android.util.AttributeSet;\nimport android.util.Property;\nimport android.widget.ImageView;\n\npublic class HomeButton extends ImageView {\n    public enum IconState {\n        BURGER, ARROW;\n        public int toDrawablePosition() {\n            switch (this) {\n                case BURGER:\n                    return 0;\n                case ARROW:\n                    return 1;\n                default:\n                    return 0;\n            }\n        }\n    }\n    private ArrowDrawablePositionProperty mArrowPositionProperty = new ArrowDrawablePositionProperty();\n    private SupportDrawerArrowDrawable mArrowDrawable;\n\n    private IconState mButtonState = IconState.BURGER;\n    private long mAnimationDuration = 300l;\n    public HomeButton(Context context) {\n        super(context);\n        init();\n    }\n\n    public HomeButton(Context context, AttributeSet attrs) {\n        super(context, attrs);\n        init();\n    }\n\n    public HomeButton(Context context, AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n        init();\n    }\n\n    @TargetApi(Build.VERSION_CODES.LOLLIPOP)\n    public HomeButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {\n        super(context, attrs, defStyleAttr, defStyleRes);\n        init();\n    }\n\n    public void setArrowDrawableColor(int color) {\n        ColorFilter colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);\n        mArrowDrawable.setColorFilter(colorFilter);\n    }\n\n    private void init() {\n        mArrowDrawable = new SupportDrawerArrowDrawable(getContext());\n        ColorFilter colorFilter = new PorterDuffColorFilter(Color.BLACK, PorterDuff.Mode.SRC_IN);\n        mArrowDrawable.setColorFilter(colorFilter);\n        this.setImageDrawable(mArrowDrawable);\n    }\n\n    public void setState(IconState state) {\n        mButtonState = state;\n        mArrowDrawable.setPosition(mButtonState.toDrawablePosition());\n    }\n\n    public void animateState(IconState state) {\n        float to = state.toDrawablePosition();\n        float from = mButtonState.toDrawablePosition();\n        mButtonState = state;\n        if(Float.compare(from, to) == 0) {\n            // mArrowDrawable.setPosition(mButtonState.toDrawablePosition());\n        } else {\n            ObjectAnimator.ofFloat(mArrowDrawable, mArrowPositionProperty, from, to).setDuration(mAnimationDuration).start();\n        }\n        //mArrowDrawable.setPosition(mButtonState.toDrawablePosition());\n    }\n\n    public void setAnimationDuration(long animationDuration) {\n        this.mAnimationDuration = animationDuration;\n    }\n\n    static class ArrowDrawablePositionProperty extends Property<SupportDrawerArrowDrawable, Float> {\n\n        public ArrowDrawablePositionProperty() {\n            super(Float.TYPE, \"position\");\n        }\n\n        @Override\n        public void set(SupportDrawerArrowDrawable object, Float value) {\n            object.setPosition(value);\n        }\n\n        @Override\n        public Float get(SupportDrawerArrowDrawable object) {\n            return object.getPosition();\n        }\n    }\n}\n"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/LogoView.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.drawable.Drawable;\nimport android.text.TextUtils;\nimport android.util.AttributeSet;\n\nimport androidx.annotation.DrawableRes;\nimport androidx.appcompat.widget.AppCompatTextView;\nimport androidx.core.content.res.ResourcesCompat;\n\npublic class LogoView extends AppCompatTextView {\n    private Drawable mLogoDrawable;\n\n    public LogoView(Context context) {\n        super(context);\n    }\n\n    public LogoView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n    }\n\n    public LogoView(Context context, AttributeSet attrs, int defStyleAttr) {\n        super(context, attrs, defStyleAttr);\n    }\n\n    public void setLogo(String logoText) {\n        setLogo(new TextDrawable(getResources(), logoText));\n    }\n\n    public void setLogo(@DrawableRes int drawableRes) {\n        setLogo(ResourcesCompat.getDrawable(getResources(), drawableRes, null));\n    }\n\n    public void setLogo(Drawable drawable) {\n        this.mLogoDrawable = drawable;\n        mLogoDrawable.setBounds(0, 0, mLogoDrawable.getIntrinsicWidth(), mLogoDrawable.getIntrinsicHeight());\n        this.invalidate();\n    }\n\n    @Override\n    protected void onDraw(Canvas canvas) {\n        if (!TextUtils.isEmpty(getText()))\n            super.onDraw(canvas);\n        else {\n            if (mLogoDrawable != null) {\n                mLogoDrawable.draw(canvas);\n            }\n        }\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/PersistentSearchView.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.animation.LayoutTransition;\nimport android.content.Context;\nimport android.content.res.Resources;\nimport android.content.res.TypedArray;\nimport android.graphics.Color;\nimport android.graphics.drawable.Drawable;\nimport android.inputmethodservice.KeyboardView;\nimport android.os.Build;\nimport android.os.Parcel;\nimport android.os.Parcelable;\nimport androidx.core.content.res.ResourcesCompat;\nimport androidx.core.view.ViewCompat;\nimport com.google.android.material.card.MaterialCardView;\nimport android.text.Editable;\nimport android.text.Layout;\nimport android.text.TextUtils;\nimport android.text.TextWatcher;\nimport android.util.AttributeSet;\nimport android.util.DisplayMetrics;\nimport android.util.SparseArray;\nimport android.util.TypedValue;\nimport android.view.KeyEvent;\nimport android.view.LayoutInflater;\nimport android.view.MotionEvent;\nimport android.view.View;\nimport android.view.ViewTreeObserver;\nimport android.view.animation.AccelerateDecelerateInterpolator;\nimport android.view.inputmethod.EditorInfo;\nimport android.view.inputmethod.InputMethodManager;\nimport android.widget.AdapterView;\nimport android.widget.EditText;\nimport android.widget.FrameLayout;\nimport android.widget.ImageView;\nimport android.widget.ListView;\nimport android.widget.RelativeLayout;\nimport android.widget.TextView;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport io.codetail.animation.SupportAnimator;\nimport io.codetail.animation.ViewAnimationUtils;\n\n@SuppressWarnings(\"unused\")\npublic class PersistentSearchView extends RevealViewGroup {\n    public static final int VOICE_RECOGNITION_CODE = 8185102;\n    final static double COS_45 = Math.cos(Math.toRadians(45));\n    private static final int[] RES_IDS_ACTION_BAR_SIZE = { R.attr.actionBarSize };\n    private static final int DURATION_REVEAL_OPEN = 400;\n    private static final int DURATION_REVEAL_CLOSE = 300;\n    private static final int DURATION_HOME_BUTTON = 300;\n    private static final int DURATION_LAYOUT_TRANSITION = 100;\n    private HomeButton.IconState mHomeButtonCloseIconState;\n    private HomeButton.IconState mHomeButtonOpenIconState;\n    private HomeButton.IconState mHomeButtonSearchIconState;\n    private SearchViewState mCurrentState;\n    private SearchViewState mLastState;\n    private DisplayMode mDisplayMode;\n    private int mHomeButtonMode;\n    private int mCardVerticalPadding;\n    private int mCardHorizontalPadding;\n    private int mCardHeight;\n    private int mCustomToolbarHeight;\n    private int mSearchCardElevation;\n    private int mFromX, mFromY, mDesireRevealWidth;\n    // Views\n    private LogoView mLogoView;\n    private CardView mSearchCardView;\n    private HomeButton mHomeButton;\n    private EditText mSearchEditText;\n    private ListView mSuggestionListView;\n    private ImageView mMicButton;\n    private SearchListener mSearchListener;\n    private HomeButtonListener mHomeButtonListener;\n    private FrameLayout mRootLayout;\n    private VoiceRecognitionDelegate mVoiceRecognitionDelegate;\n    private boolean mAvoidTriggerTextWatcher;\n    private boolean mIsMic;\n    private int mSearchTextColor;\n    private int mArrorButtonColor;\n    private Drawable mLogoDrawable;\n    private String mStringLogoDrawable;\n    private int mSearchEditTextColor;\n    private String mSearchEditTextHint;\n    private int mSearchEditTextHintColor;\n    private SearchSuggestionsBuilder mSuggestionBuilder;\n    private SearchItemAdapter mSearchItemAdapter;\n    private ArrayList<SearchItem> mSearchSuggestions;\n    private KeyboardView mCustomKeyboardView;\n    private boolean showCustomKeyboard;\n\n    public PersistentSearchView(Context context) {\n        super(context);\n        init(null);\n    }\n    public PersistentSearchView(Context context, AttributeSet attrs) {\n        super(context, attrs);\n        init(attrs);\n    }\n\n    public PersistentSearchView(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs, defStyle);\n        init(attrs);\n    }\n\n    public void setCustomKeyboardView(KeyboardView customKeyboardView)\n    {\n        mCustomKeyboardView = customKeyboardView;\n    }\n\n    public void enableCustomKeyboardView(boolean enable)\n    {\n        showCustomKeyboard = enable;\n    }\n\n    static float calculateVerticalPadding(CardView cardView) {\n        float maxShadowSize = cardView.getMaxCardElevation();\n        float cornerRadius = cardView.getRadius();\n        boolean addPaddingForCorners = cardView.getPreventCornerOverlap();\n\n        if (addPaddingForCorners) {\n            return (float) (maxShadowSize * 1.5f + (1 - COS_45) * cornerRadius);\n        } else {\n            return maxShadowSize * 1.5f;\n        }\n    }\n\n    static float calculateHorizontalPadding(CardView cardView) {\n        float maxShadowSize = cardView.getMaxCardElevation();\n        float cornerRadius = cardView.getRadius();\n        boolean addPaddingForCorners = cardView.getPreventCornerOverlap();\n        if (addPaddingForCorners) {\n            return (float) (maxShadowSize + (1 - COS_45) * cornerRadius);\n        } else {\n            return maxShadowSize;\n        }\n    }\n\n    /** Calculates the Toolbar height in pixels. */\n    static int calculateToolbarSize(Context context) {\n        if (context == null) {\n            return 0;\n        }\n\n        Resources.Theme curTheme = context.getTheme();\n        if (curTheme == null) {\n            return 0;\n        }\n\n        TypedArray att = curTheme.obtainStyledAttributes(RES_IDS_ACTION_BAR_SIZE);\n        if (att == null) {\n            return 0;\n        }\n\n        float size = att.getDimension(0, 0);\n        att.recycle();\n        return (int)size;\n    }\n\n    private void init(AttributeSet attrs) {\n        setSaveEnabled(true);\n        LayoutInflater.from(getContext()).inflate(R.layout.layout_searchview, this, true);\n        if (attrs != null) {\n            TypedArray attrsValue = getContext().obtainStyledAttributes(attrs,\n                    R.styleable.PersistentSearchView);\n            mDisplayMode = DisplayMode.fromInt(attrsValue.getInt(R.styleable.PersistentSearchView_persistentSV_displayMode, DisplayMode.MENUITEM.toInt()));\n            mSearchCardElevation = attrsValue.getDimensionPixelSize(R.styleable.PersistentSearchView_persistentSV_searchCardElevation, -1);\n            mSearchTextColor = attrsValue.getColor(R.styleable.PersistentSearchView_persistentSV_searchTextColor, Color.BLACK);\n            mLogoDrawable = attrsValue.getDrawable(R.styleable.PersistentSearchView_persistentSV_logoDrawable);\n            mStringLogoDrawable = attrsValue.getString(R.styleable.PersistentSearchView_persistentSV_logoString);\n            mSearchEditTextColor = attrsValue.getColor(R.styleable.PersistentSearchView_persistentSV_editTextColor, Color.BLACK);\n            mSearchEditTextHint = attrsValue.getString(R.styleable.PersistentSearchView_persistentSV_editHintText);\n            mSearchEditTextHintColor = attrsValue.getColor(R.styleable.PersistentSearchView_persistentSV_editHintTextColor, Color.BLACK);\n            mArrorButtonColor = attrsValue.getColor(R.styleable.PersistentSearchView_persistentSV_homeButtonColor, Color.BLACK);\n            mCustomToolbarHeight = attrsValue.getDimensionPixelSize(R.styleable.PersistentSearchView_persistentSV_customToolbarHeight, calculateToolbarSize(getContext()));\n            mHomeButtonMode = attrsValue.getInt(R.styleable.PersistentSearchView_persistentSV_homeButtonMode, 0);\n            attrsValue.recycle();\n        }\n\n        if (mSearchCardElevation < 0) {\n            mSearchCardElevation = getContext().getResources().getDimensionPixelSize(R.dimen.search_card_default_card_elevation);\n        }\n\n        mCardHeight = getResources().getDimensionPixelSize(R.dimen.search_card_height);\n        mCardVerticalPadding = (mCustomToolbarHeight - mCardHeight) / 2;\n\n        switch (mDisplayMode) {\n            case MENUITEM:\n            default:\n                mCardHorizontalPadding = getResources().getDimensionPixelSize(R.dimen.search_card_visible_padding_menu_item_mode);\n                if(mCardVerticalPadding > mCardHorizontalPadding)\n                    mCardHorizontalPadding = mCardVerticalPadding;\n                mHomeButtonCloseIconState = HomeButton.IconState.ARROW;\n                mHomeButtonOpenIconState = HomeButton.IconState.ARROW;\n                setCurrentState(SearchViewState.NORMAL);\n                break;\n            case TOOLBAR:\n                if(mHomeButtonMode == 0) { // Arrow Mode\n                    mHomeButtonCloseIconState = HomeButton.IconState.ARROW;\n                    mHomeButtonOpenIconState = HomeButton.IconState.ARROW;\n                } else { // Burger Mode\n                    mHomeButtonCloseIconState = HomeButton.IconState.BURGER;\n                    mHomeButtonOpenIconState = HomeButton.IconState.ARROW;\n                }\n                mCardHorizontalPadding = getResources().getDimensionPixelSize(R.dimen.search_card_visible_padding_toolbar_mode);\n                setCurrentState(SearchViewState.NORMAL);\n                break;\n        }\n        mHomeButtonSearchIconState = HomeButton.IconState.ARROW;\n\n        bindViews();\n        setValuesToViews();\n\n        this.mIsMic = true;\n        mSearchSuggestions = new ArrayList<>();\n        mSearchItemAdapter = new SearchItemAdapter(getContext(), mSearchSuggestions);\n        mSuggestionListView.setAdapter(mSearchItemAdapter);\n\n        setUpLayoutTransition();\n        setUpListeners();\n    }\n\n    public ArrayList<SearchItem> getSearchSuggestions() {\n        return mSearchSuggestions;\n    }\n\n    private void bindViews() {\n        this.mSearchCardView = findViewById(R.id.cardview_search);\n        this.mHomeButton = findViewById(R.id.button_home);\n        this.mLogoView = findViewById(R.id.logoview);\n        this.mSearchEditText = findViewById(R.id.edittext_search);\n        this.mSuggestionListView = findViewById(R.id.listview_suggestions);\n        this.mMicButton = findViewById(R.id.button_mic);\n    }\n\n    private void setValuesToViews() {\n        this.mSearchCardView.setCardElevation(mSearchCardElevation);\n        this.mSearchCardView.setMaxCardElevation(mSearchCardElevation);\n        this.mHomeButton.setArrowDrawableColor(mArrorButtonColor);\n        this.mHomeButton.setState(mHomeButtonCloseIconState);\n        this.mHomeButton.setAnimationDuration(DURATION_HOME_BUTTON);\n        this.mSearchEditText.setTextColor(mSearchEditTextColor);\n        this.mSearchEditText.setHint(mSearchEditTextHint);\n        this.mSearchEditText.setHintTextColor(mSearchEditTextHintColor);\n        if (mLogoDrawable != null) {\n            this.mLogoView.setLogo(mLogoDrawable);\n        }\n        else if (mStringLogoDrawable != null)\n        {\n            this.mLogoView.setLogo(mStringLogoDrawable);\n        }\n        this.mLogoView.setTextColor(mSearchTextColor);\n    }\n\n    private void setUpListeners() {\n        mHomeButton.setOnClickListener(new OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                if (mCurrentState == SearchViewState.EDITING) {\n                    cancelEditing();\n                } else if (mCurrentState == SearchViewState.SEARCH) {\n                    fromSearchToNormal();\n                } else {\n                    if (mHomeButtonListener != null)\n                        mHomeButtonListener.onHomeButtonClick();\n                }\n            }\n\n        });\n        mLogoView.setOnClickListener(new OnClickListener() {\n\n            @Override\n            public void onClick(View v) {\n                dispatchStateChange(SearchViewState.EDITING); // This would call when state is wrong.\n            }\n\n        });\n        mSearchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {\n            public boolean onEditorAction(TextView v, int actionId,\n                                          KeyEvent event) {\n                if (actionId == EditorInfo.IME_ACTION_SEARCH) {\n                    clearSuggestions();\n                    fromEditingToSearch(true, false);\n                    return true;\n                }\n                return false;\n            }\n        });\n        mSearchEditText.setOnKeyListener(new OnKeyListener() {\n            public boolean onKey(View v, int keyCode, KeyEvent event) {\n                if (keyCode == KeyEvent.KEYCODE_ENTER) {\n                    clearSuggestions();\n                    fromEditingToSearch(true, false);\n                    return true;\n                } else if (keyCode == KeyEvent.KEYCODE_BACK) {\n                    return mSearchListener != null && mSearchListener.onSearchEditBackPressed();\n                }\n                return false;\n            }\n        });\n        micStateChanged();\n        mMicButton.setOnClickListener(new OnClickListener() {\n            @Override\n            public void onClick(View v) {\n                micClick();\n            }\n        });\n        mSearchEditText.addTextChangedListener(new TextWatcher() {\n\n            @Override\n            public void afterTextChanged(Editable s) {\n                if (!mAvoidTriggerTextWatcher) {\n                    if (s.length() > 0) {\n                        showClearButton();\n                        buildSearchSuggestions(getSearchText());\n                    } else {\n                        showMicButton();\n                        buildEmptySearchSuggestions();\n                    }\n                }\n                if (mSearchListener != null)\n                    mSearchListener.onSearchTermChanged(s.toString());\n            }\n\n            @Override\n            public void beforeTextChanged(CharSequence s, int start, int count,\n                                          int after) {\n            }\n\n            @Override\n            public void onTextChanged(CharSequence s, int start, int before,\n                                      int count) {\n\n            }\n\n        });\n\n    }\n\n    public EditText getSearchEditText() {\n        return mSearchEditText;\n    }\n\n    private void setUpLayoutTransition() {\n        RelativeLayout searchRoot = (RelativeLayout) findViewById(R.id.search_root);\n        LayoutTransition layoutTransition = new LayoutTransition();\n        layoutTransition.setDuration(DURATION_LAYOUT_TRANSITION);\n        // layoutTransition.enableTransitionType(LayoutTransition.CHANGING);\n        layoutTransition.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);\n        layoutTransition.setStartDelay(LayoutTransition.CHANGING, 0);\n        layoutTransition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0);\n        mSearchCardView.setLayoutTransition(layoutTransition);\n    }\n\n    @Override\n    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {\n        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);\n        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);\n\n        int totalHeight = 0;\n        int searchCardWidth;\n        final int childCount = getChildCount();\n        for (int i = 0; i < childCount; ++i) {\n            final View child = getChildAt(i);\n            if (child.getVisibility() != GONE) {\n                if (i == 0 && child instanceof CardView) {\n                    CardView searchCard = (CardView) child;\n                    int horizontalPadding = (int) Math.ceil(calculateHorizontalPadding(searchCard));\n                    int verticalPadding = (int) Math.ceil(calculateVerticalPadding(searchCard));\n                    // searchCardWidth = widthSize - 2 * mCardVisiblePadding + horizontalPadding * 2;\n                    int searchCardLeft = mCardHorizontalPadding - horizontalPadding;\n                    // searchCardTop = mCardVisiblePadding - verticalPadding;\n                    searchCardWidth = widthSize - searchCardLeft * 2;\n                    int cardWidthSpec = MeasureSpec.makeMeasureSpec(searchCardWidth, MeasureSpec.EXACTLY);\n                    // int cardHeightSpec = MeasureSpec.makeMeasureSpec(searchCardHeight, MeasureSpec.EXACTLY);\n                    measureChild(child, cardWidthSpec, heightMeasureSpec);\n                    int childMeasuredHeight = child.getMeasuredHeight();\n                    int childMeasuredWidth = child.getMeasuredWidth();\n                    int childHeight = childMeasuredHeight - verticalPadding * 2;\n                    totalHeight = totalHeight + childHeight + mCardVerticalPadding * 2;\n                }\n            }\n        }\n        if(totalHeight < mCustomToolbarHeight)\n            totalHeight = mCustomToolbarHeight;\n        setMeasuredDimension(widthSize, totalHeight);\n    }\n\n    @Override\n    protected void onLayout(boolean changed, int l, int t, int r, int b) {\n        final int count = getChildCount();\n        int searchViewWidth = r - l;\n        int searchViewHeight = b - t;\n        int searchCardLeft;\n        int searchCardTop;\n        int searchCardRight;\n        int searchCardBottom;\n        int searchCardWidth;\n        int searchCardHeight;\n        for (int i = 0; i < count; i++) {\n            View child = getChildAt(i);\n            if (i == 0 && child instanceof CardView) {\n                CardView searchCard = (CardView) child;\n                int horizontalPadding = (int) Math.ceil(calculateHorizontalPadding(searchCard));\n                int verticalPadding = (int) Math.ceil(calculateVerticalPadding(searchCard));\n                searchCardLeft = mCardHorizontalPadding - horizontalPadding;\n                searchCardTop = mCardVerticalPadding - verticalPadding;\n                searchCardWidth = searchViewWidth - searchCardLeft * 2;\n                searchCardHeight = child.getMeasuredHeight();\n                searchCardRight = searchCardLeft + searchCardWidth;\n                searchCardBottom = searchCardTop + searchCardHeight;\n                child.layout(searchCardLeft, searchCardTop, searchCardRight, searchCardBottom);\n            }\n        }\n    }\n\n    private void revealFromMenuItem() {\n        setVisibility(View.VISIBLE);\n        revealFrom(mFromX, mFromY, mDesireRevealWidth);\n    }\n\n    private void hideCircularlyToMenuItem() {\n        if (mFromX == 0 || mFromY == 0) {\n            mFromX = getRight();\n            mFromY = getTop();\n        }\n        hideCircularly(mFromX, mFromY);\n    }\n\n    /***\n     * Hide the PersistentSearchView using the circle animation. Can be called regardless of result list length\n     */\n    private void hideCircularly(int x, int y) {\n\n        Resources r = getResources();\n        float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 96,\n                r.getDisplayMetrics());\n        int finalRadius = (int) Math.max(this.getMeasuredWidth() * 1.5, px);\n\n        SupportAnimator animator = ViewAnimationUtils.createCircularReveal(\n                mSearchCardView, x, y, 0, finalRadius);\n        animator = animator.reverse();\n        animator.setInterpolator(new AccelerateDecelerateInterpolator());\n        animator.setDuration(DURATION_REVEAL_CLOSE);\n        animator.start();\n        animator.addListener(new SupportAnimator.AnimatorListener() {\n\n            @Override\n            public void onAnimationStart() {\n\n            }\n\n            @Override\n            public void onAnimationEnd() {\n                setVisibility(View.GONE);\n                closeSearchInternal();\n                // closeSearch();\n            }\n\n            @Override\n            public void onAnimationCancel() {\n\n            }\n\n            @Override\n            public void onAnimationRepeat() {\n\n            }\n\n        });\n    }\n\n    private void hideCircularly() {\n        hideCircularly(getLeft() + getRight(), getTop());\n    }\n\n    public boolean getSearchOpen() {\n        return getVisibility() == VISIBLE && (mCurrentState == SearchViewState.SEARCH || mCurrentState == SearchViewState.EDITING);\n    }\n\n    /***\n     * Hide the search suggestions manually\n     */\n    public void hideSuggestions() {\n        this.mSearchEditText.setVisibility(View.GONE);\n        this.mSuggestionListView.setVisibility(View.GONE);\n    }\n\n    private boolean isMicEnabled() {\n        return mVoiceRecognitionDelegate != null;\n    }\n\n    private void micStateChanged() {\n        mMicButton.setVisibility((!mIsMic || isMicEnabled()) ? VISIBLE : INVISIBLE);\n    }\n\n    private void micStateChanged(boolean isMic) {\n        this.mIsMic = isMic;\n        micStateChanged();\n    }\n\n    private void showMicButton() {\n        micStateChanged(true);\n        mMicButton.setImageDrawable(\n                ResourcesCompat.getDrawable(getResources(), R.drawable.ic_action_mic_black, null));\n    }\n\n    private void showClearButton() {\n        micStateChanged(false);\n        mMicButton.setImageDrawable(\n                ResourcesCompat.getDrawable(getResources(), R.drawable.ic_action_clear_black, null));\n    }\n\n    /***\n     * Mandatory method for the onClick event\n     */\n    public void micClick() {\n        if (!mIsMic) {\n            setSearchString(\"\", false);\n        } else {\n            if (mVoiceRecognitionDelegate != null)\n                mVoiceRecognitionDelegate.onStartVoiceRecognition();\n        }\n    }\n\n    /***\n     * Populate the PersistentSearchView with words, in an ArrayList. Used by the voice input\n     *\n     * @param matches Matches\n     */\n    public void populateEditText(ArrayList<String> matches) {\n        String text = matches.get(0).trim();\n        populateEditText(text);\n    }\n\n    /***\n     * Populate the PersistentSearchView with search query\n     *\n     * @param query Matches\n     */\n    public void populateEditText(String query) {\n        String text = query.trim();\n        setSearchString(text, true);\n        dispatchStateChange(SearchViewState.SEARCH);\n    }\n\n    /***\n     * Set whether the menu button should be shown. Particularly useful for apps that adapt to screen sizes\n     *\n     * @param visibility Whether to show\n     */\n\n    public void setHomeButtonVisibility(int visibility) {\n        this.mHomeButton.setVisibility(visibility);\n    }\n\n    /***\n     * Set the menu listener\n     *\n     * @param homeButtonListener MenuListener\n     */\n    public void setHomeButtonListener(HomeButtonListener homeButtonListener) {\n        this.mHomeButtonListener = homeButtonListener;\n    }\n\n    /***\n     * Set the search listener\n     *\n     * @param listener SearchListener\n     */\n    public void setSearchListener(SearchListener listener) {\n        this.mSearchListener = listener;\n    }\n\n    /***\n     * Set the text color of the logo\n     *\n     * @param color logo text color\n     */\n    public void setLogoTextColor(int color) {\n        mLogoView.setTextColor(color);\n    }\n\n    /***\n     * Get the PersistentSearchView's current text\n     *\n     * @return Text\n     */\n    public String getSearchText() {\n        return mSearchEditText.getText().toString();\n    }\n\n    public void clearSuggestions() {\n        mSearchItemAdapter.clear();\n    }\n\n    /***\n     * Set the PersistentSearchView's current text manually\n     *\n     * @param text                    Text\n     * @param avoidTriggerTextWatcher avoid trigger TextWatcher(TextChangedListener)\n     */\n    public void setSearchString(String text, boolean avoidTriggerTextWatcher) {\n        if (avoidTriggerTextWatcher)\n            mAvoidTriggerTextWatcher = true;\n        mSearchEditText.setText(\"\");\n        mSearchEditText.append(text);\n        mAvoidTriggerTextWatcher = false;\n    }\n\n    private void buildEmptySearchSuggestions() {\n        if (mSuggestionBuilder != null) {\n            mSearchSuggestions.clear();\n            Collection<SearchItem> suggestions = mSuggestionBuilder.buildEmptySearchSuggestion(10);\n            if (suggestions != null && suggestions.size() > 0) {\n                mSearchSuggestions.addAll(suggestions);\n            }\n            mSearchItemAdapter.notifyDataSetChanged();\n        }\n    }\n\n    private void buildSearchSuggestions(String query) {\n        if (mSuggestionBuilder != null) {\n            mSearchSuggestions.clear();\n            Collection<SearchItem> suggestions = mSuggestionBuilder.buildSearchSuggestion(10, query);\n            if (suggestions != null && suggestions.size() > 0) {\n                mSearchSuggestions.addAll(suggestions);\n            }\n            mSearchItemAdapter.notifyDataSetChanged();\n        }\n    }\n\n    private void revealFrom(float x, float y, int desireRevealWidth) {\n        Resources r = getResources();\n        float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 96,\n                r.getDisplayMetrics());\n        if(desireRevealWidth <= 0)\n            desireRevealWidth = getMeasuredWidth();\n        if(desireRevealWidth <= 0) {\n            DisplayMetrics metrics = getResources().getDisplayMetrics();\n            desireRevealWidth = metrics.widthPixels;\n        }\n        if(x <= 0 )\n            x = desireRevealWidth - mCardHeight / 2f;\n        if(y <= 0)\n            y = mCardHeight / 2f;\n\n        int measuredHeight = getMeasuredWidth();\n        int finalRadius = (int) Math.max(Math.max(measuredHeight, px), desireRevealWidth);\n\n        SupportAnimator animator = ViewAnimationUtils.createCircularReveal(\n                mSearchCardView, (int) x, (int) y, 0, finalRadius);\n        animator.setInterpolator(new AccelerateDecelerateInterpolator());\n        animator.setDuration(DURATION_REVEAL_OPEN);\n        animator.addListener(new SupportAnimator.AnimatorListener() {\n\n            @Override\n            public void onAnimationCancel() {\n\n            }\n\n            @Override\n            public void onAnimationEnd() {\n                // show search view here\n                openSearchInternal(true);\n            }\n\n            @Override\n            public void onAnimationRepeat() {\n\n            }\n\n            @Override\n            public void onAnimationStart() {\n\n            }\n\n        });\n        animator.start();\n    }\n\n    private void search() {\n        String searchTerm = getSearchText();\n        if (!TextUtils.isEmpty(searchTerm)) {\n            setLogoTextInt(searchTerm);\n            if (mSearchListener != null)\n                mSearchListener.onSearch(searchTerm);\n        }\n    }\n\n    private void openSearchInternal(Boolean openKeyboard) {\n        this.mLogoView.setVisibility(View.GONE);\n        this.mSearchEditText.setVisibility(View.VISIBLE);\n        mSearchEditText.requestFocus();\n        this.mSuggestionListView.setVisibility(View.VISIBLE);\n        mSuggestionListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {\n\n            @Override\n            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {\n                hideKeyboard();\n                SearchItem result = mSearchSuggestions.get(arg2);\n                if (mSearchListener != null) {\n                    if (mSearchListener.onSuggestion(result)) {\n                        setSearchString(result.getValue(), true);\n                        fromEditingToSearch(true, false);\n                    }\n                } else {\n                    setSearchString(result.getValue(), true);\n                    fromEditingToSearch(true, false);\n                }\n            }\n\n        });\n        String currentSearchText = getSearchText();\n        if (currentSearchText.length() > 0) {\n            buildSearchSuggestions(currentSearchText);\n        } else {\n            buildEmptySearchSuggestions();\n        }\n\n        if (mSearchListener != null)\n            mSearchListener.onSearchEditOpened();\n        if (getSearchText().length() > 0) {\n            showClearButton();\n        }\n        if (openKeyboard) {\n            if(showCustomKeyboard && mCustomKeyboardView != null) { // Show custom keyboard\n                mCustomKeyboardView.setVisibility(View.VISIBLE);\n                mCustomKeyboardView.setEnabled(true);\n\n                // Enable cursor, but still prevent default keyboard from showing up\n                OnTouchListener otl = new OnTouchListener() {\n                    @Override\n                    public boolean onTouch(View v, MotionEvent event) {\n                        switch (event.getAction()) {\n                            case MotionEvent.ACTION_DOWN:\n                                mCustomKeyboardView.setVisibility(View.VISIBLE);\n                                mCustomKeyboardView.setEnabled(true);\n                                Layout layout = ((EditText) v).getLayout();\n                                float x = event.getX() + mSearchEditText.getScrollX();\n                                int offset = layout.getOffsetForHorizontal(0, x);\n                                if (offset > 0)\n                                    if (x > layout.getLineMax(0))\n                                        mSearchEditText.setSelection(offset);     // Touch was at the end of the text\n                                    else\n                                        mSearchEditText.setSelection(offset - 1);\n                                break;\n                            case MotionEvent.ACTION_MOVE:\n                                layout = ((EditText) v).getLayout();\n                                x = event.getX() + mSearchEditText.getScrollX();\n                                offset = layout.getOffsetForHorizontal(0, x);\n                                if (offset > 0)\n                                    if (x > layout.getLineMax(0))\n                                        mSearchEditText.setSelection(offset);     // Touch point was at the end of the text\n                                    else\n                                        mSearchEditText.setSelection(offset - 1);\n                                break;\n                        }\n                        return true;\n                    }\n                };\n                mSearchEditText.setOnTouchListener(otl);\n            } else { // Show default keyboard\n                mSearchEditText.setOnTouchListener(null);\n                InputMethodManager inputMethodManager = (InputMethodManager) getContext()\n                        .getSystemService(Context.INPUT_METHOD_SERVICE);\n                inputMethodManager.toggleSoftInputFromWindow(\n                        getApplicationWindowToken(),\n                        InputMethodManager.SHOW_FORCED, 0);\n            }\n        }\n    }\n\n    private void closeSearchInternal() {\n        this.mLogoView.setVisibility(View.VISIBLE);\n        this.mSearchEditText.setVisibility(View.GONE);\n        // if(mDisplayMode == DISPLAY_MODE_AS_TOOLBAR) {\n        mSuggestionListView.setVisibility(View.GONE);\n        // }\n        // this.mSuggestionListView.setVisibility(View.GONE);\n        /*if (mTintView != null && mRootLayout != null) {\n            mRootLayout.removeView(mTintView);\n        }*/\n        if (mSearchListener != null)\n            mSearchListener.onSearchEditClosed();\n        showMicButton();\n\n        hideKeyboard();\n    }\n\n    private void hideKeyboard() {\n        if(showCustomKeyboard && mCustomKeyboardView != null) {\n            mCustomKeyboardView.setVisibility(View.GONE);\n            mCustomKeyboardView.setEnabled(false);\n        }\n        else {\n            ((InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getApplicationWindowToken(), 0);\n        }\n    }\n\n    public boolean isEditing() {\n        return mCurrentState == SearchViewState.EDITING;\n    }\n\n    public boolean isSearching() {\n        return mCurrentState == SearchViewState.EDITING || mCurrentState == SearchViewState.SEARCH;\n    }\n\n    private void setLogoTextInt(String text) {\n        mLogoView.setText(text);\n    }\n\n    public void setHomeButtonOpenIconState(HomeButton.IconState homeButtonOpenIconState) {\n        this.mHomeButtonOpenIconState = homeButtonOpenIconState;\n    }\n\n    public void setHomeButtonCloseIconState(HomeButton.IconState homeButtonCloseIconState) {\n        this.mHomeButtonCloseIconState = homeButtonCloseIconState;\n    }\n\n    public void setSuggestionBuilder(SearchSuggestionsBuilder suggestionBuilder) {\n        this.mSuggestionBuilder = suggestionBuilder;\n    }\n\n    private void fromNormalToEditing() {\n        if(mDisplayMode == DisplayMode.TOOLBAR) {\n            setCurrentState(SearchViewState.EDITING);\n            openSearchInternal(true);\n        } else if(mDisplayMode == DisplayMode.MENUITEM) {\n            setCurrentState(SearchViewState.EDITING);\n            if(ViewCompat.isAttachedToWindow(this))\n                revealFromMenuItem();\n            else {\n                getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {\n                    @Override\n                    public void onGlobalLayout() {\n                        getViewTreeObserver().removeOnGlobalLayoutListener(this);\n                        revealFromMenuItem();\n                    }\n                });\n            }\n\n        }\n        mHomeButton.animateState(mHomeButtonOpenIconState);\n    }\n\n    private void fromNormalToSearch() {\n        if(mDisplayMode == DisplayMode.TOOLBAR) {\n            setCurrentState(SearchViewState.SEARCH);\n            search();\n        } else if(mDisplayMode == DisplayMode.MENUITEM) {\n            setVisibility(VISIBLE);\n            fromEditingToSearch();\n        }\n        mHomeButton.animateState(mHomeButtonSearchIconState);\n    }\n\n    private void fromSearchToNormal() {\n        setLogoTextInt(\"\");\n        setSearchString(\"\", true);\n        setCurrentState(SearchViewState.NORMAL);\n        if(mDisplayMode == DisplayMode.TOOLBAR) {\n            closeSearchInternal();\n        } else if(mDisplayMode == DisplayMode.MENUITEM) {\n            hideCircularlyToMenuItem();\n        }\n        setLogoTextInt(\"\");\n        if (mSearchListener != null)\n            mSearchListener.onSearchExit();\n        mHomeButton.animateState(mHomeButtonCloseIconState);\n    }\n\n    private void fromSearchToEditing() {\n        openSearchInternal(true);\n        setCurrentState(SearchViewState.EDITING);\n        mHomeButton.animateState(mHomeButtonOpenIconState);\n    }\n\n    private void fromEditingToNormal() {\n        setCurrentState(SearchViewState.NORMAL);\n        if(mDisplayMode == DisplayMode.TOOLBAR) {\n            setSearchString(\"\", false);\n            closeSearchInternal();\n        } else if(mDisplayMode == DisplayMode.MENUITEM) {\n            setSearchString(\"\", false);\n            hideCircularlyToMenuItem();\n        }\n        setLogoTextInt(\"\");\n        if (mSearchListener != null)\n            mSearchListener.onSearchExit();\n        mHomeButton.animateState(mHomeButtonCloseIconState);\n    }\n\n    private void fromEditingToSearch() {\n        fromEditingToSearch(false, false);\n    }\n\n    private void fromEditingToSearch(boolean avoidSearch) {\n        fromEditingToSearch(false, avoidSearch);\n    }\n\n    private void fromEditingToSearch(boolean forceSearch, boolean avoidSearch) {\n        if(TextUtils.isEmpty(getSearchText())) {\n            fromEditingToNormal();\n        } else {\n            setCurrentState(SearchViewState.SEARCH);\n            if((!getSearchText().equals(mLogoView.getText().toString()) || forceSearch) && !avoidSearch) {\n                search();\n            }\n            closeSearchInternal();\n            mHomeButton.animateState(mHomeButtonSearchIconState);\n        }\n    }\n\n    private void dispatchStateChange(SearchViewState targetState) {\n        if(targetState == SearchViewState.NORMAL) {\n            if (mCurrentState == SearchViewState.EDITING) {\n                fromEditingToNormal();\n            } else if(mCurrentState == SearchViewState.SEARCH) {\n                fromSearchToNormal();\n            }\n        } else if(targetState == SearchViewState.EDITING) {\n            if (mCurrentState == SearchViewState.NORMAL) {\n                fromNormalToEditing();\n            } else if(mCurrentState == SearchViewState.SEARCH) {\n                fromSearchToEditing();\n            }\n        } else if(targetState == SearchViewState.SEARCH) {\n            if (mCurrentState == SearchViewState.NORMAL) {\n                fromNormalToSearch();\n            } else if(mCurrentState == SearchViewState.EDITING) {\n                fromEditingToSearch();\n            }\n        }\n    }\n\n    private void setCurrentState(SearchViewState state) {\n        mLastState = mCurrentState;\n        mCurrentState = state;\n    }\n\n    public void openSearch() {\n        dispatchStateChange(SearchViewState.EDITING);\n    }\n\n    public void setStartPositionFromMenuItem(View menuItemView) {\n        DisplayMetrics metrics = getResources().getDisplayMetrics();\n        int width = metrics.widthPixels;\n        setStartPositionFromMenuItem(menuItemView, width);\n    }\n\n    public void setStartPositionFromMenuItem(View menuItemView, int desireRevealWidth) {\n        if (menuItemView != null) {\n            int[] location = new int[2];\n            menuItemView.getLocationInWindow(location);\n            int menuItemWidth = menuItemView.getWidth();\n            this.mFromX = location[0] + menuItemWidth / 2;\n            this.mFromY = location[1];\n            this.mDesireRevealWidth = desireRevealWidth;\n        }\n    }\n\n    public void openSearch(String query) {\n        setSearchString(query, true);\n        dispatchStateChange(SearchViewState.SEARCH);\n    }\n\n    public void closeSearch() {\n        dispatchStateChange(SearchViewState.NORMAL);\n    }\n\n    public void cancelEditing() {\n        if(TextUtils.isEmpty(mLogoView.getText())) {\n            fromEditingToNormal();\n        } else {\n            fromEditingToSearch(true);\n        }\n    }\n\n    public void setVoiceRecognitionDelegate(VoiceRecognitionDelegate delegate) {\n        this.mVoiceRecognitionDelegate = delegate;\n        micStateChanged();\n    }\n\n    public enum DisplayMode {\n        MENUITEM(0), TOOLBAR(1);\n        int mode;\n\n        DisplayMode(int mode) {\n            this.mode = mode;\n        }\n\n        public static DisplayMode fromInt(int mode) {\n            for (DisplayMode enumMode : values()) {\n                if (enumMode.mode == mode) return enumMode;\n            }\n            throw new IllegalArgumentException();\n        }\n\n        public int toInt() {\n            return mode;\n        }\n    }\n\n    public enum SearchViewState {\n        NORMAL(0), EDITING(1), SEARCH(2);\n        int state;\n        SearchViewState(int state) {\n            this.state = state;\n        }\n        public static SearchViewState fromInt(int state) {\n            for (SearchViewState enumState : values()) {\n                if (enumState.state == state) return enumState;\n            }\n            throw new IllegalArgumentException();\n        }\n\n        public int toInt() {\n            return state;\n        }\n    }\n\n    public interface SearchListener {\n\n        /**\n         * Called when a suggestion is pressed is pressed\n         */\n        boolean onSuggestion(SearchItem searchItem);\n\n        /**\n         * Called when the clear button is pressed\n         */\n        void onSearchCleared();\n\n        /**\n         * Called when the PersistentSearchView's EditText text changes\n         */\n        void onSearchTermChanged(String term);\n\n        /**\n         * Called when search happens\n         *\n         * @param query search string\n         */\n        void onSearch(String query);\n\n        /**\n         * Called when search state change to SEARCH and EditText, Suggestions visible\n         */\n        void onSearchEditOpened();\n\n        /**\n         * Called when search state change from SEARCH and EditText, Suggestions gone\n         */\n        void onSearchEditClosed();\n\n        /**\n         * Called when edit text get focus and backpressed\n         */\n        boolean onSearchEditBackPressed();\n\n        /**\n         * Called when search back to start state.\n         */\n        void onSearchExit();\n    }\n\n    public interface HomeButtonListener {\n        /**\n         * Called when the menu button is pressed\n         */\n        void onHomeButtonClick();\n    }\n\n    @Override\n    public Parcelable onSaveInstanceState() {\n        Parcelable superState = super.onSaveInstanceState();\n        SavedState ss = new SavedState(superState, mCurrentState);\n        ss.childrenStates = new SparseArray();\n        for (int i = 0; i < getChildCount(); i++) {\n            getChildAt(i).saveHierarchyState(ss.childrenStates);\n        }\n        return ss;\n    }\n\n    @Override\n    public void onRestoreInstanceState(Parcelable state) {\n        if(!(state instanceof SavedState)) {\n            super.onRestoreInstanceState(state);\n            return;\n        }\n        this.mAvoidTriggerTextWatcher = true;\n        SavedState ss = (SavedState) state;\n        super.onRestoreInstanceState(ss.getSuperState());\n        for (int i = 0; i < getChildCount(); i++) {\n            getChildAt(i).restoreHierarchyState(ss.childrenStates);\n        }\n        dispatchStateChange(ss.getCurrentSearchViewState());\n        this.mAvoidTriggerTextWatcher = false;\n    }\n\n    @Override\n    protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {\n        dispatchFreezeSelfOnly(container);\n    }\n\n    @Override\n    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {\n        dispatchThawSelfOnly(container);\n    }\n\n    static class SavedState extends BaseSavedState {\n        SparseArray childrenStates;\n        private SearchViewState mCurrentSearchViewState;\n\n        SavedState(Parcelable superState, SearchViewState currentSearchViewState) {\n            super(superState);\n            mCurrentSearchViewState = currentSearchViewState;\n        }\n\n        private SavedState(Parcel in, ClassLoader classLoader) {\n            super(in);\n            childrenStates = in.readSparseArray(classLoader);\n            mCurrentSearchViewState = SearchViewState.fromInt(in.readInt());\n        }\n\n        @Override\n        public void writeToParcel(Parcel out, int flags) {\n            super.writeToParcel(out, flags);\n            out.writeSparseArray(childrenStates);\n            out.writeInt(mCurrentSearchViewState.toInt());\n        }\n\n        public SearchViewState getCurrentSearchViewState() {\n            return mCurrentSearchViewState;\n        }\n\n        public static final ClassLoaderCreator<SavedState> CREATOR\n                = new ClassLoaderCreator<SavedState>() {\n            @Override\n            public SavedState createFromParcel(Parcel source, ClassLoader loader) {\n                return new SavedState(source, loader);\n            }\n\n            @Override\n            public SavedState createFromParcel(Parcel source) {\n                return createFromParcel(null);\n            }\n\n            public SavedState[] newArray(int size) {\n                return new SavedState[size];\n            }\n        };\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/RevealViewGroup.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.content.Context;\nimport android.graphics.Canvas;\nimport android.graphics.Path;\nimport android.graphics.Rect;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.view.ViewGroup;\n\nimport io.codetail.animation.RevealAnimator;\nimport io.codetail.animation.SupportAnimator;\nimport io.codetail.animation.ViewAnimationUtils;\n\npublic abstract class RevealViewGroup extends ViewGroup implements RevealAnimator {\n\n    private Path mRevealPath;\n    private final Rect mTargetBounds = new Rect();\n    private RevealInfo mRevealInfo;\n    private boolean mRunning;\n    private float mRadius;\n\n    public RevealViewGroup(Context context) {\n        this(context, null);\n    }\n\n    public RevealViewGroup(Context context, AttributeSet attrs) {\n        this(context, attrs, 0);\n    }\n\n    public RevealViewGroup(Context context, AttributeSet attrs, int defStyle) {\n        super(context, attrs);\n        mRevealPath = new Path();\n    }\n\n    @Override\n    public void onRevealAnimationStart() {\n        mRunning = true;\n    }\n\n    @Override\n    public void onRevealAnimationEnd() {\n        mRunning = false;\n        invalidate(mTargetBounds);\n    }\n\n    @Override\n    public void onRevealAnimationCancel() {\n        onRevealAnimationEnd();\n    }\n\n    /**\n     * Circle radius size\n     *\n     * @hide\n     */\n    @Override\n    public void setRevealRadius(float radius){\n        mRadius = radius;\n        mRevealInfo.getTarget().getHitRect(mTargetBounds);\n        invalidate(mTargetBounds);\n    }\n\n    /**\n     * Circle radius size\n     *\n     * @hide\n     */\n    @Override\n    public float getRevealRadius(){\n        return mRadius;\n    }\n\n    /**\n     * @hide\n     */\n    @Override\n    public void attachRevealInfo(RevealInfo info) {\n        mRevealInfo = info;\n    }\n\n    /**\n     * @hide\n     */\n    @Override\n    public SupportAnimator startReverseAnimation() {\n        if(mRevealInfo != null && mRevealInfo.hasTarget() && !mRunning) {\n            return ViewAnimationUtils.createCircularReveal(mRevealInfo.getTarget(),\n                    mRevealInfo.centerX, mRevealInfo.centerY,\n                    mRevealInfo.endRadius, mRevealInfo.startRadius);\n        }\n        return null;\n    }\n\n    @Override\n    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {\n        if(mRunning && child == mRevealInfo.getTarget()){\n            final int state = canvas.save();\n\n            mRevealPath.reset();\n            mRevealPath.addCircle(mRevealInfo.centerX, mRevealInfo.centerY, mRadius, Path.Direction.CW);\n\n            canvas.clipPath(mRevealPath);\n\n            boolean isInvalided = super.drawChild(canvas, child, drawingTime);\n\n            canvas.restoreToCount(state);\n\n            return isInvalided;\n        }\n\n        return super.drawChild(canvas, child, drawingTime);\n    }\n\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/SearchItem.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.graphics.drawable.Drawable;\n\npublic class SearchItem {\n    private String mTitle;\n    private String mValue;\n    private Drawable mIcon;\n    private int mType;\n    public static final int TYPE_SEARCH_ITEM_HISTORY = 0;\n    public static final int TYPE_SEARCH_ITEM_SUGGESTION = 1;\n    public static final int TYPE_SEARCH_ITEM_OPTION = 2;\n    public static final int TYPE_SEARCH_ITEM_CUSTOM = 3;\n    public static final int TYPE_SEARCH_ITEM_DEFAULT = TYPE_SEARCH_ITEM_HISTORY;\n\n\n    public SearchItem(String title, String value) {\n        this(title, value, TYPE_SEARCH_ITEM_DEFAULT, null);\n    }\n    /**\n     * Create a search result with text and an icon\n     * @param title display value\n     * @param value inner value for search\n     * @param type item type\n     */\n    public SearchItem(String title, String value, int type) {\n        this(title, value, type, null);\n    }\n\n    public SearchItem(String title, String value, int type, Drawable icon) {\n        this.mTitle = title;\n        this.mValue = value;\n        this.mType = type;\n        this.mIcon = icon;\n    }\n    \n    /**\n     * Return the title of the result\n     */\n    @Override\n    public String toString() {\n        return mTitle;\n    }\n\n    public String getTitle() {\n        return mTitle;\n    }\n\n    public void setTitle(String title) {\n        this.mTitle = title;\n    }\n\n    public String getValue() {\n        return mValue;\n    }\n\n    public void setValue(String value) {\n        this.mValue = value;\n    }\n\n    public Drawable getIcon() {\n        return mIcon;\n    }\n\n    public void setIcon(Drawable icon) {\n        this.mIcon = icon;\n    }\n\n    public int getType() {\n        return mType;\n    }\n\n    public void setType(int type) {\n        this.mType = type;\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/SearchItemAdapter.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.content.Context;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.ArrayAdapter;\nimport android.widget.ImageView;\nimport android.widget.TextView;\n\nimport java.util.ArrayList;\n\npublic class SearchItemAdapter extends ArrayAdapter<SearchItem> {\n\n    public SearchItemAdapter(Context context, ArrayList<SearchItem> options) {\n        super(context, 0, options);\n    }\n\n    @Override\n    public View getView(int position, View convertView, ViewGroup parent) {\n        SearchItem searchItem = getItem(position);\n        if (convertView == null) {\n            convertView = LayoutInflater.from(getContext()).inflate(\n                    R.layout.layout_searchitem, parent, false);\n        }\n\n        View border = convertView.findViewById(R.id.view_border);\n        if (position == 0) {\n            border.setVisibility(View.VISIBLE);\n        } else {\n            border.setVisibility(View.GONE);\n        }\n        final TextView title = (TextView) convertView\n                .findViewById(R.id.textview_title);\n        title.setText(searchItem.getTitle());\n        ImageView icon = (ImageView) convertView.findViewById(R.id.imageview_icon);\n        if(searchItem.getIcon() == null) {\n            switch (searchItem.getType()) {\n                case SearchItem.TYPE_SEARCH_ITEM_HISTORY:\n                    icon.setImageResource(R.drawable.ic_history_black);\n                    break;\n                default:\n                case SearchItem.TYPE_SEARCH_ITEM_SUGGESTION:\n                    icon.setImageResource(R.drawable.ic_search_black);\n                    break;\n            }\n        } else {\n            icon.setImageDrawable(searchItem.getIcon());\n        }\n        return convertView;\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/SearchSuggestionsBuilder.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport java.util.Collection;\n\npublic interface SearchSuggestionsBuilder {\n    Collection<SearchItem> buildEmptySearchSuggestion(int maxCount);\n    Collection<SearchItem> buildSearchSuggestion(int maxCount, String query);\n}\n"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/SimpleSearchListener.java",
    "content": "package org.cryse.widget.persistentsearch;\n\npublic class SimpleSearchListener implements PersistentSearchView.SearchListener {\n\n    @Override\n    public boolean onSuggestion(SearchItem searchItem) {\n        return true;\n    }\n\n    @Override\n    public void onSearchCleared() {\n\n    }\n\n    @Override\n    public void onSearchTermChanged(String term) {\n\n    }\n\n    @Override\n    public void onSearch(String query) {\n\n    }\n\n    @Override\n    public void onSearchEditOpened() {\n\n    }\n\n    @Override\n    public void onSearchEditClosed() {\n\n    }\n\n    @Override\n    public boolean onSearchEditBackPressed() {\n        return false;\n    }\n\n    @Override\n    public void onSearchExit() {\n\n    }\n}\n"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/TextDrawable.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.content.res.Resources;\nimport android.graphics.Canvas;\nimport android.graphics.Color;\nimport android.graphics.ColorFilter;\nimport android.graphics.Paint;\nimport android.graphics.PixelFormat;\nimport android.graphics.Rect;\nimport android.graphics.drawable.Drawable;\nimport android.util.TypedValue;\n\npublic class TextDrawable extends Drawable {\n\n    private final String mText;\n    private final Paint mPaint;\n    private int mIntrinsicWidth;\n    private int mIntrinsicHeight;\n    private float mTextSize;\n\n    public TextDrawable(Resources resources, String text) {\n\n        this.mText = text;\n\n        mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,\n                24f, resources.getDisplayMetrics());\n\n        this.mPaint = new Paint();\n        mPaint.setColor(Color.GRAY);\n        mPaint.setTextSize(mTextSize);\n        mPaint.setAntiAlias(true);\n        mPaint.setFakeBoldText(false);\n        mPaint.setShadowLayer(2f, 0, 0, Color.BLACK);\n        mPaint.setStyle(Paint.Style.FILL);\n        mPaint.setTextAlign(Paint.Align.LEFT);\n\n        Rect bounds = new Rect();\n        mPaint.getTextBounds(mText, 0, mText.length(), bounds);\n        mIntrinsicWidth = bounds.width();\n        mIntrinsicHeight = bounds.height();\n    }\n\n    @Override\n    public void draw(Canvas canvas) {\n        Rect r = getBounds();\n\n        int count = canvas.save();\n        canvas.translate(r.left, r.top);\n        int height = canvas.getHeight() < 0 ? r.height() : canvas.getHeight();\n        canvas.drawText(mText, 0, height / 2 - ((mPaint.descent() + mPaint.ascent()) / 2), mPaint);\n        canvas.restoreToCount(count);\n    }\n\n    @Override\n    public int getIntrinsicWidth() {\n        return mIntrinsicWidth;\n    }\n    @Override\n    public int getIntrinsicHeight() {\n        return mIntrinsicHeight;\n    }\n\n    @Override\n    public void setAlpha(int alpha) {\n        mPaint.setAlpha(alpha);\n    }\n\n    @Override\n    public void setColorFilter(ColorFilter cf) {\n        mPaint.setColorFilter(cf);\n    }\n\n    @Override\n    public int getOpacity() {\n        return PixelFormat.TRANSLUCENT;\n    }\n}"
  },
  {
    "path": "persistentsearchview/src/main/java/org/cryse/widget/persistentsearch/VoiceRecognitionDelegate.java",
    "content": "package org.cryse.widget.persistentsearch;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.content.Intent;\n\nimport androidx.fragment.app.Fragment;\n\npublic abstract class VoiceRecognitionDelegate {\n    public static final int DEFAULT_VOICE_REQUEST_CODE = 8185102;\n    private int mVoiceRecognitionRequestCode;\n    private Activity mActivity;\n    private Fragment mSupportFragment;\n\n    public VoiceRecognitionDelegate(Activity activity) {\n        this(activity, DEFAULT_VOICE_REQUEST_CODE);\n    }\n\n    public VoiceRecognitionDelegate(Activity activity, int activityRequestCode) {\n        this.mActivity = activity;\n        this.mVoiceRecognitionRequestCode = activityRequestCode;\n    }\n\n    public VoiceRecognitionDelegate(Fragment supportFragment) {\n        this(supportFragment, DEFAULT_VOICE_REQUEST_CODE);\n    }\n\n    public VoiceRecognitionDelegate(Fragment supportFragment, int activityRequestCode) {\n        this.mSupportFragment = supportFragment;\n        this.mVoiceRecognitionRequestCode = activityRequestCode;\n    }\n\n    public void onStartVoiceRecognition() {\n        if (mActivity != null) {\n            Intent intent = buildVoiceRecognitionIntent();\n            mActivity.startActivityForResult(intent, mVoiceRecognitionRequestCode);\n        } else if(mSupportFragment != null) {\n            Intent intent = buildVoiceRecognitionIntent();\n            mSupportFragment.startActivityForResult(intent, mVoiceRecognitionRequestCode);\n        }\n    }\n\n    protected Context getContext() {\n        if (mActivity != null) {\n            return mActivity;\n        } else if(mSupportFragment != null) {\n            return mSupportFragment.getContext();\n        } else {\n            throw new IllegalStateException(\"Could not get context in VoiceRecognitionDelegate.\");\n        }\n    }\n\n    public abstract Intent buildVoiceRecognitionIntent();\n\n    public abstract boolean isVoiceRecognitionAvailable();\n}\n"
  },
  {
    "path": "persistentsearchview/src/main/res/layout/layout_searchitem.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"48dp\"\n    android:layout_marginLeft=\"8dp\"\n    android:layout_marginRight=\"8dp\"\n    android:background=\"?selectableItemBackground\"\n    android:orientation=\"horizontal\" >\n\n    <ImageView\n        android:id=\"@+id/imageview_icon\"\n        android:layout_width=\"24dp\"\n        android:layout_height=\"24dp\"\n        android:layout_centerVertical=\"true\"\n        android:layout_marginLeft=\"12dp\"\n        android:layout_marginRight=\"12dp\"\n        android:scaleType=\"center\"\n        android:adjustViewBounds=\"true\"\n        android:cropToPadding=\"false\" />\n\n    <TextView\n        android:id=\"@+id/textview_title\"\n        android:singleLine=\"true\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:textColor=\"#212121\"\n        android:textSize=\"14sp\"\n        android:layout_centerVertical=\"true\"\n        android:layout_marginLeft=\"56dp\"\n        android:layout_marginStart=\"56dp\"\n        android:layout_alignParentLeft=\"true\"\n        android:layout_alignParentStart=\"true\"\n        android:textAppearance=\"?android:attr/textAppearanceMedium\" />\n\n    <View\n        android:id=\"@+id/view_border\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"1dp\"\n        android:background=\"#E8E8E8\" />\n    \n</RelativeLayout>\n"
  },
  {
    "path": "persistentsearchview/src/main/res/layout/layout_searchview.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/search_root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"56dp\"\n    android:clipChildren=\"false\"\n    android:clipToPadding=\"false\">\n\n    <com.google.android.material.card.MaterialCardView\n        android:id=\"@+id/cardview_search\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_centerInParent=\"true\"\n        android:clickable=\"true\"\n        app:cardBackgroundColor=\"#FFFFFFFF\"\n        app:cardCornerRadius=\"2dp\"\n        app:cardElevation=\"0dp\"\n        app:cardUseCompatPadding=\"true\">\n\n        <RelativeLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"48dp\">\n\n            <org.cryse.widget.persistentsearch.HomeButton\n                android:id=\"@+id/button_home\"\n                android:layout_width=\"48dp\"\n                android:layout_height=\"48dp\"\n                android:layout_alignParentLeft=\"true\"\n                android:layout_alignParentStart=\"true\"\n                android:scaleType=\"center\"/>\n\n            <org.cryse.widget.persistentsearch.LogoView\n                android:id=\"@+id/logoview\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:layout_toRightOf=\"@+id/button_home\"\n                android:layout_toEndOf=\"@+id/button_home\"\n                android:layout_toLeftOf=\"@+id/button_mic\"\n                android:layout_toStartOf=\"@+id/button_mic\"\n                android:layout_marginLeft=\"8dp\"\n                android:layout_marginStart=\"8dp\"\n                android:layout_marginRight=\"16dp\"\n                android:layout_marginEnd=\"16dp\"\n                android:gravity=\"center_vertical\"\n                android:singleLine=\"true\"\n                android:textAppearance=\"?android:attr/textAppearanceMedium\"\n                android:textColor=\"#212121\" />\n\n            <EditText\n                android:id=\"@+id/edittext_search\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:layout_toRightOf=\"@+id/button_home\"\n                android:layout_toEndOf=\"@+id/button_home\"\n                android:layout_toLeftOf=\"@+id/button_mic\"\n                android:layout_toStartOf=\"@+id/button_mic\"\n                android:layout_marginLeft=\"8dp\"\n                android:layout_marginStart=\"8dp\"\n                android:layout_marginRight=\"16dp\"\n                android:layout_marginEnd=\"16dp\"\n                android:gravity=\"start|center\"\n                android:background=\"@null\"\n                android:ems=\"10\"\n                android:imeOptions=\"actionSearch|flagNoExtractUi\"\n                android:singleLine=\"true\"\n                android:textColor=\"#212121\"\n                android:visibility=\"gone\">\n\n                <requestFocus />\n            </EditText>\n\n            <ImageView\n                android:id=\"@+id/button_mic\"\n                android:layout_width=\"48dp\"\n                android:layout_height=\"48dp\"\n                android:layout_alignParentRight=\"true\"\n                android:layout_alignParentEnd=\"true\"\n                android:scaleType=\"center\"\n                android:src=\"@drawable/ic_action_mic_black\"/>\n\n        </RelativeLayout>\n\n        <ListView\n            android:id=\"@+id/listview_suggestions\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginTop=\"48dp\"\n            android:visibility=\"gone\"/>\n    </com.google.android.material.card.MaterialCardView>\n</merge>"
  },
  {
    "path": "persistentsearchview/src/main/res/values/attrs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <declare-styleable name=\"PersistentSearchView\">\n        <attr name=\"persistentSV_searchTextColor\" format=\"color\"/>\n        <attr name=\"persistentSV_logoDrawable\" format=\"reference\"/>\n        <attr name=\"persistentSV_logoString\" format=\"string\"/>\n        <attr name=\"persistentSV_editTextColor\" format=\"color\"/>\n        <attr name=\"persistentSV_editHintText\" format=\"string\"/>\n        <attr name=\"persistentSV_editHintTextColor\" format=\"color\"/>\n        <attr name=\"persistentSV_searchCardElevation\" format=\"dimension\"/>\n        <attr name=\"persistentSV_displayMode\" format=\"enum\">\n            <enum name=\"menuItem\" value=\"0\" />\n            <enum name=\"toolbar\" value=\"1\" />\n        </attr>\n        <attr name=\"persistentSV_homeButtonColor\" format=\"color\"/>\n        <attr name=\"persistentSV_customToolbarHeight\" format=\"dimension\"/>\n        <attr name=\"persistentSV_homeButtonMode\" format=\"enum\">\n            <enum name=\"arrow\" value=\"0\" />\n            <enum name=\"burger\" value=\"1\" />\n        </attr>\n    </declare-styleable>\n</resources>"
  },
  {
    "path": "persistentsearchview/src/main/res/values/dimens.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <dimen name=\"search_card_visible_padding_toolbar_mode\">8dp</dimen>\n    <dimen name=\"search_card_visible_padding_menu_item_mode\">4dp</dimen>\n    <dimen name=\"search_card_default_card_elevation\">2dp</dimen>\n    <dimen name=\"search_card_height\">48dp</dimen>\n</resources>"
  },
  {
    "path": "persistentsearchview/src/main/res/values/strings.xml",
    "content": "<resources>\n\n    <string name=\"speak_now\">Speak now</string>\n\n</resources>\n"
  },
  {
    "path": "settings.gradle",
    "content": "include ':app'\n"
  },
  {
    "path": "version.num",
    "content": "228"
  }
]