[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: wingio\n"
  },
  {
    "path": ".github/workflows/build-debug.yml",
    "content": "name: Build debug APK\n\non:\n  push:\n    branches:\n      - '*'\n    paths-ignore:\n      - '**.md'\n      - '.idea/*'\n      - 'LICENSE'\n  pull_request:\n    branches:\n      - '*'\n    paths-ignore:\n      - '**.md'\n      - '.idea/*'\n      - 'LICENSE'\n  workflow_dispatch:\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n\n      - name: Setup JDK 17\n        uses: actions/setup-java@v2\n        with:\n          java-version: 17\n          distribution: 'temurin'\n\n      - name: Setup Android SDK\n        uses: android-actions/setup-android@v2.0.10\n\n      - name: Build APK\n        run: chmod +x ./gradlew && ./gradlew assembleDebug\n\n      - name: Upload APK\n        uses: actions/upload-artifact@v4\n        with:\n          name: manager-debug\n          path: app/build/outputs/apk/debug/app-debug.apk"
  },
  {
    "path": ".github/workflows/build-release.yml",
    "content": "name: Build Release\n\non:\n  workflow_dispatch:\n    inputs:\n      versionName:\n        required: true\n        description: This releases version name\n        default: \"1.0.0\"\n      versionCode:\n        required: true\n        description: This releases version code\n        default: \"1000\"\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@master\n\n      - name: Setup JDK 17\n        uses: actions/setup-java@v2\n        with:\n          java-version: 17\n          distribution: 'temurin'\n\n      - name: Setup Android SDK\n        uses: android-actions/setup-android@v2.0.10\n\n      - name: Set Version\n        uses: chkfung/android-version-actions@v1.1\n        with:\n          gradlePath: app/build.gradle.kts\n          versionCode: ${{github.event.inputs.versionCode}}\n          versionName: ${{github.event.inputs.versionName}}\n\n      - name: Build Signed APK\n        run: |\n          echo \"${{ secrets.keystore }}\" | base64 -d > $GITHUB_WORKSPACE/signing-key.jks\n          chmod +x ./gradlew\n          ./gradlew packageReleaseUniversalApk -Pandroid.injected.signing.store.file=$GITHUB_WORKSPACE/signing-key.jks -Pandroid.injected.signing.store.password=${{ secrets.keystore_password }} -Pandroid.injected.signing.key.alias=${{ secrets.key_alias }} -Pandroid.injected.signing.key.password=${{ secrets.key_password }}\n\n      - name: Release\n        run: |\n          mv app/build/outputs/apk_from_bundle/release/app-release-universal.apk ./Manager.apk\n          git config --local user.email \"actions@github.com\"\n          git config --local user.name \"GitHub Actions\"\n          tag=\"${{ github.event.inputs.versionCode }}\"\n          git tag \"$tag\"\n          git push origin \"$tag\"\n          gh release create \"$tag\" \\\n            --title \"${{ github.event.inputs.versionName }}\" \\\n            --generate-notes \\\n            ./Manager.apk\n        env:\n          GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'"
  },
  {
    "path": ".gitignore",
    "content": "# Built application files\n*.apk\n*.ap_\n*.aab\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated files\nbin/\ngen/\nout/\n.kotlin/\n#  Uncomment the following line in case you need and you don't have the release build type files in your app\n# release/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea\n.idea/workspace.xml\n.idea/tasks.xml\n.idea/gradle.xml\n.idea/assetWizardSettings.xml\n.idea/dictionaries\n.idea/libraries\n# Android Studio 3 in .gitignore file.\n.idea/caches\n.idea/modules.xml\n# Comment next line if keeping position of elements in Navigation Editor is relevant for you\n.idea/navEditor.xml\n\n# Keystore files\n# Uncomment the following lines if you do not want to check your keystore files in.\n#*.jks\n#*.keystore\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n.cxx/\n\n# Google Services (e.g. APIs or Firebase)\n# google-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n\n# Version control\nvcs.xml\n\n# lint\nlint/intermediates/\nlint/generated/\nlint/outputs/\nlint/tmp/\n# lint/reports/"
  },
  {
    "path": "LICENSE",
    "content": "Open Software License (\"OSL\") v. 3.0\n\nThis Open Software License (the \"License\") applies to any original work of\nauthorship (the \"Original Work\") whose owner (the \"Licensor\") has placed the\nfollowing licensing notice adjacent to the copyright notice for the Original\nWork:\n\nLicensed under the Open Software License version 3.0\n\n1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free,\nnon-exclusive, sublicensable license, for the duration of the copyright, to do\nthe following:\n\n  a) to reproduce the Original Work in copies, either alone or as part of a\n  collective work;\n\n  b) to translate, adapt, alter, transform, modify, or arrange the Original\n  Work, thereby creating derivative works (\"Derivative Works\") based upon the\n  Original Work;\n\n  c) to distribute or communicate copies of the Original Work and Derivative\n  Works to the public, with the proviso that copies of Original Work or\n  Derivative Works that You distribute or communicate shall be licensed under\n  this Open Software License;\n\n  d) to perform the Original Work publicly; and\n\n  e) to display the Original Work publicly.\n\n2) Grant of Patent License. Licensor grants You a worldwide, royalty-free,\nnon-exclusive, sublicensable license, under patent claims owned or controlled\nby the Licensor that are embodied in the Original Work as furnished by the\nLicensor, for the duration of the patents, to make, use, sell, offer for sale,\nhave made, and import the Original Work and Derivative Works.\n\n3) Grant of Source Code License. The term \"Source Code\" means the preferred\nform of the Original Work for making modifications to it and all available\ndocumentation describing how to modify the Original Work. Licensor agrees to\nprovide a machine-readable copy of the Source Code of the Original Work along\nwith each copy of the Original Work that Licensor distributes. Licensor\nreserves the right to satisfy this obligation by placing a machine-readable\ncopy of the Source Code in an information repository reasonably calculated to\npermit inexpensive and convenient access by You for as long as Licensor\ncontinues to distribute the Original Work.\n\n4) Exclusions From License Grant. Neither the names of Licensor, nor the names\nof any contributors to the Original Work, nor any of their trademarks or\nservice marks, may be used to endorse or promote products derived from this\nOriginal Work without express prior permission of the Licensor. Except as\nexpressly stated herein, nothing in this License grants any license to\nLicensor's trademarks, copyrights, patents, trade secrets or any other\nintellectual property. No patent license is granted to make, use, sell, offer\nfor sale, have made, or import embodiments of any patent claims other than the\nlicensed claims defined in Section 2. No license is granted to the trademarks\nof Licensor even if such marks are included in the Original Work. Nothing in\nthis License shall be interpreted to prohibit Licensor from licensing under\nterms different from this License any Original Work that Licensor otherwise\nwould have a right to license.\n\n5) External Deployment. The term \"External Deployment\" means the use,\ndistribution, or communication of the Original Work or Derivative Works in any\nway such that the Original Work or Derivative Works may be used by anyone\nother than You, whether those works are distributed or communicated to those\npersons or made available as an application intended for use over a network.\nAs an express condition for the grants of license hereunder, You must treat\nany External Deployment by You of the Original Work or a Derivative Work as a\ndistribution under section 1(c).\n\n6) Attribution Rights. You must retain, in the Source Code of any Derivative\nWorks that You create, all copyright, patent, or trademark notices from the\nSource Code of the Original Work, as well as any notices of licensing and any\ndescriptive text identified therein as an \"Attribution Notice.\" You must cause\nthe Source Code for any Derivative Works that You create to carry a prominent\nAttribution Notice reasonably calculated to inform recipients that You have\nmodified the Original Work.\n\n7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that\nthe copyright in and to the Original Work and the patent rights granted herein\nby Licensor are owned by the Licensor or are sublicensed to You under the\nterms of this License with the permission of the contributor(s) of those\ncopyrights and patent rights. Except as expressly stated in the immediately\npreceding sentence, the Original Work is provided under this License on an \"AS\nIS\" BASIS and WITHOUT WARRANTY, either express or implied, including, without\nlimitation, the warranties of non-infringement, merchantability or fitness for\na particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK\nIS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this\nLicense. No license to the Original Work is granted by this License except\nunder this disclaimer.\n\n8) Limitation of Liability. Under no circumstances and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise, shall the\nLicensor be liable to anyone for any indirect, special, incidental, or\nconsequential damages of any character arising as a result of this License or\nthe use of the Original Work including, without limitation, damages for loss\nof goodwill, work stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses. This limitation of liability shall not\napply to the extent applicable law prohibits such limitation.\n\n9) Acceptance and Termination. If, at any time, You expressly assented to this\nLicense, that assent indicates your clear and irrevocable acceptance of this\nLicense and all of its terms and conditions. If You distribute or communicate\ncopies of the Original Work or a Derivative Work, You must make a reasonable\neffort under the circumstances to obtain the express assent of recipients to\nthe terms of this License. This License conditions your rights to undertake\nthe activities listed in Section 1, including your right to create Derivative\nWorks based upon the Original Work, and doing so without honoring these terms\nand conditions is prohibited by copyright law and international treaty.\nNothing in this License is intended to affect copyright exceptions and\nlimitations (including \"fair use\" or \"fair dealing\"). This License shall\nterminate immediately and You may no longer exercise any of the rights granted\nto You by this License upon your failure to honor the conditions in Section\n1(c).\n\n10) Termination for Patent Action. This License shall terminate automatically\nand You may no longer exercise any of the rights granted to You by this\nLicense as of the date You commence an action, including a cross-claim or\ncounterclaim, against Licensor or any licensee alleging that the Original Work\ninfringes a patent. This termination provision shall not apply for an action\nalleging patent infringement by combinations of the Original Work with other\nsoftware or hardware.\n\n11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this\nLicense may be brought only in the courts of a jurisdiction wherein the\nLicensor resides or in which Licensor conducts its primary business, and under\nthe laws of that jurisdiction excluding its conflict-of-law provisions. The\napplication of the United Nations Convention on Contracts for the\nInternational Sale of Goods is expressly excluded. Any use of the Original\nWork outside the scope of this License or after its termination shall be\nsubject to the requirements and penalties of copyright or patent law in the\nappropriate jurisdiction. This section shall survive the termination of this\nLicense.\n\n12) Attorneys' Fees. In any action to enforce the terms of this License or\nseeking damages relating thereto, the prevailing party shall be entitled to\nrecover its costs and expenses, including, without limitation, reasonable\nattorneys' fees and costs incurred in connection with such action, including\nany appeal of such action. This section shall survive the termination of this\nLicense.\n\n13) Miscellaneous. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent necessary\nto make it enforceable.\n\n14) Definition of \"You\" in This License. \"You\" throughout this License,\nwhether in upper or lower case, means an individual or a legal entity\nexercising rights under, and complying with all of the terms of, this License.\nFor legal entities, \"You\" includes any entity that controls, is controlled by,\nor is under common control with you. For purposes of this definition,\n\"control\" means (i) the power, direct or indirect, to cause the direction or\nmanagement of such entity, whether by contract or otherwise, or (ii) ownership\nof fifty percent (50%) or more of the outstanding shares, or (iii) beneficial\nownership of such entity.\n\n15) Right to Use. You may use the Original Work in all ways not otherwise\nrestricted or conditioned by this License or by law, and Licensor promises not\nto interfere with or be responsible for such uses by You.\n\n16) Modification of This License. This License is Copyright © 2005 Lawrence\nRosen. Permission is granted to copy, distribute, or communicate this License\nwithout modification. Nothing in this License permits You to modify this\nLicense as applied to the Original Work or to Derivative Works. However, You\nmay modify the text of this License and copy, distribute or communicate your\nmodified version (the \"Modified License\") and apply it to other original works\nof authorship subject to the following conditions: (i) You may not indicate in\nany way that your Modified License is the \"Open Software License\" or \"OSL\" and\nyou may not use those names in the name of your Modified License; (ii) You\nmust replace the notice specified in the first paragraph above with the notice\n\"Licensed under <insert your license name here>\" or with a notice of your own\nthat is not confusingly similar to the notice in this License; and (iii) You\nmay not claim that your original works are open source software unless your\nModified License has been approved by Open Source Initiative (OSI) and You\ncomply with its license review and certification process.\n"
  },
  {
    "path": "README.md",
    "content": "> [!IMPORTANT]\n> ## Project Archival\n> \n> **This project is no longer actively maintained and this repository has been archived.**\n>\n> We want to thank all contributors and users for their support over the project's lifetime. While development has ceased, the code remains available for those who may find it useful.\n\n<div align=\"center\">\n\n  <img src=\"images/bunny_logo.png\" alt=\"Bunny logo\" width=\"200px\" style=\"border-radius: 50%\" />\n  \n  # Bunny Manager\n\n  Easily install Bunny on Android\n\n  [![Latest release](https://img.shields.io/github/v/release/pyoncord/BunnyManager?color=3AB8BA&display_name=release&label=Latest&style=for-the-badge)](https://github.com/pyoncord/BunnyManager/releases/latest)\n  \n  ---\n\n  <br>\n\n  ![Debug build status](https://img.shields.io/github/actions/workflow/status/pyoncord/BunnyManager/build-debug.yml?label=Debug%20Build&logo=github&style=for-the-badge&branch=main)\n  [![Stars](https://img.shields.io/github/stars/pyoncord/BunnyManager?logo=github&style=for-the-badge)](https://github.com/pyoncord/BunnyManager/stargazers)\n  [![Discord](https://img.shields.io/discord/1196075698301968455?logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/XjYgWXHb9Q)\n  \n  <br>\n  \n  ![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/pyoncord/BunnyManager?logo=github&logoColor=%23fff&style=for-the-badge)\n  ![Downloads (latest)](https://img.shields.io/github/downloads/pyoncord/BunnyManager/latest/total?style=for-the-badge&logo=github&label=Downloads%20(Latest)&color=blue)\n  ![Total downloads](https://img.shields.io/github/downloads/pyoncord/BunnyManager/total?style=for-the-badge&logo=github&label=Downloads%20(Total)&color=blue)\n  ![GitHub top language](https://img.shields.io/github/languages/top/pyoncord/BunnyManager?style=for-the-badge)\n\n  <br>\n\n  <img src=\"images/screenshot_home.jpg\" width=\"200px\">\n  \n</div>\n\nBuild\n---\n\n#### Prerequisites\n  - [Git](https://git-scm.com/downloads)\n  - [JDK 17](https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html)\n  - [Android SDK](https://developer.android.com/studio)\n\n#### Instructions\n\n1. Clone the repo\n    - `git clone https://github.com/pyoncord/BunnyManager.git && cd BunnyManager`\n2. Build the project\n    - Linux: `chmod +x ./gradlew && gradlew assembleDebug`\n    - Windows: `./gradlew assembleDebug`\n3. Install on device\n    - [Enable USB debugging](https://developer.android.com/studio/debug/dev-options) and plug in your phone\n    - Run `adb install app/build/outputs/apk/debug/app-debug.apk`\n\n## Contributing\n\nThis is an open-source project, you can do so without any programming.\n\nHere are a few things you can do:\n\n- [Test and report issues](https://github.com/pyoncord/BunnyManager/issues/new/choose)\n<!-- - [Translate the app into your language](https://crowdin.com/project/vendetta-manager) -->\n    \nLicense\n---\nBunny Manager is licensed under the Open Software License version 3.0\n\n[![License: OSL v3](https://img.shields.io/badge/License-OSL%20v3-blue.svg?style=for-the-badge)](https://github.com/pyoncord/BunnyManager/blob/main/LICENSE)\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\n/release"
  },
  {
    "path": "app/build.gradle.kts",
    "content": "import java.io.ByteArrayOutputStream\n\nplugins {\n    alias(libs.plugins.aboutlibraries)\n    alias(libs.plugins.android.application)\n    alias(libs.plugins.kotlin.android)\n    alias(libs.plugins.kotlin.serialization)\n    alias(libs.plugins.compose.compiler)\n}\n\nandroid {\n    namespace = \"dev.beefers.vendetta.manager\"\n    compileSdk = 35\n\n    defaultConfig {\n        applicationId = \"io.github.pyoncord.manager\"\n        minSdk = 28\n        targetSdk = 35\n        versionCode = 1100\n        versionName = \"1.1.0\"\n\n        buildConfigField(\"String\", \"GIT_BRANCH\", \"\\\"${getCurrentBranch()}\\\"\")\n        buildConfigField(\"String\", \"GIT_COMMIT\", \"\\\"${getLatestCommit()}\\\"\")\n        buildConfigField(\"boolean\", \"GIT_LOCAL_COMMITS\", \"${hasLocalCommits()}\")\n        buildConfigField(\"boolean\", \"GIT_LOCAL_CHANGES\", \"${hasLocalChanges()}\")\n\n        testInstrumentationRunner = \"androidx.test.runner.AndroidJUnitRunner\"\n        vectorDrawables {\n            useSupportLibrary = true\n        }\n    }\n\n    buildTypes {\n        named(\"release\") {\n            isCrunchPngs = true\n            isMinifyEnabled = true\n            isShrinkResources = true\n            proguardFiles(\n                getDefaultProguardFile(\"proguard-android-optimize.txt\"),\n                \"proguard-rules.pro\",\n            )\n        }\n    }\n\n    compileOptions {\n        sourceCompatibility = JavaVersion.VERSION_11\n        targetCompatibility = JavaVersion.VERSION_11\n    }\n\n    kotlinOptions {\n        jvmTarget = \"11\"\n        freeCompilerArgs += listOf(\n            \"-Xcontext-receivers\",\n            \"-P\",\n            \"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=\" +\n                    layout.buildDirectory.get().asFile.resolve(\"report\").absolutePath,\n        )\n    }\n\n    buildFeatures {\n        compose = true\n        buildConfig = true\n    }\n\n    composeOptions {\n        kotlinCompilerExtensionVersion = \"1.5.6\"\n    }\n\n    androidComponents {\n        onVariants(selector().withBuildType(\"release\")) {\n            it.packaging.resources.excludes.apply {\n                // Debug metadata\n                add(\"/**/*.version\")\n                add(\"/kotlin-tooling-metadata.json\")\n                // Kotlin debugging (https://github.com/Kotlin/kotlinx.coroutines/issues/2274)\n                add(\"/DebugProbesKt.bin\")\n            }\n        }\n    }\n\n    packaging {\n        resources {\n            // Reflection symbol list (https://stackoverflow.com/a/41073782/13964629)\n            excludes += \"/**/*.kotlin_builtins\"\n        }\n    }\n\n    configurations {\n        all {\n            exclude(module = \"listenablefuture\")\n            exclude(module = \"error_prone_annotations\")\n        }\n    }\n}\n\ndependencies {\n    implementation(platform(libs.compose.bom))\n\n    implementation(libs.bundles.accompanist)\n    implementation(libs.bundles.androidx)\n    implementation(libs.bundles.coil)\n    implementation(libs.bundles.compose)\n    implementation(libs.bundles.koin)\n    implementation(libs.bundles.ktor)\n    implementation(libs.bundles.shizuku)\n    implementation(libs.bundles.voyager)\n\n    implementation(files(\"libs/lspatch.aar\"))\n\n    implementation(libs.aboutlibraries.core)\n    implementation(libs.binaryResources) {\n        exclude(module = \"checker-qual\")\n        exclude(module = \"jsr305\")\n        exclude(module = \"guava\")\n    }\n    implementation(libs.kotlinx.datetime)\n    implementation(libs.kotlinx.collections)\n    implementation(libs.zip.android) {\n        artifact {\n            type = \"aar\"\n        }\n    }\n}\n\nfun getCurrentBranch(): String? =\n    exec(\"git\", \"symbolic-ref\", \"--short\", \"HEAD\")\n\nfun getLatestCommit(): String? =\n    exec(\"git\", \"rev-parse\", \"--short\", \"HEAD\")\n\nfun hasLocalCommits(): Boolean {\n    val branch = getCurrentBranch() ?: return false\n    return exec(\"git\", \"log\", \"origin/$branch..HEAD\")?.isNotBlank() ?: false\n}\n\nfun hasLocalChanges(): Boolean =\n    exec(\"git\", \"status\", \"-s\")?.isNotEmpty() ?: false\n\nfun exec(vararg command: String): String? {\n    return try {\n        val stdout = ByteArrayOutputStream()\n        val errout = ByteArrayOutputStream()\n\n        exec {\n            commandLine = command.toList()\n            standardOutput = stdout\n            errorOutput = errout\n            isIgnoreExitValue = true\n        }\n\n        if(errout.size() > 0)\n            throw Error(errout.toString(Charsets.UTF_8))\n\n        stdout.toString(Charsets.UTF_8).trim()\n    } catch (e: Throwable) {\n        e.printStackTrace()\n        null\n    }\n}\n"
  },
  {
    "path": "app/libs/convert-lspatch.sh",
    "content": "# Download LSPatch jar and convert it to an aar\n# Jars cannot be used as a dependency without breaking R8 optimization\n\n# TODO: update to latest LSPatch\n#LSPATCH_URL=\"https://github.com/LSPosed/LSPatch/releases/download/v0.6/jar-v0.6-398-release.jar\"\n\nLSPATCH_URL=\"https://github.com/vendetta-mod/VendettaManager/raw/5764b16a14c42d8449722f3656b2cb42019b82a8/app/libs/lspatch.jar\"\nLSPATCH_FILE_NAME=\"lspatch\"\n\nfunction cleanup {\n  rm -rf $LSPATCH_FILE_NAME.jar META-INF AndroidManifest.xml classes.jar R.txt\n}\n\ncleanup\n\n# download lspatch\ncurl -sSL -o $LSPATCH_FILE_NAME.jar $LSPATCH_URL\n\n# prepare aar contents\nunzip -q $LSPATCH_FILE_NAME.jar \"META-INF/**\"\nmv $LSPATCH_FILE_NAME.jar classes.jar\ntouch R.txt\ncat >AndroidManifest.xml <<EOF\n<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"org.lsposed.lspatch\">\n    <uses-sdk android:minSdkVersion=\"28\" android:targetSdkVersion=\"34\" />\n</manifest>\nEOF\n\n# add everything to aar\nrm -f $LSPATCH_FILE_NAME.aar\nzip -rq $LSPATCH_FILE_NAME.aar R.txt AndroidManifest.xml META-INF classes.jar\ncleanup\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Keep `Companion` object fields of serializable classes.\n# This avoids serializer lookup through `getDeclaredClasses` as done for named companion objects.\n-if @kotlinx.serialization.Serializable class **\n-keepclassmembers class <1> {\n    static <1>$Companion Companion;\n}\n\n# Keep `serializer()` on companion objects (both default and named) of serializable classes.\n-if @kotlinx.serialization.Serializable class ** {\n    static **$* *;\n}\n-keepclassmembers class <2>$<3> {\n    kotlinx.serialization.KSerializer serializer(...);\n}\n\n# Keep `INSTANCE.serializer()` of serializable objects.\n-if @kotlinx.serialization.Serializable class ** {\n    public static ** INSTANCE;\n}\n-keepclassmembers class <1> {\n    public static <1> INSTANCE;\n    kotlinx.serialization.KSerializer serializer(...);\n}\n\n# @Serializable and @Polymorphic are used at runtime for polymorphic serialization.\n-keepattributes RuntimeVisibleAnnotations,AnnotationDefault\n\n-keepattributes InnerClasses # Needed for `getDeclaredClasses`.\n-keepnames class <1>$$serializer { # -keepnames suffices; class is kept when serializer() is kept.\n    static <1>$$serializer INSTANCE;\n}\n\n# Fix missing apksig annotations and fields\n-keep class com.android.apksig.internal.** { *; }\n\n# Fix LSPatch breaking\n# ref: https://github.com/LSPosed/LSPatch/blob/bbe8d93fb9230f7b04babaf1c4a11642110f55a6/manager/proguard-rules.pro#L12-L18\n-keep class com.beust.jcommander.** { *; }\n-keep class org.lsposed.lspatch.Patcher$Options { *; }\n-keep class org.lsposed.lspatch.share.LSPConfig { *; }\n-keep class org.lsposed.lspatch.share.PatchConfig { *; }\n-keepclassmembers class org.lsposed.patch.LSPatch {\n    private <fields>;\n}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n-keepattributes SourceFile,LineNumberTable\n\n# Keep all names\n-dontobfuscate\n\n# Repackage classes into the top-level.\n-repackageclasses\n\n# Amount of optimization iterations, taken from an SO post\n-optimizationpasses 5\n\n# Broaden access modifiers to increase results during optimization\n-allowaccessmodification\n\n# Ignore missing classes (automatically generated by AGP)\n-dontwarn com.google.auto.value.AutoValue$Builder\n-dontwarn com.google.auto.value.AutoValue\n-dontwarn org.bouncycastle.jsse.BCSSLParameters\n-dontwarn org.bouncycastle.jsse.BCSSLSocket\n-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider\n-dontwarn org.conscrypt.Conscrypt$Version\n-dontwarn org.conscrypt.Conscrypt\n-dontwarn org.conscrypt.ConscryptHostnameVerifier\n-dontwarn org.jetbrains.annotations.ApiStatus$Internal\n-dontwarn org.openjsse.javax.net.ssl.SSLParameters\n-dontwarn org.openjsse.javax.net.ssl.SSLSocket\n-dontwarn org.openjsse.net.ssl.OpenJSSE\n-dontwarn org.slf4j.impl.StaticLoggerBinder\n\n# Can be removed once compose ui artifact is updated to 1.4.0\n# ref: https://issuetracker.google.com/issues/265188224?pli=1\n-keep,allowshrinking class * extends androidx.compose.ui.node.ModifierNodeElement {}"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\" />\n    <uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\" />\n    <uses-permission android:name=\"android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"\n        android:maxSdkVersion=\"32\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"\n        android:maxSdkVersion=\"32\" />\n    <uses-permission android:name=\"android.permission.DOWNLOAD_WITHOUT_NOTIFICATION\" />\n\n    <uses-permission\n        android:name=\"android.permission.MANAGE_EXTERNAL_STORAGE\"\n        tools:ignore=\"ScopedStorage\" />\n    <uses-permission\n        android:name=\"android.permission.REQUEST_DELETE_PACKAGES\"\n        tools:ignore=\"ProtectedPermissions\" />\n    <uses-permission\n        android:name=\"android.permission.DELETE_PACKAGES\"\n        tools:ignore=\"ProtectedPermissions\" />\n    <uses-permission\n        android:name=\"android.permission.QUERY_ALL_PACKAGES\"\n        tools:ignore=\"QueryAllPackagesPermission\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:dataExtractionRules=\"@xml/data_extraction_rules\"\n        android:fullBackupContent=\"@xml/backup_rules\"\n        android:localeConfig=\"@xml/locales_config\"\n        android:largeHeap=\"true\"\n        android:icon=\"@drawable/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@drawable/ic_launcher\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.Manager\"\n        android:name=\".ManagerApplication\"\n        tools:targetApi=\"tiramisu\">\n        <activity\n            android:name=\".ui.activity.MainActivity\"\n            android:exported=\"true\"\n            android:label=\"@string/app_name\"\n            android:theme=\"@style/Theme.Manager.Splash\"\n            android:launchMode=\"singleTask\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"dev.beefers.vendetta.actions.INSTALL\" />\n                <category android:name=\"android.intent.category.OPENABLE\" />\n            </intent-filter>\n        </activity>\n\n        <service android:name=\".installer.session.InstallService\" />\n\n        <receiver android:name=\".domain.receiver.InstallReceiver\"\n            android:exported=\"true\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.PACKAGE_ADDED\" />\n                <action android:name=\"android.intent.action.PACKAGE_REMOVED\" />\n                <action android:name=\"android.intent.action.PACKAGE_CHANGED\" />\n                <data android:scheme=\"package\" />\n            </intent-filter>\n        </receiver>\n\n        <receiver android:name=\".updatechecker.reciever.UpdateBroadcastReceiver\" android:exported=\"false\" />\n\n        <provider\n            android:name=\"rikka.shizuku.ShizukuProvider\"\n            android:authorities=\"${applicationId}.shizuku\"\n            android:multiprocess=\"false\"\n            android:enabled=\"true\"\n            android:exported=\"true\"\n            android:permission=\"android.permission.INTERACT_ACROSS_USERS_FULL\" />\n\n        <provider\n            android:name=\"androidx.core.content.FileProvider\"\n            android:authorities=\"${applicationId}.provider\"\n            android:exported=\"false\"\n            android:grantUriPermissions=\"true\">\n            <meta-data\n                android:name=\"android.support.FILE_PROVIDER_PATHS\"\n                android:resource=\"@xml/provider_paths\"/>\n        </provider>\n\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ManagerApplication.kt",
    "content": "package dev.beefers.vendetta.manager\n\nimport android.app.Application\nimport android.app.NotificationChannel\nimport android.app.NotificationManager\nimport android.content.Context\nimport androidx.work.ExistingPeriodicWorkPolicy\nimport androidx.work.PeriodicWorkRequestBuilder\nimport androidx.work.WorkManager\nimport dev.beefers.vendetta.manager.di.httpModule\nimport dev.beefers.vendetta.manager.di.managerModule\nimport dev.beefers.vendetta.manager.di.repositoryModule\nimport dev.beefers.vendetta.manager.di.viewModelModule\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.domain.manager.UpdateCheckerDuration\nimport dev.beefers.vendetta.manager.updatechecker.worker.UpdateWorker\nimport org.koin.android.ext.android.get\nimport org.koin.android.ext.koin.androidContext\nimport org.koin.core.context.startKoin\n\nclass ManagerApplication : Application() {\n\n    override fun onCreate() {\n        super.onCreate()\n        initNotificationChannels()\n\n        startKoin {\n            androidContext(this@ManagerApplication)\n            modules(\n                httpModule,\n                managerModule,\n                viewModelModule,\n                repositoryModule\n            )\n        }\n\n        val prefs: PreferenceManager = get()\n\n        if (prefs.updateDuration != UpdateCheckerDuration.DISABLED) {\n            val duration = prefs.updateDuration\n            WorkManager.getInstance(applicationContext).enqueueUniquePeriodicWork(\n                \"dev.beefers.vendetta.manager.UPDATE_CHECK\",\n                ExistingPeriodicWorkPolicy.KEEP,\n                PeriodicWorkRequestBuilder<UpdateWorker>(duration.time, duration.unit).build()\n            )\n        }\n    }\n\n    private fun initNotificationChannels() {\n        val nm = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager\n\n        val updates = NotificationChannel(\n            \"${BuildConfig.APPLICATION_ID}.notifications.UPDATE\",\n            \"Discord updates\",\n            NotificationManager.IMPORTANCE_DEFAULT\n        )\n\n        nm.createNotificationChannel(updates)\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/di/HttpModule.kt",
    "content": "package dev.beefers.vendetta.manager.di\n\nimport dev.beefers.vendetta.manager.network.service.HttpService\nimport dev.beefers.vendetta.manager.network.service.RestService\nimport io.ktor.client.HttpClient\nimport io.ktor.client.engine.cio.CIO\nimport io.ktor.client.plugins.contentnegotiation.ContentNegotiation\nimport io.ktor.serialization.kotlinx.json.json\nimport kotlinx.serialization.json.Json\nimport org.koin.core.module.dsl.singleOf\nimport org.koin.dsl.module\n\nval httpModule = module {\n\n    fun provideJson() = Json {\n        ignoreUnknownKeys = true\n        isLenient = true\n    }\n\n    fun provideHttpClient(json: Json) = HttpClient(CIO) {\n        install(ContentNegotiation) {\n            json(json)\n        }\n    }\n\n    singleOf(::provideJson)\n    singleOf(::provideHttpClient)\n    singleOf(::HttpService)\n    singleOf(::RestService)\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/di/ManagerModule.kt",
    "content": "package dev.beefers.vendetta.manager.di\n\nimport dev.beefers.vendetta.manager.domain.manager.DownloadManager\nimport dev.beefers.vendetta.manager.domain.manager.InstallManager\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport org.koin.core.module.dsl.singleOf\nimport org.koin.dsl.module\n\nval managerModule = module {\n    singleOf(::DownloadManager)\n    singleOf(::PreferenceManager)\n    singleOf(::InstallManager)\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/di/RepositoryModule.kt",
    "content": "package dev.beefers.vendetta.manager.di\n\nimport dev.beefers.vendetta.manager.domain.repository.RestRepository\nimport org.koin.core.module.dsl.singleOf\nimport org.koin.dsl.module\n\nval repositoryModule = module {\n    singleOf(::RestRepository)\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/di/ViewModelModule.kt",
    "content": "package dev.beefers.vendetta.manager.di\n\nimport dev.beefers.vendetta.manager.ui.viewmodel.home.HomeViewModel\nimport dev.beefers.vendetta.manager.ui.viewmodel.installer.InstallerViewModel\nimport dev.beefers.vendetta.manager.ui.viewmodel.installer.LogViewerViewModel\nimport dev.beefers.vendetta.manager.ui.viewmodel.libraries.LibrariesViewModel\nimport dev.beefers.vendetta.manager.ui.viewmodel.settings.AdvancedSettingsViewModel\nimport org.koin.core.module.dsl.factoryOf\nimport org.koin.dsl.module\n\nval viewModelModule = module {\n    factoryOf(::InstallerViewModel)\n    factoryOf(::AdvancedSettingsViewModel)\n    factoryOf(::HomeViewModel)\n    factoryOf(::LogViewerViewModel)\n    factoryOf(::LibrariesViewModel)\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/domain/manager/DownloadManager.kt",
    "content": "package dev.beefers.vendetta.manager.domain.manager\n\nimport android.app.DownloadManager\nimport android.content.Context\nimport android.database.Cursor\nimport android.net.Uri\nimport androidx.core.content.getSystemService\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.delay\nimport java.io.File\n\nclass DownloadManager(\n    private val context: Context,\n    private val prefs: PreferenceManager\n) {\n\n    suspend fun downloadDiscordApk(version: String, out: File, onProgressUpdate: (Float?) -> Unit): DownloadResult =\n        download(\"${prefs.mirror.baseUrl}/tracker/download/$version/base\", out, onProgressUpdate)\n\n    suspend fun downloadSplit(version: String, split: String, out: File, onProgressUpdate: (Float?) -> Unit): DownloadResult =\n        download(\"${prefs.mirror.baseUrl}/tracker/download/$version/$split\", out, onProgressUpdate)\n\n    suspend fun downloadVendetta(out: File, onProgressUpdate: (Float?) -> Unit) =\n        download(\n            \"https://github.com/pyoncord/BunnyXposed/releases/latest/download/app-release.apk\",\n            out,\n            onProgressUpdate\n        )\n\n    suspend fun downloadUpdate(out: File) =\n        download(\n            \"https://github.com/pyoncord/BunnyManager/releases/latest/download/Manager.apk\",\n            out\n        ) {\n            /* TODO: Update a progress bar in the update dialog */\n        }\n\n    /**\n     * Start a cancellable download with the system [DownloadManager].\n     * If the current [CoroutineScope] is cancelled, then the system download will be cancelled\n     * almost immediately.\n     * @param url Remote src url\n     * @param out Target path to download to\n     * @param onProgressUpdate Download progress update in a `[0,1]` range, and if null then the\n     *                         download is currently in a pending state. This is called every 100ms.\n     */\n    suspend fun download(\n        url: String,\n        out: File,\n        onProgressUpdate: (Float?) -> Unit\n    ): DownloadResult {\n        val downloadManager = context.getSystemService<DownloadManager>()\n            ?: throw IllegalStateException(\"DownloadManager service is not available\")\n\n        val downloadId = DownloadManager.Request(Uri.parse(url))\n            .setTitle(\"Bunny Manager\")\n            .setDescription(\"Downloading ${out.name}...\")\n            .setDestinationUri(Uri.fromFile(out))\n            .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)\n            .setAllowedOverMetered(true)\n            .setAllowedOverRoaming(true)\n            .let(downloadManager::enqueue)\n\n        // Repeatedly request download state until it is finished\n        while (true) {\n            try {\n                // Hand over control to a suspend function to check for cancellation\n                delay(100)\n            } catch (_: CancellationException) {\n                // If the running CoroutineScope has been cancelled, then gracefully cancel download\n                downloadManager.remove(downloadId)\n                return DownloadResult.Cancelled(systemTriggered = false)\n            }\n\n            // Request download status\n            val cursor = DownloadManager.Query()\n                .setFilterById(downloadId)\n                .let(downloadManager::query)\n\n            // No results in cursor, download was cancelled\n            if (!cursor.moveToFirst()) {\n                cursor.close()\n                return DownloadResult.Cancelled(systemTriggered = true)\n            }\n\n            val statusColumn = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)\n            val status = cursor.getInt(statusColumn)\n\n            cursor.use {\n                when (status) {\n                    DownloadManager.STATUS_PENDING, DownloadManager.STATUS_PAUSED ->\n                        onProgressUpdate(null)\n\n                    DownloadManager.STATUS_RUNNING ->\n                        onProgressUpdate(getDownloadProgress(cursor))\n\n                    DownloadManager.STATUS_SUCCESSFUL ->\n                        return DownloadResult.Success\n\n                    DownloadManager.STATUS_FAILED -> {\n                        val reasonColumn = cursor.getColumnIndex(DownloadManager.COLUMN_REASON)\n                        val reason = cursor.getInt(reasonColumn)\n\n                        return DownloadResult.Error(debugReason = convertErrorCode(reason))\n                    }\n                }\n            }\n        }\n    }\n\n    private fun getDownloadProgress(queryCursor: Cursor): Float? {\n        val bytesColumn = queryCursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)\n        val bytes = queryCursor.getLong(bytesColumn)\n\n        val totalBytesColumn = queryCursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)\n        val totalBytes = queryCursor.getLong(totalBytesColumn)\n\n        if (totalBytes <= 0) return null\n        return bytes.toFloat() / totalBytes\n    }\n\n    private fun convertErrorCode(code: Int) = when (code) {\n        DownloadManager.ERROR_UNKNOWN -> \"UNKNOWN\"\n        DownloadManager.ERROR_FILE_ERROR -> \"FILE_ERROR\"\n        DownloadManager.ERROR_UNHANDLED_HTTP_CODE -> \"UNHANDLED_HTTP_CODE\"\n        DownloadManager.ERROR_HTTP_DATA_ERROR -> \"HTTP_DATA_ERROR\"\n        DownloadManager.ERROR_TOO_MANY_REDIRECTS -> \"TOO_MANY_REDIRECTS\"\n        DownloadManager.ERROR_INSUFFICIENT_SPACE -> \"INSUFFICIENT_SPACE\"\n        DownloadManager.ERROR_DEVICE_NOT_FOUND -> \"DEVICE_NOT_FOUND\"\n        DownloadManager.ERROR_CANNOT_RESUME -> \"CANNOT_RESUME\"\n        DownloadManager.ERROR_FILE_ALREADY_EXISTS -> \"FILE_ALREADY_EXISTS\"\n        /* DownloadManager.ERROR_BLOCKED */ 1010 -> \"NETWORK_BLOCKED\"\n        else -> \"UNKNOWN_CODE\"\n    }\n\n}\n\nsealed interface DownloadResult {\n    data object Success : DownloadResult\n    data class Cancelled(val systemTriggered: Boolean) : DownloadResult\n    data class Error(val debugReason: String) : DownloadResult\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/domain/manager/InstallManager.kt",
    "content": "package dev.beefers.vendetta.manager.domain.manager\n\nimport android.annotation.SuppressLint\nimport android.app.PendingIntent\nimport android.content.Context\nimport android.content.Intent\nimport android.content.pm.PackageInfo\nimport android.content.pm.PackageManager\nimport android.os.Build\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport dev.beefers.vendetta.manager.installer.session.InstallService\n\nclass InstallManager(\n    private val context: Context,\n    private val prefs: PreferenceManager,\n) {\n\n    var current by mutableStateOf<PackageInfo?>(null)\n\n    init {\n        getInstalled()\n    }\n\n    fun getInstalled() {\n        current = try {\n            when {\n                Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {\n                    context.packageManager.getPackageInfo(\n                        prefs.packageName.ifBlank { \"io.github.pyoncord.app\" },\n                        PackageManager.PackageInfoFlags.of(\n                            0L\n                        )\n                    )\n                }\n\n                else -> {\n                    context.packageManager.getPackageInfo(\n                        prefs.packageName.ifBlank { \"io.github.pyoncord.app\" },\n                        0\n                    )\n                }\n            }\n        } catch (e: PackageManager.NameNotFoundException) {\n            null\n        }\n    }\n\n    fun uninstall() {\n        current?.let {\n            val callbackIntent = Intent(context, InstallService::class.java).apply {\n                action = \"vendetta.actions.ACTION_UNINSTALL\"\n            }\n\n            @SuppressLint(\"UnspecifiedImmutableFlag\")\n            val contentIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {\n                PendingIntent.getService(context, 0, callbackIntent, PendingIntent.FLAG_MUTABLE)\n            } else {\n                PendingIntent.getService(context, 0, callbackIntent, 0)\n            }\n\n            context.packageManager.packageInstaller.uninstall(\n                it.packageName,\n                contentIntent.intentSender\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/domain/manager/PreferenceManager.kt",
    "content": "package dev.beefers.vendetta.manager.domain.manager\n\nimport android.content.Context\nimport android.os.Build\nimport android.os.Environment\nimport androidx.annotation.StringRes\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.base.BasePreferenceManager\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport java.io.File\nimport java.util.concurrent.TimeUnit\n\nclass PreferenceManager(context: Context) :\n    BasePreferenceManager(context.getSharedPreferences(\"prefs\", Context.MODE_PRIVATE)) {\n\n    val DEFAULT_MODULE_LOCATION =\n        (context.externalCacheDir ?: File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DOWNLOADS).resolve(\"BunnyManager\").also { it.mkdirs() }).resolve(\"xposed.apk\")\n\n    var packageName by stringPreference(\"package_name\", \"io.github.pyoncord.app\")\n\n    var appName by stringPreference(\"app_name\", \"Bunny\")\n\n    var discordVersion by stringPreference(\"discord_version\", \"\")\n\n    var moduleVersion by stringPreference(\"module_version\", \"\")\n\n    var patchIcon by booleanPreference(\"patch_icon\", true)\n\n    var debuggable by booleanPreference(\"debuggable\", false)\n\n    var mirror by enumPreference(\"mirror\", Mirror.DEFAULT)\n\n    var monet by booleanPreference(\"monet\", Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)\n\n    var isDeveloper by booleanPreference(\"is_developer\", false)\n\n    var autoClearCache by booleanPreference(\"auto_clear_cache\", true)\n\n    var theme by enumPreference(\"theme\", Theme.SYSTEM)\n\n    var channel by enumPreference(\"channel\", DiscordVersion.Type.STABLE)\n\n    var updateDuration by enumPreference(\"update_duration\", UpdateCheckerDuration.HOURLY)\n\n    var moduleLocation by filePreference(\"module_location\", DEFAULT_MODULE_LOCATION)\n\n    var installMethod by enumPreference(\"install_method\", InstallMethod.DEFAULT)\n\n    var logsAlternateBackground by booleanPreference(\"logs_alternate_bg\", true)\n\n    var logsLineWrap by booleanPreference(\"logs_line_wrap\", false)\n\n    var allowDowngrade by booleanPreference(\"allow_downgrade\", false)\n\n    init {\n        // Will be removed next update\n        if(mirror == Mirror.VENDETTA_ROCKS) mirror = Mirror.VENDETTA_ROCKS_ALT\n    }\n\n}\n\nenum class Theme(@StringRes val labelRes: Int) {\n    SYSTEM(R.string.theme_system),\n    LIGHT(R.string.theme_light),\n    DARK(R.string.theme_dark)\n}\n\nenum class UpdateCheckerDuration(@StringRes val labelRes: Int, val time: Long, val unit: TimeUnit) {\n    DISABLED(R.string.duration_disabled, 0, TimeUnit.SECONDS),\n    QUARTERLY(R.string.duration_fifteen_min, 15, TimeUnit.MINUTES),\n    HALF_HOUR(R.string.duration_half_hour, 30, TimeUnit.MINUTES),\n    HOURLY(R.string.duration_hourly, 1, TimeUnit.HOURS),\n    BIHOURLY(R.string.duration_bihourly, 2, TimeUnit.HOURS),\n    TWICE_DAILY(R.string.duration_twice_daily, 12, TimeUnit.HOURS),\n    DAILY(R.string.duration_daily, 1, TimeUnit.DAYS),\n    WEEKLY(R.string.duration_weekly, 7, TimeUnit.DAYS)\n}\n\nenum class Mirror(val baseUrl: String) {\n    DEFAULT(\"https://tracker.vendetta.rocks\"),\n    VENDETTA_ROCKS(\"https://proxy.vendetta.rocks\"), // Temporarily added for compatibility\n    VENDETTA_ROCKS_ALT(\"https://proxy.vendetta.rocks\"),\n    K6(\"https://vd.k6.tf\"),\n    NEXPID(\"https://tracker.vd.nexpid.xyz\")\n}\n\nenum class InstallMethod(@StringRes val labelRes: Int) {\n    DEFAULT(R.string.default_installer),\n    SHIZUKU(R.string.shizuku_installer)\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/domain/manager/base/BasePreferenceManager.kt",
    "content": "package dev.beefers.vendetta.manager.domain.manager.base\n\nimport android.content.SharedPreferences\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.graphics.Color\nimport androidx.core.content.edit\nimport java.io.File\nimport kotlin.reflect.KProperty\n\nabstract class BasePreferenceManager(\n    private val prefs: SharedPreferences\n) {\n    protected fun getString(key: String, defaultValue: String?) =\n        prefs.getString(key, defaultValue)!!\n\n    private fun getBoolean(key: String, defaultValue: Boolean) = prefs.getBoolean(key, defaultValue)\n    private fun getInt(key: String, defaultValue: Int) = prefs.getInt(key, defaultValue)\n    private fun getFloat(key: String, defaultValue: Float) = prefs.getFloat(key, defaultValue)\n    private fun getColor(key: String, defaultValue: Color): Color {\n        val c = prefs.getString(key, null)\n        return if (c == null) defaultValue else Color(c.toULong())\n    }\n\n    private fun getFile(key: String, defaultValue: File) =\n        File(getString(key, defaultValue.absolutePath))\n\n    protected inline fun <reified E : Enum<E>> getEnum(key: String, defaultValue: E) =\n        enumValueOf<E>(getString(key, defaultValue.name))\n\n    protected fun putString(key: String, value: String?) = prefs.edit { putString(key, value) }\n    private fun putBoolean(key: String, value: Boolean) = prefs.edit { putBoolean(key, value) }\n    private fun putInt(key: String, value: Int) = prefs.edit { putInt(key, value) }\n    private fun putFloat(key: String, value: Float) = prefs.edit { putFloat(key, value) }\n    private fun putColor(key: String, value: Color) =\n        prefs.edit { putString(key, value.value.toString()) }\n\n    private fun putFile(key: String, value: File) =\n        putString(key, value.absolutePath)\n\n    protected inline fun <reified E : Enum<E>> putEnum(key: String, value: E) =\n        putString(key, value.name)\n\n    protected class Preference<T>(\n        private val key: String,\n        defaultValue: T,\n        getter: (key: String, defaultValue: T) -> T,\n        private val setter: (key: String, newValue: T) -> Unit\n    ) {\n        @Suppress(\"RedundantSetter\")\n        var value by mutableStateOf(getter(key, defaultValue))\n            private set\n\n        operator fun getValue(thisRef: Any?, property: KProperty<*>) = value\n        operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: T) {\n            value = newValue\n            setter(key, newValue)\n        }\n    }\n\n    protected fun stringPreference(\n        key: String,\n        defaultValue: String = \"\"\n    ) = Preference(\n        key = key,\n        defaultValue = defaultValue,\n        getter = ::getString,\n        setter = ::putString\n    )\n\n    protected fun booleanPreference(\n        key: String,\n        defaultValue: Boolean\n    ) = Preference(\n        key = key,\n        defaultValue = defaultValue,\n        getter = ::getBoolean,\n        setter = ::putBoolean\n    )\n\n    protected fun intPreference(\n        key: String,\n        defaultValue: Int\n    ) = Preference(\n        key = key,\n        defaultValue = defaultValue,\n        getter = ::getInt,\n        setter = ::putInt\n    )\n\n    protected fun floatPreference(\n        key: String,\n        defaultValue: Float\n    ) = Preference(\n        key = key,\n        defaultValue = defaultValue,\n        getter = ::getFloat,\n        setter = ::putFloat\n    )\n\n    protected fun colorPreference(\n        key: String,\n        defaultValue: Color\n    ) = Preference(\n        key = key,\n        defaultValue = defaultValue,\n        getter = ::getColor,\n        setter = ::putColor\n    )\n\n    protected fun filePreference(\n        key: String,\n        defaultValue: File\n    ) = Preference(\n        key = key,\n        defaultValue = defaultValue,\n        getter = ::getFile,\n        setter = ::putFile\n    )\n\n    protected inline fun <reified E : Enum<E>> enumPreference(\n        key: String,\n        defaultValue: E\n    ) = Preference(\n        key = key,\n        defaultValue = defaultValue,\n        getter = ::getEnum,\n        setter = ::putEnum\n    )\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/domain/receiver/InstallReceiver.kt",
    "content": "package dev.beefers.vendetta.manager.domain.receiver\n\nimport android.annotation.SuppressLint\nimport android.content.BroadcastReceiver\nimport android.content.Context\nimport android.content.Intent\nimport dev.beefers.vendetta.manager.domain.manager.InstallManager\nimport org.koin.core.component.KoinComponent\nimport org.koin.core.component.inject\n\nclass InstallReceiver : BroadcastReceiver(), KoinComponent {\n\n    private val installManager: InstallManager by inject()\n\n    @SuppressLint(\"UnsafeProtectedBroadcastReceiver\")\n    override fun onReceive(context: Context?, intent: Intent?) {\n        installManager.getInstalled()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/domain/repository/RestRepository.kt",
    "content": "package dev.beefers.vendetta.manager.domain.repository\n\nimport dev.beefers.vendetta.manager.network.service.RestService\nimport dev.beefers.vendetta.manager.network.utils.transform\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\n\nclass RestRepository(\n    private val service: RestService\n) {\n\n    suspend fun getLatestRelease(repo: String) = service.getLatestRelease(repo)\n\n    suspend fun getLatestDiscordVersions() = service.getLatestDiscordVersions().transform {\n        mapOf(\n            DiscordVersion.Type.ALPHA to DiscordVersion.fromVersionCode(it.latest.alpha),\n            DiscordVersion.Type.BETA to DiscordVersion.fromVersionCode(it.latest.beta),\n            DiscordVersion.Type.STABLE to DiscordVersion.fromVersionCode(it.latest.stable)\n        )\n    }\n\n    suspend fun getCommits(repo: String, page: Int = 1) = service.getCommits(repo, page)\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/Installer.kt",
    "content": "package dev.beefers.vendetta.manager.installer\n\nimport java.io.File\n\ninterface Installer {\n    suspend fun installApks(silent: Boolean = false, vararg apks: File)\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/session/SessionInstaller.kt",
    "content": "package dev.beefers.vendetta.manager.installer.session\n\nimport android.annotation.SuppressLint\nimport android.app.PendingIntent\nimport android.content.Context\nimport android.content.Intent\nimport android.content.pm.PackageInstaller.SessionParams\nimport android.content.pm.PackageManager\nimport android.os.Build\nimport dev.beefers.vendetta.manager.installer.Installer\nimport java.io.File\n\ninternal class SessionInstaller(private val context: Context) : Installer {\n\n    private val packageManager: PackageManager = context.packageManager\n\n    override suspend fun installApks(silent: Boolean, vararg apks: File) {\n        val params = SessionParams(SessionParams.MODE_FULL_INSTALL).apply {\n            if (Build.VERSION.SDK_INT >= 31) {\n                setInstallScenario(PackageManager.INSTALL_SCENARIO_FAST)\n\n                if (silent) {\n                    setRequireUserAction(SessionParams.USER_ACTION_NOT_REQUIRED)\n                }\n            }\n        }\n\n        val packageInstaller = packageManager.packageInstaller\n        val sessionId = packageInstaller.createSession(params)\n        val session = packageInstaller.openSession(sessionId)\n\n        apks.forEach { apk ->\n            session.openWrite(apk.name, 0, apk.length()).use {\n                it.write(apk.readBytes())\n                session.fsync(it)\n            }\n        }\n\n        val callbackIntent = Intent(context, InstallService::class.java).apply {\n            action = \"vendetta.actions.ACTION_INSTALL\"\n        }\n\n        @SuppressLint(\"UnspecifiedImmutableFlag\")\n        val contentIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {\n            PendingIntent.getService(context, 0, callbackIntent, PendingIntent.FLAG_MUTABLE)\n        } else {\n            PendingIntent.getService(context, 0, callbackIntent, 0)\n        }\n\n        session.commit(contentIntent.intentSender)\n        session.close()\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/session/SessionInstallerService.kt",
    "content": "package dev.beefers.vendetta.manager.installer.session\n\nimport android.app.Service\nimport android.content.Intent\nimport android.content.pm.PackageInstaller\nimport android.os.IBinder\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.ui.activity.MainActivity\nimport dev.beefers.vendetta.manager.utils.showToast\n\nclass InstallService : Service() {\n\n    private val messages = mapOf(\n        PackageInstaller.STATUS_FAILURE to R.string.install_fail_generic,\n        PackageInstaller.STATUS_FAILURE_BLOCKED to R.string.install_fail_blocked,\n        PackageInstaller.STATUS_FAILURE_INVALID to R.string.install_fail_invalid,\n        PackageInstaller.STATUS_FAILURE_CONFLICT to R.string.install_fail_conflict,\n        PackageInstaller.STATUS_FAILURE_STORAGE to R.string.install_fail_storage,\n        PackageInstaller.STATUS_FAILURE_INCOMPATIBLE to R.string.install_fail_incompatible,\n        8 /* STATUS_FAILURE_TIMEOUT (Added in Android 14) */ to R.string.install_fail_timeout\n    )\n\n    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {\n        val isInstall = intent.action == \"vendetta.actions.ACTION_INSTALL\"\n        when (val statusCode = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) {\n            PackageInstaller.STATUS_PENDING_USER_ACTION -> {\n                @Suppress(\"DEPRECATION\") // No.\n                val confirmationIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)!!\n                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n\n                startActivity(confirmationIntent)\n            }\n\n            PackageInstaller.STATUS_SUCCESS -> if (isInstall) showToast(R.string.installer_success)\n\n            PackageInstaller.STATUS_FAILURE_ABORTED -> if (isInstall) showToast(R.string.installer_aborted)\n\n            else -> {\n                if (isInstall) {\n                    messages[statusCode]?.let(::showToast)\n\n                    // Send error messages back to the activity for debugging (to be received by InstallerScreen)\n                    startActivity(\n                        Intent(\"vendetta.actions.ACTION_INSTALL_FINISHED\").apply {\n                            setClass(this@InstallService, MainActivity::class.java)\n                            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n                            putExtra(\"vendetta.extras.EXTRA_MESSAGE\", intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE))\n                        }\n                    )\n                }\n            }\n        }\n\n        stopSelf()\n        return START_NOT_STICKY\n    }\n\n    override fun onBind(intent: Intent): IBinder? = null\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/shizuku/ShizukuInstaller.kt",
    "content": "package dev.beefers.vendetta.manager.installer.shizuku\n\nimport android.content.Context\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.InstallManager\nimport dev.beefers.vendetta.manager.installer.Installer\nimport dev.beefers.vendetta.manager.utils.showToast\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport org.koin.core.component.KoinComponent\nimport org.koin.core.component.inject\nimport rikka.shizuku.Shizuku\nimport java.io.File\n\nclass ShizukuInstaller(private val context: Context) : Installer, KoinComponent {\n\n    val installManager: InstallManager by inject()\n\n    override suspend fun installApks(silent: Boolean, vararg apks: File) {\n        if (!ShizukuPermissions.waitShizukuPermissions()) {\n            withContext(Dispatchers.Main) {\n                context.showToast(R.string.msg_shizuku_denied, short = false)\n            }\n\n            throw Error(\"Failed to install due to missing Shizuku permissions\")\n        }\n\n        val tempDir = File(\"/data/local/tmp\")\n        val movedApks = mutableListOf<File>()\n\n        // Copy each split to tmp\n        apks.forEach {\n            val moveCommand = \"cp ${it.absolutePath} ${tempDir.absolutePath}\"\n            val moveResult = executeShellCommand(moveCommand)\n\n            if(moveResult.isBlank())\n                movedApks.add(File(tempDir.absolutePath, it.name))\n            else\n                throw RuntimeException(\"Failed to move ${it.absolutePath} to temp dir\")\n        }\n\n        val installCommand = \"pm install ${movedApks.joinToString(\" \") { it.absolutePath }}\"\n        executeShellCommand(installCommand)\n\n        installManager.getInstalled()\n        movedApks.forEach {\n            it.delete()\n        }\n    }\n\n    private fun executeShellCommand(command: String): String {\n        @Suppress(\"DEPRECATION\")\n        val process = Shizuku.newProcess(arrayOf(\"sh\", \"-c\", command), null, null)\n\n        val errorStr = process.errorStream.bufferedReader().use { it.readText().trim() }\n        if(errorStr.isNotBlank()) throw RuntimeException(\"Failed to execute $command:\\n\\n$errorStr\")\n\n        return process.inputStream.bufferedReader().use { it.readText().trim() }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/shizuku/ShizukuPermissions.kt",
    "content": "package dev.beefers.vendetta.manager.installer.shizuku\n\nimport android.content.pm.PackageManager\nimport kotlinx.coroutines.DelicateCoroutinesApi\nimport kotlinx.coroutines.GlobalScope\nimport kotlinx.coroutines.flow.MutableSharedFlow\nimport kotlinx.coroutines.flow.first\nimport kotlinx.coroutines.launch\nimport rikka.shizuku.Shizuku\nimport rikka.shizuku.Shizuku.OnRequestPermissionResultListener\n\n@OptIn(DelicateCoroutinesApi::class)\nobject ShizukuPermissions {\n\n    private const val REQUEST_CODE = 1\n\n    private val _permissionsGranted = MutableSharedFlow<Boolean>(replay = 0)\n    private lateinit var permissionResultListener: OnRequestPermissionResultListener\n\n    fun requestShizukuPermissions() {\n        if (!Shizuku.pingBinder()) {\n            GlobalScope.launch { _permissionsGranted.emit(false) }\n            return\n        }\n        if (Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) {\n            GlobalScope.launch { _permissionsGranted.emit(true) }\n            return\n        }\n\n        Shizuku.addRequestPermissionResultListener(permissionResultListener)\n        Shizuku.requestPermission(REQUEST_CODE)\n    }\n\n    suspend fun waitShizukuPermissions(): Boolean {\n        requestShizukuPermissions()\n        return _permissionsGranted.first()\n    }\n\n    init {\n        permissionResultListener = OnRequestPermissionResultListener { requestCode, grantResult ->\n            if (requestCode != REQUEST_CODE) return@OnRequestPermissionResultListener\n\n            Shizuku.removeRequestPermissionResultListener(permissionResultListener)\n\n            GlobalScope.launch {\n                _permissionsGranted.emit(grantResult == PackageManager.PERMISSION_GRANTED)\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/Step.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step\n\nimport androidx.annotation.StringRes\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport org.koin.core.component.KoinComponent\nimport kotlin.time.measureTimedValue\n\n/**\n * A distinct step to be ran while patching\n */\n@Stable\nabstract class Step: KoinComponent {\n\n    /**\n     * Group this step belongs to\n     */\n    abstract val group: StepGroup\n\n    /**\n     * Label used in the installer ui\n     */\n    @get:StringRes\n    abstract val nameRes: Int\n\n    /**\n     * Current status for this step\n     */\n    var status by mutableStateOf(StepStatus.QUEUED)\n        protected set\n\n    /**\n     * How much progress this step has made, use null if unknown\n     */\n    var progress by mutableStateOf<Float?>(null)\n        protected set\n\n    /**\n     * How long this step took to run, in milliseconds\n     */\n    var durationMs by mutableIntStateOf(0)\n        private set\n\n    /**\n     * Runs this step\n     *\n     * @param runner The host runner, used to share information between steps\n     */\n    protected abstract suspend fun run(runner: StepRunner)\n\n    /**\n     * Safely runs this step, catching any errors and timing how long it runs.\n     *\n     * @param runner The host runner, used to share information between steps\n     */\n    suspend fun runCatching(runner: StepRunner): Throwable? {\n        if (status != StepStatus.QUEUED)\n            throw IllegalStateException(\"Cannot execute a step that has already started\")\n\n        status = StepStatus.ONGOING\n\n        val (error, time) = measureTimedValue {\n            try {\n                run(runner)\n                status = StepStatus.SUCCESSFUL\n                null\n            } catch (t: Throwable) {\n                status = StepStatus.UNSUCCESSFUL\n                t\n            }\n        }\n\n        durationMs = time.inWholeMilliseconds.toInt()\n        return error\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/StepGroup.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step\n\nimport androidx.annotation.StringRes\nimport dev.beefers.vendetta.manager.R\n\n/**\n * Represents a group of [Step]s\n */\nenum class StepGroup(@StringRes val nameRes: Int) {\n    /**\n     * All steps deal with downloading files remotely\n     */\n    DL(R.string.group_download),\n\n    /**\n     * Steps that modify the APKs\n     */\n    PATCHING(R.string.group_patch),\n\n    /**\n     * Only contains the [install step][dev.beefers.vendetta.manager.installer.step.installing.InstallStep]\n     */\n    INSTALLING(R.string.group_installing)\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/StepRunner.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step\n\nimport android.content.Context\nimport android.os.Build\nimport android.os.Environment\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport dev.beefers.vendetta.manager.BuildConfig\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadBaseStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadLangStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadLibsStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadResourcesStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadVendettaStep\nimport dev.beefers.vendetta.manager.installer.step.installing.InstallStep\nimport dev.beefers.vendetta.manager.installer.step.patching.AddVendettaStep\nimport dev.beefers.vendetta.manager.installer.step.patching.PatchManifestsStep\nimport dev.beefers.vendetta.manager.installer.step.patching.PresignApksStep\nimport dev.beefers.vendetta.manager.installer.step.patching.ReplaceIconStep\nimport dev.beefers.vendetta.manager.installer.util.LogEntry\nimport dev.beefers.vendetta.manager.installer.util.Logger\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport kotlinx.collections.immutable.ImmutableList\nimport kotlinx.collections.immutable.toImmutableList\nimport kotlinx.coroutines.delay\nimport org.koin.core.component.KoinComponent\nimport org.koin.core.component.inject\nimport java.io.File\n\n/**\n * Runs all installation steps in order\n *\n * Credit to rushii (github.com/rushiiMachine)\n *\n * @param discordVersion Version of Discord to inject Vendetta into\n */\n@Stable\nclass StepRunner(\n    private val discordVersion: DiscordVersion\n): KoinComponent {\n\n    private val preferenceManager: PreferenceManager by inject()\n    private val context: Context by inject()\n    private val debugInfo = \"\"\"\n            Bunny Manager v${BuildConfig.VERSION_NAME}\n            Built from commit ${BuildConfig.GIT_COMMIT} on ${BuildConfig.GIT_BRANCH} ${if (BuildConfig.GIT_LOCAL_CHANGES || BuildConfig.GIT_LOCAL_COMMITS) \"(Changes Present)\" else \"\"}\n            \n            Running Android ${Build.VERSION.RELEASE}, API level ${Build.VERSION.SDK_INT}\n            Supported ABIs: ${Build.SUPPORTED_ABIS.joinToString()}\n            Device: ${Build.MANUFACTURER} - ${Build.MODEL} (${Build.DEVICE})\n            ${if(Build.VERSION.SDK_INT > Build.VERSION_CODES.S) \"SOC: ${Build.SOC_MANUFACTURER} ${Build.SOC_MODEL}\\n\" else \"\\n\\n\"} \n            Adding Bunny to Discord v$discordVersion\n            \n            \n        \"\"\".trimIndent()\n\n    /**\n     * Logger associated with this runner\n     */\n    val logger = Logger(\"StepRunner\").also { logger ->\n        debugInfo.split(\"\\n\").forEach {\n            logger.logs += LogEntry(it, LogEntry.Level.INFO) // Add debug information to logs but don't print to logcat\n        }\n    }\n\n    /**\n     * Root directory for all downloaded files\n     */\n    private val cacheDir =\n        context.externalCacheDir\n        ?: File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DOWNLOADS)\n            .resolve(\"BunnyManager\")\n            .also { it.mkdirs() }\n\n    /**\n     * Where version specific downloads are persisted\n     */\n    private val discordCacheDir = cacheDir.resolve(discordVersion.toVersionCode())\n\n    /**\n     * Working directory where apks are directly modified (i.e. replacing the app icon)\n     */\n    private val patchedDir = discordCacheDir.resolve(\"patched\").also { it.deleteRecursively() }\n\n    /**\n     * Where apks are moved to once signed\n     */\n    private val signedDir = discordCacheDir.resolve(\"signed\").also { it.deleteRecursively() }\n\n    /**\n     * Output directory for LSPatch\n     */\n    private val lspatchedDir = patchedDir.resolve(\"lspatched\").also { it.deleteRecursively() }\n\n    var currentStep by mutableStateOf<Step?>(null)\n        private set\n\n    /**\n     * Whether or not the patching/installation process has completed.\n     * Note that this does not mean all steps were finished successfully\n     */\n    var completed by mutableStateOf(false)\n        private set\n\n    /**\n     * Whether or not a download step failed, this is only for errors related to network conditions and not cancellations\n     */\n    var downloadErrored by mutableStateOf(false)\n\n    /**\n     * List of steps to go through for this install\n     *\n     * ORDER MATTERS\n     */\n    val steps: ImmutableList<Step> = buildList {\n        // Downloading\n        add(DownloadBaseStep(discordCacheDir, patchedDir, discordVersion.toVersionCode()))\n        add(DownloadLibsStep(discordCacheDir, patchedDir, discordVersion.toVersionCode()))\n        add(DownloadLangStep(discordCacheDir, patchedDir, discordVersion.toVersionCode()))\n        add(DownloadResourcesStep(discordCacheDir, patchedDir, discordVersion.toVersionCode()))\n        add(DownloadVendettaStep(patchedDir))\n\n        // Patching\n        if (preferenceManager.patchIcon) add(ReplaceIconStep())\n        add(PatchManifestsStep())\n        add(PresignApksStep(signedDir))\n        add(AddVendettaStep(signedDir, lspatchedDir))\n\n        // Installing\n        add(InstallStep(lspatchedDir))\n    }.toImmutableList()\n\n    /**\n     * Get a step that has already been successfully executed.\n     * This is used to retrieve previously executed dependency steps from a later step.\n     */\n    inline fun <reified T : Step> getCompletedStep(): T {\n        val step = steps.asSequence()\n            .filterIsInstance<T>()\n            .filter { it.status == StepStatus.SUCCESSFUL }\n            .firstOrNull()\n\n        if (step == null) {\n            throw IllegalArgumentException(\"No completed step ${T::class.simpleName} exists in container\")\n        }\n\n        return step\n    }\n\n    /**\n     * Clears all cached files\n     */\n    fun clearCache() {\n        cacheDir.deleteRecursively()\n    }\n\n    /**\n     * Run all the [steps] in order\n     */\n    suspend fun runAll(): Throwable? {\n        for (step in steps) {\n            if (completed) return null // Failsafe in case runner is incorrectly marked as not completed too early\n\n            currentStep = step\n            val error = step.runCatching(this)\n            if (error != null) {\n                logger.e(\"Failed on ${step::class.simpleName}\", error)\n\n                completed = true\n                return error\n            }\n\n            // Add delay for human psychology and\n            // better group visibility in UI (the active group can change way too fast)\n            if (!preferenceManager.isDeveloper && step.durationMs < 1000) {\n                delay(1000L - step.durationMs)\n            }\n        }\n\n        completed = true\n        return null\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/StepStatus.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step\n\nenum class StepStatus {\n    /**\n     * Currently in progress\n     */\n    ONGOING,\n\n    /**\n     * Completed with no errors\n     */\n    SUCCESSFUL,\n\n    /**\n     * Completed with an error\n     */\n    UNSUCCESSFUL,\n\n    /**\n     * Has not yet been ran\n     */\n    QUEUED\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/download/DownloadBaseStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.download\n\nimport androidx.compose.runtime.Stable\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.download.base.DownloadStep\nimport java.io.File\n\n/**\n * Downloads the base Discord APK\n */\n@Stable\nclass DownloadBaseStep(\n    dir: File,\n    workingDir: File,\n    version: String\n): DownloadStep() {\n\n    override val nameRes = R.string.step_dl_base\n\n    override val url: String = \"$baseUrl/tracker/download/$version/base\"\n    override val destination = dir.resolve(\"base-$version.apk\")\n    override val workingCopy = workingDir.resolve(\"base-$version.apk\")\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/download/DownloadLangStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.download\n\nimport androidx.compose.runtime.Stable\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.download.base.DownloadStep\nimport java.io.File\n\n/**\n * Downloads the languages split, will always be English because Discord doesn't store their strings in this split\n */\n@Stable\nclass DownloadLangStep(\n    dir: File,\n    workingDir: File,\n    version: String\n): DownloadStep() {\n\n    override val nameRes = R.string.step_dl_lang\n\n    override val url: String = \"$baseUrl/tracker/download/$version/config.en\"\n    override val destination = dir.resolve(\"config.en-$version.apk\")\n    override val workingCopy = workingDir.resolve(\"config.en-$version.apk\")\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/download/DownloadLibsStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.download\n\nimport android.os.Build\nimport androidx.compose.runtime.Stable\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.download.base.DownloadStep\nimport java.io.File\n\n/**\n * Downloads the split containing the native libraries for the current devices architecture\n */\n@Stable\nclass DownloadLibsStep(\n    dir: File,\n    workingDir: File,\n    version: String\n): DownloadStep() {\n\n    /**\n     * Supported CPU architecture for this device, used to download the correct library split\n     */\n    private val arch = Build.SUPPORTED_ABIS.first().replace(\"-v\", \"_v\")\n\n    override val nameRes = R.string.step_dl_lib\n\n    override val url: String = \"$baseUrl/tracker/download/$version/config.$arch\"\n    override val destination = dir.resolve(\"config.$arch-$version.apk\")\n    override val workingCopy = workingDir.resolve(\"config.$arch-$version.apk\")\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/download/DownloadResourcesStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.download\n\nimport androidx.compose.runtime.Stable\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.download.base.DownloadStep\nimport java.io.File\n\n/**\n * Downloads the split containing all images, fonts, and other assets\n */\n@Stable\nclass DownloadResourcesStep(\n    dir: File,\n    workingDir: File,\n    version: String\n): DownloadStep() {\n\n    override val nameRes = R.string.step_dl_res\n\n    override val url: String = \"$baseUrl/tracker/download/$version/config.xxhdpi\"\n    override val destination = dir.resolve(\"config.xxhdpi-$version.apk\")\n    override val workingCopy = workingDir.resolve(\"config.xxhdpi-$version.apk\")\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/download/DownloadVendettaStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.download\n\nimport androidx.compose.runtime.Stable\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.download.base.DownloadStep\nimport java.io.File\n\n/**\n * Downloads the Vendetta XPosed module\n *\n * https://github.com/pyoncord/BunnyXposed\n */\n@Stable\nclass DownloadVendettaStep(\n    workingDir: File\n): DownloadStep() {\n\n    override val nameRes = R.string.step_dl_vd\n\n    override val url: String = \"https://github.com/pyoncord/BunnyXposed/releases/latest/download/app-release.apk\"\n    override val destination = preferenceManager.moduleLocation\n    override val workingCopy = workingDir.resolve(\"xposed.apk\")\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/download/base/DownloadStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.download.base\n\nimport android.content.Context\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.DownloadManager\nimport dev.beefers.vendetta.manager.domain.manager.DownloadResult\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.installer.step.Step\nimport dev.beefers.vendetta.manager.installer.step.StepGroup\nimport dev.beefers.vendetta.manager.installer.step.StepRunner\nimport dev.beefers.vendetta.manager.installer.step.StepStatus\nimport dev.beefers.vendetta.manager.utils.mainThread\nimport dev.beefers.vendetta.manager.utils.showToast\nimport kotlinx.coroutines.CancellationException\nimport org.koin.core.component.inject\nimport java.io.File\nimport kotlin.math.roundToInt\n\n/**\n * Specialized step used to download a file\n *\n * Files are downloaded to [destination] then copied to [workingCopy] for safe patching\n */\n@Stable\nabstract class DownloadStep: Step() {\n\n    protected val preferenceManager: PreferenceManager by inject()\n    protected val baseUrl = preferenceManager.mirror.baseUrl\n\n    private val downloadManager: DownloadManager by inject()\n    private val context: Context by inject()\n\n    /**\n     * Url of the desired file to download\n     */\n    abstract val url: String\n\n    /**\n     * Where to download the file to\n     */\n    abstract val destination: File\n\n    /**\n     * Where the downloaded file should be copied to so that it can be used for patching\n     */\n    abstract val workingCopy: File\n\n    override val group: StepGroup = StepGroup.DL\n\n    var cached by mutableStateOf(false)\n        private set\n\n    /**\n     * Verifies that a file was properly downloaded\n     */\n    open suspend fun verify() {\n        if (!destination.exists())\n            error(\"Downloaded file is missing: ${destination.absolutePath}\")\n\n        if (destination.length() <= 0)\n            error(\"Downloaded file is empty: ${destination.absolutePath}\")\n    }\n\n    override suspend fun run(runner: StepRunner) {\n        val fileName = destination.name\n        runner.logger.i(\"Checking if $fileName is cached\")\n        if (destination.exists()) {\n            runner.logger.i(\"Checking if $fileName isn't empty\")\n            if (destination.length() > 0) {\n                runner.logger.i(\"$fileName is cached\")\n                cached = true\n\n                runner.logger.i(\"Moving $fileName to working directory\")\n                destination.copyTo(workingCopy, true)\n\n                status = StepStatus.SUCCESSFUL\n                return\n            }\n\n            runner.logger.i(\"Deleting empty file: $fileName\")\n            destination.delete()\n        }\n\n        runner.logger.i(\"$fileName was not properly cached, downloading now\")\n        var lastProgress: Float? = null\n        val result = downloadManager.download(url, destination) { newProgress ->\n            progress = newProgress\n            if (newProgress != lastProgress && newProgress != null) {\n                lastProgress = newProgress\n                runner.logger.d(\"$fileName download progress: ${(lastProgress!! * 100f).roundToInt()}%\")\n            }\n        }\n\n        when (result) {\n            is DownloadResult.Success -> {\n                try {\n                    runner.logger.i(\"Verifying downloaded file\")\n                    verify()\n                    runner.logger.i(\"$fileName downloaded successfully\")\n                } catch (t: Throwable) {\n                    mainThread {\n                        context.showToast(R.string.msg_download_verify_failed)\n                    }\n\n                    throw t\n                }\n                runner.logger.i(\"Moving $fileName to working directory\")\n                destination.copyTo(workingCopy, true)\n            }\n\n            is DownloadResult.Error -> {\n                mainThread {\n                    context.showToast(R.string.msg_download_failed)\n                    runner.downloadErrored = true\n                }\n\n                throw Error(\"Failed to download: ${result.debugReason}\")\n            }\n\n            is DownloadResult.Cancelled -> {\n                status = StepStatus.UNSUCCESSFUL\n                throw CancellationException(\"$fileName download cancelled\")\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/installing/InstallStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.installing\n\nimport android.content.Context\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.InstallMethod\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.installer.Installer\nimport dev.beefers.vendetta.manager.installer.session.SessionInstaller\nimport dev.beefers.vendetta.manager.installer.shizuku.ShizukuInstaller\nimport dev.beefers.vendetta.manager.installer.step.Step\nimport dev.beefers.vendetta.manager.installer.step.StepGroup\nimport dev.beefers.vendetta.manager.installer.step.StepRunner\nimport dev.beefers.vendetta.manager.utils.isMiui\nimport org.koin.core.component.inject\nimport java.io.File\n\n/**\n * Installs all the modified splits with the users desired [Installer]\n *\n * @see SessionInstaller\n * @see ShizukuInstaller\n *\n * @param lspatchedDir Where all the patched APKs are\n */\nclass InstallStep(\n    private val lspatchedDir: File\n): Step() {\n\n    private val preferences: PreferenceManager by inject()\n    private val context: Context by inject()\n\n    override val group = StepGroup.INSTALLING\n    override val nameRes = R.string.step_installing\n\n    override suspend fun run(runner: StepRunner) {\n        runner.logger.i(\"Installing apks\")\n        val files = lspatchedDir.listFiles()\n            ?.takeIf { it.isNotEmpty() }\n            ?: throw Error(\"Missing APKs from LSPatch step; failure likely\")\n\n        val installer: Installer = when (preferences.installMethod) {\n            InstallMethod.DEFAULT -> SessionInstaller(context)\n            InstallMethod.SHIZUKU -> ShizukuInstaller(context)\n        }\n\n        installer.installApks(silent = !isMiui, *files)\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/patching/AddVendettaStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.patching\n\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.Step\nimport dev.beefers.vendetta.manager.installer.step.StepGroup\nimport dev.beefers.vendetta.manager.installer.step.StepRunner\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadVendettaStep\nimport dev.beefers.vendetta.manager.installer.util.Patcher\nimport java.io.File\n\n/**\n * Uses LSPatch to inject the Vendetta XPosed module into Discord\n *\n * @param signedDir The signed apks to patch\n * @param lspatchedDir Output directory for LSPatch\n */\nclass AddVendettaStep(\n    private val signedDir: File,\n    private val lspatchedDir: File\n) : Step() {\n\n    override val group = StepGroup.PATCHING\n    override val nameRes = R.string.step_add_vd\n\n    override suspend fun run(runner: StepRunner) {\n        val vendetta = runner.getCompletedStep<DownloadVendettaStep>().workingCopy\n\n        runner.logger.i(\"Adding BunnyXposed module with LSPatch\")\n        val files = signedDir.listFiles()\n            ?.takeIf { it.isNotEmpty() }\n            ?: throw Error(\"Missing APKs from signing step\")\n\n        Patcher.patch(\n            runner.logger,\n            outputDir = lspatchedDir,\n            apkPaths = files.map { it.absolutePath },\n            embeddedModules = listOf(vendetta.absolutePath)\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/patching/PatchManifestsStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.patching\n\nimport com.github.diamondminer88.zip.ZipReader\nimport com.github.diamondminer88.zip.ZipWriter\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.installer.step.Step\nimport dev.beefers.vendetta.manager.installer.step.StepGroup\nimport dev.beefers.vendetta.manager.installer.step.StepRunner\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadBaseStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadLangStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadLibsStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadResourcesStep\nimport dev.beefers.vendetta.manager.installer.util.ManifestPatcher\nimport org.koin.core.component.inject\n\n/**\n * Modifies each APKs manifest in order to change the package and app name as well as whether or not its debuggable\n */\nclass PatchManifestsStep : Step() {\n\n    private val preferences: PreferenceManager by inject()\n\n    override val group = StepGroup.PATCHING\n    override val nameRes = R.string.step_patch_manifests\n\n    override suspend fun run(runner: StepRunner) {\n        val baseApk = runner.getCompletedStep<DownloadBaseStep>().workingCopy\n        val libsApk = runner.getCompletedStep<DownloadLibsStep>().workingCopy\n        val langApk = runner.getCompletedStep<DownloadLangStep>().workingCopy\n        val resApk = runner.getCompletedStep<DownloadResourcesStep>().workingCopy\n\n        arrayOf(baseApk, libsApk, langApk, resApk).forEach { apk ->\n            runner.logger.i(\"Reading AndroidManifest.xml from ${apk.name}\")\n            val manifest = ZipReader(apk)\n                .use { zip -> zip.openEntry(\"AndroidManifest.xml\")?.read() }\n                ?: throw IllegalStateException(\"No manifest in ${apk.name}\")\n\n            ZipWriter(apk, true).use { zip ->\n                runner.logger.i(\"Changing package and app name in ${apk.name}\")\n                val patchedManifestBytes = if (apk == baseApk) {\n                    ManifestPatcher.patchManifest(\n                        manifestBytes = manifest,\n                        packageName = preferences.packageName,\n                        appName = preferences.appName,\n                        debuggable = preferences.debuggable,\n                    )\n                } else {\n                    runner.logger.i(\"Changing package name in ${apk.name}\")\n                    ManifestPatcher.renamePackage(manifest, preferences.packageName)\n                }\n\n                runner.logger.i(\"Deleting old AndroidManifest.xml in ${apk.name}\")\n                zip.deleteEntry(\n                    \"AndroidManifest.xml\",\n                    /* fillVoid = */ apk == libsApk || apk == baseApk\n                ) // Preserve alignment in libs apk\n\n                runner.logger.i(\"Adding patched AndroidManifest.xml in ${apk.name}\")\n                zip.writeEntry(\"AndroidManifest.xml\", patchedManifestBytes)\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/patching/PresignApksStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.patching\n\nimport android.os.Build\nimport com.github.diamondminer88.zip.ZipCompression\nimport com.github.diamondminer88.zip.ZipReader\nimport com.github.diamondminer88.zip.ZipWriter\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.Step\nimport dev.beefers.vendetta.manager.installer.step.StepGroup\nimport dev.beefers.vendetta.manager.installer.step.StepRunner\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadBaseStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadLangStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadLibsStep\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadResourcesStep\nimport dev.beefers.vendetta.manager.installer.util.Signer\nimport java.io.File\n\n/**\n * Sign all patched apks before being ran through LSPatch, this is required due to LSPatch not liking unsigned apks.\n *\n * @param signedDir Where to output all signed apks\n */\nclass PresignApksStep(\n    private val signedDir: File\n) : Step() {\n\n    override val group = StepGroup.PATCHING\n    override val nameRes = R.string.step_signing\n\n    override suspend fun run(runner: StepRunner) {\n        val baseApk = runner.getCompletedStep<DownloadBaseStep>().workingCopy\n        val libsApk = runner.getCompletedStep<DownloadLibsStep>().workingCopy\n        val langApk = runner.getCompletedStep<DownloadLangStep>().workingCopy\n        val resApk = runner.getCompletedStep<DownloadResourcesStep>().workingCopy\n\n        runner.logger.i(\"Creating dir for signed apks: ${signedDir.absolutePath}\")\n        signedDir.mkdirs()\n        val apks = listOf(baseApk, libsApk, langApk, resApk)\n\n        // Align resources.arsc due to targeting api 30 for silent install\n        if(Build.VERSION.SDK_INT >= 30) {\n            for (file in apks) {\n                runner.logger.i(\"Byte aligning ${file.name}\")\n                val bytes = ZipReader(file).use {\n                    if (it.entryNames.contains(\"resources.arsc\")) {\n                        it.openEntry(\"resources.arsc\")?.read()\n                    } else {\n                        null\n                    }\n                } ?: continue\n\n                ZipWriter(file, true).use {\n                    runner.logger.i(\"Removing old resources.arsc\")\n                    it.deleteEntry(\"resources.arsc\", true)\n\n                    runner.logger.i(\"Adding aligned resources.arsc\")\n                    it.writeEntry(\"resources.arsc\", bytes, ZipCompression.NONE, 4096)\n                }\n            }\n        }\n\n        apks.forEach {\n            runner.logger.i(\"Signing ${it.name}\")\n            Signer.signApk(it, File(signedDir, it.name))\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/step/patching/ReplaceIconStep.kt",
    "content": "package dev.beefers.vendetta.manager.installer.step.patching\n\nimport android.content.Context\nimport androidx.compose.ui.graphics.Color\nimport com.github.diamondminer88.zip.ZipWriter\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.installer.step.Step\nimport dev.beefers.vendetta.manager.installer.step.StepGroup\nimport dev.beefers.vendetta.manager.installer.step.StepRunner\nimport dev.beefers.vendetta.manager.installer.step.download.DownloadBaseStep\nimport dev.beefers.vendetta.manager.installer.util.ArscUtil\nimport dev.beefers.vendetta.manager.installer.util.ArscUtil.addColorResource\nimport dev.beefers.vendetta.manager.installer.util.ArscUtil.getMainArscChunk\nimport dev.beefers.vendetta.manager.installer.util.ArscUtil.getPackageChunk\nimport dev.beefers.vendetta.manager.installer.util.ArscUtil.getResourceFileName\nimport dev.beefers.vendetta.manager.installer.util.AxmlUtil\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport org.koin.core.component.inject\n\n/**\n * Replaces the existing app icons with Vendetta tinted ones\n */\nclass ReplaceIconStep : Step() {\n\n    private val preferences: PreferenceManager by inject()\n\n    val context: Context by inject()\n\n    override val group = StepGroup.PATCHING\n    override val nameRes = R.string.step_change_icon\n\n    override suspend fun run(runner: StepRunner) {\n        val baseApk = runner.getCompletedStep<DownloadBaseStep>().workingCopy\n\n        runner.logger.i(\"Reading resources.arsc\")\n        val arsc = ArscUtil.readArsc(baseApk)\n        \n        val iconRscIds = AxmlUtil.readManifestIconInfo(baseApk)\n        val squareIconFile = arsc.getMainArscChunk().getResourceFileName(iconRscIds.squareIcon, \"anydpi-v26\")\n        val roundIconFile = arsc.getMainArscChunk().getResourceFileName(iconRscIds.roundIcon, \"anydpi-v26\")\n\n        runner.logger.i(\"Patching icon assets (squareIcon=$squareIconFile, roundIcon=$roundIconFile)\")\n\n        val backgroundColor = arsc.getPackageChunk().addColorResource(\"bunny_color\", Color(0xFF48488B))\n\n        val postfix = when (preferences.channel) {\n            DiscordVersion.Type.BETA -> \"beta\"\n            DiscordVersion.Type.ALPHA -> \"canary\"\n            else -> null\n        }\n        \n        for (rscFile in setOf(squareIconFile, roundIconFile)) { // setOf to not possibly patch same file twice\n            val referencePath = if (postfix == null) rscFile else {\n                rscFile.replace(\"_$postfix.xml\", \".xml\")\n            }\n\n            runner.logger.i(\"Patching adaptive icon ($rscFile <- $referencePath)\")\n\n            AxmlUtil.patchAdaptiveIcon(\n                apk = baseApk,\n                resourcePath = rscFile,\n                referencePath = referencePath,\n                backgroundColor = backgroundColor,\n            )\n        }\n\n        runner.logger.i(\"Writing and compiling resources.arsc\")\n        ZipWriter(baseApk, /* append = */ true).use {\n            it.deleteEntry(\"resources.arsc\")\n            it.writeEntry(\"resources.arsc\", arsc.toByteArray())\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/util/ArscUtil.kt",
    "content": "// https://github.com/Aliucord/Manager/blob/main/app/src/main/kotlin/com/aliucord/manager/installer/util/ArscUtil.kt\npackage dev.beefers.vendetta.manager.installer.util\n\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.toArgb\nimport com.github.diamondminer88.zip.ZipReader\nimport com.google.devrel.gmscore.tools.apk.arsc.*\nimport dev.beefers.vendetta.manager.BuildConfig\nimport java.io.File\n\nobject ArscUtil {\n    /**\n     * Read and parse `resources.arsc` from an APK.\n     */\n    fun readArsc(apk: File): BinaryResourceFile {\n        val bytes = ZipReader(apk).use { it.openEntry(\"resources.arsc\")?.read() }\n            ?: error(\"APK missing resources.arsc\")\n\n        return try {\n            BinaryResourceFile(bytes)\n        } catch (t: Throwable) {\n            throw Error(\"Failed to parse resources.arsc\", t)\n        }\n    }\n\n    /**\n     * Get the only top-level chunk in an arsc file.\n     */\n    fun BinaryResourceFile.getMainArscChunk(): ResourceTableChunk {\n        if (this.chunks.size > 1)\n            error(\"More than 1 top level chunk in resources.arsc\")\n\n        return this.chunks.first() as? ResourceTableChunk\n            ?: error(\"Invalid top-level resources.arsc chunk\")\n    }\n\n    /**\n     * Get a singular package chunk in an arsc file.\n     */\n    fun BinaryResourceFile.getPackageChunk(): PackageChunk {\n        return this.getMainArscChunk().packages.singleOrNull()\n            ?: error(\"resources.arsc must contain exactly 1 package chunk\")\n    }\n\n    /**\n     * Adds a new color resource to all configuration variants in an arsc package.\n     *\n     * @param name The new resource name.\n     * @param color The value of the new color resource.\n     * @return The resource ID of the newly added resource.\n     */\n    fun PackageChunk.addColorResource(\n        name: String,\n        color: Color,\n    ): BinaryResourceIdentifier {\n        return this.addResource(\n            typeName = \"color\",\n            resourceName = name,\n            configurations = { true },\n            valueType = BinaryResourceValue.Type.INT_COLOR_ARGB8,\n            valueData = color.toArgb(),\n        )\n    }\n\n    /**\n     * Adds a new color resource to the matching configuration variants in an arsc package.\n     *\n     * @param typeName The type of the resource (ex: `mipmap`, `drawable`, etc.)\n     * @param resourceName The new resource name.\n     * @param configurations A predicate whether to add the value into a matching type chunk.\n     * @param valueType The type of the resource value.\n     * @param valueData The raw data of the resource value.\n     * @return The resource ID of the newly added resource.\n     */\n    fun PackageChunk.addResource(\n        typeName: String,\n        resourceName: String,\n        configurations: (BinaryResourceConfiguration) -> Boolean,\n        valueType: BinaryResourceValue.Type,\n        valueData: Int,\n    ): BinaryResourceIdentifier {\n        // Add a new resource entry to the \"type spec chunk\" and,\n        // a new resource entry to all matching \"type chunks\"\n\n        val specChunk = this.getTypeSpecChunk(typeName)\n        val typeChunks = this.getTypeChunks(typeName)\n\n        // Add a new string to the pool to be used as a key\n        val resourceNameIdx = this.keyStringPool.addString(resourceName, /* deduplicate = */ true)\n\n        // Add a new resource entry to the type spec chunk\n\t    // HACK: Resource index returned by addResource is off by 1 in release builds due to optimizations or something\n        val resourceIdx = specChunk.addResource(/* flags = */ 0) + if (BuildConfig.DEBUG) 0 else 1\n\n        for (typeChunk in typeChunks) {\n            // If no matching config, add a null entry and try next chunk\n            if (!configurations(typeChunk.configuration)) {\n                typeChunk.addEntry(null)\n                continue\n            }\n\n            val entry = TypeChunk.Entry(\n                /* headerSize = */ 8,\n                /* flags = */ 0,\n                /* keyIndex = */ resourceNameIdx,\n                /* value = */\n                BinaryResourceValue(\n                    /* type = */ valueType,\n                    /* data = */ valueData,\n                ),\n                /* values = */ null, // not a complex resource\n                /* parentEntry = */ 0, // not a complex resource\n                /* parent = */ typeChunk,\n            )\n\n            typeChunk.addEntry(entry)\n        }\n\n        return BinaryResourceIdentifier.create(\n            /* packageId = */ this.id,\n            /* typeId = */ specChunk.id,\n            /* entryId = */ resourceIdx,\n        )\n    }\n\n    /**\n     * In an arsc file, for a specific resource in a configuration, get it's value.\n     *\n     * @param resourceId The target resource id.\n     * @param configurationName The target configuration variant of the resource. (ex: `anydpi-v26`, `xxhdpi`, `ldtrl-mpi`, etc.)\n     * @return The string value of the resource, which should be a file path inside the apk.\n     */\n    fun ResourceTableChunk.getResourceFileName(\n        resourceId: BinaryResourceIdentifier,\n        configurationName: String,\n    ): String {\n        val packageChunk = this.packages.find { it.id == resourceId.packageId() }\n            ?: error(\"Unable to find target resource\")\n\n        val typeChunk = packageChunk.getTypeChunks(resourceId.typeId())\n            .find { it.configuration.toString() == configurationName }\n            ?: error(\"Unable to find target resource\")\n\n        val entry = try {\n            typeChunk.getEntry(resourceId.entryId())!!\n        } catch (_: Throwable) {\n            error(\"Unable to find target resource\")\n        }\n\n        if (entry.isComplex || entry.value().type() != BinaryResourceValue.Type.STRING)\n            error(\"Target resource value type is not STRING\")\n\n        val valueIdx = entry.value().data()\n        val value = this.stringPool.getString(valueIdx)\n\n        return value\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/util/AxmlUtil.kt",
    "content": "// https://github.com/Aliucord/Manager/blob/main/app/src/main/kotlin/com/aliucord/manager/installer/util/AxmlUtil.kt\npackage dev.beefers.vendetta.manager.installer.util\n\nimport dev.beefers.vendetta.manager.utils.find\nimport com.github.diamondminer88.zip.ZipReader\nimport com.github.diamondminer88.zip.ZipWriter\nimport com.google.devrel.gmscore.tools.apk.arsc.*\nimport java.io.File\n\nobject AxmlUtil {\n    /**\n     * Read and parse a specific axml resource inside an APK\n     * @param apk The source apk\n     * @param resourcePath The full path to the axml file inside the apk, which may be flattened.\n     */\n    private fun readAxml(apk: File, resourcePath: String): BinaryResourceFile {\n        val bytes = ZipReader(apk).use { it.openEntry(resourcePath)?.read() }\n            ?: error(\"APK missing resource file at $resourcePath\")\n\n        return try {\n            BinaryResourceFile(bytes)\n        } catch (t: Throwable) {\n            throw Error(\"Failed to parse axml at $resourcePath\", t)\n        }\n    }\n\n    /**\n     * Get the only top-level chunk in an axml file.\n     */\n    private fun BinaryResourceFile.getMainAxmlChunk(): XmlChunk {\n        if (this.chunks.size > 1)\n            error(\"More than 1 top level chunk in axml\")\n\n        return this.chunks.first() as? XmlChunk\n            ?: error(\"Invalid top-level axml chunk\")\n    }\n\n    /**\n     * Finds the first chunk with a matching [name] in a flattened chunk list.\n     * @receiver The top level XmlChunk ([getMainAxmlChunk])\n     */\n    private fun XmlChunk.getStartElementChunk(name: String): XmlStartElementChunk? {\n        val nameIdx = this.stringPool.indexOf(name)\n\n        return this.chunks\n            .find { it is XmlStartElementChunk && it.nameIndex == nameIdx }\n            as? XmlStartElementChunk\n    }\n\n    /**\n     * Finds the first attribute with a matching name (ignoring namespace)\n     * in a starting element chunk.\n     */\n    private fun XmlStartElementChunk.getAttribute(name: String): XmlAttribute {\n        val nameIdx = (this.parent as XmlChunk).stringPool.indexOf(name)\n\n        return this.attributes\n            .find { it.nameIndex() == nameIdx }\n            ?: error(\"Failed to find $name attribute in an axml chunk\")\n    }\n\n    /**\n     * Patches an <adaptive-icon> axml file to change the `background`, `foreground`, and `monochrome` resource references.\n     * If any of the following are not null, then they will be patched.\n     * @param backgroundColor A color resource id to replace <background> with.\n     *\n     * @param foregroundIcon A drawable resource id to replace <foreground> with.\n     * @param monochromeIcon A drawable resource id to add or replace <monochrome> with.\n     */\n    fun patchAdaptiveIcon(\n        apk: File,\n        resourcePath: String,\n        referencePath: String,\n        backgroundColor: BinaryResourceIdentifier? = null,\n        foregroundIcon: BinaryResourceIdentifier? = null,\n        monochromeIcon: BinaryResourceIdentifier? = null,\n    ) {\n        val xml = readAxml(apk, referencePath)\n        val xmlChunk = xml.getMainAxmlChunk()\n\n        // Patch the background color resource reference\n        if (backgroundColor != null) {\n            val chunk = xmlChunk.getStartElementChunk(\"background\")!!\n            val attribute = chunk.getAttribute(\"drawable\")\n            attribute.typedValue().setValue(\n                /* type = */ BinaryResourceValue.Type.REFERENCE,\n                /* data = */ backgroundColor.resourceId(),\n            )\n        }\n\n        // Patch the foreground drawable reference\n        if (foregroundIcon != null) {\n            val chunk = xmlChunk.getStartElementChunk(\"foreground\")!!\n            val attribute = chunk.getAttribute(\"drawable\")\n            attribute.typedValue().setValue(\n                /* type = */ BinaryResourceValue.Type.REFERENCE,\n                /* data = */ foregroundIcon.resourceId(),\n            )\n        }\n\n        // Add or replace the monochrome drawable reference\n        if (monochromeIcon != null) {\n            // <monochrome> already exists, patch existing chunk\n            val existingChunk = xmlChunk.getStartElementChunk(\"monochrome\")\n            if (existingChunk != null) {\n                val attribute = existingChunk.getAttribute(\"drawable\")\n                attribute.typedValue().setValue(\n                    /* type = */ BinaryResourceValue.Type.REFERENCE,\n                    /* data = */ monochromeIcon.resourceId(),\n                )\n            }\n            // Add a new start & end chunk since they don't exist\n            // `<monochrome android:drawable=\"@drawable/xyz\"></monochrome>\n            else {\n                val iconEndChunkIdx = xmlChunk.chunks\n                    .indexOfLast { it is XmlEndElementChunk && it.name == \"adaptive-icon\" }\n\n                val namespaceIdx = xmlChunk.stringPool.indexOf(\"http://schemas.android.com/apk/res/android\")\n                val drawableIdx = xmlChunk.stringPool.indexOf(\"drawable\")\n                val monochromeIdx = xmlChunk.stringPool.addString(\"monochrome\")\n\n                val startChunk = XmlStartElementChunk(\n                    /* namespaceIndex = */ -1,\n                    /* nameIndex = */ monochromeIdx,\n                    /* idIndex = */ -1,\n                    /* classIndex = */ -1,\n                    /* styleIndex = */ -1,\n                    /* attributes = */\n                    listOf(\n                        XmlAttribute(\n                            /* namespaceIndex = */ namespaceIdx,\n                            /* nameIndex = */ drawableIdx,\n                            /* rawValueIndex = */ -1,\n                            /* typedValue = */\n                            BinaryResourceValue(\n                                /* type = */ BinaryResourceValue.Type.REFERENCE,\n                                /* data = */ monochromeIcon.resourceId(),\n                            ),\n                            // This is wrong but it doesn't matter here as long as this attribute isn't stringified\n                            /* parent = */ null,\n                        )\n                    ),\n                    /* parent = */ xmlChunk,\n                )\n                val endChunk = XmlEndElementChunk(\n                    /* namespaceIndex = */ namespaceIdx,\n                    /* nameIndex = */ monochromeIdx,\n                    /* parent = */ xmlChunk,\n                )\n\n                xmlChunk.addChunk(iconEndChunkIdx, startChunk)\n                xmlChunk.addChunk(iconEndChunkIdx + 1, endChunk)\n            }\n        }\n\n        ZipWriter(apk, /* append = */ true).use { zip ->\n            zip.deleteEntry(resourcePath)\n            zip.writeEntry(resourcePath, xml.toByteArray())\n        }\n    }\n\n    /**\n     * From an APK, read the manifest's `icon` and `roundIcon` references to a resource.\n     * This is then used to get the filename of the resource from `resources.arsc`.\n     */\n    fun readManifestIconInfo(apk: File): ManifestIconInfo {\n        val manifestBytes = ZipReader(apk).use { it.openEntry(\"AndroidManifest.xml\")?.read() }\n            ?: error(\"APK missing manifest\")\n        val manifest = BinaryResourceFile(manifestBytes)\n        val mainChunk = manifest.getMainAxmlChunk()\n\n        // Prefetch string indexes to avoid parsing the entire string pool\n        val iconStringIdx = mainChunk.stringPool.indexOf(\"icon\")\n        val roundIconStringIdx = mainChunk.stringPool.indexOf(\"roundIcon\")\n        val applicationStringIdx = mainChunk.stringPool.indexOf(\"application\")\n\n        val applicationChunk = mainChunk.chunks\n            .find { it is XmlStartElementChunk && it.nameIndex == applicationStringIdx } as? XmlStartElementChunk\n            ?: error(\"Unable to find <application> in manifest\")\n\n        val squareIcon = applicationChunk.attributes\n            .find { it.nameIndex() == iconStringIdx }\n            ?: error(\"Unable to find android:icon in manifest\")\n\n        val roundIcon = applicationChunk.attributes\n            .find { it.nameIndex() == roundIconStringIdx }\n            ?: error(\"Unable to find android:roundIcon in manifest\")\n\n        assert(squareIcon.typedValue().type() == BinaryResourceValue.Type.REFERENCE)\n        assert(roundIcon.typedValue().type() == BinaryResourceValue.Type.REFERENCE)\n\n        return ManifestIconInfo(\n            // Resource IDs into resources.arsc\n            squareIcon = BinaryResourceIdentifier.create(squareIcon.typedValue().data()),\n            roundIcon = BinaryResourceIdentifier.create(roundIcon.typedValue().data()),\n        )\n    }\n\n    data class ManifestIconInfo(\n        val squareIcon: BinaryResourceIdentifier,\n        val roundIcon: BinaryResourceIdentifier,\n    )\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/util/LogEntry.kt",
    "content": "package dev.beefers.vendetta.manager.installer.util\n\nimport android.annotation.SuppressLint\nimport android.os.Parcel\nimport android.os.Parcelable\nimport androidx.compose.runtime.Stable\nimport kotlinx.datetime.Clock\nimport java.io.Serializable\nimport java.text.SimpleDateFormat\nimport java.util.Date\n\n@Stable\ndata class LogEntry(\n    val message: String,\n    val level: Level,\n    private val timestampMillis: Long = Clock.System.now().toEpochMilliseconds()\n): Parcelable, Serializable {\n\n    override fun describeContents() = 0\n\n    override fun writeToParcel(dest: Parcel, flags: Int) {\n        dest.writeString(message)\n        dest.writeInt(level.ordinal)\n        dest.writeLong(timestampMillis)\n    }\n\n    override fun toString(): String {\n        return \"${formatTimestamp()} [${level.name[0]}] $message\"\n    }\n\n    @SuppressLint(\"SimpleDateFormat\")\n    fun formatTimestamp(): String {\n        return SimpleDateFormat(\"MM-dd-yyyy h:mm:ssa\").format(Date(timestampMillis))\n    }\n\n    enum class Level {\n        DEBUG,\n        INFO,\n        ERROR\n    }\n\n    companion object CREATOR: Parcelable.Creator<LogEntry?> {\n\n        override fun createFromParcel(source: Parcel): LogEntry {\n            val message = source.readString()!!\n            val level = Level.entries[source.readInt()]\n            val timestamp = source.readLong()\n            return LogEntry(message, level, timestamp)\n        }\n\n        override fun newArray(size: Int): Array<LogEntry?> {\n            return arrayOfNulls(size)\n        }\n\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/util/Logger.kt",
    "content": "package dev.beefers.vendetta.manager.installer.util\n\nimport android.util.Log\nimport androidx.compose.runtime.Stable\nimport org.lsposed.patch.util.Logger\n\n/**\n * Used to log events done during the patching process\n *\n * @param tag The tag to use for logcat\n */\n@Stable\nclass Logger(\n    private val tag: String\n): Logger() {\n\n    /**\n     * All logs made with this [Logger]\n     */\n    val logs = mutableListOf<LogEntry>()\n\n    /**\n     * Prints a debug message to logcat and stores it in [logs]\n     */\n    override fun d(msg: String?) {\n        log(msg, LogEntry.Level.DEBUG)\n        Log.d(tag, msg.toString())\n    }\n\n    /**\n     * Prints an info message to logcat and stores it in [logs]\n     */\n    override fun i(msg: String?) {\n        log(msg, LogEntry.Level.INFO)\n        Log.i(tag, msg.toString())\n    }\n\n    /**\n     * Prints an error message to logcat and stores it in [logs]\n     */\n    override fun e(msg: String?) {\n        log(msg, LogEntry.Level.ERROR)\n        Log.e(tag, msg.toString())\n    }\n\n    /**\n     * Prints an error message and stacktrace with a preceding empty line.\n     */\n    fun e(msg: String?, th: Throwable?) {\n        newline()\n        e(msg)\n        if (th != null) e(th.stackTraceToString().trim())\n    }\n\n    /**\n     * Stores a log entry\n     */\n    private fun log(msg: String?, level: LogEntry.Level) {\n        msg?.let {\n            msg.split(\"\\n\").forEach {\n                logs += LogEntry(it, level)\n            }\n        }\n    }\n\n    /**\n     * Prints an empty line\n     */\n    private fun newline() {\n        i(\"\\n\")\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/util/ManifestPatcher.kt",
    "content": "package dev.beefers.vendetta.manager.installer.util\n\nimport android.Manifest\nimport pxb.android.axml.AxmlReader\nimport pxb.android.axml.AxmlVisitor\nimport pxb.android.axml.AxmlWriter\nimport pxb.android.axml.NodeVisitor\n\nobject ManifestPatcher {\n    private const val ANDROID_NAMESPACE = \"http://schemas.android.com/apk/res/android\"\n    private const val USES_CLEARTEXT_TRAFFIC = \"usesCleartextTraffic\"\n    private const val DEBUGGABLE = \"debuggable\"\n    private const val REQUEST_LEGACY_EXTERNAL_STORAGE = \"requestLegacyExternalStorage\"\n    private const val NETWORK_SECURITY_CONFIG = \"networkSecurityConfig\"\n    private const val LABEL = \"label\"\n    private const val PACKAGE = \"package\"\n    private const val COMPILE_SDK_VERSION = \"compileSdkVersion\"\n    private const val COMPILE_SDK_VERSION_CODENAME = \"compileSdkVersionCodename\"\n    private const val DRNE_PERMISSION = \"DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION\"\n    private const val DISCORD_DRNE_PERMISSION = \"com.discord.$DRNE_PERMISSION\"\n\n    fun patchManifest(\n        manifestBytes: ByteArray,\n        packageName: String,\n        appName: String,\n        debuggable: Boolean\n    ): ByteArray {\n        val reader = AxmlReader(manifestBytes)\n        val writer = AxmlWriter()\n\n        reader.accept(object : AxmlVisitor(writer) {\n            override fun child(ns: String?, name: String?) =\n                object : ReplaceAttrsVisitor(\n                    super.child(ns, name),\n                    mapOf(\n                        PACKAGE to packageName,\n                        COMPILE_SDK_VERSION to 23,\n                        COMPILE_SDK_VERSION_CODENAME to \"6.0-2438415\"\n                    )\n                ) {\n                    private var addExternalStoragePerm = false\n\n                    override fun child(ns: String?, name: String): NodeVisitor {\n                        val nv = super.child(ns, name)\n\n                        // Add MANAGE_EXTERNAL_STORAGE when necessary\n                        if (addExternalStoragePerm) {\n                            super\n                                .child(null, \"uses-permission\")\n                                .attr(\n                                    ANDROID_NAMESPACE,\n                                    \"name\",\n                                    android.R.attr.name,\n                                    TYPE_STRING,\n                                    Manifest.permission.MANAGE_EXTERNAL_STORAGE\n                                )\n                            addExternalStoragePerm = false\n                        }\n\n                        return when (name) {\n                            \"permission\" -> object : NodeVisitor(nv) {\n                                override fun attr(\n                                    ns: String?,\n                                    name: String?,\n                                    resourceId: Int,\n                                    type: Int,\n                                    value: Any?\n                                ) {\n                                    if(name == \"name\" && value == DISCORD_DRNE_PERMISSION) {\n                                        super.attr(ns, name, resourceId, type, \"$packageName.$DRNE_PERMISSION\")\n                                    } else {\n                                        super.attr(ns, name, resourceId, type, value)\n                                    }\n                                }\n                            }\n\n                            \"uses-permission\" -> object : NodeVisitor(nv) {\n                                override fun attr(\n                                    ns: String?,\n                                    name: String?,\n                                    resourceId: Int,\n                                    type: Int,\n                                    value: Any?\n                                ) {\n                                    if(name == \"name\" && value == DISCORD_DRNE_PERMISSION) {\n                                        super.attr(ns, name, resourceId, type, \"$packageName.$DRNE_PERMISSION\")\n                                    }\n\n                                    if (name != \"maxSdkVersion\") {\n                                        super.attr(ns, name, resourceId, type, value)\n                                    }\n\n                                    // Set the add external storage permission to be added after WRITE_EXTERNAL_STORAGE (which is after read)\n                                    if (name == \"name\" && value == Manifest.permission.READ_EXTERNAL_STORAGE) {\n                                        addExternalStoragePerm = true\n                                    }\n                                }\n                            }\n\n                            \"application\" -> object : ReplaceAttrsVisitor(\n                                nv,\n                                mapOf(\n                                    LABEL to appName,\n                                    DEBUGGABLE to debuggable,\n                                    USES_CLEARTEXT_TRAFFIC to true,\n                                    REQUEST_LEGACY_EXTERNAL_STORAGE to true\n                                )\n                            ) {\n                                private var addDebuggable = debuggable\n                                private var addLegacyStorage = true\n                                private var addUseClearTextTraffic = true\n\n                                override fun attr(\n                                    ns: String?,\n                                    name: String,\n                                    resourceId: Int,\n                                    type: Int,\n                                    value: Any?\n                                ) {\n                                    super.attr(ns, name, resourceId, type, value)\n                                    if (name == REQUEST_LEGACY_EXTERNAL_STORAGE) addLegacyStorage =\n                                        false\n                                    if (name == DEBUGGABLE) addDebuggable = false\n                                    if (name == USES_CLEARTEXT_TRAFFIC) addUseClearTextTraffic =\n                                        false\n                                }\n\n                                override fun child(ns: String?, name: String): NodeVisitor {\n                                    val visitor = super.child(ns, name)\n\n                                    return when (name) {\n                                        \"activity\" -> ReplaceAttrsVisitor(\n                                            visitor,\n                                            mapOf(\"label\" to appName)\n                                        )\n\n                                        \"provider\" -> object : NodeVisitor(visitor) {\n                                            override fun attr(\n                                                ns: String?,\n                                                name: String,\n                                                resourceId: Int,\n                                                type: Int,\n                                                value: Any?\n                                            ) {\n                                                super.attr(\n                                                    ns,\n                                                    name,\n                                                    resourceId,\n                                                    type,\n                                                    if (name == \"authorities\") {\n                                                        (value as String).replace(\n                                                            \"com.discord\",\n                                                            packageName\n                                                        )\n                                                    } else {\n                                                        value\n                                                    }\n                                                )\n                                            }\n                                        }\n\n                                        else -> visitor\n                                    }\n                                }\n\n                                override fun end() {\n                                    if (addLegacyStorage) super.attr(\n                                        ANDROID_NAMESPACE,\n                                        REQUEST_LEGACY_EXTERNAL_STORAGE,\n                                        -1,\n                                        TYPE_INT_BOOLEAN,\n                                        1\n                                    )\n                                    if (addDebuggable) super.attr(\n                                        ANDROID_NAMESPACE,\n                                        DEBUGGABLE,\n                                        -1,\n                                        TYPE_INT_BOOLEAN,\n                                        1\n                                    )\n                                    if (addUseClearTextTraffic) super.attr(\n                                        ANDROID_NAMESPACE,\n                                        USES_CLEARTEXT_TRAFFIC,\n                                        -1,\n                                        TYPE_INT_BOOLEAN,\n                                        1\n                                    )\n                                    super.end()\n                                }\n                            }\n\n                            else -> nv\n                        }\n                    }\n                }\n        })\n\n        return writer.toByteArray()\n    }\n\n    fun renamePackage(\n        manifestBytes: ByteArray,\n        packageName: String\n    ): ByteArray {\n        val reader = AxmlReader(manifestBytes)\n        val writer = AxmlWriter()\n\n        reader.accept(\n            object : AxmlVisitor(writer) {\n                override fun child(ns: String?, name: String?): ReplaceAttrsVisitor {\n                    return ReplaceAttrsVisitor(\n                        super.child(ns, name),\n                        mapOf(\"package\" to packageName)\n                    )\n                }\n            }\n        )\n\n        return writer.toByteArray()\n    }\n\n    private open class ReplaceAttrsVisitor(\n        nv: NodeVisitor,\n        private val attrs: Map<String, Any>\n    ) : NodeVisitor(nv) {\n        override fun attr(ns: String?, name: String, resourceId: Int, type: Int, value: Any?) {\n            val replace = attrs.containsKey(name)\n            val newValue = attrs[name]\n\n            super.attr(\n                ns,\n                name,\n                resourceId,\n                if (newValue is String) TYPE_STRING else type,\n                if (replace) newValue else value\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/util/Patcher.kt",
    "content": "package dev.beefers.vendetta.manager.installer.util\n\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport org.lsposed.patch.LSPatch\nimport org.lsposed.patch.util.Logger\nimport java.io.File\n\nobject Patcher {\n\n    suspend fun patch(\n        logger: Logger,\n        outputDir: File,\n        apkPaths: List<String>,\n        embeddedModules: List<String>\n    ) {\n        withContext(Dispatchers.IO) {\n            LSPatch(\n                logger,\n                *apkPaths.toTypedArray(),\n                \"-o\",\n                outputDir.absolutePath,\n                \"-l\",\n                \"0\",\n                \"-v\",\n                \"-m\",\n                *embeddedModules.toTypedArray(),\n                \"-k\",\n                Signer.keyStore.absolutePath,\n                \"password\",\n                \"alias\",\n                \"password\"\n            ).doCommandLine()\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/installer/util/Signer.kt",
    "content": "package dev.beefers.vendetta.manager.installer.util\n\nimport android.content.Context\nimport com.android.apksig.ApkSigner\nimport dev.beefers.vendetta.manager.utils.Constants\nimport org.bouncycastle.asn1.x500.X500Name\nimport org.bouncycastle.asn1.x509.SubjectPublicKeyInfo\nimport org.bouncycastle.cert.X509v3CertificateBuilder\nimport org.bouncycastle.cert.jcajce.JcaX509CertificateConverter\nimport org.bouncycastle.operator.jcajce.JcaContentSignerBuilder\nimport org.koin.core.component.KoinComponent\nimport org.koin.core.component.inject\nimport java.io.File\nimport java.math.BigInteger\nimport java.security.KeyPairGenerator\nimport java.security.KeyStore\nimport java.security.PrivateKey\nimport java.security.SecureRandom\nimport java.security.cert.Certificate\nimport java.security.cert.X509Certificate\nimport java.util.Date\nimport java.util.Locale\nimport kotlin.io.path.Path\nimport kotlin.io.path.moveTo\n\nobject Signer : KoinComponent {\n    private val password = \"password\".toCharArray()\n    private val context by inject<Context>()\n    private val cacheDir = context.cacheDir\n    private val filesDir = context.filesDir\n\n    val keyStore: File by lazy {\n        val ks = filesDir.resolve(\"ks.keystore\")\n        migrate(cacheDir, filesDir)\n        migrate(Constants.VENDETTA_DIR, filesDir)\n        ks.also {\n            if (!it.exists()) {\n                it.createNewFile()\n                newKeystore(it)\n            }\n        }\n        ks\n    }\n\n    private val signerConfig: ApkSigner.SignerConfig by lazy {\n        val keyStore = KeyStore.getInstance(KeyStore.getDefaultType())\n\n        this.keyStore.inputStream().use { stream ->\n            keyStore.load(stream, null)\n        }\n\n        val alias = keyStore.aliases().nextElement()\n        val certificate = keyStore.getCertificate(alias) as X509Certificate\n\n        ApkSigner.SignerConfig.Builder(\n            \"Bunny\",\n            keyStore.getKey(alias, password) as PrivateKey,\n            listOf(certificate)\n        ).build()\n    }\n\n    private fun newKeystore(out: File) {\n        val key = createKey()\n\n        with(KeyStore.getInstance(KeyStore.getDefaultType())) {\n            load(null, password)\n            setKeyEntry(\"alias\", key.privateKey, password, arrayOf<Certificate>(key.publicKey))\n            store(out.outputStream(), password)\n        }\n    }\n\n    private fun createKey(): KeySet {\n        var serialNumber: BigInteger\n\n        do serialNumber = SecureRandom().nextInt().toBigInteger()\n        while (serialNumber < BigInteger.ZERO)\n\n        val x500Name = X500Name(\"CN=Bunny Manager\")\n        val pair = KeyPairGenerator.getInstance(\"RSA\").run {\n            initialize(2048)\n            generateKeyPair()\n        }\n        val builder = X509v3CertificateBuilder(\n            /* issuer = */ x500Name,\n            /* serial = */\n            serialNumber,\n            /* notBefore = */\n            Date(System.currentTimeMillis() - 1000L * 60L * 60L * 24L * 30L),\n            /* notAfter = */\n            Date(System.currentTimeMillis() + 1000L * 60L * 60L * 24L * 366L * 30L),\n            /* dateLocale = */\n            Locale.ENGLISH,\n            /* subject = */\n            x500Name,\n            /* publicKeyInfo = */\n            SubjectPublicKeyInfo.getInstance(pair.public.encoded)\n        )\n        val signer = JcaContentSignerBuilder(\"SHA1withRSA\").build(pair.private)\n\n        return KeySet(\n            JcaX509CertificateConverter().getCertificate(builder.build(signer)),\n            pair.private\n        )\n    }\n\n    fun signApk(apkFile: File, output: File) {\n        val outputApk = cacheDir.resolve(apkFile.name)\n\n        ApkSigner.Builder(listOf(signerConfig))\n            .setV1SigningEnabled(false) // TODO: enable so api <24 devices can work, however zip-alignment breaks\n            .setV2SigningEnabled(true)\n            .setV3SigningEnabled(true)\n            .setInputApk(apkFile)\n            .setOutputApk(output)\n            .build()\n            .sign()\n\n        outputApk.renameTo(apkFile)\n    }\n\n    private fun migrate(oldDir: File, newDir: File) {\n        oldDir.resolve(\"ks.keystore\").also {\n            if (it.exists()) {\n                Path(it.absolutePath)\n                    .moveTo(\n                        Path(newDir.resolve(\"ks.keystore\").absolutePath),\n                        overwrite = true\n                    )\n            }\n        }\n    }\n\n    private class KeySet(val publicKey: X509Certificate, val privateKey: PrivateKey)\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/network/dto/Commit.kt",
    "content": "package dev.beefers.vendetta.manager.network.dto\n\nimport kotlinx.datetime.Instant\nimport kotlinx.serialization.SerialName\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class Commit(\n    val sha: String,\n    @SerialName(\"commit\") val info: Info,\n    @SerialName(\"html_url\") val url: String,\n    val author: User?\n) {\n\n    @Serializable\n    data class Info(\n        val message: String,\n        val committer: Committer\n    )\n\n    @Serializable\n    data class Committer(\n        val date: Instant\n    )\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/network/dto/Index.kt",
    "content": "package dev.beefers.vendetta.manager.network.dto\n\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class Index(\n    val latest: Versions\n) {\n\n    @Serializable\n    data class Versions(\n        val alpha: String,\n        val beta: String,\n        val stable: String\n    )\n\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/network/dto/Release.kt",
    "content": "package dev.beefers.vendetta.manager.network.dto\n\nimport kotlinx.serialization.SerialName\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class Release(\n    @SerialName(\"tag_name\") val tagName: String,\n    @SerialName(\"name\") val versionName: String\n)"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/network/dto/User.kt",
    "content": "package dev.beefers.vendetta.manager.network.dto\n\nimport kotlinx.serialization.SerialName\nimport kotlinx.serialization.Serializable\n\n@Serializable\ndata class User(\n    @SerialName(\"login\") val username: String,\n    @SerialName(\"avatar_url\") val avatar: String\n)"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/network/service/HttpService.kt",
    "content": "package dev.beefers.vendetta.manager.network.service\n\nimport dev.beefers.vendetta.manager.network.utils.ApiError\nimport dev.beefers.vendetta.manager.network.utils.ApiFailure\nimport dev.beefers.vendetta.manager.network.utils.ApiResponse\nimport io.ktor.client.HttpClient\nimport io.ktor.client.request.HttpRequestBuilder\nimport io.ktor.client.request.request\nimport io.ktor.client.statement.bodyAsText\nimport io.ktor.http.isSuccess\nimport kotlinx.serialization.json.Json\n\nclass HttpService(\n    val json: Json,\n    val http: HttpClient\n) {\n\n    suspend inline fun <reified T> request(builder: HttpRequestBuilder.() -> Unit = {}): ApiResponse<T> {\n        var body: String? = null\n\n        val response = try {\n            val response = http.request(builder)\n\n            if (response.status.isSuccess()) {\n                body = response.bodyAsText()\n\n                if (T::class == String::class) {\n                    return ApiResponse.Success(body as T)\n                }\n\n                ApiResponse.Success(json.decodeFromString<T>(body))\n            } else {\n                body = try {\n                    response.bodyAsText()\n                } catch (e: Throwable) {\n                    null\n                }\n\n                ApiResponse.Error(ApiError(response.status, body))\n            }\n        } catch (e: Throwable) {\n            ApiResponse.Failure(ApiFailure(e, body))\n        }\n\n        return response\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/network/service/RestService.kt",
    "content": "package dev.beefers.vendetta.manager.network.service\n\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.network.dto.Commit\nimport dev.beefers.vendetta.manager.network.dto.Index\nimport dev.beefers.vendetta.manager.network.dto.Release\nimport io.ktor.client.request.parameter\nimport io.ktor.client.request.url\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\n\nclass RestService(\n    private val httpService: HttpService,\n    private val prefs: PreferenceManager\n) {\n\n    suspend fun getLatestRelease(repo: String) = withContext(Dispatchers.IO) {\n        httpService.request<Release> {\n            url(\"https://api.github.com/repos/$repo/releases/latest\")\n        }\n    }\n\n    suspend fun getLatestDiscordVersions() = withContext(Dispatchers.IO) {\n        httpService.request<Index> {\n            url(\"${prefs.mirror.baseUrl}/tracker/index\")\n        }\n    }\n\n    suspend fun getCommits(repo: String, page: Int = 1) = withContext(Dispatchers.IO) {\n        httpService.request<List<Commit>> {\n            url(\"https://api.github.com/repos/$repo/commits\")\n            parameter(\"page\", page)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/network/utils/ApiResponse.kt",
    "content": "package dev.beefers.vendetta.manager.network.utils\n\nimport io.ktor.http.HttpStatusCode\n\nsealed interface ApiResponse<D> {\n    data class Success<D>(val data: D) : ApiResponse<D>\n    data class Error<D>(val error: ApiError) : ApiResponse<D>\n    data class Failure<D>(val error: ApiFailure) : ApiResponse<D>\n}\n\nclass ApiError(code: HttpStatusCode, body: String?) : Error(\"HTTP Code $code, Body: $body\")\nclass ApiFailure(error: Throwable, body: String?) : Error(body, error)\n\nval <D> ApiResponse<D>.dataOrNull\n    get() = if (this is ApiResponse.Success) data else null\n\nval <D> ApiResponse<D>.dataOrThrow\n    get() = when (this) {\n        is ApiResponse.Success -> data\n        is ApiResponse.Error -> throw error\n        is ApiResponse.Failure -> throw error\n    }\n\ninline fun <D> ApiResponse<D>.ifSuccessful(block: (D) -> Unit) {\n    if (this is ApiResponse.Success) block(data)\n}\n\nfun <D> ApiResponse<D>.fold(\n    onSuccess: (D) -> Unit = {},\n    onError: () -> Unit = {}\n) {\n    when (this) {\n        is ApiResponse.Success -> onSuccess(data)\n        is ApiResponse.Error,\n        is ApiResponse.Failure -> onError()\n    }\n}\n\n@Suppress(\"UNCHECKED_CAST\")\nfun <T, R> ApiResponse<T>.transform(block: (T) -> R): ApiResponse<R> {\n    return when (this) {\n        is ApiResponse.Success -> ApiResponse.Success(block(data))\n        is ApiResponse.Error -> this as ApiResponse.Error<R>\n        is ApiResponse.Failure -> this as ApiResponse.Failure<R>\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/network/utils/CommitsPagingSource.kt",
    "content": "package dev.beefers.vendetta.manager.network.utils\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport dev.beefers.vendetta.manager.domain.repository.RestRepository\nimport dev.beefers.vendetta.manager.network.dto.Commit\n\nclass CommitsPagingSource(\n    private val repo: RestRepository\n) : PagingSource<Int, Commit>() {\n\n    override fun getRefreshKey(state: PagingState<Int, Commit>): Int? =\n        state.anchorPosition?.let {\n            state.closestPageToPosition(it)?.prevKey\n        }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Commit> {\n        val page = params.key ?: 0\n\n        return when (val response = repo.getCommits(\"pyoncord/Bunny\", page)) {\n            is ApiResponse.Success -> LoadResult.Page(\n                data = response.data,\n                prevKey = if (page > 0) page - 1 else null,\n                nextKey = if (response.data.isNotEmpty()) page + 1 else null\n            )\n\n            is ApiResponse.Failure -> LoadResult.Error(response.error)\n            is ApiResponse.Error -> LoadResult.Error(response.error)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/activity/MainActivity.kt",
    "content": "package dev.beefers.vendetta.manager.ui.activity\n\nimport android.Manifest\nimport android.content.pm.PackageManager\nimport android.os.Bundle\nimport androidx.activity.ComponentActivity\nimport androidx.activity.compose.setContent\nimport androidx.activity.enableEdgeToEdge\nimport androidx.core.app.ActivityCompat\nimport androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen\nimport androidx.lifecycle.lifecycleScope\nimport cafe.adriel.voyager.navigator.Navigator\nimport cafe.adriel.voyager.transitions.SlideTransition\nimport dev.beefers.vendetta.manager.domain.manager.InstallMethod\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.installer.shizuku.ShizukuPermissions\nimport dev.beefers.vendetta.manager.ui.screen.home.HomeScreen\nimport dev.beefers.vendetta.manager.ui.screen.installer.InstallerScreen\nimport dev.beefers.vendetta.manager.ui.theme.VendettaManagerTheme\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport dev.beefers.vendetta.manager.utils.Intents\nimport kotlinx.coroutines.launch\nimport org.koin.android.ext.android.inject\n\nclass MainActivity : ComponentActivity() {\n\n    private val preferences: PreferenceManager by inject()\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        installSplashScreen()\n        enableEdgeToEdge()\n        super.onCreate(savedInstanceState)\n        val version = intent.getStringExtra(Intents.Extras.VERSION)\n\n        if (checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {\n            ActivityCompat.requestPermissions(\n                this,\n                arrayOf(\"android.permission.POST_NOTIFICATIONS\"),\n                0\n            )\n        }\n\n        if (preferences.installMethod == InstallMethod.SHIZUKU) {\n            lifecycleScope.launch {\n                if (!ShizukuPermissions.waitShizukuPermissions()) {\n                    preferences.installMethod = InstallMethod.DEFAULT\n                }\n            }\n        }\n\n        val screen = if (intent.action == Intents.Actions.INSTALL && version != null) {\n            InstallerScreen(DiscordVersion.fromVersionCode(version)!!)\n        } else {\n            HomeScreen()\n        }\n\n        setContent {\n            VendettaManagerTheme {\n                Navigator(screen) {\n                    SlideTransition(it)\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/Label.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\n\n@Composable\nfun Label(\n    modifier: Modifier = Modifier,\n    text: String? = null,\n    icon: ImageVector? = null,\n    textColor: Color,\n    borderColor: Color = textColor,\n    fillColor: Color = Color.Transparent,\n    iconColor: Color = textColor\n) {\n    Row(\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.spacedBy(4.dp),\n        modifier = Modifier\n            .then(modifier)\n            .clip(CircleShape)\n            .background(fillColor)\n            .border(1.dp, borderColor, CircleShape)\n            .then(\n                if (text == null)\n                    Modifier.padding(5.dp)\n                else\n                    Modifier.padding(vertical = 5.dp, horizontal = 7.dp)\n            )\n    ) {\n        icon?.let {\n            Icon(\n                imageVector = it,\n                contentDescription = null,\n                tint = iconColor,\n                modifier = Modifier.size(12.dp)\n            )\n        }\n        text?.let {\n            Text(\n                text = text,\n                style = MaterialTheme.typography.labelSmall,\n                fontSize = 10.sp,\n                color = textColor,\n                maxLines = 1\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/NavBarSpacer.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components\n\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport dev.beefers.vendetta.manager.utils.DimenUtils\n\n@Composable\nfun NavBarSpacer() {\n    Spacer(\n        modifier = Modifier.height(DimenUtils.navBarPadding)\n    )\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/RadioController.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components\n\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material3.RadioButton\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\n\n@Composable\ninline fun <reified E : Enum<E>> EnumRadioController(\n    default: E,\n    excludedOptions: List<E> = emptyList(),\n    labelFactory: (E) -> String = { it.toString() },\n    crossinline onChoiceSelected: (E) -> Unit\n) {\n    var choice by remember { mutableStateOf(default) }\n\n    Column {\n        enumValues<E>().filterNot { excludedOptions.contains(it) }.forEach {\n            Row(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .clickable {\n                        choice = it\n                        onChoiceSelected(it)\n                    },\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                Text(labelFactory(it))\n                Spacer(Modifier.weight(1f))\n                RadioButton(\n                    selected = it == choice,\n                    onClick = {\n                        choice = it\n                        onChoiceSelected(it)\n                    })\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/SegmentedButton.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.basicMarquee\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun RowScope.SegmentedButton(\n    icon: Any,\n    iconDescription: String? = null,\n    text: String,\n    onClick: () -> Unit\n) {\n    Column(\n        horizontalAlignment = Alignment.CenterHorizontally,\n        verticalArrangement = Arrangement.spacedBy(12.dp, Alignment.CenterVertically),\n        modifier = Modifier\n            .clickable(onClick = onClick)\n            .background(MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp))\n            .weight(1f)\n            .padding(16.dp)\n    ) {\n        when (icon) {\n            is ImageVector -> {\n                Icon(\n                    imageVector = icon,\n                    contentDescription = iconDescription,\n                    tint = MaterialTheme.colorScheme.primary\n                )\n            }\n\n            is Painter -> {\n                Icon(\n                    painter = icon,\n                    contentDescription = iconDescription,\n                    tint = MaterialTheme.colorScheme.primary\n                )\n            }\n        }\n\n        Text(\n            text = text,\n            style = MaterialTheme.typography.labelLarge,\n            color = MaterialTheme.colorScheme.primary,\n            maxLines = 1,\n            modifier = Modifier.basicMarquee()\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/ThinDivider.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components\n\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun ThinDivider() = HorizontalDivider(\n    thickness = 0.5.dp,\n    color = MaterialTheme.colorScheme.onSurface.copy(0.1f)\n)"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/settings/SettingsButton.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components.settings\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Button\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun SettingsButton(\n    label: String,\n    onClick: () -> Unit = {}\n) {\n    Box(\n        modifier = Modifier\n            .heightIn(min = 64.dp)\n            .fillMaxWidth()\n            .padding(horizontal = 18.dp, vertical = 14.dp)\n    ) {\n        Button(onClick, modifier = Modifier.fillMaxWidth()) {\n            Text(text = label)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/settings/SettingsCategory.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components.settings\n\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport dev.beefers.vendetta.manager.utils.navigate\n\n@Composable\nfun SettingsCategory(\n    icon: ImageVector,\n    text: String,\n    subtext: String,\n    destination: (() -> Screen)? = null\n) {\n    val screen = destination?.invoke()\n    val nav = LocalNavigator.current\n\n    Box(\n        modifier = Modifier\n            .clickable {\n                screen?.let { nav?.navigate(it) }\n            }\n    ) {\n        SettingsItem(\n            icon = { Icon(icon, null) },\n            text = { Text(text) },\n            secondaryText = { Text(subtext) }\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/settings/SettingsChoiceDialog.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components.settings\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.slideInVertically\nimport androidx.compose.animation.slideOutVertically\nimport androidx.compose.material3.AlertDialog\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.res.stringResource\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.ui.components.EnumRadioController\n\n@Composable\ninline fun <reified E : Enum<E>> SettingsChoiceDialog(\n    visible: Boolean = false,\n    default: E,\n    excludedOptions: List<E> = emptyList(),\n    noinline title: @Composable () -> Unit,\n    crossinline labelFactory: (E) -> String = { it.toString() },\n    noinline onRequestClose: () -> Unit = {},\n    crossinline description: @Composable () -> Unit = {},\n    noinline onChoice: (E) -> Unit = {},\n) {\n\n    var choice by remember { mutableStateOf(default) }\n\n    AnimatedVisibility(\n        visible = visible,\n        enter = slideInVertically(),\n        exit = slideOutVertically()\n    ) {\n        AlertDialog(\n            onDismissRequest = { onRequestClose() },\n            title = title,\n            text = {\n                description()\n                EnumRadioController(\n                    default,\n                    excludedOptions,\n                    labelFactory\n                ) { choice = it }\n            },\n            confirmButton = {\n                FilledTonalButton(onClick = { onChoice(choice) }) {\n                    Text(text = stringResource(id = R.string.action_confirm))\n                }\n            }\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/settings/SettingsHeader.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components.settings\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun SettingsHeader(\n    text: String\n) {\n    Text(\n        text = text,\n        style = MaterialTheme.typography.titleSmall,\n        modifier = Modifier.padding(18.dp, 24.dp, 18.dp, 10.dp)\n    )\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/settings/SettingsItem.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components.settings\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\n\n@Composable\nfun SettingsItem(\n    modifier: Modifier = Modifier,\n    icon: @Composable (() -> Unit)? = null,\n    text: @Composable () -> Unit,\n    secondaryText: @Composable (() -> Unit) = { },\n    trailing: @Composable (() -> Unit) = { },\n) {\n    Row(\n        modifier = modifier\n            .heightIn(min = 64.dp)\n            .fillMaxWidth()\n            .padding(horizontal = 18.dp, vertical = 14.dp),\n        horizontalArrangement = Arrangement.spacedBy(14.dp),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        if (icon != null) Box(modifier = Modifier.padding(8.dp)) {\n            icon()\n        }\n\n        Column(\n            verticalArrangement = Arrangement.spacedBy(5.dp),\n            modifier = Modifier.weight(1f, true)\n        ) {\n            ProvideTextStyle(\n                MaterialTheme.typography.titleLarge.copy(\n                    fontWeight = FontWeight.Normal,\n                    fontSize = 19.sp\n                )\n            ) {\n                text()\n            }\n            ProvideTextStyle(\n                MaterialTheme.typography.bodyMedium.copy(\n                    color = MaterialTheme.colorScheme.onSurface.copy(0.6f)\n                )\n            ) {\n                secondaryText()\n            }\n        }\n\n        trailing()\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/settings/SettingsItemChoice.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components.settings\n\nimport androidx.compose.foundation.clickable\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalContext\n\n@Composable\ninline fun <reified E : Enum<E>> SettingsItemChoice(\n    label: String,\n    title: String = label,\n    disabled: Boolean = false,\n    pref: E,\n    excludedOptions: List<E> = emptyList(),\n    crossinline labelFactory: (E) -> String = { it.toString() },\n    crossinline onPrefChange: (E) -> Unit,\n) {\n    val ctx = LocalContext.current\n    val choiceLabel = labelFactory(pref)\n    val opened = remember {\n        mutableStateOf(false)\n    }\n\n    SettingsItem(\n        modifier = Modifier.clickable(enabled = !disabled) { opened.value = true },\n        text = { Text(text = label) },\n    ) {\n        SettingsChoiceDialog(\n            visible = opened.value,\n            title = { Text(title) },\n            default = pref,\n            labelFactory = labelFactory,\n            excludedOptions = excludedOptions,\n            onRequestClose = {\n                opened.value = false\n            },\n            onChoice = {\n                opened.value = false\n                onPrefChange(it)\n            }\n        )\n        FilledTonalButton(onClick = { opened.value = true }, enabled = !disabled) {\n            Text(choiceLabel)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/settings/SettingsSwitch.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components.settings\n\nimport androidx.compose.foundation.clickable\nimport androidx.compose.material3.Switch\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\n\n@Composable\nfun SettingsSwitch(\n    label: String,\n    secondaryLabel: String? = null,\n    disabled: Boolean = false,\n    pref: Boolean,\n    onPrefChange: (Boolean) -> Unit,\n) {\n    SettingsItem(\n        modifier = Modifier.clickable(enabled = !disabled) { onPrefChange(!pref) },\n        text = { Text(text = label) },\n        secondaryText = {\n            secondaryLabel?.let {\n                Text(text = it)\n            }\n        }\n    ) {\n        Switch(\n            checked = pref,\n            enabled = !disabled,\n            onCheckedChange = { onPrefChange(!pref) }\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/components/settings/SettingsTextField.kt",
    "content": "package dev.beefers.vendetta.manager.ui.components.settings\n\nimport androidx.compose.foundation.layout.*\nimport androidx.compose.material3.*\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun SettingsTextField(\n    label: String,\n    disabled: Boolean = false,\n    pref: String,\n    error: Boolean = false,\n    supportingText: String? = null,\n    onPrefChange: (String) -> Unit,\n) {\n    Box(modifier = Modifier.padding(horizontal = 18.dp, vertical = 10.dp)) {\n        OutlinedTextField(\n            modifier = Modifier.fillMaxWidth(),\n            value = pref,\n            onValueChange = onPrefChange,\n            enabled = !disabled,\n            label = { Text(label) },\n            isError = error,\n            singleLine = true,\n            supportingText = if (supportingText != null) { -> Text(supportingText) } else null\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/about/AboutScreen.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.about\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.ArrowBack\nimport androidx.compose.material3.ElevatedCard\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.asImageBitmap\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.BuildConfig\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.ui.screen.libraries.LibrariesScreen\nimport dev.beefers.vendetta.manager.ui.widgets.about.LinkItem\nimport dev.beefers.vendetta.manager.ui.widgets.about.ListItem\nimport dev.beefers.vendetta.manager.ui.widgets.about.UserEntry\nimport dev.beefers.vendetta.manager.utils.Constants\nimport dev.beefers.vendetta.manager.utils.DimenUtils\nimport dev.beefers.vendetta.manager.utils.getBitmap\nimport dev.beefers.vendetta.manager.utils.showToast\nimport org.koin.compose.koinInject\n\nclass AboutScreen : Screen {\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    override fun Content() {\n        val uriHandler = LocalUriHandler.current\n        val prefs: PreferenceManager = koinInject()\n        val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n        val ctx = LocalContext.current\n        val bitmap = remember {\n            ctx.getBitmap(R.drawable.ic_launcher, 60).asImageBitmap()\n        }\n        var tapCount by remember {\n            mutableIntStateOf(0)\n        }\n\n        Scaffold(\n            topBar = { TitleBar(scrollBehavior) },\n            contentWindowInsets = WindowInsets(0, 0, 0, 0),\n            modifier = Modifier\n                .nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) {\n            Column(\n                modifier = Modifier\n                    .padding(it)\n                    .verticalScroll(rememberScrollState())\n                    .padding(bottom = DimenUtils.navBarPadding)\n            ) {\n                Column(\n                    verticalArrangement = Arrangement.spacedBy(16.dp),\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(top = 16.dp, bottom = 20.dp)\n                ) {\n                    Image(\n                        bitmap = bitmap,\n                        contentDescription = null,\n                        modifier = Modifier\n                            .size(60.dp)\n                            .clip(CircleShape)\n                    )\n\n                    Text(\n                        stringResource(R.string.app_name),\n                        style = MaterialTheme.typography.titleLarge\n                    )\n\n                    Text(\n                        text = \"v${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE})\",\n                        style = MaterialTheme.typography.labelLarge,\n                        color = LocalContentColor.current.copy(alpha = 0.5f),\n                        modifier = Modifier.clickable(\n                            enabled = !prefs.isDeveloper\n                        ) {\n                            tapCount++\n                            when (tapCount) {\n                                3 -> ctx.showToast(R.string.msg_seven_left)\n                                5 -> ctx.showToast(R.string.msg_five_left)\n                                8 -> ctx.showToast(R.string.msg_two_left)\n                                10 -> {\n                                    ctx.showToast(R.string.msg_unlocked)\n                                    prefs.isDeveloper = true\n                                }\n                            }\n                        }\n                    )\n\n                    Row(\n                        verticalAlignment = Alignment.CenterVertically,\n                        horizontalArrangement = Arrangement.SpaceEvenly,\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        LinkItem(\n                            icon = R.drawable.ic_github,\n                            label = R.string.label_github,\n                            link = \"https://github.com/bunny-mod\"\n                        )\n\n                        LinkItem(\n                            icon = R.drawable.ic_discord,\n                            label = R.string.label_discord,\n                            link = \"https://discord.gg/XjYgWXHb9Q\"\n                        )\n                    }\n                }\n\n                Row(\n                    verticalAlignment = Alignment.CenterVertically,\n                    horizontalArrangement = Arrangement.SpaceEvenly,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(top = 16.dp, bottom = 20.dp)\n                ) {\n                    UserEntry(\"Fiery\", \"Lead dev\\niOS\", \"FieryFlames\")\n                    UserEntry(\"Maisy\", \"Creator\\nVendetta\", \"maisymoe\", isLarge = true)\n                    UserEntry(\"Wing\", \"Lead dev\\nManager\", \"wingio\")\n                }\n\n                Text(\n                    text = stringResource(R.string.label_team),\n                    style = MaterialTheme.typography.labelLarge,\n                    modifier = Modifier.padding(16.dp),\n                    color = MaterialTheme.colorScheme.primary\n                )\n                Box(\n                    modifier = Modifier.padding(horizontal = 16.dp)\n                ) {\n                    ElevatedCard {\n                        Constants.TEAM_MEMBERS.forEachIndexed { i, member ->\n                            ListItem(\n                                text = member.name,\n                                subtext = member.role,\n                                imageUrl = \"https://github.com/${member.username}.png\",\n                                onClick = {\n                                    uriHandler.openUri(\"https://github.com/${member.username}\")\n                                }\n                            )\n                            if (i != Constants.TEAM_MEMBERS.lastIndex) {\n                                HorizontalDivider(\n                                    modifier = Modifier.padding(horizontal = 16.dp),\n                                    thickness = 0.5.dp,\n                                    color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)\n                                )\n                            }\n                        }\n                    }\n                }\n\n                Text(\n                    text = stringResource(R.string.label_special_thanks),\n                    style = MaterialTheme.typography.labelLarge,\n                    modifier = Modifier.padding(16.dp),\n                    color = MaterialTheme.colorScheme.primary\n                )\n                Box(\n                    modifier = Modifier.padding(horizontal = 16.dp)\n                ) {\n                    ElevatedCard {\n                        ListItem(\n                            text = \"rushii\",\n                            subtext = \"Installer, zip library, and a portion of patching\",\n                            imageUrl = \"https://github.com/rushiiMachine.png\",\n                            onClick = {\n                                uriHandler.openUri(\"https://github.com/rushiiMachine\")\n                            }\n                        )\n                        HorizontalDivider(\n                            modifier = Modifier.padding(horizontal = 16.dp),\n                            thickness = 0.5.dp,\n                            color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)\n                        )\n                        ListItem(\n                            text = \"Xinto\",\n                            subtext = \"for the preference manager\",\n                            imageUrl = \"https://github.com/X1nto.png\",\n                            onClick = {\n                                uriHandler.openUri(\"https://github.com/X1nto\")\n                            }\n                        )\n                    }\n                }\n\n                Box(\n                    modifier = Modifier.padding(16.dp)\n                ) {\n                    ElevatedCard {\n                        val navigator = LocalNavigator.currentOrThrow\n\n                        // ListItem(\n                        //     text = stringResource(R.string.label_translate),\n                        //     onClick = { uriHandler.openUri(\"https://crowdin.com/project/vendetta-manager\") }\n                        // )\n                        // HorizontalDivider(\n                        //     modifier = Modifier.padding(horizontal = 16.dp),\n                        //     thickness = 0.5.dp,\n                        //     color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)\n                        // )\n                        ListItem(\n                            text = stringResource(R.string.title_os_libraries),\n                            onClick = { navigator.push(LibrariesScreen()) }\n                        )\n                    }\n                }\n            }\n        }\n    }\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    private fun TitleBar(\n        scrollBehavior: TopAppBarScrollBehavior\n    ) {\n        val navigator = LocalNavigator.currentOrThrow\n\n        TopAppBar(\n            title = { Text(stringResource(R.string.title_about)) },\n            scrollBehavior = scrollBehavior,\n            navigationIcon = {\n                IconButton(onClick = { navigator.pop() }) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,\n                        contentDescription = stringResource(R.string.action_back)\n                    )\n                }\n            }\n        )\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/home/HomeScreen.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.home\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.basicMarquee\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.OpenInNew\nimport androidx.compose.material.icons.filled.Delete\nimport androidx.compose.material.icons.filled.Info\nimport androidx.compose.material.icons.filled.Refresh\nimport androidx.compose.material.icons.outlined.Settings\nimport androidx.compose.material3.Button\nimport androidx.compose.material3.ElevatedCard\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.koin.koinScreenModel\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.BuildConfig\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.ui.components.SegmentedButton\nimport dev.beefers.vendetta.manager.ui.screen.installer.InstallerScreen\nimport dev.beefers.vendetta.manager.ui.screen.settings.SettingsScreen\nimport dev.beefers.vendetta.manager.ui.viewmodel.home.HomeViewModel\nimport dev.beefers.vendetta.manager.ui.widgets.AppIcon\nimport dev.beefers.vendetta.manager.ui.widgets.dialog.EndOfLifeDialog\nimport dev.beefers.vendetta.manager.ui.widgets.dialog.StoragePermissionsDialog\nimport dev.beefers.vendetta.manager.ui.widgets.home.CommitList\nimport dev.beefers.vendetta.manager.ui.widgets.updater.UpdateDialog\nimport dev.beefers.vendetta.manager.utils.Constants\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport dev.beefers.vendetta.manager.utils.navigate\nimport org.koin.compose.koinInject\n\nclass HomeScreen : Screen {\n\n    @Composable\n    override fun Content() {\n        val navigator = LocalNavigator.currentOrThrow\n        val prefs: PreferenceManager = koinInject()\n        val viewModel: HomeViewModel = koinScreenModel()\n\n        val currentVersion = remember {\n            DiscordVersion.fromVersionCode(viewModel.installManager.current?.longVersionCode.toString())\n        }\n\n        val latestVersion =\n            remember(prefs.discordVersion, viewModel.discordVersions, prefs.channel) {\n                when {\n                    prefs.discordVersion.isBlank() -> {\n                        val ver = viewModel.discordVersions?.get(prefs.channel)\n                        if (ver == null) return@remember null\n\n                        if (ver.isSupported()) ver\n                        else DiscordVersion.fromVersionCode(ver.type.maxVersionCode.toString())\n                    }\n                    else -> DiscordVersion.fromVersionCode(prefs.discordVersion)\n                }\n            }\n\n        // == Dialogs == //\n\n        StoragePermissionsDialog()\n\n        if (viewModel.showEolDialog)\n            EndOfLifeDialog { viewModel.showEolDialog = false }\n\n\n        if (\n            viewModel.showUpdateDialog &&\n            viewModel.release != null &&\n            !BuildConfig.DEBUG\n        ) {\n            UpdateDialog(\n                release = viewModel.release!!,\n                isUpdating = viewModel.isUpdating,\n                onDismiss = { viewModel.showUpdateDialog = false },\n                onConfirm = {\n                    viewModel.downloadAndInstallUpdate()\n                }\n            )\n        }\n\n        // == Screen == //\n\n        Scaffold(\n            topBar = { TitleBar() },\n        ) { pv ->\n            Column(\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.spacedBy(16.dp),\n                modifier = Modifier\n                    .padding(pv)\n                    .padding(16.dp)\n                    .fillMaxWidth()\n            ) {\n                AppIcon(\n                    customIcon = prefs.patchIcon,\n                    releaseChannel = prefs.channel,\n                    modifier = Modifier.size(60.dp)\n                )\n\n                Text(\n                    text = prefs.appName,\n                    style = MaterialTheme.typography.titleLarge\n                )\n\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    AnimatedVisibility(visible = currentVersion != null) {\n                        Text(\n                            text = stringResource(\n                                R.string.version_current,\n                                currentVersion.toString()\n                            ),\n                            style = MaterialTheme.typography.labelLarge,\n                            color = LocalContentColor.current.copy(alpha = 0.5f),\n                            textAlign = TextAlign.Center\n                        )\n                    }\n\n                    val latestLabel =\n                        if (prefs.discordVersion.isNotBlank()) R.string.version_target else R.string.version_latest\n\n                    AnimatedVisibility(visible = latestVersion != null) {\n                        Text(\n                            text = stringResource(latestLabel, latestVersion.toString()),\n                            style = MaterialTheme.typography.labelLarge,\n                            color = LocalContentColor.current.copy(alpha = 0.5f),\n                            textAlign = TextAlign.Center\n                        )\n                    }\n                }\n\n                Button(\n                    onClick = {\n                        navigator.navigate(InstallerScreen(latestVersion!!))\n                    },\n                    enabled = latestVersion != null && (prefs.allowDowngrade || latestVersion >= (currentVersion ?: Constants.DUMMY_VERSION)),\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    val label = when {\n                        latestVersion == null -> R.string.msg_loading\n                        currentVersion == null -> R.string.action_install\n                        currentVersion == latestVersion -> R.string.action_reinstall\n                        latestVersion > currentVersion -> R.string.action_update\n                        else -> if (prefs.allowDowngrade) R.string.msg_downgrade else R.string.msg_downgrade_disallowed\n                    }\n\n                    Text(\n                        text = stringResource(label),\n                        textAlign = TextAlign.Center,\n                        maxLines = 1,\n                        modifier = Modifier\n                            .basicMarquee()\n                            .fillMaxWidth()\n                    )\n                }\n\n                AnimatedVisibility(visible = viewModel.installManager.current != null) {\n                    Row(\n                        horizontalArrangement = Arrangement.spacedBy(2.dp),\n                        modifier = Modifier.clip(RoundedCornerShape(16.dp))\n                    ) {\n                        SegmentedButton(\n                            icon = Icons.AutoMirrored.Filled.OpenInNew,\n                            text = stringResource(R.string.action_launch),\n                            onClick = { viewModel.launchVendetta() }\n                        )\n                        SegmentedButton(\n                            icon = Icons.Filled.Info,\n                            text = stringResource(R.string.action_info),\n                            onClick = { viewModel.launchVendettaInfo() }\n                        )\n                        SegmentedButton(\n                            icon = Icons.Filled.Delete,\n                            text = stringResource(R.string.action_uninstall),\n                            onClick = { viewModel.uninstallVendetta() }\n                        )\n                    }\n                }\n\n                ElevatedCard(\n                    modifier = Modifier\n                        .fillMaxSize()\n                ) {\n                    CommitList(\n                        commits = viewModel.commits.collectAsLazyPagingItems()\n                    )\n                }\n            }\n        }\n    }\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    private fun TitleBar() {\n        TopAppBar(\n            title = { Text(stringResource(R.string.title_home)) },\n            actions = { Actions() }\n        )\n    }\n\n    @Composable\n    private fun Actions() {\n        val viewModel: HomeViewModel = koinScreenModel()\n        val navigator = LocalNavigator.currentOrThrow\n\n        IconButton(onClick = { viewModel.getDiscordVersions() }) {\n            Icon(\n                imageVector = Icons.Filled.Refresh,\n                contentDescription = stringResource(R.string.action_reload)\n            )\n        }\n        IconButton(onClick = { navigator.navigate(SettingsScreen()) }) {\n            Icon(\n                imageVector = Icons.Outlined.Settings,\n                contentDescription = stringResource(R.string.action_open_about)\n            )\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/installer/InstallerScreen.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.installer\n\nimport android.content.Intent\nimport androidx.activity.ComponentActivity\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.ArrowBack\nimport androidx.compose.material.icons.automirrored.outlined.Article\nimport androidx.compose.material3.Button\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.core.screen.ScreenKey\nimport cafe.adriel.voyager.koin.koinScreenModel\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.installer.step.StepStatus\nimport dev.beefers.vendetta.manager.ui.viewmodel.installer.InstallerViewModel\nimport dev.beefers.vendetta.manager.ui.widgets.dialog.BackWarningDialog\nimport dev.beefers.vendetta.manager.ui.widgets.dialog.DownloadFailedDialog\nimport dev.beefers.vendetta.manager.ui.widgets.installer.StepGroupCard\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport okhttp3.internal.toImmutableList\nimport org.koin.compose.koinInject\nimport org.koin.core.parameter.parametersOf\nimport java.util.UUID\n\nclass InstallerScreen(\n    val version: DiscordVersion\n) : Screen {\n\n    override val key: ScreenKey = \"Installer-${UUID.randomUUID()}\"\n\n    @Composable\n    override fun Content() {\n        val nav = LocalNavigator.currentOrThrow\n        val activity = LocalContext.current as? ComponentActivity\n        val viewModel: InstallerViewModel = koinScreenModel {\n            parametersOf(version)\n        }\n\n        LaunchedEffect(viewModel.runner.currentStep) {\n            viewModel.expandGroup(viewModel.runner.currentStep?.group)\n        }\n\n        // Listen for error messages from InstallService\n        val intentListener: (Intent) -> Unit = remember {\n            {\n                val msg = it.getStringExtra(\"vendetta.extras.EXTRA_MESSAGE\")\n                if (msg?.isNotBlank() == true) viewModel.logError(msg)\n            }\n        }\n\n        DisposableEffect(Unit) {\n            activity?.addOnNewIntentListener(intentListener)\n            onDispose {\n                activity?.removeOnNewIntentListener(intentListener)\n            }\n        }\n\n        BackHandler(\n            enabled = !viewModel.runner.completed\n        ) {\n            viewModel.openBackDialog()\n        }\n\n        if(viewModel.backDialogOpened) {\n            BackWarningDialog(\n                onExitClick = {\n                    viewModel.closeBackDialog()\n                    viewModel.cancelInstall()\n                    nav.pop()\n                },\n                onClose = { viewModel.closeBackDialog() }\n            )\n        }\n\n        if(viewModel.runner.downloadErrored) {\n            DownloadFailedDialog(\n                onTryAgainClick = {\n                    viewModel.dismissDownloadFailedDialog()\n                    viewModel.cancelInstall()\n                    nav.replace(InstallerScreen(version))\n                },\n                onDismiss = {\n                    viewModel.dismissDownloadFailedDialog()\n                }\n            )\n        }\n\n        Scaffold(\n            topBar = {\n                TitleBar(\n                    viewModel = viewModel,\n                    onBackClick = {\n                        if(!viewModel.runner.completed)\n                            viewModel.openBackDialog()\n                        else\n                            nav.pop()\n                    }\n                )\n            }\n        ) {\n            Column(\n                modifier = Modifier\n                    .padding(it)\n                    .padding(16.dp)\n                    .verticalScroll(rememberScrollState())\n            ) {\n                for ((group, steps) in viewModel.groupedSteps) {\n                    key(group) {\n                        StepGroupCard(\n                            name = stringResource(group.nameRes),\n                            isCurrent = viewModel.expandedGroup == group,\n                            onClick = { viewModel.expandGroup(group) },\n                            steps = steps,\n                        )\n                    }\n                }\n\n                if (viewModel.runner.completed) {\n                    Spacer(modifier = Modifier.height(16.dp))\n\n                    // Show launch only if success\n                    val installSuccessful = viewModel.runner.currentStep?.status == StepStatus.SUCCESSFUL\n                    if (installSuccessful) {\n                        Button(\n                            onClick = { viewModel.launchVendetta() },\n                            modifier = Modifier.fillMaxWidth()\n                        ) {\n                            Text(stringResource(R.string.action_launch))\n                        }\n                    }\n\n                    Spacer(modifier = Modifier.height(8.dp))\n\n                    Row(\n                        horizontalArrangement = Arrangement.spacedBy(8.dp),\n                        modifier = Modifier\n                            .fillMaxWidth()\n                    ) {\n                        FilledTonalButton(\n                            onClick = { viewModel.shareLogs(activity!!) },\n                            modifier = Modifier.weight(1f)\n                        ) {\n                            Text(stringResource(R.string.action_share_logs))\n                        }\n\n                        FilledTonalButton(\n                            onClick = { viewModel.clearCache() },\n                            modifier = Modifier.weight(1f)\n                        ) {\n                            Text(stringResource(R.string.action_clear_cache))\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    private fun TitleBar(\n        onBackClick: () -> Unit,\n        viewModel: InstallerViewModel\n    ) {\n        val prefs: PreferenceManager = koinInject()\n        val nav = LocalNavigator.currentOrThrow\n\n        TopAppBar(\n            title = { Text(stringResource(R.string.title_installer)) },\n            navigationIcon = {\n                IconButton(onClick = onBackClick) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,\n                        contentDescription = stringResource(R.string.action_back)\n                    )\n                }\n            },\n            actions = {\n                if (prefs.isDeveloper && viewModel.runner.completed) {\n                    IconButton(onClick = { nav.push(LogViewerScreen(viewModel.runner.logger.logs.toImmutableList())) }) {\n                        Icon(\n                            imageVector = Icons.AutoMirrored.Outlined.Article,\n                            contentDescription = stringResource(R.string.action_view_logs)\n                        )\n                    }\n                }\n            }\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/installer/LogViewerScreen.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.installer\n\nimport androidx.compose.foundation.horizontalScroll\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.ArrowBack\nimport androidx.compose.material.icons.filled.Share\nimport androidx.compose.material.icons.outlined.MoreVert\nimport androidx.compose.material.icons.outlined.Save\nimport androidx.compose.material3.Checkbox\nimport androidx.compose.material3.DropdownMenu\nimport androidx.compose.material3.DropdownMenuItem\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.DpOffset\nimport androidx.compose.ui.unit.dp\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.koin.koinScreenModel\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.installer.util.LogEntry\nimport dev.beefers.vendetta.manager.ui.viewmodel.installer.LogViewerViewModel\nimport dev.beefers.vendetta.manager.ui.widgets.installer.LogLine\nimport dev.beefers.vendetta.manager.utils.DimenUtils\nimport dev.beefers.vendetta.manager.utils.rememberFileSaveLauncher\nimport dev.beefers.vendetta.manager.utils.thenIf\nimport org.koin.compose.koinInject\nimport org.koin.core.parameter.parametersOf\n\n@OptIn(ExperimentalMaterial3Api::class)\nclass LogViewerScreen(\n    val logs: List<LogEntry>\n) : Screen {\n\n    @Composable\n    override fun Content() {\n        val prefs: PreferenceManager = koinInject()\n        val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n        val viewModel: LogViewerViewModel = koinScreenModel {\n            parametersOf(logs)\n        }\n\n        Scaffold(\n            topBar = { Toolbar(scrollBehavior, viewModel) },\n            contentWindowInsets = WindowInsets(0, 0, 0, 0),\n            modifier = Modifier\n                .nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) { pv ->\n            LazyColumn(\n                contentPadding = PaddingValues(bottom = DimenUtils.navBarPadding),\n                modifier = Modifier\n                    .padding(pv)\n                    .thenIf(!prefs.logsLineWrap) {\n                        horizontalScroll(rememberScrollState())\n                    }\n            ) {\n                itemsIndexed(viewModel.logs) { i, log ->\n                    LogLine(\n                        log = log,\n                        alternateBackground = i % 2 == 0 && prefs.logsAlternateBackground,\n                        wrapText = prefs.logsLineWrap,\n                        logPadding = viewModel.maxLogLength,\n                        onLongClick = { viewModel.copyLog(log) }\n                    )\n                }\n            }\n        }\n    }\n\n    @Composable\n    private fun Toolbar(\n        scrollBehavior: TopAppBarScrollBehavior,\n        viewModel: LogViewerViewModel\n    ) {\n        val navigator = LocalNavigator.currentOrThrow\n        val context = LocalContext.current\n        val saveFile = rememberFileSaveLauncher(content = viewModel.logsString)\n\n        TopAppBar(\n            title = { Text(stringResource(R.string.title_logs)) },\n            navigationIcon = {\n                IconButton(onClick = { navigator.pop() }) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,\n                        contentDescription = stringResource(R.string.action_back)\n                    )\n                }\n            },\n            actions = {\n                var showDropdown by remember {\n                    mutableStateOf(false)\n                }\n\n                IconButton(onClick = { saveFile.launch(\"VD-Manager-${System.currentTimeMillis()}.log\") }) {\n                    Icon(\n                        imageVector = Icons.Outlined.Save,\n                        contentDescription = stringResource(R.string.action_save_logs)\n                    )\n                }\n\n                IconButton(onClick = { viewModel.shareLogs(context) }) {\n                    Icon(\n                        imageVector = Icons.Filled.Share,\n                        contentDescription = stringResource(R.string.action_share_logs)\n                    )\n                }\n\n                IconButton(onClick = { showDropdown = true }) {\n                    Icon(\n                        imageVector = Icons.Outlined.MoreVert,\n                        contentDescription = stringResource(R.string.action_more_options)\n                    )\n                }\n\n                Dropdown(\n                    viewModel,\n                    expanded = showDropdown,\n                    onDismiss = { showDropdown = false }\n                )\n            },\n            scrollBehavior = scrollBehavior\n        )\n    }\n\n    @Composable\n    fun Dropdown(\n        viewModel: LogViewerViewModel,\n        expanded: Boolean,\n        onDismiss: () -> Unit\n    ) {\n        val prefs: PreferenceManager = koinInject()\n\n        Box {\n            DropdownMenu(\n                expanded = expanded,\n                onDismissRequest = onDismiss,\n                offset = DpOffset(\n                    10.dp, 26.dp\n                )\n            ) {\n                DropdownMenuItem(\n                    text = { Text(stringResource(R.string.settings_logs_line_wrap)) },\n                    onClick = { prefs.logsLineWrap = !prefs.logsLineWrap },\n                    trailingIcon = {\n                        Checkbox(\n                            checked = prefs.logsLineWrap,\n                            onCheckedChange = { prefs.logsLineWrap = it }\n                        )\n                    }\n                )\n\n                DropdownMenuItem(\n                    text = { Text(stringResource(R.string.settings_logs_alternate_lines)) },\n                    onClick = { prefs.logsAlternateBackground = !prefs.logsAlternateBackground },\n                    trailingIcon = {\n                        Checkbox(\n                            checked = prefs.logsAlternateBackground,\n                            onCheckedChange = { prefs.logsAlternateBackground = it }\n                        )\n                    }\n                )\n\n                DropdownMenuItem(\n                    text = { Text(stringResource(R.string.action_copy_logs)) },\n                    onClick = { viewModel.copyLogs() }\n                )\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/libraries/LibrariesScreen.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.libraries\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.ArrowBack\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.LargeTopAppBar\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.koin.koinScreenModel\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.ui.components.ThinDivider\nimport dev.beefers.vendetta.manager.ui.viewmodel.libraries.LibrariesViewModel\nimport dev.beefers.vendetta.manager.ui.widgets.libraries.LibraryItem\n\nclass LibrariesScreen: Screen {\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    override fun Content() {\n        val viewModel: LibrariesViewModel = koinScreenModel()\n        val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n        Scaffold(\n            topBar = { TitleBar(scrollBehavior) },\n            contentWindowInsets = WindowInsets(0, 0, 0, 0),\n            modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) { pv ->\n            LazyColumn(\n                modifier = Modifier.padding(pv)\n            ) {\n                itemsIndexed(viewModel.libraries.libraries) { i, library ->\n                    Column {\n                        LibraryItem(\n                            library = library\n                        )\n                        if(i != viewModel.libraries.libraries.lastIndex) {\n                            ThinDivider()\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    fun TitleBar(\n        scrollBehavior: TopAppBarScrollBehavior\n    ) {\n        val navigator = LocalNavigator.currentOrThrow\n\n        LargeTopAppBar(\n            title = {\n                Text(stringResource(R.string.title_libraries))\n            },\n            navigationIcon = {\n                IconButton(onClick = { navigator.pop() }) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,\n                        contentDescription = stringResource(R.string.action_back)\n                    )\n                }\n            },\n            scrollBehavior = scrollBehavior\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/settings/AdvancedSettings.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.settings\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.ArrowBack\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.LargeTopAppBar\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.core.net.toUri\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.koin.koinScreenModel\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.Mirror\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsButton\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsItemChoice\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsSwitch\nimport dev.beefers.vendetta.manager.ui.viewmodel.settings.AdvancedSettingsViewModel\nimport dev.beefers.vendetta.manager.utils.DimenUtils\nimport org.koin.compose.koinInject\n\nclass AdvancedSettings: Screen {\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    override fun Content() {\n        val ctx = LocalContext.current\n        val prefs: PreferenceManager = koinInject()\n        val viewModel: AdvancedSettingsViewModel = koinScreenModel()\n        val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n        Scaffold(\n            topBar = { TitleBar(scrollBehavior) },\n            contentWindowInsets = WindowInsets(0, 0, 0, 0),\n            modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) { pv ->\n            Column(\n                modifier = Modifier\n                    .padding(pv)\n                    .verticalScroll(rememberScrollState())\n                    .padding(bottom = DimenUtils.navBarPadding)\n            ) {\n                SettingsItemChoice(\n                    label = stringResource(R.string.settings_check_updates),\n                    pref = prefs.updateDuration,\n                    labelFactory = {\n                        ctx.getString(it.labelRes)\n                    },\n                    onPrefChange = {\n                        prefs.updateDuration = it\n                        viewModel.updateCheckerDuration(it)\n                    }\n                )\n\n                SettingsItemChoice(\n                    label = stringResource(R.string.settings_mirror),\n                    pref = prefs.mirror,\n                    excludedOptions = listOf(Mirror.VENDETTA_ROCKS),\n                    labelFactory = {\n                        it.baseUrl.toUri().authority ?: it.baseUrl\n                    },\n                    onPrefChange = {\n                        prefs.mirror = it\n                    }\n                )\n\n                SettingsItemChoice(\n                    label = stringResource(R.string.install_method),\n                    pref = prefs.installMethod,\n                    labelFactory = {\n                        ctx.getString(it.labelRes)\n                    },\n                    onPrefChange = viewModel::setInstallMethod,\n                )\n\n                SettingsSwitch(\n                    label = stringResource(R.string.settings_auto_clear_cache),\n                    secondaryLabel = stringResource(R.string.settings_auto_clear_cache_description),\n                    pref = prefs.autoClearCache,\n                    onPrefChange = {\n                        prefs.autoClearCache = it\n                    }\n                )\n\n                SettingsButton(\n                    label = stringResource(R.string.action_clear_cache),\n                    onClick = {\n                        viewModel.clearCache()\n                    }\n                )\n            }\n        }\n    }\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    fun TitleBar(\n        scrollBehavior: TopAppBarScrollBehavior\n    ) {\n        val navigator = LocalNavigator.currentOrThrow\n\n        LargeTopAppBar(\n            title = {\n                Text(stringResource(R.string.settings_advanced))\n            },\n            navigationIcon = {\n                IconButton(onClick = { navigator.pop() }) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,\n                        contentDescription = stringResource(R.string.action_back)\n                    )\n                }\n            },\n            scrollBehavior = scrollBehavior\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/settings/AppearanceSettings.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.settings\n\nimport android.os.Build\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.ArrowBack\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.LargeTopAppBar\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsSwitch\nimport dev.beefers.vendetta.manager.ui.widgets.settings.ThemePicker\nimport dev.beefers.vendetta.manager.utils.DimenUtils\nimport org.koin.compose.koinInject\n\nclass AppearanceSettings: Screen {\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    override fun Content() {\n        val prefs: PreferenceManager = koinInject()\n        val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n        Scaffold(\n            topBar = { TitleBar(scrollBehavior) },\n            contentWindowInsets = WindowInsets(0, 0, 0, 0),\n            modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) { pv ->\n            Column(\n                modifier = Modifier\n                    .padding(pv)\n                    .verticalScroll(rememberScrollState())\n                    .padding(bottom = DimenUtils.navBarPadding)\n            ) {\n                ThemePicker(prefs = prefs)\n\n                Spacer(modifier = Modifier.height(16.dp))\n\n                SettingsSwitch(\n                    label = stringResource(R.string.settings_dynamic_color),\n                    secondaryLabel = stringResource(R.string.settings_dynamic_color_description),\n                    pref = prefs.monet,\n                    onPrefChange = {\n                        prefs.monet = it\n                    },\n                    disabled = Build.VERSION.SDK_INT < Build.VERSION_CODES.S\n                )\n            }\n        }\n    }\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    fun TitleBar(\n        scrollBehavior: TopAppBarScrollBehavior\n    ) {\n        val navigator = LocalNavigator.currentOrThrow\n\n        LargeTopAppBar(\n            title = {\n                Text(stringResource(R.string.settings_appearance))\n            },\n            navigationIcon = {\n                IconButton(onClick = { navigator.pop() }) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,\n                        contentDescription = stringResource(R.string.action_back)\n                    )\n                }\n            },\n            scrollBehavior = scrollBehavior\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/settings/CustomizationSettings.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.settings\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.ArrowBack\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.LargeTopAppBar\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsItemChoice\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsSwitch\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsTextField\nimport dev.beefers.vendetta.manager.utils.DimenUtils\nimport org.koin.compose.koinInject\n\nclass CustomizationSettings: Screen {\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    override fun Content() {\n        val ctx = LocalContext.current\n        val prefs: PreferenceManager = koinInject()\n        val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n        Scaffold(\n            topBar = { TitleBar(scrollBehavior) },\n            contentWindowInsets = WindowInsets(0, 0, 0, 0),\n            modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) { pv ->\n            Column(\n                modifier = Modifier\n                    .padding(pv)\n                    .verticalScroll(rememberScrollState())\n                    .padding(bottom = DimenUtils.navBarPadding)\n            ) {\n                SettingsTextField(\n                    label = stringResource(R.string.settings_app_name),\n                    pref = prefs.appName,\n                    onPrefChange = {\n                        prefs.appName = it\n                    }\n                )\n\n                SettingsSwitch(\n                    label = stringResource(R.string.settings_app_icon),\n                    secondaryLabel = stringResource(R.string.settings_app_icon_description),\n                    pref = prefs.patchIcon,\n                    onPrefChange = {\n                        prefs.patchIcon = it\n                    }\n                )\n\n                SettingsItemChoice(\n                    label = stringResource(R.string.settings_channel),\n                    pref = prefs.channel,\n                    labelFactory = {\n                        ctx.getString(it.labelRes)\n                    },\n                    onPrefChange = {\n                        prefs.channel = it\n                    }\n                )\n            }\n        }\n    }\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    fun TitleBar(\n        scrollBehavior: TopAppBarScrollBehavior\n    ) {\n        val navigator = LocalNavigator.currentOrThrow\n\n        LargeTopAppBar(\n            title = {\n                Text(stringResource(R.string.settings_customization))\n            },\n            navigationIcon = {\n                IconButton(onClick = { navigator.pop() }) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,\n                        contentDescription = stringResource(R.string.action_back)\n                    )\n                }\n            },\n            scrollBehavior = scrollBehavior\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/settings/DeveloperSettings.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.settings\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.ArrowBack\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.LargeTopAppBar\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.InstallManager\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsButton\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsSwitch\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsTextField\nimport dev.beefers.vendetta.manager.utils.DimenUtils\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport org.koin.compose.koinInject\nimport java.io.File\n\nclass DeveloperSettings: Screen {\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    override fun Content() {\n        val prefs: PreferenceManager = koinInject()\n        val installManager: InstallManager = koinInject()\n        val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n        var version by remember {\n            mutableStateOf(prefs.discordVersion)\n        }\n        var versionError by remember {\n            mutableStateOf(false)\n        }\n\n        val supportingText = when {\n            versionError -> stringResource(R.string.msg_invalid_version)\n            version.isNotBlank() -> DiscordVersion.fromVersionCode(version).toString()\n            else -> null\n        }\n\n        var moduleLocation by remember {\n            mutableStateOf(prefs.moduleLocation.absolutePath)\n        }\n\n        Scaffold(\n            topBar = { TitleBar(scrollBehavior) },\n            contentWindowInsets = WindowInsets(0, 0, 0, 0),\n            modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) { pv ->\n            Column(\n                modifier = Modifier\n                    .padding(pv)\n                    .verticalScroll(rememberScrollState())\n                    .padding(bottom = DimenUtils.navBarPadding)\n            ) {\n                SettingsTextField(\n                    label = stringResource(R.string.settings_package_name),\n                    pref = prefs.packageName,\n                    onPrefChange = {\n                        prefs.packageName = it\n                        installManager.getInstalled()\n                    }\n                )\n\n                SettingsTextField(\n                    label = stringResource(R.string.settings_version),\n                    pref = version,\n                    error = versionError,\n                    supportingText = supportingText,\n                    onPrefChange = {\n                        version = it\n                        if (DiscordVersion.fromVersionCode(it) == null && it.isNotBlank()) {\n                            versionError = true\n                        } else {\n                            versionError = false\n                            prefs.discordVersion = it\n                        }\n                    }\n                )\n\n                SettingsSwitch(\n                    label = stringResource(R.string.settings_debuggable),\n                    secondaryLabel = stringResource(R.string.settings_debuggable_description),\n                    pref = prefs.debuggable,\n                    onPrefChange = { prefs.debuggable = it }\n                )\n\n                SettingsTextField(\n                    label = stringResource(R.string.settings_module_location),\n                    supportingText = stringResource(R.string.settings_module_location_description),\n                    pref = moduleLocation,\n                    onPrefChange = {\n                        moduleLocation = it\n                        prefs.moduleLocation = File(it)\n                    }\n                )\n\n                SettingsButton(\n                    label = stringResource(R.string.settings_module_location_reset),\n                    onClick = {\n                        prefs.moduleLocation = prefs.DEFAULT_MODULE_LOCATION\n                    }\n                )\n\n                SettingsSwitch(\n                    label = stringResource(R.string.settings_allow_downgrade),\n                    secondaryLabel = stringResource(R.string.settings_allow_downgrade_description),\n                    pref = prefs.allowDowngrade,\n                    onPrefChange = { prefs.allowDowngrade = it }\n                )\n            }\n        }\n    }\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    fun TitleBar(\n        scrollBehavior: TopAppBarScrollBehavior\n    ) {\n        val navigator = LocalNavigator.currentOrThrow\n\n        LargeTopAppBar(\n            title = {\n                Text(stringResource(R.string.settings_developer))\n            },\n            navigationIcon = {\n                IconButton(onClick = { navigator.pop() }) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,\n                        contentDescription = stringResource(R.string.action_back)\n                    )\n                }\n            },\n            scrollBehavior = scrollBehavior\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/screen/settings/SettingsScreen.kt",
    "content": "package dev.beefers.vendetta.manager.ui.screen.settings\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.filled.ArrowBack\nimport androidx.compose.material.icons.outlined.AutoAwesome\nimport androidx.compose.material.icons.outlined.Code\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material.icons.outlined.Palette\nimport androidx.compose.material.icons.outlined.Tune\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.LargeTopAppBar\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.navigator.LocalNavigator\nimport cafe.adriel.voyager.navigator.currentOrThrow\nimport dev.beefers.vendetta.manager.BuildConfig\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsCategory\nimport dev.beefers.vendetta.manager.ui.screen.about.AboutScreen\nimport dev.beefers.vendetta.manager.utils.DimenUtils\nimport org.koin.compose.koinInject\n\nclass SettingsScreen : Screen {\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    override fun Content() {\n        val preferences: PreferenceManager = koinInject()\n        val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n\n        Scaffold(\n            topBar = { TitleBar(scrollBehavior) },\n            contentWindowInsets = WindowInsets(0, 0, 0, 0),\n            modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)\n        ) { pv ->\n            Column(\n                modifier = Modifier\n                    .padding(pv)\n                    .verticalScroll(rememberScrollState())\n                    .padding(bottom = DimenUtils.navBarPadding)\n            ) {\n                SettingsCategory(\n                    icon = Icons.Outlined.Palette,\n                    text = stringResource(R.string.settings_appearance),\n                    subtext = stringResource(R.string.settings_appearance_description),\n                    destination = ::AppearanceSettings\n                )\n\n                SettingsCategory(\n                    icon = Icons.Outlined.AutoAwesome,\n                    text = stringResource(R.string.settings_customization),\n                    subtext = stringResource(R.string.settings_customization_description),\n                    destination = ::CustomizationSettings\n                )\n\n                SettingsCategory(\n                    icon = Icons.Outlined.Tune,\n                    text = stringResource(R.string.settings_advanced),\n                    subtext = stringResource(R.string.settings_advanced_description),\n                    destination = ::AdvancedSettings\n                )\n\n                if (preferences.isDeveloper) {\n                    SettingsCategory(\n                        icon = Icons.Outlined.Code,\n                        text = stringResource(R.string.settings_developer),\n                        subtext = stringResource(R.string.settings_developer_description),\n                        destination = ::DeveloperSettings\n                    )\n                }\n\n                SettingsCategory(\n                    icon = Icons.Outlined.Info,\n                    text = stringResource(R.string.title_about),\n                    subtext = buildString {\n                        append(stringResource(R.string.app_name))\n                        append(\" v${BuildConfig.VERSION_NAME}\")\n                        if (preferences.isDeveloper) {\n                            append(\" (${BuildConfig.GIT_COMMIT}\")\n                            if (BuildConfig.GIT_LOCAL_CHANGES || BuildConfig.GIT_LOCAL_COMMITS) {\n                                append(\" - Local\")\n                            }\n                            append(\")\")\n                        }\n                    },\n                    destination = ::AboutScreen\n                )\n            }\n        }\n    }\n\n    @Composable\n    @OptIn(ExperimentalMaterial3Api::class)\n    fun TitleBar(\n        scrollBehavior: TopAppBarScrollBehavior\n    ) {\n        val navigator = LocalNavigator.currentOrThrow\n\n        LargeTopAppBar(\n            title = {\n                Text(stringResource(R.string.title_settings))\n            },\n            navigationIcon = {\n                IconButton(onClick = { navigator.pop() }) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Filled.ArrowBack,\n                        contentDescription = stringResource(R.string.action_back)\n                    )\n                }\n            },\n            scrollBehavior = scrollBehavior\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/theme/Theme.kt",
    "content": "package dev.beefers.vendetta.manager.ui.theme\n\nimport android.os.Build\nimport androidx.compose.foundation.isSystemInDarkTheme\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.darkColorScheme\nimport androidx.compose.material3.dynamicDarkColorScheme\nimport androidx.compose.material3.dynamicLightColorScheme\nimport androidx.compose.material3.lightColorScheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.platform.LocalContext\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.domain.manager.Theme\nimport org.koin.compose.koinInject\n\n@Composable\nfun VendettaManagerTheme(\n    content: @Composable () -> Unit\n) {\n    val prefs = koinInject<PreferenceManager>()\n    val dynamicColor = prefs.monet\n    val darkTheme = when (prefs.theme) {\n        Theme.SYSTEM -> isSystemInDarkTheme()\n        Theme.DARK -> true\n        Theme.LIGHT -> false\n    }\n\n    val colorScheme = when {\n        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {\n            val context = LocalContext.current\n            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)\n        }\n\n        darkTheme -> darkColorScheme()\n        else -> lightColorScheme()\n    }\n\n    MaterialTheme(\n        colorScheme = colorScheme,\n        typography = Typography,\n        content = content\n    )\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/theme/Type.kt",
    "content": "package dev.beefers.vendetta.manager.ui.theme\n\nimport androidx.compose.material3.Typography\n\n// Set of Material typography styles to start with\nval Typography = Typography()"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/viewmodel/home/HomeViewModel.kt",
    "content": "package dev.beefers.vendetta.manager.ui.viewmodel.home\n\nimport android.content.Context\nimport android.content.Intent\nimport android.net.Uri\nimport android.os.Environment\nimport android.provider.Settings\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.cachedIn\nimport cafe.adriel.voyager.core.model.ScreenModel\nimport cafe.adriel.voyager.core.model.screenModelScope\nimport dev.beefers.vendetta.manager.BuildConfig\nimport dev.beefers.vendetta.manager.domain.manager.DownloadManager\nimport dev.beefers.vendetta.manager.domain.manager.InstallManager\nimport dev.beefers.vendetta.manager.domain.manager.InstallMethod\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.domain.repository.RestRepository\nimport dev.beefers.vendetta.manager.installer.Installer\nimport dev.beefers.vendetta.manager.installer.session.SessionInstaller\nimport dev.beefers.vendetta.manager.installer.shizuku.ShizukuInstaller\nimport dev.beefers.vendetta.manager.network.dto.Release\nimport dev.beefers.vendetta.manager.network.utils.CommitsPagingSource\nimport dev.beefers.vendetta.manager.network.utils.dataOrNull\nimport dev.beefers.vendetta.manager.network.utils.ifSuccessful\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport dev.beefers.vendetta.manager.utils.isMiui\nimport kotlinx.coroutines.launch\nimport java.io.File\n\nclass HomeViewModel(\n    private val repo: RestRepository,\n    val context: Context,\n    val prefs: PreferenceManager,\n    val installManager: InstallManager,\n    private val downloadManager: DownloadManager\n) : ScreenModel {\n\n    private val cacheDir = context.externalCacheDir ?: File(\n        Environment.getExternalStorageDirectory(),\n        Environment.DIRECTORY_DOWNLOADS\n    ).resolve(\"BunnyManager\").also { it.mkdirs() }\n\n    var discordVersions by mutableStateOf<Map<DiscordVersion.Type, DiscordVersion?>?>(null)\n        private set\n\n    var release by mutableStateOf<Release?>(null)\n        private set\n\n    var showUpdateDialog by mutableStateOf(false)\n    var showEolDialog by mutableStateOf(true)\n    var isUpdating by mutableStateOf(false)\n    val commits = Pager(PagingConfig(pageSize = 30)) { CommitsPagingSource(repo) }.flow.cachedIn(screenModelScope)\n\n    init {\n        getDiscordVersions()\n        checkForUpdate()\n    }\n\n    fun getDiscordVersions() {\n        screenModelScope.launch {\n            discordVersions = repo.getLatestDiscordVersions().dataOrNull\n            if (prefs.autoClearCache) autoClearCache()\n        }\n    }\n\n    fun launchVendetta() {\n        installManager.current?.let {\n            val intent = context.packageManager.getLaunchIntentForPackage(it.packageName)?.apply {\n                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n            }\n            context.startActivity(intent)\n        }\n    }\n\n    fun uninstallVendetta() {\n        installManager.uninstall()\n    }\n\n    fun launchVendettaInfo() {\n        installManager.current?.let {\n            Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {\n                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n                data = Uri.parse(\"package:${it.packageName}\")\n                context.startActivity(this)\n            }\n        }\n    }\n\n    private fun autoClearCache() {\n        val currentVersion =\n            DiscordVersion.fromVersionCode(installManager.current?.longVersionCode.toString()) ?: return\n        val latestVersion = when {\n            prefs.discordVersion.isBlank() -> discordVersions?.get(prefs.channel)\n            else -> DiscordVersion.fromVersionCode(prefs.discordVersion)\n        } ?: return\n\n        if (latestVersion > currentVersion) {\n            for (file in (context.externalCacheDir ?: context.cacheDir).listFiles()\n                ?: emptyArray()) {\n                if (file.isDirectory) file.deleteRecursively()\n            }\n        }\n    }\n\n    private fun checkForUpdate() {\n        screenModelScope.launch {\n            release = repo.getLatestRelease(\"pyoncord/BunnyManager\").dataOrNull\n            release?.let {\n                showUpdateDialog = it.tagName.toInt() > BuildConfig.VERSION_CODE\n            }\n            repo.getLatestRelease(\"pyoncord/BunnyXposed\").ifSuccessful {\n                if (prefs.moduleVersion != it.tagName) {\n                    prefs.moduleVersion = it.tagName\n                    val module = File(cacheDir, \"xposed.apk\")\n                    if (module.exists()) module.delete()\n                }\n            }\n        }\n    }\n\n    fun downloadAndInstallUpdate() {\n        screenModelScope.launch {\n            val update = File(cacheDir, \"update.apk\")\n            if (update.exists()) update.delete()\n            isUpdating = true\n            downloadManager.downloadUpdate(update)\n            isUpdating = false\n\n            val installer: Installer = when (prefs.installMethod) {\n                InstallMethod.DEFAULT -> SessionInstaller(context)\n                InstallMethod.SHIZUKU -> ShizukuInstaller(context)\n            }\n\n            installer.installApks(silent = !isMiui, update)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/viewmodel/installer/InstallerViewModel.kt",
    "content": "package dev.beefers.vendetta.manager.ui.viewmodel.installer\n\nimport android.content.Context\nimport android.content.Intent\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.core.app.ShareCompat\nimport androidx.core.content.FileProvider\nimport cafe.adriel.voyager.core.model.ScreenModel\nimport cafe.adriel.voyager.core.model.screenModelScope\nimport dev.beefers.vendetta.manager.BuildConfig\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.InstallManager\nimport dev.beefers.vendetta.manager.installer.step.Step\nimport dev.beefers.vendetta.manager.installer.step.StepGroup\nimport dev.beefers.vendetta.manager.installer.step.StepRunner\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport dev.beefers.vendetta.manager.utils.showToast\nimport kotlinx.collections.immutable.ImmutableMap\nimport kotlinx.collections.immutable.toImmutableMap\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.cancel\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport java.util.concurrent.atomic.AtomicBoolean\n\nclass InstallerViewModel(\n    private val context: Context,\n    private val installManager: InstallManager,\n    discordVersion: DiscordVersion\n) : ScreenModel {\n\n    val runner = StepRunner(discordVersion)\n\n    val groupedSteps: ImmutableMap<StepGroup, List<Step>> = StepGroup.entries\n        .associateWith { group ->\n            runner.steps.filter { step -> step.group == group }\n        }\n        .toImmutableMap()\n\n    private val tempLogStorageDir = context.filesDir.resolve(\"logsTmp\").also {\n        it.mkdirs()\n    }\n\n    private val logsString by lazy {\n        runner.logger.logs.joinToString(\"\\n\") { it.toString() }\n    }\n\n    private val installationRunning = AtomicBoolean(false)\n\n    private val job = screenModelScope.launch(Dispatchers.Main) {\n        if (installationRunning.getAndSet(true)) {\n            return@launch\n        }\n\n        withContext(Dispatchers.IO) {\n            runner.runAll()\n        }\n    }\n\n    var backDialogOpened by mutableStateOf(false)\n        private set\n\n    var expandedGroup by mutableStateOf<StepGroup?>(null)\n        private set\n\n    fun logError(msg: String?) {\n        runner.logger.e(\"\")\n        runner.logger.e(msg)\n    }\n\n    fun clearCache() {\n        runner.clearCache()\n        context.showToast(R.string.msg_cleared_cache)\n    }\n\n    fun openBackDialog() {\n        backDialogOpened = true\n    }\n\n    fun closeBackDialog() {\n        backDialogOpened = false\n    }\n\n    fun dismissDownloadFailedDialog() {\n        runner.downloadErrored = false\n    }\n\n    fun expandGroup(group: StepGroup?) {\n        expandedGroup = group\n    }\n\n    fun launchVendetta() {\n        installManager.current?.let {\n            val intent = context.packageManager.getLaunchIntentForPackage(it.packageName)?.apply {\n                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n            }\n            context.startActivity(intent)\n        }\n    }\n\n    fun cancelInstall() {\n        runCatching {\n            job.cancel(\"User exited the installer\")\n        }\n    }\n\n    private fun saveToAppStorage(): File {\n        // Delete old logs to prevent junk buildup\n        tempLogStorageDir.deleteRecursively()\n        tempLogStorageDir.mkdirs()\n\n        val tmpFile = tempLogStorageDir.resolve(\"VD-Manager-${System.currentTimeMillis()}.log\")\n        tmpFile.outputStream().use { stream ->\n            stream.write(logsString.toByteArray())\n        }\n\n        return tmpFile\n    }\n\n    fun shareLogs(activityContext: Context) {\n        val saved = saveToAppStorage()\n        val uri = FileProvider.getUriForFile(\n            activityContext,\n            BuildConfig.APPLICATION_ID + \".provider\",\n            saved\n        )\n\n        ShareCompat.IntentBuilder(activityContext)\n            .setType(\"text/plain\")\n            .setStream(uri)\n            .apply {\n                intent.apply {\n                    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)\n                }\n            }\n            .startChooser()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/viewmodel/installer/LogViewerViewModel.kt",
    "content": "package dev.beefers.vendetta.manager.ui.viewmodel.installer\n\nimport android.content.Context\nimport android.content.Intent\nimport androidx.core.app.ShareCompat\nimport androidx.core.content.FileProvider\nimport cafe.adriel.voyager.core.model.ScreenModel\nimport dev.beefers.vendetta.manager.BuildConfig\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.util.LogEntry\nimport dev.beefers.vendetta.manager.utils.copyText\nimport dev.beefers.vendetta.manager.utils.showToast\nimport java.io.File\n\nclass LogViewerViewModel(\n    private val context: Context,\n    val logs: List<LogEntry>\n): ScreenModel {\n\n    private val tempLogStorageDir = context.filesDir.resolve(\"logsTmp\").also {\n        it.mkdirs()\n    }\n\n    val logsString by lazy {\n        logs.joinToString(\"\\n\") { it.toString() }\n    }\n\n    val maxLogLength = logs.maxOf { it.message.length }\n\n    fun copyLog(log: LogEntry) {\n        context.copyText(log.toString())\n        context.showToast(R.string.msg_copied)\n    }\n\n    fun copyLogs() {\n        context.copyText(logsString)\n        context.showToast(R.string.msg_copied)\n    }\n\n    private fun saveToAppStorage(): File {\n        tempLogStorageDir.deleteRecursively()\n        tempLogStorageDir.mkdirs()\n\n        val tmpFile = tempLogStorageDir.resolve(\"VD-Manager-${System.currentTimeMillis()}.log\")\n        tmpFile.outputStream().use { stream ->\n            stream.write(logsString.toByteArray())\n        }\n\n        return tmpFile\n    }\n\n    fun shareLogs(activityContext: Context) {\n        val saved = saveToAppStorage()\n        val uri = FileProvider.getUriForFile(\n            activityContext,\n            BuildConfig.APPLICATION_ID + \".provider\",\n            saved\n        )\n\n        ShareCompat.IntentBuilder(activityContext)\n            .setType(\"text/plain\")\n            .setStream(uri)\n            .apply {\n                intent.apply {\n                    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)\n                }\n            }\n            .startChooser()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/viewmodel/libraries/LibrariesViewModel.kt",
    "content": "package dev.beefers.vendetta.manager.ui.viewmodel.libraries\n\nimport android.content.Context\nimport cafe.adriel.voyager.core.model.ScreenModel\nimport com.mikepenz.aboutlibraries.Libs\nimport com.mikepenz.aboutlibraries.util.withContext\n\nclass LibrariesViewModel(\n    context: Context\n): ScreenModel {\n\n    val libraries = Libs.Builder().withContext(context).build()\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/viewmodel/settings/AdvancedSettingsViewModel.kt",
    "content": "package dev.beefers.vendetta.manager.ui.viewmodel.settings\n\nimport android.content.Context\nimport android.os.Environment\nimport androidx.work.ExistingPeriodicWorkPolicy\nimport androidx.work.PeriodicWorkRequestBuilder\nimport androidx.work.WorkManager\nimport cafe.adriel.voyager.core.model.ScreenModel\nimport cafe.adriel.voyager.core.model.screenModelScope\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.InstallMethod\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.domain.manager.UpdateCheckerDuration\nimport dev.beefers.vendetta.manager.installer.shizuku.ShizukuPermissions\nimport dev.beefers.vendetta.manager.updatechecker.worker.UpdateWorker\nimport dev.beefers.vendetta.manager.utils.showToast\nimport kotlinx.coroutines.launch\nimport java.io.File\n\nclass AdvancedSettingsViewModel(\n    private val context: Context,\n    private val prefs: PreferenceManager,\n) : ScreenModel {\n    private val cacheDir = context.externalCacheDir ?: File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DOWNLOADS).resolve(\"BunnyManager\").also { it.mkdirs() }\n\n    fun clearCache() {\n        cacheDir.deleteRecursively()\n        context.showToast(R.string.msg_cleared_cache)\n    }\n\n    fun updateCheckerDuration(updateCheckerDuration: UpdateCheckerDuration) {\n        val wm = WorkManager.getInstance(context)\n        when (updateCheckerDuration) {\n            UpdateCheckerDuration.DISABLED -> wm.cancelUniqueWork(\"dev.beefers.vendetta.manager.UPDATE_CHECK\")\n            else -> wm.enqueueUniquePeriodicWork(\n                \"dev.beefers.vendetta.manager.UPDATE_CHECK\",\n                ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,\n                PeriodicWorkRequestBuilder<UpdateWorker>(\n                    updateCheckerDuration.time,\n                    updateCheckerDuration.unit\n                ).build()\n            )\n        }\n    }\n\n    fun setInstallMethod(method: InstallMethod) {\n        when (method) {\n            InstallMethod.SHIZUKU -> screenModelScope.launch {\n                if (ShizukuPermissions.waitShizukuPermissions()) {\n                    prefs.installMethod = InstallMethod.SHIZUKU\n                } else {\n                    context.showToast(R.string.msg_shizuku_denied)\n                }\n            }\n\n            else -> prefs.installMethod = method\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/AppIcon.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.painterResource\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\n\n@Composable\nfun AppIcon(\n    customIcon: Boolean,\n    releaseChannel: DiscordVersion.Type,\n    modifier: Modifier = Modifier\n) {\n    val iconColor = remember(customIcon, releaseChannel) {\n        when {\n            customIcon -> Color(0xFF48488B)\n            releaseChannel == DiscordVersion.Type.ALPHA -> Color(0xFFFBB33C)\n            else -> Color(0xFF5865F2)\n        }\n    }\n\n    Image(\n        painter = painterResource(id = R.drawable.ic_discord_icon),\n        contentDescription = null,\n        modifier = modifier\n            .clip(CircleShape)\n            .background(iconColor)\n    )\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/about/LinkItem.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.about\n\nimport androidx.annotation.DrawableRes\nimport androidx.annotation.StringRes\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.ripple\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun LinkItem(\n    @DrawableRes icon: Int,\n    @StringRes label: Int,\n    link: String\n) {\n    val uriHandler = LocalUriHandler.current\n\n    Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp),\n        horizontalAlignment = Alignment.CenterHorizontally,\n        modifier = Modifier\n            .clickable(\n                onClick = { uriHandler.openUri(link) },\n                indication = ripple(bounded = false, radius = 40.dp),\n                interactionSource = remember { MutableInteractionSource() }\n            )\n            .padding(8.dp)\n    ) {\n        Icon(\n            painter = painterResource(icon),\n            contentDescription = stringResource(label),\n            modifier = Modifier.size(30.dp)\n        )\n        Text(\n            text = stringResource(label),\n            style = MaterialTheme.typography.labelMedium\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/about/ListItem.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.about\n\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.unit.dp\nimport coil.compose.AsyncImage\n\n@Composable\nfun ListItem(\n    text: String,\n    subtext: String? = null,\n    imageUrl: String? = null,\n    onClick: (() -> Unit)? = null\n) {\n\n    Row(\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.spacedBy(16.dp),\n        modifier = Modifier\n            .clickable(\n                enabled = onClick != null,\n                onClick = onClick ?: { }\n            )\n            .padding(16.dp)\n            .fillMaxWidth()\n    ) {\n        imageUrl?.let {\n            AsyncImage(\n                model = it,\n                contentDescription = null,\n                modifier = Modifier\n                    .size(35.dp)\n                    .clip(CircleShape)\n            )\n        }\n\n        Column(\n            verticalArrangement = Arrangement.spacedBy(4.dp)\n        ) {\n            Text(\n                text = text,\n                style = MaterialTheme.typography.bodyLarge\n            )\n            subtext?.let {\n                Text(\n                    text = it,\n                    style = MaterialTheme.typography.labelMedium,\n                    color = LocalContentColor.current.copy(alpha = 0.5f)\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/about/UserEntry.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.about\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.ripple\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport coil.compose.AsyncImage\n\n@Composable\nfun UserEntry(\n    name: String,\n    roles: String,\n    username: String = name,\n    isLarge: Boolean = false\n) {\n    val uriHandler = LocalUriHandler.current\n    Column(\n        horizontalAlignment = Alignment.CenterHorizontally,\n        verticalArrangement = Arrangement.spacedBy(16.dp),\n        modifier = Modifier\n            .clickable(\n                onClick = { uriHandler.openUri(\"https://github.com/$username\") },\n                indication = ripple(bounded = false, radius = 90.dp),\n                interactionSource = remember { MutableInteractionSource() }\n            )\n            .widthIn(min = 100.dp)\n    ) {\n        AsyncImage(\n            modifier = Modifier\n                .size(if (isLarge) 70.dp else 50.dp)\n                .clip(CircleShape)\n                .background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)),\n            model = \"https://github.com/$username.png\",\n            contentDescription = username\n        )\n\n        Column(\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Text(\n                text = name,\n                style = MaterialTheme.typography.titleMedium.copy(\n                    fontSize = 18.sp\n                )\n            )\n\n            Text(\n                text = roles,\n                style = MaterialTheme.typography.titleSmall.copy(\n                    color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)\n                ),\n                textAlign = TextAlign.Center\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/dialog/BackWarningDialog.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.dialog\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Warning\nimport androidx.compose.material3.AlertDialog\nimport androidx.compose.material3.ButtonDefaults\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TextButton\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport dev.beefers.vendetta.manager.R\n\n@Composable\nfun BackWarningDialog(\n    onExitClick: () -> Unit,\n    onClose: () -> Unit\n) {\n    AlertDialog(\n        onDismissRequest = onClose,\n        confirmButton = {\n            FilledTonalButton(\n                onClick = onClose,\n                colors = ButtonDefaults.filledTonalButtonColors(\n                    containerColor = MaterialTheme.colorScheme.error,\n                    contentColor = MaterialTheme.colorScheme.onError\n                )\n            ) {\n                Text(stringResource(R.string.action_dismiss_nevermind))\n            }\n        },\n        dismissButton = {\n            TextButton(\n                onClick = onExitClick,\n                colors = ButtonDefaults.textButtonColors(\n                    contentColor = MaterialTheme.colorScheme.onErrorContainer\n                )\n            ) {\n                Text(stringResource(R.string.action_confirm_exit))\n            }\n        },\n        title = {\n            Text(stringResource(R.string.title_warning))\n        },\n        text = {\n            Text(stringResource(R.string.msg_back_warning))\n        },\n        icon = {\n            Icon(Icons.Filled.Warning, contentDescription = null)\n        },\n        containerColor = MaterialTheme.colorScheme.errorContainer,\n        iconContentColor = MaterialTheme.colorScheme.onErrorContainer,\n        titleContentColor = MaterialTheme.colorScheme.onErrorContainer,\n        textContentColor = MaterialTheme.colorScheme.onErrorContainer\n    )\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/dialog/DownloadFailedDialog.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.dialog\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material3.AlertDialog\nimport androidx.compose.material3.Button\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TextButton\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.ui.components.settings.SettingsChoiceDialog\nimport org.koin.compose.koinInject\n\n@Composable\nfun DownloadFailedDialog(\n    onTryAgainClick: () -> Unit,\n    onDismiss: () -> Unit\n) {\n    val prefs: PreferenceManager = koinInject()\n    var mirrorPickerOpened by remember {\n        mutableStateOf(false)\n    }\n\n    SettingsChoiceDialog(\n        visible = mirrorPickerOpened,\n        default = prefs.mirror,\n        title = { Text(stringResource(R.string.settings_mirror)) },\n        labelFactory = { it.baseUrl.toUri().authority ?: it.baseUrl },\n        onRequestClose = { mirrorPickerOpened = false },\n        onChoice = {\n            prefs.mirror = it\n            mirrorPickerOpened = false\n        }\n    )\n\n    AlertDialog(\n        onDismissRequest = onDismiss,\n        text = {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(16.dp)\n            ) {\n                Text(stringResource(R.string.msg_change_mirror))\n                FilledTonalButton(\n                    onClick = { mirrorPickerOpened = true },\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    Text(\n                        text = prefs.mirror.baseUrl.toUri().authority ?: prefs.mirror.baseUrl\n                    )\n                }\n            }\n        },\n        dismissButton = {\n            TextButton(onClick = onDismiss) {\n                Text(stringResource(R.string.action_dismiss_no_thanks))\n            }\n        },\n        confirmButton = {\n            Button(onClick = onTryAgainClick) {\n                Text(stringResource(R.string.action_try_again))\n            }\n        },\n        title = {\n            Text(stringResource(R.string.title_dl_failed))\n        }\n    )\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/dialog/EndOfLifeDialog.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.dialog\n\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Warning\nimport androidx.compose.material3.AlertDialog\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport kotlinx.coroutines.delay\n\n@Composable\nfun EndOfLifeDialog(onDismiss: () -> Unit) {\n    var secondsLeft by remember { mutableIntStateOf(5) }\n    val canDismiss = secondsLeft <= 0\n\n    LaunchedEffect(secondsLeft) {\n        if (secondsLeft > 0) {\n            delay(1000L)\n            secondsLeft--\n        }\n    }\n\n    val maybeOnDismiss = { if (canDismiss) onDismiss() }\n\n    AlertDialog(\n        onDismissRequest = maybeOnDismiss,\n        title = { Text(text = \"Project Unmaintained\") },\n        text = {\n            Text(\n                text = \"Bunny is no longer maintained. Versions have been set to the latest ones supported by Bunny. Please consider switching to an alternative client mod.\"\n            )\n        },\n        icon = {\n            Icon(Icons.Filled.Warning, contentDescription = null)\n        },\n        confirmButton = {\n            FilledTonalButton(\n                enabled = canDismiss,\n                onClick = maybeOnDismiss,\n            ) {\n                Text(text = \"Understood${if (!canDismiss) \" ($secondsLeft)\" else \"\"}\")\n            }\n        }\n    )\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/dialog/StoragePermissionsDialog.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.dialog\n\nimport android.Manifest\nimport android.annotation.SuppressLint\nimport android.content.Intent\nimport android.os.Build\nimport android.os.Environment\nimport android.provider.Settings\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.compose.material3.*\nimport androidx.compose.runtime.*\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.window.DialogProperties\nimport androidx.core.net.toUri\nimport com.google.accompanist.permissions.*\nimport dev.beefers.vendetta.manager.BuildConfig\nimport dev.beefers.vendetta.manager.R\n\n@Composable\nfun StoragePermissionsDialog() {\n    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {\n        ManageStorageDialog()\n    } else {\n        ExternalStorageDialog()\n    }\n}\n\n@Composable\n@SuppressLint(\"NewApi\")\nprivate fun ManageStorageDialog() {\n    var manageStorageGranted by remember { mutableStateOf(Environment.isExternalStorageManager()) }\n\n    if (!manageStorageGranted) {\n        AlertDialog(\n            onDismissRequest = {},\n            confirmButton = {\n                val launcher =\n                    rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {\n                        if (Environment.isExternalStorageManager()) {\n                            manageStorageGranted = true\n                        }\n                    }\n\n                Button(\n                    onClick = {\n                        Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)\n                            .setData(\"package:${BuildConfig.APPLICATION_ID}\".toUri())\n                            .let { launcher.launch(it) }\n                    }\n                ) {\n                    Text(stringResource(R.string.action_open_settings))\n                }\n            },\n            title = { Text(stringResource(R.string.title_permission_grant)) },\n            text = { Text(stringResource(R.string.msg_permission_grant)) },\n            properties = DialogProperties(\n                dismissOnBackPress = false,\n                dismissOnClickOutside = false\n            )\n        )\n    }\n}\n\n@OptIn(ExperimentalPermissionsApi::class)\n@Composable\nprivate fun ExternalStorageDialog() {\n    val writeStorageState = rememberPermissionState(Manifest.permission.WRITE_EXTERNAL_STORAGE)\n\n    if (!writeStorageState.status.isGranted) {\n        AlertDialog(\n            onDismissRequest = {},\n            confirmButton = {\n                Button(onClick = writeStorageState::launchPermissionRequest) {\n                    Text(stringResource(R.string.action_confirm))\n                }\n            },\n            title = { Text(stringResource(R.string.title_permission_grant)) },\n            text = { Text(stringResource(R.string.msg_permission_grant)) },\n            properties = DialogProperties(\n                dismissOnBackPress = false,\n                dismissOnClickOutside = false\n            )\n        )\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/home/Commit.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.home\n\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport coil.compose.AsyncImage\nimport dev.beefers.vendetta.manager.network.dto.Commit\nimport kotlinx.datetime.toJavaInstant\nimport java.text.SimpleDateFormat\nimport java.util.Date\n\n@Composable\nfun Commit(\n    commit: Commit\n) {\n    val uriHandler = LocalUriHandler.current\n\n    Column(\n        verticalArrangement = Arrangement.spacedBy(10.dp),\n        modifier = Modifier\n            .fillMaxWidth()\n            .clickable { uriHandler.openUri(commit.url) }\n            .padding(16.dp)\n    ) {\n        Row(\n            horizontalArrangement = Arrangement.spacedBy(8.dp),\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            Row(\n                horizontalArrangement = Arrangement.spacedBy(10.dp),\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                AsyncImage(\n                    model = commit.author?.avatar ?: \"https://github.com/ghost.png\",\n                    contentDescription = commit.author?.username ?: \"ghost\",\n                    modifier = Modifier\n                        .size(20.dp)\n                        .clip(CircleShape)\n                )\n\n                Text(\n                    text = commit.author?.username ?: \"ghost\",\n                    style = MaterialTheme.typography.labelMedium\n                )\n            }\n\n            Text(\n                \"•\",\n                style = MaterialTheme.typography.labelLarge\n            )\n\n            Text(\n                text = commit.sha.substring(0, 7),\n                style = MaterialTheme.typography.labelMedium,\n                color = MaterialTheme.colorScheme.primary,\n                fontFamily = FontFamily.Monospace\n            )\n\n            Text(\n                text = SimpleDateFormat\n                    .getDateInstance(SimpleDateFormat.SHORT)\n                    .format(Date.from(commit.info.committer.date.toJavaInstant())),\n                style = MaterialTheme.typography.labelMedium,\n                color = LocalContentColor.current.copy(alpha = 0.5f),\n                textAlign = TextAlign.End,\n                modifier = Modifier.weight(1f)\n            )\n        }\n\n        Text(\n            text = commit.info.message.split(\"\\n\").first(),\n            style = MaterialTheme.typography.labelLarge\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/home/CommitList.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.home\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.material3.Button\nimport androidx.compose.material3.CircularProgressIndicator\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.paging.LoadState\nimport androidx.paging.compose.LazyPagingItems\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.network.dto.Commit\nimport dev.beefers.vendetta.manager.utils.itemsIndexed\n\n@Composable\nfun CommitList(\n    commits: LazyPagingItems<Commit>\n) {\n    val loading =\n        commits.loadState.append is LoadState.Loading || commits.loadState.refresh is LoadState.Loading\n    val failed =\n        commits.loadState.append is LoadState.Error || commits.loadState.refresh is LoadState.Error\n\n    LazyColumn {\n        itemsIndexed(\n            items = commits,\n            key = { _, commit -> commit.sha }\n        ) { i, commit ->\n            Column {\n                Commit(commit = commit)\n                if (i < commits.itemSnapshotList.lastIndex) {\n                    HorizontalDivider(\n                        modifier = Modifier.padding(horizontal = 16.dp),\n                        thickness = 0.5.dp,\n                        color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)\n                    )\n                }\n            }\n        }\n\n        if (loading) {\n            item {\n                Box(\n                    contentAlignment = Alignment.TopCenter,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(16.dp)\n                ) {\n                    CircularProgressIndicator(\n                        strokeWidth = 3.dp,\n                        modifier = Modifier.size(30.dp)\n                    )\n                }\n            }\n        }\n\n        if (failed) {\n            item {\n                Column(\n                    verticalArrangement = Arrangement.spacedBy(12.dp),\n                    horizontalAlignment = Alignment.CenterHorizontally,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(16.dp)\n                ) {\n                    Text(\n                        text = stringResource(R.string.msg_load_fail),\n                        style = MaterialTheme.typography.labelLarge,\n                        textAlign = TextAlign.Center\n                    )\n\n                    Button(onClick = { commits.retry() }) {\n                        Text(stringResource(R.string.action_retry))\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/installer/LogLine.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.installer\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.combinedClickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.util.LogEntry\nimport dev.beefers.vendetta.manager.utils.thenIf\n\n/**\n * UI for a log entry, displays the level and message and can be expanded with a click to show the timestamp\n *\n * @param log The log to display\n * @param alternateBackground Whether or not to use the alternating background\n * @param wrapText Whether or not the message should have line wrapping\n * @param logPadding Force message to contain this many characters, used to make all lines equal in length\n * @param onLongClick Action to take when long clicking, should just copy the log to clipboard\n * @param modifier [Modifier] for this component\n */\n@Composable\n@OptIn(ExperimentalFoundationApi::class)\nfun LogLine(\n    log: LogEntry,\n    alternateBackground: Boolean,\n    wrapText: Boolean,\n    logPadding: Int,\n    onLongClick: () -> Unit,\n    modifier: Modifier = Modifier\n) {\n    var expanded by remember {\n        mutableStateOf(false)\n    }\n\n    val levelColor = when (log.level) {\n        LogEntry.Level.DEBUG -> Color(0xFF10AF6F) // Green\n        LogEntry.Level.INFO -> if (MaterialTheme.colorScheme.background.luminance() >= 0.5f) Color.Black else Color.White\n        LogEntry.Level.ERROR -> MaterialTheme.colorScheme.error\n    }\n\n    Row (\n        verticalAlignment = Alignment.CenterVertically,\n        modifier = modifier\n            .combinedClickable(\n                onLongClickLabel = stringResource(R.string.action_copy_log),\n                onLongClick = onLongClick,\n                onClickLabel = stringResource(R.string.action_show_timestamp),\n                onClick = {\n                    expanded = !expanded\n                }\n            )\n            .thenIf(alternateBackground) { // Alternate background on each line\n                background(MaterialTheme.colorScheme.secondaryContainer.copy(alpha = 0.15f))\n            }\n            .thenIf(log.level == LogEntry.Level.ERROR) {\n                background(MaterialTheme.colorScheme.errorContainer.copy(alpha = 0.3f))\n            }\n            .padding(vertical = 4.5.dp, horizontal = 16.dp)\n    ) {\n        Text(\n            text = \"[${log.level.name[0]}]  \",\n            color = levelColor.copy(alpha = 0.5f),\n            fontSize = 11.sp,\n            fontFamily = FontFamily.Monospace\n        )\n\n        Column(\n            verticalArrangement = Arrangement.spacedBy(3.dp)\n        ) {\n            Text(\n                text = log.message.padEnd(logPadding),\n                softWrap = wrapText,\n                fontSize = 13.sp,\n                fontFamily = FontFamily.Monospace,\n                color = LocalContentColor.current.copy(alpha = if (log.level == LogEntry.Level.DEBUG) 0.5f else 0.85f)\n            )\n\n            if (expanded) {\n                Text(\n                    text = log.formatTimestamp(),\n                    softWrap = false,\n                    fontSize = 11.sp,\n                    fontFamily = FontFamily.Monospace,\n                    color = LocalContentColor.current.copy(alpha = 0.5f)\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/installer/StepGroupCard.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.installer\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.KeyboardArrowDown\nimport androidx.compose.material.icons.filled.KeyboardArrowUp\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.Step\nimport dev.beefers.vendetta.manager.installer.step.StepStatus\nimport dev.beefers.vendetta.manager.installer.step.download.base.DownloadStep\nimport dev.beefers.vendetta.manager.utils.thenIf\n\n/**\n * Collapsable card containing a group of steps\n *\n * @param name The name of this group\n * @param isCurrent Whether this card is expanded\n * @param steps The steps belonging to this group\n * @param onClick Action taken when the header of the group is clicked\n */\n@Composable\nfun StepGroupCard(\n    name: String,\n    isCurrent: Boolean,\n    steps: List<Step>,\n    onClick: () -> Unit\n) {\n    val status = when {\n        steps.all { it.status == StepStatus.QUEUED } -> StepStatus.QUEUED\n        steps.all { it.status == StepStatus.SUCCESSFUL } -> StepStatus.SUCCESSFUL\n        steps.any { it.status == StepStatus.ONGOING } -> StepStatus.ONGOING\n        else -> StepStatus.UNSUCCESSFUL\n    }\n\n    Column(\n        modifier = Modifier\n            .fillMaxWidth()\n            .clip(RoundedCornerShape(16.dp))\n            .thenIf(isCurrent) {\n                background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp))\n            }\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.spacedBy(12.dp),\n            modifier = Modifier\n                .clickable(onClick = onClick)\n                .fillMaxWidth()\n                .padding(16.dp)\n        ) {\n            StepIcon(status, 24.dp, progress = null)\n\n            Text(text = name)\n\n            Spacer(modifier = Modifier.weight(1f))\n\n            if (status != StepStatus.ONGOING && status != StepStatus.QUEUED) {\n                Text(\n                    text = \"%.2fs\".format(steps.sumOf { it.durationMs } / 1000f), // Displays the duration rounded to the hundredths place. ex. 10.13s\n                    style = MaterialTheme.typography.labelMedium\n                )\n            }\n\n            val (arrow, cd) = when {\n                isCurrent -> Icons.Filled.KeyboardArrowUp to R.string.action_collapse\n                else -> Icons.Filled.KeyboardArrowDown to R.string.action_expand\n            }\n\n            Icon(\n                imageVector = arrow,\n                contentDescription = stringResource(cd)\n            )\n        }\n\n        AnimatedVisibility(visible = isCurrent) {\n            Column(\n                verticalArrangement = Arrangement.spacedBy(16.dp),\n                modifier = Modifier\n                    .background(MaterialTheme.colorScheme.background.copy(0.6f))\n                    .fillMaxWidth()\n                    .padding(16.dp)\n                    .padding(start = 4.dp)\n            ) {\n                steps.forEach { step ->\n                    StepRow(\n                        name = stringResource(step.nameRes),\n                        status = step.status,\n                        progress = step.progress,\n                        cached = (step as? DownloadStep)?.cached ?: false,\n                        duration = step.durationMs / 1000f\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/installer/StepIcon.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.installer\n\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Cancel\nimport androidx.compose.material.icons.filled.CheckCircle\nimport androidx.compose.material.icons.outlined.Circle\nimport androidx.compose.material3.CircularProgressIndicator\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProgressIndicatorDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.semantics.contentDescription\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Dp\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.StepStatus\nimport kotlin.math.floor\nimport kotlin.math.roundToInt\n\n/**\n * Icon representing the status of a step\n *\n * Ongoing - Progress indicator\n *\n * Queued - Outlined circle, tinted grey\n *\n * Successful - Green check\n *\n * Unsuccessful - Red X\n */\n@Composable\nfun StepIcon(\n    status: StepStatus,\n    size: Dp,\n    progress: Float?\n) {\n    val strokeWidth = Dp(floor(size.value / 10) + 1)\n    val context = LocalContext.current\n\n    when (status) {\n        StepStatus.ONGOING -> {\n            if(progress != null) {\n                CircularProgressIndicator(\n                    progress = { progress },\n                    modifier = Modifier\n                        .size(size)\n                        .semantics {\n                            contentDescription = \"${(progress * 100).roundToInt()}%\"\n                        },\n                    strokeWidth = strokeWidth,\n                    trackColor = ProgressIndicatorDefaults.circularIndeterminateTrackColor,\n                )\n            } else {\n                CircularProgressIndicator(\n                    strokeWidth = strokeWidth,\n                    modifier = Modifier\n                        .size(size)\n                        .semantics {\n                            contentDescription = context.getString(R.string.status_ongoing)\n                        }\n                )\n            }\n        }\n\n        StepStatus.SUCCESSFUL -> {\n            Icon(\n                imageVector = Icons.Filled.CheckCircle,\n                contentDescription = stringResource(R.string.status_successful),\n                tint = Color(0xFF59B463),\n                modifier = Modifier.size(size)\n            )\n        }\n\n        StepStatus.UNSUCCESSFUL -> {\n            Icon(\n                imageVector = Icons.Filled.Cancel,\n                contentDescription = stringResource(R.string.status_fail),\n                tint = MaterialTheme.colorScheme.error,\n                modifier = Modifier.size(size)\n            )\n        }\n\n        StepStatus.QUEUED -> {\n            Icon(\n                imageVector = Icons.Outlined.Circle,\n                contentDescription = stringResource(R.string.status_queued),\n                tint = LocalContentColor.current.copy(alpha = 0.4f),\n                modifier = Modifier.size(size)\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/installer/StepRow.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.installer\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontStyle\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.installer.step.StepStatus\n\n/**\n * Displays a steps name, status, and progress\n *\n * @param name The name of the step\n * @param status The steps current status\n * @param progress Represents the download progress, as a decimal\n * @param cached Whether the file this step downloads was already cached\n * @param duration How long the step took to run, in seconds\n * @param modifier [Modifier] for this StepRow\n */\n@Composable\nfun StepRow(\n    name: String,\n    status: StepStatus,\n    progress: Float?,\n    cached: Boolean,\n    duration: Float,\n    modifier: Modifier = Modifier\n) {\n    Row(\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalArrangement = Arrangement.spacedBy(16.dp),\n        modifier = modifier\n    ) {\n        @Suppress(\"LocalVariableName\")\n        val _progress by animateFloatAsState(progress ?: 0f, label = \"Progress\") // Smoothly animate the progress indicator\n\n        StepIcon(status, size = 18.dp, progress = if(progress == null) null else _progress)\n\n        Text(\n            text = name,\n            style = MaterialTheme.typography.labelLarge,\n            maxLines = 1,\n            overflow = TextOverflow.Ellipsis,\n            modifier = Modifier.weight(1f, true),\n        )\n\n        if (status != StepStatus.ONGOING && status != StepStatus.QUEUED) { // Only display for completed steps\n            if (cached) {\n                Text(\n                    text = stringResource(R.string.installer_cached),\n                    style = MaterialTheme.typography.labelSmall,\n                    color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f),\n                    fontStyle = FontStyle.Italic,\n                    fontSize = 11.sp,\n                    maxLines = 1,\n                )\n            }\n\n            Text(\n                text = \"%.2fs\".format(duration), // Displays the duration rounded to the hundredths place. ex. 10.13s\n                style = MaterialTheme.typography.labelSmall,\n                maxLines = 1,\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/libraries/LibraryItem.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.libraries\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.combinedClickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ExperimentalLayoutApi\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Balance\nimport androidx.compose.material.icons.outlined.Info\nimport androidx.compose.material.icons.outlined.Person\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalUriHandler\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.mikepenz.aboutlibraries.entity.Library\nimport com.mikepenz.aboutlibraries.util.author\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.ui.components.Label\nimport dev.beefers.vendetta.manager.utils.contentDescription\n\n@Composable\n@OptIn(ExperimentalLayoutApi::class, ExperimentalFoundationApi::class)\nfun LibraryItem(\n    library: Library\n) {\n    val linkHandler = LocalUriHandler.current\n    var licenseSheetOpened by remember {\n        mutableStateOf(false)\n    }\n\n    if (licenseSheetOpened && library.licenses.firstOrNull()?.licenseContent != null) {\n        LicenseBottomSheet(\n            license = library.licenses.first(),\n            libraryName = library.name,\n            onDismiss = {\n                licenseSheetOpened = false\n            }\n        )\n    }\n\n    Column(\n        verticalArrangement = Arrangement.spacedBy(6.dp),\n        modifier = Modifier\n            .combinedClickable(\n                onClick = { licenseSheetOpened = true },\n                onLongClick = { library.website?.let { linkHandler.openUri(it) } }\n            )\n            .fillMaxWidth()\n            .padding(16.dp)\n    ) {\n        Text(\n            text = library.name,\n            style = MaterialTheme.typography.bodyMedium,\n            fontSize = 15.sp,\n            fontWeight = FontWeight.Bold\n        )\n\n        if (!library.description.isNullOrBlank()) {\n            Text(\n                text = library.description!!,\n                style = MaterialTheme.typography.bodyMedium,\n                fontSize = 15.sp,\n                color = LocalContentColor.current.copy(alpha = 0.7f)\n            )\n        }\n\n        FlowRow(\n            horizontalArrangement = Arrangement.spacedBy(6.dp),\n            verticalArrangement = Arrangement.spacedBy(10.dp),\n            modifier = Modifier.padding(top = 4.dp)\n        ) {\n            val labelColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp)\n\n            library.artifactVersion?.let {\n                Label(\n                    text = \"v$it\",\n                    icon = Icons.Outlined.Info,\n                    textColor = MaterialTheme.colorScheme.onSurface,\n                    borderColor = labelColor,\n                    fillColor = labelColor\n                )\n            }\n\n            if (library.author.isNotBlank()) {\n                Label(\n                    text = library.author,\n                    icon = Icons.Outlined.Person,\n                    textColor = MaterialTheme.colorScheme.onSurface,\n                    borderColor = labelColor,\n                    fillColor = labelColor,\n                    modifier = Modifier.contentDescription(\n                        R.string.cd_library_author,\n                        library.author,\n                        merge = true\n                    )\n                )\n            }\n\n            library.licenses.forEach { license ->\n                Label(\n                    text = license.name,\n                    icon = Icons.Outlined.Balance,\n                    textColor = MaterialTheme.colorScheme.onSurface,\n                    borderColor = labelColor,\n                    fillColor = labelColor,\n                    modifier = Modifier.contentDescription(\n                        R.string.cd_library_license,\n                        license.name,\n                        merge = true\n                    )\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/libraries/LicenseBottomSheet.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.libraries\n\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.foundation.text.selection.SelectionContainer\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ModalBottomSheet\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport com.mikepenz.aboutlibraries.entity.License\nimport dev.beefers.vendetta.manager.utils.DimenUtils\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun LicenseBottomSheet(\n    license: License,\n    libraryName: String,\n    onDismiss: () -> Unit\n) {\n    ModalBottomSheet(\n        onDismissRequest = onDismiss,\n        contentWindowInsets = { WindowInsets(0, 0, 0, 0) }\n    ) {\n        Column(\n            verticalArrangement = Arrangement.spacedBy(12.dp),\n            modifier = Modifier\n                .padding(16.dp)\n                .padding(bottom = DimenUtils.navBarPadding)\n        ) {\n            Text(\n                text = license.name,\n                style = MaterialTheme.typography.headlineMedium,\n                textAlign = TextAlign.Center,\n                modifier = Modifier.fillMaxWidth()\n            )\n\n            Text(\n                text = libraryName,\n                style = MaterialTheme.typography.titleSmall,\n                textAlign = TextAlign.Center,\n                modifier = Modifier.fillMaxWidth()\n            )\n\n            Spacer(Modifier)\n\n            SelectionContainer {\n                Text(\n                    text = license.licenseContent!!,\n                    style = MaterialTheme.typography.bodySmall,\n                    fontFamily = FontFamily.Monospace,\n                    color = MaterialTheme.colorScheme.onSecondaryContainer,\n                    modifier = Modifier\n                        .clip(RoundedCornerShape(12.dp))\n                        .background(MaterialTheme.colorScheme.secondaryContainer)\n                        .verticalScroll(rememberScrollState())\n                        .padding(12.dp)\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/settings/ThemePicker.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.settings\n\nimport android.annotation.SuppressLint\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.isSystemInDarkTheme\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.pager.HorizontalPager\nimport androidx.compose.foundation.pager.rememberPagerState\nimport androidx.compose.foundation.selection.selectableGroup\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.automirrored.outlined.NavigateBefore\nimport androidx.compose.material.icons.automirrored.outlined.NavigateNext\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.darkColorScheme\nimport androidx.compose.material3.dynamicDarkColorScheme\nimport androidx.compose.material3.dynamicLightColorScheme\nimport androidx.compose.material3.lightColorScheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.domain.manager.Theme\nimport dev.beefers.vendetta.manager.utils.contentDescription\nimport dev.beefers.vendetta.manager.utils.thenIf\nimport kotlinx.coroutines.launch\n\n@Composable\n@SuppressLint(\"NewApi\") // Dynamic color option shouldn't ever be enabled on unsupported apis anyways\nfun ThemePicker(\n    prefs: PreferenceManager\n) {\n    val context = LocalContext.current\n    val pagerState = rememberPagerState(prefs.theme.ordinal) {\n        Theme.entries.size\n    }\n    val scope = rememberCoroutineScope()\n\n    val lightScheme = remember(prefs.monet) { if(prefs.monet) dynamicLightColorScheme(context) else lightColorScheme() }\n    val darkScheme = remember(prefs.monet) { if(prefs.monet) dynamicDarkColorScheme(context) else darkColorScheme() }\n    val systemTheme = if(isSystemInDarkTheme()) darkScheme else lightScheme\n\n    Column(\n        verticalArrangement = Arrangement.spacedBy(16.dp)\n    ) {\n        Box {\n            HorizontalPager(\n                state = pagerState,\n                contentPadding = PaddingValues(16.dp)\n            ) { page ->\n                val (colors, theme) = when (page) {\n                    0 -> systemTheme to Theme.SYSTEM\n                    1 -> lightScheme to Theme.LIGHT\n                    2 -> darkScheme to Theme.DARK\n                    else -> systemTheme to Theme.SYSTEM\n                }\n\n                Box(\n                    contentAlignment = Alignment.Center,\n                    modifier = Modifier.fillMaxWidth()\n                ) {\n                    Column(\n                        horizontalAlignment = Alignment.CenterHorizontally,\n                        verticalArrangement = Arrangement.spacedBy(12.dp),\n                        modifier = Modifier\n                            .clip(RoundedCornerShape(16.dp))\n                            .thenIf(prefs.theme == theme) {\n                                background(MaterialTheme.colorScheme.tertiaryContainer)\n                            }\n                            .clickable { prefs.theme = theme }\n                            .padding(16.dp)\n                    ) {\n                        ThemePreview(\n                            colorScheme = colors,\n                            modifier = Modifier.contentDescription(theme.labelRes, merge = true)\n                        )\n\n                        Text(\n                            text = stringResource(theme.labelRes),\n                            style = MaterialTheme.typography.labelLarge,\n                            fontSize = 16.sp\n                        )\n                    }\n                }\n            }\n\n            if (pagerState.currentPage > 0) { // Not first page\n                IconButton(\n                    onClick = {\n                        scope.launch {\n                            pagerState.animateScrollToPage(pagerState.currentPage - 1)\n                        }\n                    },\n                    modifier = Modifier.align(Alignment.CenterStart)\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Outlined.NavigateBefore,\n                        contentDescription = stringResource(R.string.action_previous_theme),\n                        modifier = Modifier.size(34.dp)\n                    )\n                }\n            }\n\n            if (pagerState.currentPage < 2) { // Not last page\n                IconButton(\n                    onClick = {\n                        scope.launch {\n                            pagerState.animateScrollToPage(pagerState.currentPage + 1)\n                        }\n                    },\n                    modifier = Modifier.align(Alignment.CenterEnd)\n                ) {\n                    Icon(\n                        imageVector = Icons.AutoMirrored.Outlined.NavigateNext,\n                        contentDescription = stringResource(R.string.action_next_theme),\n                        modifier = Modifier.size(34.dp)\n                    )\n                }\n            }\n        }\n\n        Row(\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = Arrangement.spacedBy(32.dp, Alignment.CenterHorizontally),\n            modifier = Modifier\n                .fillMaxWidth()\n                .height(80.dp)\n                .selectableGroup()\n        ) {\n            ThemePickerOption(\n                theme = Theme.SYSTEM,\n                colors = systemTheme,\n                page = 0,\n                pagerState = pagerState,\n                prefs = prefs\n            )\n\n            ThemePickerOption(\n                theme = Theme.LIGHT,\n                colors = lightScheme,\n                page = 1,\n                pagerState = pagerState,\n                prefs = prefs\n            )\n\n            ThemePickerOption(\n                theme = Theme.DARK,\n                colors = darkScheme,\n                page = 2,\n                pagerState = pagerState,\n                prefs = prefs\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/settings/ThemePickerOption.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.settings\n\nimport androidx.compose.animation.animateContentSize\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.BorderStroke\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.pager.PagerState\nimport androidx.compose.foundation.selection.selectable\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.outlined.Sync\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.unit.dp\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.domain.manager.Theme\nimport dev.beefers.vendetta.manager.utils.contentDescription\nimport kotlinx.coroutines.launch\n\n@Composable\nfun ThemePickerOption(\n    theme: Theme,\n    colors: ColorScheme,\n    page: Int,\n    pagerState: PagerState,\n    prefs: PreferenceManager\n) {\n    val scope = rememberCoroutineScope()\n    val isSelected = pagerState.currentPage == page\n\n    Column(\n        verticalArrangement = Arrangement.spacedBy(10.dp),\n        horizontalAlignment = Alignment.CenterHorizontally,\n        modifier = Modifier\n            .animateContentSize(animationSpec = tween())\n    ) {\n        if (isSelected) {\n            Box(\n                modifier = Modifier\n                    .size(8.dp)\n                    .background(\n                        color = MaterialTheme.colorScheme.secondary,\n                        shape = CircleShape\n                    )\n            )\n        }\n\n        Box(\n            contentAlignment = Alignment.Center,\n            modifier = Modifier\n                .clip(CircleShape)\n                .background(colors.background)\n                .size(50.dp)\n                .contentDescription(theme.labelRes, merge = true)\n                .selectable(prefs.theme == theme) {\n                    prefs.theme = theme\n                    scope.launch {\n                        pagerState.animateScrollToPage(page)\n                    }\n                }\n                .run {\n                    if (prefs.theme == theme)\n                        border(BorderStroke(4.dp, MaterialTheme.colorScheme.tertiary), CircleShape)\n                    else\n                        border(BorderStroke(2.dp, colors.inverseSurface), CircleShape)\n                }\n        ) {\n            if (theme == Theme.SYSTEM) {\n                Icon(\n                    imageVector = Icons.Outlined.Sync,\n                    contentDescription = null, // Covered by parent component\n                    tint = colors.onSurface\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/settings/ThemePreview.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.settings\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.luminance\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.unit.dp\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport org.koin.compose.koinInject\n\n@Composable\nfun ThemePreview(\n    colorScheme: ColorScheme,\n    modifier: Modifier = Modifier\n) {\n    val prefs: PreferenceManager = koinInject()\n    val light = colorScheme.background.luminance() > 0.5f\n    val layerModifier = Modifier.height(300.dp)\n    val iconColor = remember(prefs.patchIcon, prefs.channel) {\n        when {\n            prefs.patchIcon -> Color(0xFF48488B)\n            prefs.channel == DiscordVersion.Type.ALPHA -> Color(0xFFFBB33C)\n            else -> Color(0xFF5865F2)\n        }\n    }\n\n    Box(\n        modifier = modifier\n    ) {\n        Icon(\n            painter = painterResource(R.drawable.ts_bg),\n            contentDescription = null,\n            tint = colorScheme.background,\n            modifier = layerModifier\n        )\n\n        Icon(\n            painter = painterResource(R.drawable.ts_surface_l2),\n            contentDescription = null,\n            tint = colorScheme.surfaceColorAtElevation(2.dp),\n            modifier = layerModifier\n        )\n\n        Icon(\n            painter = painterResource(R.drawable.ts_surface_l1),\n            contentDescription = null,\n            tint = colorScheme.surfaceColorAtElevation(1.dp),\n            modifier = layerModifier\n        )\n\n        Icon(\n            painter = painterResource(R.drawable.ts_outline),\n            contentDescription = null,\n            tint = colorScheme.outline.copy(alpha = 0.3f),\n            modifier = layerModifier\n        )\n\n        Image(\n            painter = painterResource(R.drawable.ts_avatars),\n            contentDescription = null,\n            modifier = layerModifier\n        )\n\n        Icon(\n            painter = painterResource(R.drawable.ts_primary),\n            contentDescription = null,\n            tint = colorScheme.primary,\n            modifier = layerModifier\n        )\n\n        Icon(\n            painter = painterResource(R.drawable.ts_content_50),\n            contentDescription = null,\n            tint = colorScheme.contentColorFor(colorScheme.background).copy(alpha = 0.5f),\n            modifier = layerModifier\n        )\n\n        Icon(\n            painter = painterResource(R.drawable.ts_content),\n            contentDescription = null,\n            tint = colorScheme.contentColorFor(colorScheme.background),\n            modifier = layerModifier\n        )\n\n        Icon(\n            painter = painterResource(R.drawable.ts_icon),\n            contentDescription = null,\n            tint = iconColor,\n            modifier = layerModifier\n        )\n\n        Icon(\n            painter = painterResource(R.drawable.ts_status),\n            contentDescription = null,\n            tint = if(light) Color(0xFF686568) else Color.White,\n            modifier = layerModifier\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/ui/widgets/updater/UpdateDialog.kt",
    "content": "package dev.beefers.vendetta.manager.ui.widgets.updater\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.SystemUpdate\nimport androidx.compose.material3.AlertDialog\nimport androidx.compose.material3.CircularProgressIndicator\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.window.DialogProperties\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.network.dto.Release\n\n@Composable\nfun UpdateDialog(\n    release: Release,\n    isUpdating: Boolean,\n    onDismiss: () -> Unit,\n    onConfirm: () -> Unit\n) {\n    AlertDialog(\n        properties = DialogProperties(\n            dismissOnBackPress = true,\n            dismissOnClickOutside = true\n        ),\n        onDismissRequest = {\n            onDismiss()\n        },\n        confirmButton = {\n            FilledTonalButton(\n                onClick = onConfirm,\n                enabled = !isUpdating\n            ) {\n                Box {\n                    Text(\n                        text = stringResource(R.string.action_start_update),\n                        color = if (isUpdating) Color.Transparent else LocalContentColor.current\n                    )\n                    if (isUpdating) {\n                        CircularProgressIndicator(\n                            strokeWidth = 3.dp,\n                            modifier = Modifier\n                                .size(24.dp)\n                                .align(Alignment.Center)\n                        )\n                    }\n                }\n\n            }\n        },\n        title = {\n            Text(stringResource(R.string.title_update))\n        },\n        text = {\n            Text(\n                text = stringResource(R.string.update_description, release.versionName),\n                textAlign = TextAlign.Center\n            )\n        },\n        icon = {\n            Icon(\n                imageVector = Icons.Filled.SystemUpdate,\n                contentDescription = null\n            )\n        }\n    )\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/updatechecker/reciever/UpdateBroadcastReceiver.kt",
    "content": "package dev.beefers.vendetta.manager.updatechecker.reciever\n\nimport android.app.NotificationManager\nimport android.app.PendingIntent\nimport android.content.BroadcastReceiver\nimport android.content.Context\nimport android.content.Intent\nimport androidx.core.app.NotificationCompat\nimport dev.beefers.vendetta.manager.BuildConfig\nimport dev.beefers.vendetta.manager.R\nimport dev.beefers.vendetta.manager.utils.Channels\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport dev.beefers.vendetta.manager.utils.Intents\n\nclass UpdateBroadcastReceiver : BroadcastReceiver() {\n\n    override fun onReceive(context: Context, intent: Intent) {\n        val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager\n        val versionCode = intent.getStringExtra(Intents.Extras.VERSION) ?: return\n        val version = DiscordVersion.fromVersionCode(versionCode) ?: return\n\n        val notificationId = versionCode.toInt()\n\n        val clickIntent = PendingIntent.getActivity(\n            context,\n            notificationId,\n            context.packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID)!!.apply {\n                action = Intents.Actions.INSTALL\n                putExtra(Intents.Extras.VERSION, versionCode)\n                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)\n            },\n            PendingIntent.FLAG_IMMUTABLE\n        )\n\n        NotificationCompat.Builder(context, Channels.UPDATE).apply {\n            setSmallIcon(R.drawable.ic_update)\n            setContentTitle(context.getString(R.string.title_update_available))\n            setContentText(context.getString(R.string.action_tap_to_install, version.toString()))\n            setContentIntent(clickIntent)\n            setAutoCancel(true)\n            priority = NotificationCompat.PRIORITY_DEFAULT\n\n            nm.notify(notificationId, build())\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/updatechecker/worker/UpdateWorker.kt",
    "content": "package dev.beefers.vendetta.manager.updatechecker.worker\n\nimport android.content.Context\nimport android.content.Intent\nimport androidx.work.CoroutineWorker\nimport androidx.work.WorkerParameters\nimport dev.beefers.vendetta.manager.domain.manager.InstallManager\nimport dev.beefers.vendetta.manager.domain.manager.PreferenceManager\nimport dev.beefers.vendetta.manager.domain.repository.RestRepository\nimport dev.beefers.vendetta.manager.network.utils.ApiResponse\nimport dev.beefers.vendetta.manager.updatechecker.reciever.UpdateBroadcastReceiver\nimport dev.beefers.vendetta.manager.utils.DiscordVersion\nimport dev.beefers.vendetta.manager.utils.Intents\nimport org.koin.core.component.KoinComponent\nimport org.koin.core.component.inject\n\nclass UpdateWorker(\n    private val context: Context,\n    params: WorkerParameters\n) : CoroutineWorker(context, params), KoinComponent {\n\n    val api: RestRepository by inject()\n    val prefs: PreferenceManager by inject()\n    val installManager: InstallManager by inject()\n\n    override suspend fun doWork(): Result {\n        if (prefs.discordVersion.isNotBlank()) return Result.success()\n        return when (val res = api.getLatestDiscordVersions()) {\n            is ApiResponse.Success -> {\n                val currentVersion =\n                    DiscordVersion.fromVersionCode(installManager.current?.longVersionCode.toString())\n                val latestVersion = res.data[prefs.channel]\n\n                if (latestVersion == null || currentVersion == null) return Result.failure()\n\n                if (latestVersion > currentVersion && latestVersion.isSupported()) {\n                    context.sendBroadcast(\n                        Intent(\n                            context,\n                            UpdateBroadcastReceiver::class.java\n                        ).apply {\n                            putExtra(Intents.Extras.VERSION, latestVersion.toVersionCode())\n                        })\n                }\n\n                Result.success()\n            }\n\n            else -> Result.failure()\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/utils/Constants.kt",
    "content": "package dev.beefers.vendetta.manager.utils\n\nimport android.os.Environment\nimport dev.beefers.vendetta.manager.BuildConfig\n\nobject Constants {\n\n    val TEAM_MEMBERS = listOf(\n        TeamMember(\"Pylix\", \"Developer - Bunny & Vendetta\", \"pylixonly\"),\n        TeamMember(\"Kasi\", \"Developer - Xposed Module\", \"redstonekasi\")\n    )\n\n    // NOTE: This is no longer used\n    val VENDETTA_DIR = Environment.getExternalStorageDirectory().resolve(\"Bunny\")\n\n    val DUMMY_VERSION = DiscordVersion(1, 0, DiscordVersion.Type.STABLE)\n\n    val START_TIME = System.currentTimeMillis()\n}\n\nobject Intents {\n\n    object Actions {\n        const val INSTALL = \"${BuildConfig.APPLICATION_ID}.intents.actions.INSTALL\"\n    }\n\n    object Extras {\n        const val VERSION = \"${BuildConfig.APPLICATION_ID}.intents.extras.VERSION\"\n    }\n\n}\n\nobject Channels {\n    const val UPDATE = \"${BuildConfig.APPLICATION_ID}.notifications.UPDATE\"\n}\n\ndata class TeamMember(\n    val name: String,\n    val role: String,\n    val username: String = name\n)"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/utils/Context.kt",
    "content": "package dev.beefers.vendetta.manager.utils\n\nimport android.content.Context\nimport android.util.TypedValue\nimport androidx.annotation.AnyRes\nimport java.io.InputStream\n\n/**\n * Get the raw bytes for a resource.\n * @param id The resource identifier\n * @return The resource's raw bytes as stored inside the APK\n */\nfun Context.getResBytes(@AnyRes id: Int): ByteArray {\n    val tValue = TypedValue()\n    this.resources.getValue(\n        /* id = */ id,\n        /* outValue = */ tValue,\n        /* resolveRefs = */ true,\n    )\n\n    val resPath = tValue.string.toString()\n\n    return this.javaClass.classLoader\n        ?.getResourceAsStream(resPath)\n        ?.use(InputStream::readBytes)\n        ?: error(\"Failed to get resource file $resPath from APK\")\n}\n"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/utils/DimenUtils.kt",
    "content": "package dev.beefers.vendetta.manager.utils\n\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.systemBars\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.unit.Dp\n\nobject DimenUtils {\n\n    val navBarPadding: Dp\n        @Composable get() = WindowInsets.systemBars.asPaddingValues().calculateBottomPadding()\n\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/utils/LazyUtils.kt",
    "content": "package dev.beefers.vendetta.manager.utils\n\nimport androidx.compose.foundation.lazy.LazyListScope\nimport androidx.compose.runtime.Composable\nimport androidx.paging.compose.LazyPagingItems\nimport androidx.paging.compose.itemContentType\n\ninline fun <T : Any> LazyListScope.itemsIndexed(\n    items: LazyPagingItems<T>,\n    noinline key: ((i: Int, item: T) -> Any)? = null,\n    crossinline itemContent: @Composable (i: Int, item: T) -> Unit\n) {\n    items(\n        count = items.itemCount,\n        key = { i -> key?.invoke(i, items[i]!!) ?: Unit },\n        contentType = items.itemContentType()\n    ) {\n        itemContent(it, items[it]!!)\n    }\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/utils/ModifierUtils.kt",
    "content": "package dev.beefers.vendetta.manager.utils\n\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.semantics.contentDescription\nimport androidx.compose.ui.semantics.semantics\n\nfun Modifier.contentDescription(description: String, merge: Boolean = false): Modifier = semantics(mergeDescendants = merge) {\n    contentDescription = description\n}\n\nfun Modifier.contentDescription(res: Int, vararg param: Any, merge: Boolean = false): Modifier\n    = composed { contentDescription(stringResource(res, *param), merge) }\n\ninline fun Modifier.thenIf(predicate: Boolean, block: Modifier.() -> Modifier): Modifier =\n    if (predicate) then(Modifier.Companion.block()) else this"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/utils/NavUtils.kt",
    "content": "package dev.beefers.vendetta.manager.utils\n\nimport cafe.adriel.voyager.core.screen.Screen\nimport cafe.adriel.voyager.navigator.Navigator\n\ntailrec fun Navigator.navigate(screen: Screen) {\n    if (level == 0)\n        push(screen)\n    else\n        this.parent!!.navigate(screen)\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/utils/Utils.kt",
    "content": "package dev.beefers.vendetta.manager.utils\n\nimport android.content.ClipData\nimport android.content.ClipboardManager\nimport android.content.Context\nimport android.graphics.Bitmap\nimport android.net.Uri\nimport android.os.Handler\nimport android.os.Looper\nimport android.widget.Toast\nimport androidx.activity.compose.ManagedActivityResultLauncher\nimport androidx.activity.compose.rememberLauncherForActivityResult\nimport androidx.activity.result.contract.ActivityResultContracts\nimport androidx.annotation.DrawableRes\nimport androidx.annotation.StringRes\nimport androidx.appcompat.content.res.AppCompatResources\nimport androidx.collection.ObjectList\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.core.graphics.drawable.toBitmap\nimport dev.beefers.vendetta.manager.BuildConfig\nimport java.io.BufferedReader\nimport java.io.IOException\nimport java.io.InputStreamReader\n\nval mainThread = Handler(Looper.getMainLooper())\n\nfun mainThread(block: () -> Unit) {\n    mainThread.post(block)\n}\n\nfun Context.copyText(text: String) {\n    val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager\n\n    clipboardManager.setPrimaryClip(ClipData.newPlainText(BuildConfig.APPLICATION_ID, text))\n}\n\nfun Context.showToast(@StringRes res: Int, vararg params: Any, short: Boolean = true) {\n    Toast.makeText(\n        this,\n        getString(res, *params),\n        if (short) Toast.LENGTH_SHORT else Toast.LENGTH_LONG\n    ).show()\n}\n\n/**\n * Remembers an activity result launcher used to save files to a user-specified location\n */\n@Composable\nfun rememberFileSaveLauncher(content: String, mimeType: String = \"text/plain\"): ManagedActivityResultLauncher<String, Uri?> {\n    val context = LocalContext.current\n    return rememberLauncherForActivityResult(contract = ActivityResultContracts.CreateDocument(mimeType)) { uri ->\n        uri?.let {\n            context.contentResolver.openOutputStream(uri).use { stream ->\n                stream?.write(content.toByteArray())\n            }\n        }\n    }\n}\n\nprivate val cachedBitmaps: MutableMap<Int, MutableMap<Int, Bitmap>> = mutableMapOf()\n\ncontext(Context)\nprivate val Int.dp: Int\n    get() = (45 * this@Context.resources.displayMetrics.density + 0.5f).toInt()\n\nfun Context.getBitmap(@DrawableRes icon: Int, size: Int): Bitmap {\n    cachedBitmaps[icon]?.let { it[size]?.let { bitmap -> return bitmap } }\n    val sizePx = size.dp\n\n    val bitmap = AppCompatResources.getDrawable(this, icon)!!.toBitmap(\n        height = sizePx,\n        width = sizePx\n    )\n\n    cachedBitmaps[icon] = mutableMapOf()\n    cachedBitmaps[icon]?.let {\n        it[size] = bitmap\n    }\n\n    return bitmap\n}\n\n// Thanks to https://gist.github.com/Muyangmin/e8ec1002c930d8df3df46b306d03315d\nfun getSystemProp(prop: String): String? {\n    val line: String\n    var input = null as BufferedReader?\n    try {\n        val proc = Runtime.getRuntime().exec(\"getprop $prop\")\n        input = BufferedReader(InputStreamReader(proc.inputStream), 1024)\n        line = input.readLine()\n        input.close()\n    } catch (e: IOException) {\n        return null\n    } finally {\n        input?.let {\n            try {\n                input.close()\n            } catch (e: IOException) {\n                e.printStackTrace()\n            }\n        }\n    }\n    return line\n}\n\nval isMiui: Boolean\n    get() = getSystemProp(\"ro.miui.ui.version.name\")?.isNotEmpty() ?: false\n\n\ninline fun <E> ObjectList<E>.find(block: (E) -> Boolean): E? {\n    forEach { value ->\n        if (block(value))\n            return value\n    }\n\n    return null\n}"
  },
  {
    "path": "app/src/main/java/dev/beefers/vendetta/manager/utils/VersionUtils.kt",
    "content": "package dev.beefers.vendetta.manager.utils\n\nimport androidx.annotation.StringRes\nimport dev.beefers.vendetta.manager.R\nimport java.io.Serializable\nimport kotlin.text.toCharArray\n\ndata class DiscordVersion(\n    val major: Int,\n    val minor: Int,\n    val type: Type\n) : Serializable, Comparable<DiscordVersion> {\n\n    enum class Type(val label: String, @StringRes val labelRes: Int, val maxVersionCode: Int) {\n        STABLE(\"Stable\", R.string.channel_stable, 279013),\n        BETA(\"Beta\", R.string.channel_beta, 279112),\n        ALPHA(\"Alpha\", R.string.channel_alpha, 280200)\n    }\n\n    override fun compareTo(other: DiscordVersion): Int =\n        toVersionCode().toInt() - other.toVersionCode().toInt()\n\n    override fun toString() = \"$major.$minor - ${type.label}\"\n\n    fun toVersionCode() = \"$major${type.ordinal}${if (minor < 10) 0 else \"\"}${minor}\"\n\n    fun isSupported() = toVersionCode().toInt() <= type.maxVersionCode\n\n    companion object {\n        fun fromVersionCode(string: String): DiscordVersion? = with(string) {\n            if (length < 4) return@with null\n            val versionCodeInt = toIntOrNull() ?: return@with null\n            if (versionCodeInt <= 126021) return@with null\n            val codeReversed = toCharArray().reversed().joinToString(\"\")\n            val typeInt = codeReversed[2].toString().toInt()\n            val type = Type.entries.getOrNull(typeInt) ?: return@with null\n\n            DiscordVersion(\n                codeReversed.slice(3..codeReversed.lastIndex).reversed().toInt(),\n                codeReversed.substring(0, 2).reversed().toInt(),\n                type\n            )\n        }\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/res/drawable/bunny_logo.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\" xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:viewportWidth=\"1024\"\n    android:viewportHeight=\"1024\"\n    android:width=\"1024dp\"\n    android:height=\"1024dp\">\n    <path\n        android:pathData=\"M609.332 411.689C615.011 434.45 617.274 456.024 616.433 473.487C686.495 520.19 723.419 549.406 689.187 577.24L687.835 577.12L713.41 619.67C715.508 623.159 711.612 627.23 707.993 625.366C594.412 566.856 509.331 565.278 346.508 680.553C343.283 682.836 338.923 679.639 340.289 675.931L369.178 597.52C351.374 597.335 337 583.271 337 565.948C337 551.66 346.779 539.588 360.197 535.694C367.36 533.305 374.586 534.478 384.334 536.061C396.367 538.014 412.241 540.592 436.578 537.862C476.446 533.39 507.559 502 519.545 486.839C507.557 480.206 494.889 471.671 482.409 461.545C439.976 427.113 415.798 387.335 428.408 372.699C441.017 358.062 485.638 374.109 528.072 408.541C531.35 411.2 534.518 413.892 537.57 416.601C527.923 369.273 533.459 329.516 551.166 325.355C570.272 320.864 596.313 359.518 609.332 411.689ZM636.43 545.531C645.943 545.531 653.654 538.048 653.654 528.816C653.654 519.584 645.943 512.1 636.43 512.1C626.918 512.1 619.207 519.584 619.207 528.816C619.207 538.048 626.918 545.531 636.43 545.531Z\"\n        android:fillType=\"evenOdd\"\n        android:fillColor=\"#FFFFFF\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_discord.xml",
    "content": "<vector android:height=\"24dp\" android:viewportHeight=\"512\"\n    android:viewportWidth=\"512\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <group>\n        <clip-path android:pathData=\"M0,0h512v512h-512z\"/>\n        <path android:fillColor=\"#FFFFFF\" android:pathData=\"M420.81,104.8C390.5,90.88 358,80.65 324,74.78C323.39,74.67 322.78,74.94 322.45,75.5C318.28,82.94 313.63,92.64 310.39,100.27C273.85,94.8 237.48,94.8 201.67,100.27C198.43,92.48 193.62,82.94 189.43,75.5C189.11,74.96 188.5,74.68 187.87,74.78C153.9,80.61 121.4,90.87 91.07,104.8C90.8,104.91 90.57,105.1 90.43,105.35C28.78,197.46 11.88,287.31 20.17,376.05C20.2,376.48 20.44,376.88 20.78,377.16C61.47,407.03 100.88,425.17 139.55,437.18C140.16,437.37 140.83,437.15 141.21,436.63C150.35,424.15 158.51,410.98 165.51,397.12C165.93,396.31 165.52,395.34 164.69,395.02C151.76,390.12 139.44,384.14 127.59,377.35C126.65,376.8 126.57,375.45 127.43,374.82C129.93,372.95 132.43,371 134.8,369.03C135.23,368.68 135.83,368.61 136.34,368.84C214.18,404.37 298.43,404.37 375.35,368.84C375.86,368.58 376.46,368.66 376.91,369.02C379.28,370.98 381.78,372.95 384.3,374.82C385.15,375.45 385.1,376.8 384.17,377.35C372.32,384.27 360,390.12 347.04,395C346.2,395.33 345.83,396.31 346.23,397.12C353.38,410.95 361.53,424.12 370.51,436.61C370.88,437.15 371.56,437.37 372.19,437.18C411.04,425.17 450.44,407.03 491.14,377.16C491.49,376.88 491.71,376.5 491.75,376.06C501.66,273.48 475.14,184.36 421.42,105.36C421.3,105.1 421.07,104.91 420.81,104.8ZM177.13,322.01C153.69,322.01 134.39,300.5 134.39,274.08C134.39,247.65 153.32,226.15 177.13,226.15C201.12,226.15 220.24,247.85 219.87,274.08C219.87,300.5 200.94,322.01 177.13,322.01ZM335.16,322.01C311.73,322.01 292.42,300.5 292.42,274.08C292.42,247.65 311.35,226.15 335.16,226.15C359.16,226.15 378.28,247.85 377.9,274.08C377.9,300.5 359.16,322.01 335.16,322.01Z\"/>\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_discord_icon.xml",
    "content": "<vector android:height=\"24dp\" android:viewportHeight=\"512\"\n    android:viewportWidth=\"512\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <group>\n        <clip-path android:pathData=\"M0,0h512v512h-512z\"/>\n        <path android:fillColor=\"#FFFFFF\" android:pathData=\"M366.27,150.56C346.2,141.35 324.68,134.57 302.17,130.68C301.77,130.61 301.36,130.79 301.15,131.16C298.38,136.08 295.31,142.51 293.16,147.56C268.97,143.94 244.89,143.94 221.18,147.56C219.03,142.4 215.85,136.08 213.08,131.16C212.86,130.8 212.46,130.62 212.04,130.68C189.55,134.55 168.03,141.34 147.96,150.56C147.77,150.63 147.63,150.76 147.53,150.92C106.71,211.91 95.53,271.4 101.01,330.15C101.03,330.43 101.19,330.7 101.42,330.88C128.36,350.66 154.45,362.67 180.05,370.62C180.46,370.75 180.9,370.6 181.15,370.26C187.2,362 192.6,353.28 197.24,344.1C197.51,343.56 197.25,342.92 196.69,342.71C188.13,339.46 179.98,335.5 172.13,331.01C171.51,330.65 171.46,329.75 172.03,329.33C173.68,328.1 175.34,326.8 176.9,325.5C177.19,325.27 177.59,325.23 177.93,325.38C229.46,348.9 285.24,348.9 336.17,325.38C336.51,325.2 336.9,325.26 337.2,325.49C338.77,326.79 340.43,328.1 342.09,329.33C342.66,329.75 342.63,330.65 342.01,331.01C334.16,335.59 326.01,339.46 317.42,342.7C316.87,342.91 316.63,343.56 316.89,344.1C321.62,353.26 327.02,361.98 332.97,370.25C333.21,370.6 333.66,370.75 334.08,370.62C359.8,362.67 385.89,350.66 412.83,330.88C413.06,330.7 413.21,330.45 413.23,330.16C419.8,262.24 402.24,203.23 366.67,150.93C366.59,150.76 366.44,150.63 366.27,150.56ZM204.93,294.37C189.41,294.37 176.64,280.13 176.64,262.63C176.64,245.14 189.17,230.9 204.93,230.9C220.82,230.9 233.48,245.27 233.23,262.63C233.23,280.13 220.7,294.37 204.93,294.37ZM309.56,294.37C294.05,294.37 281.26,280.13 281.26,262.63C281.26,245.14 293.79,230.9 309.56,230.9C325.45,230.9 338.11,245.27 337.86,262.63C337.86,280.13 325.45,294.37 309.56,294.37Z\"/>\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_github.xml",
    "content": "<vector android:height=\"24dp\" android:viewportHeight=\"1024\"\n    android:viewportWidth=\"1024\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <group>\n        <clip-path android:pathData=\"M0,0h1024v1024h-1024z\"/>\n        <path android:fillColor=\"#000000\" android:pathData=\"M512,83.4C278.9,83.4 88.1,274.1 88.1,507.2C88.1,687.4 201.2,841 358.3,902.9C374.2,899.3 388.4,885.2 388.4,867.5L388.4,789.8L342.5,789.8C308.9,789.8 280.6,773.9 266.5,749.2C263,742.1 259.4,733.3 255.9,724.5C248.8,705.1 240,683.9 222.4,671.5C215.3,666.2 211.8,655.6 213.5,646.8C217.1,637.9 225.9,630.9 241.8,632.6C259.4,634.4 285.9,653.8 301.8,675C316,692.7 326.6,703.3 347.7,703.3L353,703.3C368.9,703.3 407.8,703.3 414.9,696.2C420.2,689.2 423.7,683.9 429,678.6C323,657.4 263,595.6 263,501.9C263,470.2 271.8,438.4 291.2,410.1C284.2,383.6 268.3,314.7 301.8,284.7L307.1,279.4L314.2,279.4C360.1,279.4 393.7,298.8 414.9,314.7C476.7,291.8 547.3,291.8 609.1,314.7C628.6,298.8 662.1,279.4 709.8,279.4L716.9,279.4L722.2,284.7C755.7,316.5 739.8,383.6 732.8,410.1C750.4,438.4 761,470.2 761,501.9C761,595.6 701,657.4 596.8,678.6C623.3,706.8 637.4,749.2 637.4,782.8L637.4,869.3C637.4,887 649.8,901.1 667.4,904.6C822.8,841 935.9,687.4 935.9,507.2C935.9,274.1 745.1,83.4 512,83.4Z\"/>\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_update.xml",
    "content": "<vector android:height=\"24dp\" android:viewportHeight=\"512\"\n    android:viewportWidth=\"512\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <group>\n        <clip-path android:pathData=\"M0,0h512v512h-512z\"/>\n        <path android:fillColor=\"#FFFFFF\" android:fillType=\"evenOdd\" android:pathData=\"M312.52,381.87C256.16,394.27 197.76,387.92 142.75,362.8C142.26,362.59 141.69,362.65 141.28,362.98C139.04,364.85 136.67,366.69 134.31,368.46C133.5,369.06 133.57,370.34 134.46,370.86C145.68,377.28 157.33,382.94 169.57,387.58C170.37,387.89 170.75,388.8 170.35,389.57C163.73,402.69 156.01,415.15 147.35,426.97C146.99,427.45 146.36,427.67 145.78,427.48C109.18,416.12 71.88,398.95 33.37,370.67C33.05,370.42 32.82,370.03 32.79,369.62C24.94,285.64 40.94,200.6 99.29,113.4C99.43,113.18 99.64,112.99 99.9,112.89C128.6,99.7 159.36,90 191.51,84.47C192.11,84.38 192.69,84.64 192.99,85.16C196.96,92.19 201.51,101.23 204.58,108.6C238.47,103.43 272.89,103.43 307.48,108.6C310.55,101.38 314.95,92.19 318.9,85.16C319.2,84.63 319.78,84.37 320.36,84.47C352.54,90.03 383.31,99.72 411.99,112.89L411.99,112.89C412.24,112.99 412.45,113.18 412.57,113.42C448.1,165.67 471.06,222.59 478.46,285.27C460.5,267.19 435.61,256 408.14,256C394.84,256 382.14,258.62 370.55,263.39L370.55,263.39C366.8,243.14 350.6,227.74 330.92,227.74C308.38,227.74 290.47,248.1 290.47,273.11C290.47,292.66 301.64,309.36 317.11,315.72C311.83,327.82 308.9,341.19 308.9,355.24C308.9,364.46 310.16,373.39 312.52,381.87ZM181.35,318.47C159.16,318.47 140.9,298.12 140.9,273.11C140.9,248.1 158.81,227.74 181.35,227.74C204.06,227.74 222.15,248.28 221.8,273.11C221.8,298.12 203.89,318.47 181.35,318.47L181.35,318.47Z\"/>\n        <path android:fillColor=\"#FFFFFF\" android:fillType=\"evenOdd\" android:pathData=\"M435.05,342.2L450.84,326.41L449.83,325.01C440.14,311.65 424.64,303.72 408.14,303.68C386.85,303.68 367.71,316.89 360.07,336.7L335.47,336.7C343.85,303.82 374,280.21 408.14,280.21C430.7,280.21 451.86,290.3 466.2,307.88L467.62,309.62L483.16,294.09L483.16,342.2L435.05,342.2L435.05,342.2ZM408.14,430.26C385.57,430.26 364.41,420.17 350.07,402.59L348.65,400.85L333.11,416.39L333.11,368.27L381.23,368.27L365.43,384.06L366.45,385.46C376.14,398.82 391.63,406.75 408.13,406.8C429.42,406.8 448.56,393.59 456.2,373.77L480.8,373.77C472.43,406.65 442.27,430.26 408.14,430.26Z\"/>\n    </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_avatars.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:pathData=\"M31.5,362.5m-7.5,0a7.5,7.5 0,1 1,15 0a7.5,7.5 0,1 1,-15 0\"\n        android:fillColor=\"#E8B3B3\"/>\n    <path\n        android:pathData=\"M31.5,423.5m-7.5,0a7.5,7.5 0,1 1,15 0a7.5,7.5 0,1 1,-15 0\"\n        android:fillColor=\"#E8B3B3\"/>\n    <path\n        android:pathData=\"M31.5,483.5m-7.5,0a7.5,7.5 0,1 1,15 0a7.5,7.5 0,1 1,-15 0\"\n        android:fillColor=\"#E8B3B3\"/>\n    <path\n        android:pathData=\"M31.5,604.5m-7.5,0a7.5,7.5 0,1 1,15 0a7.5,7.5 0,1 1,-15 0\"\n        android:fillColor=\"#E8B3B3\"/>\n    <path\n        android:pathData=\"M31.5,543.5m-7.5,0a7.5,7.5 0,1 1,15 0a7.5,7.5 0,1 1,-15 0\"\n        android:fillColor=\"#56BBBB\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_bg.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:pathData=\"M17,0L288,0C297.38,0 305,7.62 305,17L305,644C305,653.38 297.38,661 288,661L17,661C7.62,661 0,653.38 0,644L0,17C0,7.62 7.62,0 17,0Z\"\n        android:fillColor=\"#FFFFFF\"\n        android:strokeColor=\"#00000000\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_content.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:pathData=\"M284.5,54.5m-8.5,0a8.5,8.5 0,1 1,17 0a8.5,8.5 0,1 1,-17 0\"\n        android:fillColor=\"#444144\"/>\n    <path\n        android:pathData=\"M248.5,54.5m-8.5,0a8.5,8.5 0,1 1,17 0a8.5,8.5 0,1 1,-17 0\"\n        android:fillColor=\"#444144\"/>\n    <path\n        android:pathData=\"M124.5,149L180.5,149C185.19,149 189,152.81 189,157.5L189,157.5C189,162.19 185.19,166 180.5,166L124.5,166C119.81,166 116,162.19 116,157.5L116,157.5C116,152.81 119.81,149 124.5,149Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M16.76,46L50.24,46C55.07,46 59,49.81 59,54.5L59,54.5C59,59.19 55.07,63 50.24,63L16.76,63C11.93,63 8,59.19 8,54.5L8,54.5C8,49.81 11.93,46 16.76,46Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M109,363m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0\"\n        android:fillColor=\"#444144\"/>\n    <path\n        android:pathData=\"M27.5,379L196.5,379C200.09,379 203,381.91 203,385.5L203,385.5C203,389.09 200.09,392 196.5,392L27.5,392C23.91,392 21,389.09 21,385.5L21,385.5C21,381.91 23.91,379 27.5,379Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M27.5,439L151.5,439C155.09,439 158,441.91 158,445.5L158,445.5C158,449.09 155.09,452 151.5,452L27.5,452C23.91,452 21,449.09 21,445.5L21,445.5C21,441.91 23.91,439 27.5,439Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M27.5,499L193.5,499C197.09,499 200,501.91 200,505.5L200,505.5C200,509.09 197.09,512 193.5,512L27.5,512C23.91,512 21,509.09 21,505.5L21,505.5C21,501.91 23.91,499 27.5,499Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M27.5,559L159.5,559C163.09,559 166,561.91 166,565.5L166,565.5C166,569.09 163.09,572 159.5,572L27.5,572C23.91,572 21,569.09 21,565.5L21,565.5C21,561.91 23.91,559 27.5,559Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M50.25,357.75L94.75,357.75C97.65,357.75 100,360.1 100,363L100,363C100,365.9 97.65,368.25 94.75,368.25L50.25,368.25C47.35,368.25 45,365.9 45,363L45,363C45,360.1 47.35,357.75 50.25,357.75Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M109,423.25m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0\"\n        android:fillColor=\"#444144\"/>\n    <path\n        android:pathData=\"M109,483.58m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0\"\n        android:fillColor=\"#444144\"/>\n    <path\n        android:pathData=\"M98.67,544.04m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0\"\n        android:fillColor=\"#444144\"/>\n    <path\n        android:pathData=\"M50.25,418L94.75,418C97.65,418 100,420.35 100,423.25L100,423.25C100,426.15 97.65,428.5 94.75,428.5L50.25,428.5C47.35,428.5 45,426.15 45,423.25L45,423.25C45,420.35 47.35,418 50.25,418Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M50.25,478.25L94.75,478.25C97.65,478.25 100,480.6 100,483.5L100,483.5C100,486.4 97.65,488.75 94.75,488.75L50.25,488.75C47.35,488.75 45,486.4 45,483.5L45,483.5C45,480.6 47.35,478.25 50.25,478.25Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M109,604.08m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0\"\n        android:fillColor=\"#444144\"/>\n    <path\n        android:pathData=\"M50.25,598.75L94.75,598.75C97.65,598.75 100,601.1 100,604L100,604C100,606.9 97.65,609.25 94.75,609.25L50.25,609.25C47.35,609.25 45,606.9 45,604L45,604C45,601.1 47.35,598.75 50.25,598.75Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M50.25,538.5L86.75,538.5C89.65,538.5 92,540.85 92,543.75L92,543.75C92,546.65 89.65,549 86.75,549L50.25,549C47.35,549 45,546.65 45,543.75L45,543.75C45,540.85 47.35,538.5 50.25,538.5Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M281.46,632C283.29,630.85 284.5,628.82 284.5,626.5L284.5,626.5C284.5,622.91 281.59,620 278,620L27.5,620C23.91,620 21,622.91 21,626.5L21,626.5C21,628.82 22.21,630.85 24.04,632L281.46,632Z\"\n        android:fillColor=\"#444144\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_content_50.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:pathData=\"M106.68,196.38L198.32,196.38C201.46,196.38 204,198.92 204,202.05L204,202.33C204,205.46 201.46,208 198.32,208L106.68,208C103.54,208 101,205.46 101,202.33L101,202.05C101,198.92 103.54,196.38 106.68,196.38Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M103.81,181.38L200.19,181.38C203.4,181.38 206,183.98 206,187.19L206,187.19C206,190.4 203.4,193 200.19,193L103.81,193C100.6,193 98,190.4 98,187.19L98,187.19C98,183.98 100.6,181.38 103.81,181.38Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M245.38,357.75L277.62,357.75C280.59,357.75 283,360.1 283,363L283,363C283,365.9 280.59,368.25 277.62,368.25L245.38,368.25C242.41,368.25 240,365.9 240,363L240,363C240,360.1 242.41,357.75 245.38,357.75Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M245.38,418.5L277.62,418.5C280.59,418.5 283,420.85 283,423.75L283,423.75C283,426.65 280.59,429 277.62,429L245.38,429C242.41,429 240,426.65 240,423.75L240,423.75C240,420.85 242.41,418.5 245.38,418.5Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M245.38,478.25L277.62,478.25C280.59,478.25 283,480.6 283,483.5L283,483.5C283,486.4 280.59,488.75 277.62,488.75L245.38,488.75C242.41,488.75 240,486.4 240,483.5L240,483.5C240,480.6 242.41,478.25 245.38,478.25Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M245.38,539L277.62,539C280.59,539 283,541.35 283,544.25L283,544.25C283,547.15 280.59,549.5 277.62,549.5L245.38,549.5C242.41,549.5 240,547.15 240,544.25L240,544.25C240,541.35 242.41,539 245.38,539Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M245.38,599.75L277.62,599.75C280.59,599.75 283,602.1 283,605L283,605C283,607.9 280.59,610.25 277.62,610.25L245.38,610.25C242.41,610.25 240,607.9 240,605L240,605C240,602.1 242.41,599.75 245.38,599.75Z\"\n        android:fillColor=\"#444144\"\n        android:strokeColor=\"#00000000\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_icon.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:pathData=\"M152.5,112m-22,0a22,22 0,1 1,44 0a22,22 0,1 1,-44 0\"\n        android:fillColor=\"#60B8B5\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_outline.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M24,525L280,525\"\n        android:strokeAlpha=\"0.25\"\n        android:strokeLineJoin=\"miter\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#444144\"\n        android:fillAlpha=\"0.5\"\n        android:strokeLineCap=\"square\"/>\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M24,585L280,585\"\n        android:strokeAlpha=\"0.25\"\n        android:strokeLineJoin=\"miter\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#444144\"\n        android:fillAlpha=\"0.5\"\n        android:strokeLineCap=\"square\"/>\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M24,464L280,464\"\n        android:strokeAlpha=\"0.25\"\n        android:strokeLineJoin=\"miter\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#444144\"\n        android:fillAlpha=\"0.5\"\n        android:strokeLineCap=\"square\"/>\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"M24,403L280,403\"\n        android:strokeAlpha=\"0.25\"\n        android:strokeLineJoin=\"miter\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#444144\"\n        android:fillAlpha=\"0.5\"\n        android:strokeLineCap=\"square\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_primary.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:pathData=\"M27,223L278,223C286.28,223 293,229.72 293,238L293,238C293,246.28 286.28,253 278,253L27,253C18.72,253 12,246.28 12,238L12,238C12,229.72 18.72,223 27,223Z\"\n        android:fillColor=\"#5F5E6A\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M44.48,307.71L71.86,307.71C75.07,307.71 77.67,310.31 77.67,313.52L77.67,313.52C77.67,316.73 75.07,319.33 71.86,319.33L44.48,319.33C41.27,319.33 38.67,316.73 38.67,313.52L38.67,313.52C38.67,310.31 41.27,307.71 44.48,307.71Z\"\n        android:fillColor=\"#5F5E6A\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M58.17,287.5m-8.5,0a8.5,8.5 0,1 1,17 0a8.5,8.5 0,1 1,-17 0\"\n        android:fillColor=\"#5F5E6A\"/>\n    <path\n        android:pathData=\"M146.76,307.71L158.24,307.71C161.6,307.71 164.33,310.24 164.33,313.36L164.33,313.36C164.33,316.47 161.6,319 158.24,319L146.76,319C143.4,319 140.67,316.47 140.67,313.36L140.67,313.36C140.67,310.24 143.4,307.71 146.76,307.71Z\"\n        android:fillColor=\"#5F5E6A\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M152.5,287.5m-8.5,0a8.5,8.5 0,1 1,17 0a8.5,8.5 0,1 1,-17 0\"\n        android:fillColor=\"#5F5E6A\"/>\n    <path\n        android:pathData=\"M230.67,307.38L262.33,307.38C265.73,307.38 268.5,309.98 268.5,313.19L268.5,313.19C268.5,316.4 265.73,319 262.33,319L230.67,319C227.27,319 224.5,316.4 224.5,313.19L224.5,313.19C224.5,309.98 227.27,307.38 230.67,307.38Z\"\n        android:fillColor=\"#5F5E6A\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M246.5,287.5m-8.5,0a8.5,8.5 0,1 1,17 0a8.5,8.5 0,1 1,-17 0\"\n        android:fillColor=\"#5F5E6A\"/>\n    <path\n        android:pathData=\"M123.25,357.75L153.75,357.75C156.65,357.75 159,360.1 159,363L159,363C159,365.9 156.65,368.25 153.75,368.25L123.25,368.25C120.35,368.25 118,365.9 118,363L118,363C118,360.1 120.35,357.75 123.25,357.75Z\"\n        android:fillColor=\"#5F5E6A\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M123.25,418L153.75,418C156.65,418 159,420.35 159,423.25L159,423.25C159,426.15 156.65,428.5 153.75,428.5L123.25,428.5C120.35,428.5 118,426.15 118,423.25L118,423.25C118,420.35 120.35,418 123.25,418Z\"\n        android:fillColor=\"#5F5E6A\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M123.25,478.25L153.75,478.25C156.65,478.25 159,480.6 159,483.5L159,483.5C159,486.4 156.65,488.75 153.75,488.75L123.25,488.75C120.35,488.75 118,486.4 118,483.5L118,483.5C118,480.6 120.35,478.25 123.25,478.25Z\"\n        android:fillColor=\"#5F5E6A\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M123.25,598.75L153.75,598.75C156.65,598.75 159,601.1 159,604L159,604C159,606.9 156.65,609.25 153.75,609.25L123.25,609.25C120.35,609.25 118,606.9 118,604L118,604C118,601.1 120.35,598.75 123.25,598.75Z\"\n        android:fillColor=\"#5F5E6A\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M111.25,538.5L141.75,538.5C144.65,538.5 147,540.85 147,543.75L147,543.75C147,546.65 144.65,549 141.75,549L111.25,549C108.35,549 106,546.65 106,543.75L106,543.75C106,540.85 108.35,538.5 111.25,538.5Z\"\n        android:fillColor=\"#5F5E6A\"\n        android:strokeColor=\"#00000000\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_status.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:pathData=\"M257,15m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-10 0\"\n        android:fillColor=\"#686568\"/>\n    <path\n        android:pathData=\"M245,15m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-10 0\"\n        android:fillColor=\"#686568\"/>\n    <path\n        android:pathData=\"M233,15m-5,0a5,5 0,1 1,10 0a5,5 0,1 1,-10 0\"\n        android:fillColor=\"#686568\"/>\n    <path\n        android:pathData=\"M267.81,10L282.19,10C284.84,10 287,12.02 287,14.5L287,14.5C287,16.98 284.84,19 282.19,19L267.81,19C265.16,19 263,16.98 263,14.5L263,14.5C263,12.02 265.16,10 267.81,10Z\"\n        android:fillColor=\"#686568\"\n        android:strokeColor=\"#00000000\"/>\n    <path\n        android:pathData=\"M25.71,10L39.29,10C41.89,10 44,12.02 44,14.5L44,14.5C44,16.98 41.89,19 39.29,19L25.71,19C23.11,19 21,16.98 21,14.5L21,14.5C21,12.02 23.11,10 25.71,10Z\"\n        android:fillColor=\"#686568\"\n        android:strokeColor=\"#00000000\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_surface_l1.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:pathData=\"M20.43,343L284.57,343C289.22,343 293,346.78 293,351.43L293,623.57C293,628.22 289.22,632 284.57,632L20.43,632C15.78,632 12,628.22 12,623.57L12,351.43C12,346.78 15.78,343 20.43,343Z\"\n        android:fillColor=\"#F6F3F9\"\n        android:strokeColor=\"#00000000\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ts_surface_l2.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"305dp\"\n    android:height=\"661dp\"\n    android:viewportWidth=\"305\"\n    android:viewportHeight=\"661\">\n  <group>\n    <clip-path\n        android:pathData=\"M0,0h305v661h-305z\"/>\n    <path\n        android:pathData=\"M0,0h305v661h-305z\"\n        android:fillColor=\"#000000\"\n        android:fillAlpha=\"0\"/>\n    <path\n        android:pathData=\"M198.63,267.63L106,267.63L106,267.63L106,332L198.63,332L198.63,267.63ZM200.13,267.63L284.63,267.63C289.25,267.63 293,271.38 293,275.99L293,323.63C293,328.25 289.25,332 284.63,332L200.13,332L200.13,267.63ZM104.5,267.63L20.37,267.63C15.75,267.63 12,271.38 12,275.99L12,323.63C12,328.25 15.75,332 20.37,332L104.5,332L104.5,267.63L104.5,267.63Z\"\n        android:fillColor=\"#F3EFF5\"\n        android:fillType=\"evenOdd\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-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/bunny_brand\" />\n    <foreground android:drawable=\"@drawable/bunny_logo\" />\n    <monochrome android:drawable=\"@drawable/bunny_logo\" />\n</adaptive-icon>"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"purple_200\">#FFBB86FC</color>\n    <color name=\"purple_500\">#FF6200EE</color>\n    <color name=\"purple_700\">#FF3700B3</color>\n    <color name=\"teal_200\">#FF03DAC5</color>\n    <color name=\"teal_700\">#FF018786</color>\n    <color name=\"black\">#FF000000</color>\n    <color name=\"white\">#FFFFFFFF</color>\n    <color name=\"bunny_brand\">#FF48488B</color>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n\n    <string name=\"msg_cleared_cache\">Cache cleared successfully</string>\n    <string name=\"msg_load_fail\">Failed to load commits</string>\n    <string name=\"msg_coming_soon\">Coming soon</string>\n    <string name=\"msg_invalid_version\">Invalid Discord version</string>\n    <string name=\"msg_seven_left\">7 more taps</string>\n    <string name=\"msg_five_left\">5 more taps</string>\n    <string name=\"msg_two_left\">2 more taps</string>\n    <string name=\"msg_loading\">Loading…</string>\n    <string name=\"msg_downgrade\">Downgrade</string>\n    <string name=\"msg_downgrade_disallowed\">Cannot downgrade, try uninstalling first</string>\n    <string name=\"msg_unlocked\">You are now a developer</string>\n    <string name=\"msg_permission_grant\">In order for Bunny Manager to function, file permissions are required. Since shared data is stored in ~/Bunny, permissions are required in order to access it.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n\n    <string name=\"group_download\">Download APKs</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Installing</string>\n\n    <string name=\"step_dl_base\">Downloading base apk</string>\n    <string name=\"step_dl_lib\">Downloading libraries apk</string>\n    <string name=\"step_dl_lang\">Downloading language apk</string>\n    <string name=\"step_dl_res\">Downloading resources apk</string>\n    <string name=\"step_dl_vd\">Downloading Bunny module</string>\n\n    <string name=\"step_change_icon\">Changing app icon</string>\n    <string name=\"step_patch_manifests\">Patching app manifests</string>\n    <string name=\"step_add_vd\">Injecting Bunny</string>\n\n    <string name=\"step_signing\">Signing APKs</string>\n    <string name=\"step_installing\">Installing APKs</string>\n\n    <string name=\"installer_success\">Installed successfully</string>\n    <string name=\"installer_aborted\">Install canceled</string>\n\n    <string name=\"install_fail_generic\">Failed to install: Unknown reason</string>\n    <string name=\"install_fail_blocked\">Installation was blocked</string>\n    <string name=\"install_fail_invalid\">One or more APKs were invalid or corrupt</string>\n    <string name=\"install_fail_conflict\">Conflicts with an existing app, usually due to mismatched signatures</string>\n    <string name=\"install_fail_storage\">Not enough available storage to install</string>\n    <string name=\"install_fail_incompatible\">Application is incompatible with this device</string>\n    <string name=\"install_fail_timeout\">Installation timed out</string>\n\n    <string name=\"status_ongoing\">Ongoing</string>\n    <string name=\"status_successful\">Successful</string>\n    <string name=\"status_fail\">Failed</string>\n    <string name=\"status_queued\">Queued</string>\n\n    <string name=\"action_collapse\">Collapse</string>\n    <string name=\"action_expand\">Expand</string>\n    <string name=\"action_back\">Go back</string>\n    <string name=\"action_copy_logs\">Copy logs</string>\n    <string name=\"action_clear_cache\">Clear cache</string>\n    <string name=\"action_confirm\">Confirm</string>\n    <string name=\"action_start_update\">Start update</string>\n    <string name=\"action_install\">Install</string>\n    <string name=\"action_update\">Update</string>\n    <string name=\"action_reinstall\">Reinstall</string>\n    <string name=\"action_launch\">Launch</string>\n    <string name=\"action_uninstall\">Uninstall</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Retry</string>\n    <string name=\"action_reload\">Reload</string>\n    <string name=\"action_open_about\">Open about</string>\n    <string name=\"action_open_settings\">Open settings</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n\n    <string name=\"installer_cached\">Cached</string>\n\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Settings</string>\n    <string name=\"title_update\">Update available!</string>\n    <string name=\"title_about\">About</string>\n    <string name=\"title_permission_grant\">Grant Permissions</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Light</string>\n    <string name=\"theme_dark\">Dark</string>\n\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n\n    <string name=\"settings_appearance\">Appearance</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamic color</string>\n    <string name=\"settings_dynamic_color_description\">Only available on Android 12 and up</string>\n    <string name=\"settings_theme\">Theme</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">App name</string>\n    <string name=\"settings_app_icon\">Replace app icon</string>\n    <string name=\"settings_app_icon_description\">Uses the Bunny icon instead of Discord\\'s</string>\n\n    <string name=\"settings_advanced\">Advanced</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Release channel</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n\n    <string name=\"settings_developer\">Developer only</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Package name</string>\n    <string name=\"settings_version\">Discord version</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Enable debuggable flag</string>\n    <string name=\"settings_allow_downgrade\">Allow downgrading</string>\n    <string name=\"settings_allow_downgrade_description\">Bypass downgrade check by Bunny Manager, useful if your device already allows downgrading through root</string>\n\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n\n    <string name=\"update_description\">Bunny Manager version %1$s is now available!</string>\n\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Special thanks</string>\n    <string name=\"label_translate\">Translate</string>\n\n    <string name=\"version_latest\">Latest: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Current: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">PackageManager (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/themes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <style name=\"Theme.Manager\" parent=\"android:Theme.Material.NoActionBar\" />\n\n    <style name=\"Theme.Manager.Splash\" parent=\"Theme.SplashScreen\">\n        <item name=\"windowSplashScreenAnimatedIcon\">@drawable/bunny_logo</item>\n        <item name=\"windowSplashScreenBackground\">@color/bunny_brand</item>\n        <item name=\"postSplashScreenTheme\">@style/Theme.Manager</item>\n    </style>\n</resources>"
  },
  {
    "path": "app/src/main/res/values-af-rZA/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Bestuurder</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Kas is suksesvol skoongemaak</string>\n    <string name=\"msg_load_fail\">Kon nie commits laai nie</string>\n    <string name=\"msg_coming_soon\">Kom binnekort</string>\n    <string name=\"msg_invalid_version\">Ongeldige Discord-weergawe</string>\n    <string name=\"msg_seven_left\">Nog 7 krane</string>\n    <string name=\"msg_five_left\">Nog 5 krane</string>\n    <string name=\"msg_two_left\">Nog 2 krane</string>\n    <string name=\"msg_loading\">Laai tans…</string>\n    <string name=\"msg_downgrade_disallowed\">Kan nie afgradeer nie, probeer eers deïnstalleer</string>\n    <string name=\"msg_unlocked\">Jy is nou \\'n ontwikkelaar</string>\n    <string name=\"msg_permission_grant\">Vir Bunny Bestuurder om te funksioneer, word lêertoestemmings vereis. Aangesien gedeelde data in ~/Bunny gestoor word, word toestemmings vereis om toegang daartoe te verkry.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Wil jy weer probeer met \\'n aflaaispieël?</string>\n    <string name=\"msg_invalid_apk\">APK is korrupteer, probeer om kas skoon te maak en dan weer te installeer</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Laai APK\\'s af</string>\n    <string name=\"group_patch\">Pleister</string>\n    <string name=\"group_installing\">Installeer tans</string>\n    <string name=\"step_dl_base\">Laai tans basis apk af</string>\n    <string name=\"step_dl_lib\">Laai library base apk af</string>\n    <string name=\"step_dl_lang\">Laai tans taalbasis Apk af</string>\n    <string name=\"step_dl_res\">Laai tans hulpbronne Apk af</string>\n    <string name=\"step_dl_vd\">Laai tans Bunny-module af</string>\n    <string name=\"step_change_icon\">Verander toepassing-ikoon</string>\n    <string name=\"step_patch_manifests\">Patching app manifesteer</string>\n    <string name=\"step_add_vd\">Inspuiting van Bunny</string>\n    <string name=\"step_signing\">Ondertekening van APK\\'s</string>\n    <string name=\"step_installing\">Installeer tans APK\\'s</string>\n    <string name=\"installer_success\">Suksesvol geïnstalleer</string>\n    <string name=\"installer_aborted\">Installering is gekanselleer</string>\n    <string name=\"install_fail_generic\">Kon nie installeer nie: Onbekende rede</string>\n    <string name=\"install_fail_blocked\">Installasie is geblokkeer</string>\n    <string name=\"install_fail_invalid\">Een of meer APK\\'s was ongeldig of korrup</string>\n    <string name=\"install_fail_conflict\">Konflik met \\'n bestaande toepassing, gewoonlik as gevolg van nie-ooreenstemmende handtekeninge</string>\n    <string name=\"install_fail_storage\">Nie genoeg beskikbare berging om te installeer nie</string>\n    <string name=\"install_fail_incompatible\">Toepassing is onversoenbaar met hierdie toestel</string>\n    <string name=\"install_fail_timeout\">Installasie het uitgetel</string>\n    <string name=\"status_ongoing\">Deurlopend</string>\n    <string name=\"status_successful\">Suksesvol</string>\n    <string name=\"status_fail\">Misluk</string>\n    <string name=\"status_queued\">In die ry</string>\n    <string name=\"action_collapse\">Inval</string>\n    <string name=\"action_expand\">Brei uit</string>\n    <string name=\"action_back\">Gaan terug</string>\n    <string name=\"action_copy_logs\">Kopieer logs</string>\n    <string name=\"action_clear_cache\">Vee kas uit</string>\n    <string name=\"action_confirm\">Bevestig</string>\n    <string name=\"action_start_update\">Begin opdatering</string>\n    <string name=\"action_install\">Installeer</string>\n    <string name=\"action_update\">Opdateer</string>\n    <string name=\"action_reinstall\">Herinstalleer</string>\n    <string name=\"action_launch\">Begin</string>\n    <string name=\"action_uninstall\">Deïnstalleer</string>\n    <string name=\"action_info\">Inligting</string>\n    <string name=\"action_retry\">Probeer weer</string>\n    <string name=\"action_reload\">Herlaai</string>\n    <string name=\"action_open_about\">Maak oop oor</string>\n    <string name=\"action_open_settings\">Maak instellings oop</string>\n    <string name=\"action_tap_to_install\">Tik om Bunny vir Discord %1$s te installeer</string>\n    <string name=\"action_confirm_exit\">Verlaat in elk geval</string>\n    <string name=\"action_dismiss_nevermind\">Toemaar</string>\n    <string name=\"action_dismiss_no_thanks\">Nee dankie</string>\n    <string name=\"action_try_again\">Probeer weer</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">As jy die installeerder verlaat voordat dit klaar is, kan afgelaaide lêers beskadig word. Is jy seker jy wil dit doen?</string>\n    <string name=\"installer_cached\">Gekas</string>\n    <string name=\"title_installer\">Installeerder</string>\n    <string name=\"title_home\">Tuis</string>\n    <string name=\"title_settings\">Instellings</string>\n    <string name=\"title_update\">Opdatering beskikbaar!</string>\n    <string name=\"title_about\">Oor</string>\n    <string name=\"title_permission_grant\">Gee toestemmings</string>\n    <string name=\"title_update_available\">Nuwe Discord-opdatering beskikbaar!</string>\n    <string name=\"title_warning\">Waarskuwing</string>\n    <string name=\"title_dl_failed\">Aflaai het misluk</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Stelsel</string>\n    <string name=\"theme_light\">Lig</string>\n    <string name=\"theme_dark\">Donker</string>\n    <string name=\"duration_disabled\">Gestrem</string>\n    <string name=\"duration_fifteen_min\">Kwartierliks</string>\n    <string name=\"duration_half_hour\">Halfuurliks</string>\n    <string name=\"duration_hourly\">Uurliks</string>\n    <string name=\"duration_bihourly\">Twee-uurliks</string>\n    <string name=\"duration_twice_daily\">Twee keer per dag</string>\n    <string name=\"duration_daily\">Daagliks</string>\n    <string name=\"duration_weekly\">Weekliks</string>\n    <string name=\"settings_appearance\">Voorkoms</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dinamiese kleur</string>\n    <string name=\"settings_dynamic_color_description\">Slegs beskikbaar op Android 12 en hoër</string>\n    <string name=\"settings_theme\">Tema</string>\n    <string name=\"settings_check_updates\">Kyk vir Discord-opdaterings</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">Programnaam</string>\n    <string name=\"settings_app_icon\">Vervang app-ikoon</string>\n    <string name=\"settings_app_icon_description\">Gebruik die Bunny-ikoon in plaas van Discord s\\'n</string>\n    <string name=\"settings_advanced\">Gevorderd</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Stel kanaal vry</string>\n    <string name=\"settings_mirror\">Laai spieël af</string>\n    <string name=\"settings_auto_clear_cache\">Vee kas outomaties uit</string>\n    <string name=\"settings_auto_clear_cache_description\">Vee kas uit wanneer Discord \\'n opdatering kry</string>\n    <string name=\"settings_developer\">Slegs ontwikkelaar</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module ligging</string>\n    <string name=\"settings_module_location_description\">Vir gebruik met die ontwikkeling van die Xposed-module. WEES VERSIGTIG</string>\n    <string name=\"settings_module_location_reset\">Stel module ligging terug</string>\n    <string name=\"settings_package_name\">Pakketnaam</string>\n    <string name=\"settings_version\">Discord weergawe</string>\n    <string name=\"settings_debuggable\">Ontfoutbaar</string>\n    <string name=\"settings_debuggable_description\">Aktiveer ontfoutbare vlag</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Bestuurder weergawe %1$s is nou beskikbaar!</string>\n    <string name=\"channel_stable\">Stabiel</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alfa</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Onenigheid</string>\n    <string name=\"label_team\">Span</string>\n    <string name=\"label_special_thanks\">Spesiale dankie</string>\n    <string name=\"label_translate\">Vertaal</string>\n    <string name=\"version_latest\">Nuutste: %1$s</string>\n    <string name=\"version_target\">Teiken: %1$s</string>\n    <string name=\"version_current\">Huidig: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-ar-rSA/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">مدير الثأر</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">تم مسح ذاكرة التخزين المؤقت بنجاح</string>\n    <string name=\"msg_load_fail\">فشل تحميل البيانات</string>\n    <string name=\"msg_coming_soon\">سيأتي قريباً</string>\n    <string name=\"msg_invalid_version\">إصدار ديسكورد غير صحيح</string>\n    <string name=\"msg_seven_left\">7 نقرات أخرى</string>\n    <string name=\"msg_five_left\">5 نقرات أخرى</string>\n    <string name=\"msg_two_left\">نقرتان أخران</string>\n    <string name=\"msg_loading\">جاري التحميل…</string>\n    <string name=\"msg_downgrade_disallowed\">لا يمكن رجوع إلى النسخة السابقة، حاول إزالة التثبيت أولاً</string>\n    <string name=\"msg_unlocked\">أنت الآن مبرمِج</string>\n    <string name=\"msg_permission_grant\">لكي يعمل Bunny Manager، مطلوب أذونات التخزين. بما أن البيانات المخزنة يتم تخزينها في ~/Bunny، فإن الأذونات مطلوبة الحصول عليها.</string>\n    <string name=\"msg_shizuku_denied\">أخفق الحصول على أذوات Shizuku</string>\n    <string name=\"msg_change_mirror\">هل ترغب في التحميل مرة اخري من مصدر بديل؟</string>\n    <string name=\"msg_invalid_apk\">ملف الAPK تالف، حاول مسح ذاكرة التخزين المؤقت ثم إعادة التثبيت</string>\n    <string name=\"msg_download_cancelled\">تم إحباط التنزيل</string>\n    <string name=\"msg_download_failed\">فشل التنزيل</string>\n    <string name=\"msg_download_verify_failed\">تعذر التحقق من المِلَفّ الذي تم تنزيله، راجع السجلات للحصول على مزيد من التفاصيل</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">تنزيل برنامج التشغيل للأندرويد (APKs)</string>\n    <string name=\"group_patch\">تصحيح</string>\n    <string name=\"group_installing\">جاري التثبيت</string>\n    <string name=\"step_dl_base\">تنزيل APK الأساسي</string>\n    <string name=\"step_dl_lib\">تحميل الملفات الأساسية APK</string>\n    <string name=\"step_dl_lang\">تحميل لغة APK</string>\n    <string name=\"step_dl_res\">تحميل موارد APK</string>\n    <string name=\"step_dl_vd\">تحميل وحدة Bunny</string>\n    <string name=\"step_change_icon\">تغيير ايقونة التطبيق</string>\n    <string name=\"step_patch_manifests\">تصحيح بيانات التطبيق</string>\n    <string name=\"step_add_vd\">تحقين Bunny</string>\n    <string name=\"step_signing\">توقيع APKs</string>\n    <string name=\"step_installing\">تثبيت APKs</string>\n    <string name=\"installer_success\">تم التثبيت بنجاح</string>\n    <string name=\"installer_aborted\">تم إلغاء التثبيت</string>\n    <string name=\"install_fail_generic\">فشل في التثبيت: سبب غير معروف</string>\n    <string name=\"install_fail_blocked\">تم حظر التثبيت</string>\n    <string name=\"install_fail_invalid\">واحد أو أكثر من ال APKs غير صالح أو فاسد</string>\n    <string name=\"install_fail_conflict\">التعارض مع تطبيق مثبت، عادة ما يكون ذلك بسبب عدم تطابق التوقيعات</string>\n    <string name=\"install_fail_storage\">لا توجد مساحة تخزين كافية للتثبيت</string>\n    <string name=\"install_fail_incompatible\">التطبيق غير متوافق مع هذا الجهاز</string>\n    <string name=\"install_fail_timeout\">انتهت مهلة تثبيت</string>\n    <string name=\"status_ongoing\">مستمر</string>\n    <string name=\"status_successful\">تم بنجاح</string>\n    <string name=\"status_fail\">فشلت العملية</string>\n    <string name=\"status_queued\">في قائمة الإنتظار</string>\n    <string name=\"action_collapse\">انهدام</string>\n    <string name=\"action_expand\">إظهار</string>\n    <string name=\"action_back\">رجوع</string>\n    <string name=\"action_copy_logs\">نسخ السجلات</string>\n    <string name=\"action_clear_cache\">مسح ذاكرة التخزين المؤقت</string>\n    <string name=\"action_confirm\">تأكيد</string>\n    <string name=\"action_start_update\">بدء التحديث</string>\n    <string name=\"action_install\">تثبيت</string>\n    <string name=\"action_update\">تحديث</string>\n    <string name=\"action_reinstall\">إعادة التثبيت</string>\n    <string name=\"action_launch\">تشغيل</string>\n    <string name=\"action_uninstall\">إزالة التثبيت</string>\n    <string name=\"action_info\">معلومات</string>\n    <string name=\"action_retry\">إعادة المحاولة</string>\n    <string name=\"action_reload\">إعادة التحميل</string>\n    <string name=\"action_open_about\">فتح حول</string>\n    <string name=\"action_open_settings\">فتح الإعدادات</string>\n    <string name=\"action_tap_to_install\">انقر لتثبيت Bunny للديسكورد %1$s</string>\n    <string name=\"action_confirm_exit\">الإنهاء على أية حال</string>\n    <string name=\"action_dismiss_nevermind\">رجوع</string>\n    <string name=\"action_dismiss_no_thanks\">لا، شكراً</string>\n    <string name=\"action_try_again\">حاول مرة أخرى</string>\n    <string name=\"action_previous_theme\">راجع الموضوع السابق</string>\n    <string name=\"action_next_theme\">انظر الموضوع التالي</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">الخروج من المثبت قبل انتهائه يمكن أن يؤدي إلى تلف الملفات التي تم تحميلها، هل أنت متأكد من أنك تريد القيام بذلك؟</string>\n    <string name=\"installer_cached\">ذاكرة التخزين المؤقت</string>\n    <string name=\"title_installer\">المثبت</string>\n    <string name=\"title_home\">الصفحة الرئيسية</string>\n    <string name=\"title_settings\">الإعدادات</string>\n    <string name=\"title_update\">تحديث متوفر!</string>\n    <string name=\"title_about\">حول</string>\n    <string name=\"title_permission_grant\">منح الأذونات</string>\n    <string name=\"title_update_available\">تحديث ديسكورد جديد متوفر!</string>\n    <string name=\"title_warning\">تحذير</string>\n    <string name=\"title_dl_failed\">فشل التنزيل</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">النظام</string>\n    <string name=\"theme_light\">مضيء</string>\n    <string name=\"theme_dark\">مظلم</string>\n    <string name=\"duration_disabled\">معطل</string>\n    <string name=\"duration_fifteen_min\">ربع ساعة</string>\n    <string name=\"duration_half_hour\">نصف الساعة</string>\n    <string name=\"duration_hourly\">كل ساعة</string>\n    <string name=\"duration_bihourly\">كل ساعتين</string>\n    <string name=\"duration_twice_daily\">مرتين يومياً</string>\n    <string name=\"duration_daily\">يومياً</string>\n    <string name=\"duration_weekly\">إسبوعياً</string>\n    <string name=\"settings_appearance\">إعدادات المظهر</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">ألوان حيويّة</string>\n    <string name=\"settings_dynamic_color_description\">متوفر فقط على أندرويد 12 وما فوق</string>\n    <string name=\"settings_theme\">المظهر</string>\n    <string name=\"settings_check_updates\">تحقق من وجود تحديثات للديسكورد</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">اسم التطبيق</string>\n    <string name=\"settings_app_icon\">استبدال أيقونة التطبيق</string>\n    <string name=\"settings_app_icon_description\">استخدم أيقونة Bunny بدلا من ديسكورد</string>\n    <string name=\"settings_advanced\">خيارات متقدمة</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">اصدار القناة</string>\n    <string name=\"settings_mirror\">تحميل بديل</string>\n    <string name=\"settings_auto_clear_cache\">مسح الذاكرة المؤقتة تلقائياً</string>\n    <string name=\"settings_auto_clear_cache_description\">مسح الذاكرة المؤقتة عندما يحصل ديسكورد على تحديث</string>\n    <string name=\"settings_developer\">المطوِّر فقط</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">موقع الوحدة</string>\n    <string name=\"settings_module_location_description\">للاستخدام في تطوير وحدة Xpose. احرص</string>\n    <string name=\"settings_module_location_reset\">إعادة تعيين موقع الوحدة</string>\n    <string name=\"settings_package_name\">اسم الباقة</string>\n    <string name=\"settings_version\">إصدار ديسكورد</string>\n    <string name=\"settings_debuggable\">قابل للتصحيح</string>\n    <string name=\"settings_debuggable_description\">تفعيل علم التصحيح</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">إصدار Bunny Manager %1$s متاح الآن!</string>\n    <string name=\"channel_stable\">مستقر</string>\n    <string name=\"channel_beta\">تجريبي</string>\n    <string name=\"channel_alpha\">نسخة أولية</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">الفريق</string>\n    <string name=\"label_special_thanks\">شكر خاص</string>\n    <string name=\"label_translate\">الترجمة</string>\n    <string name=\"version_latest\">الإصدار الأخير: %1$s</string>\n    <string name=\"version_target\">الهدف: %1$s</string>\n    <string name=\"version_current\">الحالي: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-ca-rES/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Gerent Bunny</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">La memòria cau s\\'ha esborrat correctament</string>\n    <string name=\"msg_load_fail\">No s\\'han pogut carregar les confirmacions</string>\n    <string name=\"msg_coming_soon\">Pròximament</string>\n    <string name=\"msg_invalid_version\">Versió de Discord no vàlida</string>\n    <string name=\"msg_seven_left\">7 tocs més</string>\n    <string name=\"msg_five_left\">5 tocs més</string>\n    <string name=\"msg_two_left\">2 tocs més</string>\n    <string name=\"msg_loading\">Carregant…</string>\n    <string name=\"msg_downgrade_disallowed\">No es pot desactualitzar, primer prova de desinstal·lar</string>\n    <string name=\"msg_unlocked\">Ara ets desenvolupador</string>\n    <string name=\"msg_permission_grant\">Perquè Bunny Manager funcioni, calen permisos de fitxers. Com que les dades compartides s\\'emmagatzemen a ~/Bunny, calen permisos per accedir-hi.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Vols tornar-ho a provar amb una baixada?</string>\n    <string name=\"msg_invalid_apk\">L\\'APK s\\'ha fet malbé, proveu d\\'esborrar la memòria cau i torna-ho a instal·lar</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Baixa APK</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Instal·lant</string>\n    <string name=\"step_dl_base\">Baixant l\\'apk base</string>\n    <string name=\"step_dl_lib\">Baixant biblioteques apk</string>\n    <string name=\"step_dl_lang\">Baixant l\\'apk d\\'idioma</string>\n    <string name=\"step_dl_res\">Baixant l\\'apk de recursos</string>\n    <string name=\"step_dl_vd\">Baixant el mòdul Bunny</string>\n    <string name=\"step_change_icon\">Canviant l\\'icona de l\\'app</string>\n    <string name=\"step_patch_manifests\">Patching app manifests</string>\n    <string name=\"step_add_vd\">Injectant Bunny</string>\n    <string name=\"step_signing\">Signant APK</string>\n    <string name=\"step_installing\">Instal·lació d\\'APK</string>\n    <string name=\"installer_success\">Instal·lat correctament</string>\n    <string name=\"installer_aborted\">Instal·lació cancelada</string>\n    <string name=\"install_fail_generic\">No s\\'ha pogut instal·lar: motiu desconegut</string>\n    <string name=\"install_fail_blocked\">La instal·lació s\\'ha bloquejat</string>\n    <string name=\"install_fail_invalid\">Un o més APK no eren vàlids o malmesos</string>\n    <string name=\"install_fail_conflict\">Conflictes amb una aplicació existent, normalment a causa de signatures que no coincideixen</string>\n    <string name=\"install_fail_storage\">No hi ha prou espai disponible per instal·lar-lo</string>\n    <string name=\"install_fail_incompatible\">L\\'aplicació és incompatible amb aquest dispositiu</string>\n    <string name=\"install_fail_timeout\">S\\'ha esgotat el temps d\\'instal·lació</string>\n    <string name=\"status_ongoing\">En marxa</string>\n    <string name=\"status_successful\">Correcte</string>\n    <string name=\"status_fail\">Error</string>\n    <string name=\"status_queued\">En cua</string>\n    <string name=\"action_collapse\">Col·lapse</string>\n    <string name=\"action_expand\">Expandir</string>\n    <string name=\"action_back\">Torna</string>\n    <string name=\"action_copy_logs\">Copia els registres</string>\n    <string name=\"action_clear_cache\">Netejar cache</string>\n    <string name=\"action_confirm\">Confirmar</string>\n    <string name=\"action_start_update\">Inicia actualització</string>\n    <string name=\"action_install\">Instal·lar</string>\n    <string name=\"action_update\">Actualitzar</string>\n    <string name=\"action_reinstall\">Reinstal·lar</string>\n    <string name=\"action_launch\">Iniciar</string>\n    <string name=\"action_uninstall\">Desinstal·lar</string>\n    <string name=\"action_info\">Informació</string>\n    <string name=\"action_retry\">Torna-ho a provar</string>\n    <string name=\"action_reload\">Recarregar</string>\n    <string name=\"action_open_about\">Obre sobre</string>\n    <string name=\"action_open_settings\">Obre la configuració</string>\n    <string name=\"action_tap_to_install\">Toca per instal·lar Bunny per a Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Sortiu de totes maneres</string>\n    <string name=\"action_dismiss_nevermind\">No importa</string>\n    <string name=\"action_dismiss_no_thanks\">No gràcies</string>\n    <string name=\"action_try_again\">Torna-ho a provar</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Sortir de l\\'instal·lador abans que s\\'acabi podria danyar els fitxers descarregats, esteu segur que voleu fer-ho?</string>\n    <string name=\"installer_cached\">Cached</string>\n    <string name=\"title_installer\">Instal·lador</string>\n    <string name=\"title_home\">Inici</string>\n    <string name=\"title_settings\">Configuració</string>\n    <string name=\"title_update\">Actualització disponible!</string>\n    <string name=\"title_about\">Sobre</string>\n    <string name=\"title_permission_grant\">Concedir permisos</string>\n    <string name=\"title_update_available\">Nova actualització de Discord disponible!</string>\n    <string name=\"title_warning\">Avís</string>\n    <string name=\"title_dl_failed\">La baixada ha fallat</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Sistema</string>\n    <string name=\"theme_light\">Llum</string>\n    <string name=\"theme_dark\">Fosc</string>\n    <string name=\"duration_disabled\">Inhabilitat</string>\n    <string name=\"duration_fifteen_min\">Quart d\\'hora</string>\n    <string name=\"duration_half_hour\">Mitja hora</string>\n    <string name=\"duration_hourly\">Cada hora</string>\n    <string name=\"duration_bihourly\">Cada dues hores</string>\n    <string name=\"duration_twice_daily\">Dues vegades al dia</string>\n    <string name=\"duration_daily\">Diàriament</string>\n    <string name=\"duration_weekly\">Setmanalment</string>\n    <string name=\"settings_appearance\">Aparença</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Color dinàmic</string>\n    <string name=\"settings_dynamic_color_description\">Només disponible a Android 12 i posteriors</string>\n    <string name=\"settings_theme\">Tema</string>\n    <string name=\"settings_check_updates\">Comprova si hi ha actualitzacions de Discord</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">Nom de l\\'aplicació</string>\n    <string name=\"settings_app_icon\">Substitueix la icona de l\\'aplicació</string>\n    <string name=\"settings_app_icon_description\">Utilitza la icona de Bunny en comptes de la de Discord</string>\n    <string name=\"settings_advanced\">Avançat</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Canal release</string>\n    <string name=\"settings_mirror\">Descàrrega mirall</string>\n    <string name=\"settings_auto_clear_cache\">Esborra cache automàticament</string>\n    <string name=\"settings_auto_clear_cache_description\">Esborra cache quan Discord rep una actualització</string>\n    <string name=\"settings_developer\">Només desenvolupador</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Ubicació del mòdul</string>\n    <string name=\"settings_module_location_description\">Per utilitzar-lo amb el desenvolupament del mòdul Xposed. VES AMB COMPTE</string>\n    <string name=\"settings_module_location_reset\">Restableix la ubicació del mòdul</string>\n    <string name=\"settings_package_name\">Nom del paquet</string>\n    <string name=\"settings_version\">Versió de Discord</string>\n    <string name=\"settings_debuggable\">Depurable</string>\n    <string name=\"settings_debuggable_description\">Activa el senyalador depurable</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">La versió %1$s de Bunny Manager ja està disponible!</string>\n    <string name=\"channel_stable\">Estable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Equip</string>\n    <string name=\"label_special_thanks\">Agraïments especials</string>\n    <string name=\"label_translate\">Traduir</string>\n    <string name=\"version_latest\">Última: %1$s</string>\n    <string name=\"version_target\">Objectiu: %1$s</string>\n    <string name=\"version_current\">Actual: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-cs-rCZ/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Správce Vendetty</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Mezipaměť úspěšně vymazána</string>\n    <string name=\"msg_load_fail\">Nepodařilo se načíst commity</string>\n    <string name=\"msg_coming_soon\">Již brzy</string>\n    <string name=\"msg_invalid_version\">Neplatná verze Discordu</string>\n    <string name=\"msg_seven_left\">Ještě 7 klepnutí</string>\n    <string name=\"msg_five_left\">Ještě 5 klepnutí</string>\n    <string name=\"msg_two_left\">Ještě 2 klepnutí</string>\n    <string name=\"msg_loading\">Načítání…</string>\n    <string name=\"msg_downgrade_disallowed\">Nelze jít o verzi zpět. Nejdříve zkuste odinstalovat</string>\n    <string name=\"msg_unlocked\">Nyní jste vývojářem</string>\n    <string name=\"msg_permission_grant\">Aby Správce Vendetty fungoval, jsou vyžadována oprávnění k přístupu k souborům. Protože jsou sdílená data uložena ve složce ~/Bunny, je pro přístup k ní požadováno oprávnění.</string>\n    <string name=\"msg_shizuku_denied\">Nepodařilo se získat oprávnění pro Shizuku</string>\n    <string name=\"msg_change_mirror\">Chcete to zkusit znovu pomocí zrcadla?</string>\n    <string name=\"msg_invalid_apk\">Soubor APK byl poškozen, zkuste vyčistit paměť cache a poté přeinstalovat</string>\n    <string name=\"msg_download_cancelled\">Stahování bylo přerušeno</string>\n    <string name=\"msg_download_failed\">Stahování selhalo</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Stáhnout soubory APK</string>\n    <string name=\"group_patch\">Vkládání</string>\n    <string name=\"group_installing\">Instalování</string>\n    <string name=\"step_dl_base\">Stahování základní apk</string>\n    <string name=\"step_dl_lib\">Stahování apk knihoven</string>\n    <string name=\"step_dl_lang\">Stahování apk jazyků</string>\n    <string name=\"step_dl_res\">Stahování apk zdrojů</string>\n    <string name=\"step_dl_vd\">Stahování modulu Bunny</string>\n    <string name=\"step_change_icon\">Měnění ikony aplikace</string>\n    <string name=\"step_patch_manifests\">Vkládání manifestů aplikace</string>\n    <string name=\"step_add_vd\">Vkládání Vendetty</string>\n    <string name=\"step_signing\">Podepisování APK souborů</string>\n    <string name=\"step_installing\">Instalování APK souborů</string>\n    <string name=\"installer_success\">Instalace úspěšná</string>\n    <string name=\"installer_aborted\">Instalace zrušena</string>\n    <string name=\"install_fail_generic\">Instalace se nepovedla: Neznámý důvod</string>\n    <string name=\"install_fail_blocked\">Instalace byla zablokována</string>\n    <string name=\"install_fail_invalid\">Některé APK soubory byly neplatné nebo požkozené</string>\n    <string name=\"install_fail_conflict\">Konflikuje s existující aplikací, obvykle kvůli neshodě podpisů</string>\n    <string name=\"install_fail_storage\">Nedostatek úložiště pro instalaci</string>\n    <string name=\"install_fail_incompatible\">Aplikace není s tímto zařízením kompatibilní</string>\n    <string name=\"install_fail_timeout\">Instalace dosáhla časového limitu</string>\n    <string name=\"status_ongoing\">Probíhající</string>\n    <string name=\"status_successful\">Úspěšné</string>\n    <string name=\"status_fail\">Selhalo</string>\n    <string name=\"status_queued\">Čekající</string>\n    <string name=\"action_collapse\">Sbalit</string>\n    <string name=\"action_expand\">Rozbalit</string>\n    <string name=\"action_back\">Jít zpět</string>\n    <string name=\"action_copy_logs\">Zkopírovat zápisy</string>\n    <string name=\"action_clear_cache\">Vyčistit mezipaměť</string>\n    <string name=\"action_confirm\">Potvrdit</string>\n    <string name=\"action_start_update\">Spustit aktualizaci</string>\n    <string name=\"action_install\">Nainstalovat</string>\n    <string name=\"action_update\">Aktualizovat</string>\n    <string name=\"action_reinstall\">Přeinstalovat</string>\n    <string name=\"action_launch\">Spustit</string>\n    <string name=\"action_uninstall\">Odinstalovat</string>\n    <string name=\"action_info\">Informace</string>\n    <string name=\"action_retry\">Opakovat</string>\n    <string name=\"action_reload\">Obnovit</string>\n    <string name=\"action_open_about\">Otevřít O aplikaci</string>\n    <string name=\"action_open_settings\">Otevřít nastavení</string>\n    <string name=\"action_tap_to_install\">Klepni pro nainstalování Vendetty pro Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Přesto ukončit</string>\n    <string name=\"action_dismiss_nevermind\">Zrušit</string>\n    <string name=\"action_dismiss_no_thanks\">Ne, díky</string>\n    <string name=\"action_try_again\">Zkusit znovu</string>\n    <string name=\"action_previous_theme\">Zobrazit předchozí motiv</string>\n    <string name=\"action_next_theme\">Zobrazit další motiv</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Opuštění instalátoru před dokončením může poškodit stažené soubory, opravdu chcete pokračovat?</string>\n    <string name=\"installer_cached\">V mezipaměti</string>\n    <string name=\"title_installer\">Instalátor</string>\n    <string name=\"title_home\">Domů</string>\n    <string name=\"title_settings\">Nastavení</string>\n    <string name=\"title_update\">Dostupná aktualizace!</string>\n    <string name=\"title_about\">O aplikaci</string>\n    <string name=\"title_permission_grant\">Udělit oprávnění</string>\n    <string name=\"title_update_available\">Je k dispozici nová verze Discordu!</string>\n    <string name=\"title_warning\">Pozor</string>\n    <string name=\"title_dl_failed\">Stahování se nezdařilo</string>\n    <string name=\"title_logs\">Záznamy</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Systémový</string>\n    <string name=\"theme_light\">Světlý</string>\n    <string name=\"theme_dark\">Tmavý</string>\n    <string name=\"duration_disabled\">Nikdy</string>\n    <string name=\"duration_fifteen_min\">Každou čtvrt hodinu</string>\n    <string name=\"duration_half_hour\">Každou půl hodinu</string>\n    <string name=\"duration_hourly\">Každou hodinu</string>\n    <string name=\"duration_bihourly\">Každé dvě hodiny</string>\n    <string name=\"duration_twice_daily\">Dvakrát denně</string>\n    <string name=\"duration_daily\">Denně</string>\n    <string name=\"duration_weekly\">Týdně</string>\n    <string name=\"settings_appearance\">Vzhled</string>\n    <string name=\"settings_appearance_description\">Změnit vzhled aplikace</string>\n    <string name=\"settings_dynamic_color\">Dynamická barva</string>\n    <string name=\"settings_dynamic_color_description\">Dostupné jen na Androidu 12 a výš</string>\n    <string name=\"settings_theme\">Motiv</string>\n    <string name=\"settings_check_updates\">Kontrolovat pro aktualizace Discordu</string>\n    <string name=\"settings_customization\">Přizpůsobení</string>\n    <string name=\"settings_customization_description\">Přizpůsobte si instalaci Vendetty</string>\n    <string name=\"settings_app_name\">Jméno aplikace</string>\n    <string name=\"settings_app_icon\">Nahradit ikonu aplikace</string>\n    <string name=\"settings_app_icon_description\">Používá ikonu Bunny místo ikony Discordu</string>\n    <string name=\"settings_advanced\">Pokročilé</string>\n    <string name=\"settings_advanced_description\">Upravit stahování a instalaci</string>\n    <string name=\"settings_channel\">Kanál vydání</string>\n    <string name=\"settings_mirror\">Zrcadlo stahování</string>\n    <string name=\"settings_auto_clear_cache\">Automaticky mazat mezipaměť</string>\n    <string name=\"settings_auto_clear_cache_description\">Vymaže mezipaměť když se aktualizuje Discord</string>\n    <string name=\"settings_developer\">Pouze pro vývojáře</string>\n    <string name=\"settings_developer_description\">Tyto nastavení mohou při nesprávném použití něco pokazit</string>\n    <string name=\"settings_module_location\">Umístění modulu</string>\n    <string name=\"settings_module_location_description\">Pro použití při programování Xposed modulu. DÁVEJTE SI POZOR</string>\n    <string name=\"settings_module_location_reset\">Resetovat umístění modulu</string>\n    <string name=\"settings_package_name\">Jméno balíčku</string>\n    <string name=\"settings_version\">Verze Discordu</string>\n    <string name=\"settings_debuggable\">Laditelné</string>\n    <string name=\"settings_debuggable_description\">Povolit vlajku laditelné</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Verze %1$s Správce Vendetty je nyní dostupná!</string>\n    <string name=\"channel_stable\">Stabilní</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Tým</string>\n    <string name=\"label_special_thanks\">Zvláštní poděkování</string>\n    <string name=\"label_translate\">Přeložit</string>\n    <string name=\"version_latest\">Nejnovější: %1$s</string>\n    <string name=\"version_target\">Cílená: %1$s</string>\n    <string name=\"version_current\">Aktuální: %1$s</string>\n    <string name=\"install_method\">Metoda instalace</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-da-rDK/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cache ryddet</string>\n    <string name=\"msg_load_fail\">Kunne ikke indlæse commits</string>\n    <string name=\"msg_coming_soon\">Kommer snart</string>\n    <string name=\"msg_invalid_version\">Ugyldig Discord version</string>\n    <string name=\"msg_seven_left\">7 tryk mere</string>\n    <string name=\"msg_five_left\">5 tryk mere</string>\n    <string name=\"msg_two_left\">2 tryk mere</string>\n    <string name=\"msg_loading\">Indlæser…</string>\n    <string name=\"msg_downgrade_disallowed\">Kan ikke nedgradere, Prøv at afinstallere først</string>\n    <string name=\"msg_unlocked\">Du er nu udvikler</string>\n    <string name=\"msg_permission_grant\">For at Bunny Manager kan fungere, kræves filtilladelser. Da delte data er gemt i ~/Bunny, kræves der tilladelser for at få adgang til dem.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Vil du prøve igen med et downloadspejl?</string>\n    <string name=\"msg_invalid_apk\">APK var beskadiget, Prøv at rydde cachen og derefter geninstallere</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Download APK\\'er</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Installerer</string>\n    <string name=\"step_dl_base\">Henter grund Apk\\'en</string>\n    <string name=\"step_dl_lib\">Henter biblioteks Apk\\'en</string>\n    <string name=\"step_dl_lang\">Henter sprog Apk\\'en</string>\n    <string name=\"step_dl_res\">Henter ressource Apk\\'en</string>\n    <string name=\"step_dl_vd\">Henter Bunny modulet</string>\n    <string name=\"step_change_icon\">Ændring af app ikon</string>\n    <string name=\"step_patch_manifests\">Patching app manifesterer</string>\n    <string name=\"step_add_vd\">Injicerer Bunny</string>\n    <string name=\"step_signing\">Signering af APK\\'er</string>\n    <string name=\"step_installing\">Installerer APK\\'er</string>\n    <string name=\"installer_success\">Installeret med succes</string>\n    <string name=\"installer_aborted\">Installationen blev annulleret</string>\n    <string name=\"install_fail_generic\">Kunne ikke installere: Ukendt årsag</string>\n    <string name=\"install_fail_blocked\">Installationen blev blokeret</string>\n    <string name=\"install_fail_invalid\">En eller flere APK-filer var ugyldige eller korruptes</string>\n    <string name=\"install_fail_conflict\">Konflikter med en eksisterende app, normalt på grund af uoverensstemmende signaturer</string>\n    <string name=\"install_fail_storage\">Ikke nok tilgængelig lagerplads til at installere</string>\n    <string name=\"install_fail_incompatible\">Applikationen er inkompatibel med denne enhed</string>\n    <string name=\"install_fail_timeout\">Installationen udløb</string>\n    <string name=\"status_ongoing\">Igangværende</string>\n    <string name=\"status_successful\">Vellykket</string>\n    <string name=\"status_fail\">Mislykkedes</string>\n    <string name=\"status_queued\">I kø</string>\n    <string name=\"action_collapse\">Bryder sammen</string>\n    <string name=\"action_expand\">Udvide</string>\n    <string name=\"action_back\">Gå tilbage</string>\n    <string name=\"action_copy_logs\">Kopier logfiler</string>\n    <string name=\"action_clear_cache\">Ryd cache</string>\n    <string name=\"action_confirm\">Bekræfte</string>\n    <string name=\"action_start_update\">Start opdatering</string>\n    <string name=\"action_install\">Installere</string>\n    <string name=\"action_update\">Opdatering</string>\n    <string name=\"action_reinstall\">Geninstaller</string>\n    <string name=\"action_launch\">Lancering</string>\n    <string name=\"action_uninstall\">Afinstaller</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Prøve igen</string>\n    <string name=\"action_reload\">Genindlæs</string>\n    <string name=\"action_open_about\">Åben om</string>\n    <string name=\"action_open_settings\">Åbn indstillinger</string>\n    <string name=\"action_tap_to_install\">Tryk for at installere Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Afslut alligevel</string>\n    <string name=\"action_dismiss_nevermind\">Glem det</string>\n    <string name=\"action_dismiss_no_thanks\">Nej tak</string>\n    <string name=\"action_try_again\">Prøv igen</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Hvis du afslutter installationsprogrammet, før det er færdigt, kan det ødelægge downloadede filer. Er du sikker på, at du vil gøre det?</string>\n    <string name=\"installer_cached\">Cachelagret</string>\n    <string name=\"title_installer\">Installatør</string>\n    <string name=\"title_home\">Hjem</string>\n    <string name=\"title_settings\">Indstillinger</string>\n    <string name=\"title_update\">Opdatering tilgængelig!</string>\n    <string name=\"title_about\">Om</string>\n    <string name=\"title_permission_grant\">Giv tilladelser</string>\n    <string name=\"title_update_available\">Ny Discord opdatering tilgængelig!</string>\n    <string name=\"title_warning\">Advarsel</string>\n    <string name=\"title_dl_failed\">Download fejlede</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Lys</string>\n    <string name=\"theme_dark\">Mørk</string>\n    <string name=\"duration_disabled\">Handicappet</string>\n    <string name=\"duration_fifteen_min\">Kvartals time</string>\n    <string name=\"duration_half_hour\">En halv time</string>\n    <string name=\"duration_hourly\">Hver time</string>\n    <string name=\"duration_bihourly\">Hver time</string>\n    <string name=\"duration_twice_daily\">To gange dagligt</string>\n    <string name=\"duration_daily\">Daglige</string>\n    <string name=\"duration_weekly\">Ugentlig</string>\n    <string name=\"settings_appearance\">Udseende</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamisk farve</string>\n    <string name=\"settings_dynamic_color_description\">Kun tilgængelig på Android 12 og nyere</string>\n    <string name=\"settings_theme\">Tema</string>\n    <string name=\"settings_check_updates\">Se efter Discord opdateringer</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">App navn</string>\n    <string name=\"settings_app_icon\">Udskift app ikon</string>\n    <string name=\"settings_app_icon_description\">Bruger Bunny ikonet i stedet for Discords</string>\n    <string name=\"settings_advanced\">Fremskreden</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Slip kanal</string>\n    <string name=\"settings_mirror\">Hent spejl</string>\n    <string name=\"settings_auto_clear_cache\">Ryd cache automatisk</string>\n    <string name=\"settings_auto_clear_cache_description\">Rydder cachen, når Discord får en opdatering</string>\n    <string name=\"settings_developer\">Kun udvikler</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Modulplacering</string>\n    <string name=\"settings_module_location_description\">Til brug ved udvikling af Xposed modulet. VÆR FORSIGTIG</string>\n    <string name=\"settings_module_location_reset\">Nulstil modulplacering</string>\n    <string name=\"settings_package_name\">Pakkenavn</string>\n    <string name=\"settings_version\">Discord version</string>\n    <string name=\"settings_debuggable\">Fejlbarlig</string>\n    <string name=\"settings_debuggable_description\">Aktiver flag, der kan fejlfindes</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager version %1$s er nu tilgængelig!</string>\n    <string name=\"channel_stable\">Stabil</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alfa</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Hold</string>\n    <string name=\"label_special_thanks\">Specielt tak</string>\n    <string name=\"label_translate\">Oversætte</string>\n    <string name=\"version_latest\">Seneste: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Current: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-de-rDE/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cache wurde erfolgreich geleert</string>\n    <string name=\"msg_load_fail\">Laden von Commits fehlgeschlagen</string>\n    <string name=\"msg_coming_soon\">Demnächst</string>\n    <string name=\"msg_invalid_version\">Ungültige Discord-Version</string>\n    <string name=\"msg_seven_left\">Noch 7 mal tippen</string>\n    <string name=\"msg_five_left\">Noch 5 mal tippen</string>\n    <string name=\"msg_two_left\">Noch 2 mal tippen</string>\n    <string name=\"msg_loading\">Wird geladen…</string>\n    <string name=\"msg_downgrade_disallowed\">Downgraden nicht möglich, versuche zuerst zu deinstallieren</string>\n    <string name=\"msg_unlocked\">Du bist jetzt ein Entwickler</string>\n    <string name=\"msg_permission_grant\">Damit Bunny Manager funktionieren kann, sind Dateiberechtigungen erforderlich. Da freigegebene Daten in ~/Bunny gespeichert sind, sind Berechtigungen erforderlich, um darauf zuzugreifen.</string>\n    <string name=\"msg_shizuku_denied\">Fehler beim Abruf der Shizuku-Berechtigungen</string>\n    <string name=\"msg_change_mirror\">Möchten Sie es noch einmal mit einem Download Mirror versuchen?</string>\n    <string name=\"msg_invalid_apk\">APK wurde beschädigt. versuche den Cache zu leeren und danach neu zu installieren</string>\n    <string name=\"msg_download_cancelled\">Download abgebrochen</string>\n    <string name=\"msg_download_failed\">Download fehlgeschlagen</string>\n    <string name=\"msg_download_verify_failed\">Konnte nicht die heruntergeladene Datei überprüfen, siehe Logs für mehr Details</string>\n    <string name=\"msg_copied\">In die Zwischenablage kopiert</string>\n    <string name=\"group_download\">APKs herunterladen</string>\n    <string name=\"group_patch\">App wird gepatcht</string>\n    <string name=\"group_installing\">Wird installiert</string>\n    <string name=\"step_dl_base\">Base apk wird heruntergeladen</string>\n    <string name=\"step_dl_lib\">Bibliotheken APK wird heruntergeladen</string>\n    <string name=\"step_dl_lang\">Language apk wird heruntergeladen</string>\n    <string name=\"step_dl_res\">Resources apk wird heruntergeladen</string>\n    <string name=\"step_dl_vd\">Bunny-Modul wird heruntergeladen</string>\n    <string name=\"step_change_icon\">App-Icon wird geändert</string>\n    <string name=\"step_patch_manifests\">App-Manifest wird gepatcht</string>\n    <string name=\"step_add_vd\">Bunny wird hinzugefügt</string>\n    <string name=\"step_signing\">APKs werden signiert</string>\n    <string name=\"step_installing\">APKs werden installiert</string>\n    <string name=\"installer_success\">Erfolgreich installiert</string>\n    <string name=\"installer_aborted\">Installation abgebrochen</string>\n    <string name=\"install_fail_generic\">Fehler bei der Installation: Unbekannter Fehler</string>\n    <string name=\"install_fail_blocked\">Installation wurde blockiert</string>\n    <string name=\"install_fail_invalid\">Ein oder mehrere APKs sind korrupt</string>\n    <string name=\"install_fail_conflict\">Konflikt mit einer existierenden App, meist durch nicht übereinstimmende Signaturen</string>\n    <string name=\"install_fail_storage\">Nicht genug Speicher für Installation</string>\n    <string name=\"install_fail_incompatible\">App ist inkompatibel mit diesem Gerät</string>\n    <string name=\"install_fail_timeout\">Installation hat zu lange gedauert</string>\n    <string name=\"status_ongoing\">Fortlaufend</string>\n    <string name=\"status_successful\">Erfolgreich</string>\n    <string name=\"status_fail\">Fehlgeschlagen</string>\n    <string name=\"status_queued\">In der Warteschlange</string>\n    <string name=\"action_collapse\">Minimieren</string>\n    <string name=\"action_expand\">Erweitern</string>\n    <string name=\"action_back\">Zurück</string>\n    <string name=\"action_copy_logs\">Logs kopieren</string>\n    <string name=\"action_clear_cache\">Cache leeren</string>\n    <string name=\"action_confirm\">Bestätigen</string>\n    <string name=\"action_start_update\">Update starten</string>\n    <string name=\"action_install\">Installieren</string>\n    <string name=\"action_update\">Aktualisieren</string>\n    <string name=\"action_reinstall\">Neuinstallieren</string>\n    <string name=\"action_launch\">Starten</string>\n    <string name=\"action_uninstall\">Deinstallieren</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Erneut versuchen</string>\n    <string name=\"action_reload\">Neuladen</string>\n    <string name=\"action_open_about\">Über</string>\n    <string name=\"action_open_settings\">Einstellungen öffnen</string>\n    <string name=\"action_tap_to_install\">Tippen um Bunny für Discord %1$s zu installieren</string>\n    <string name=\"action_confirm_exit\">Trotzdem verlassen</string>\n    <string name=\"action_dismiss_nevermind\">Vergiss es</string>\n    <string name=\"action_dismiss_no_thanks\">Nein danke</string>\n    <string name=\"action_try_again\">Versuch es noch einmal</string>\n    <string name=\"action_previous_theme\">Vorheriges Theme ansehen</string>\n    <string name=\"action_next_theme\">Nächstes Theme ansehen</string>\n    <string name=\"action_view_logs\">Logs ansehen</string>\n    <string name=\"action_show_timestamp\">Zeitstempel anzeigen</string>\n    <string name=\"action_copy_log\">Log kopieren</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Verlassen könnte heruntergeladene Dateien beschädigen. Sind sie sich sicher, dass Sie den Installer verlassen wollen?</string>\n    <string name=\"installer_cached\">Zwischengespeichert</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Einstellungen</string>\n    <string name=\"title_update\">Aktualisierung verfügbar!</string>\n    <string name=\"title_about\">Über</string>\n    <string name=\"title_permission_grant\">Berechtigungen erteilen</string>\n    <string name=\"title_update_available\">Neue Aktualisierung verfügbar!</string>\n    <string name=\"title_warning\">Achtung</string>\n    <string name=\"title_dl_failed\">Herunterladen fehlgeschlagen</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Hell</string>\n    <string name=\"theme_dark\">Dunkel</string>\n    <string name=\"duration_disabled\">Deaktiviert</string>\n    <string name=\"duration_fifteen_min\">Viertelstündlich</string>\n    <string name=\"duration_half_hour\">Halbstündlich</string>\n    <string name=\"duration_hourly\">Stündlich</string>\n    <string name=\"duration_bihourly\">Zweistündig</string>\n    <string name=\"duration_twice_daily\">Zweimal täglich</string>\n    <string name=\"duration_daily\">Täglich</string>\n    <string name=\"duration_weekly\">Wöchentlich</string>\n    <string name=\"settings_appearance\">Erscheinungsbild</string>\n    <string name=\"settings_appearance_description\">Ändere das Aussehen der App</string>\n    <string name=\"settings_dynamic_color\">Dynamische Farbe</string>\n    <string name=\"settings_dynamic_color_description\">Nur verfügbar ab Android 12</string>\n    <string name=\"settings_theme\">Erscheinungsbild</string>\n    <string name=\"settings_check_updates\">Nach Aktualisierung suchen</string>\n    <string name=\"settings_customization\">Personalisierung</string>\n    <string name=\"settings_customization_description\">Personalisiere deine Bunny-Installation</string>\n    <string name=\"settings_app_name\">App Name</string>\n    <string name=\"settings_app_icon\">App-Icon ersetzen</string>\n    <string name=\"settings_app_icon_description\">Bunny-Icon anstatt Discord-Icon benutzen</string>\n    <string name=\"settings_advanced\">Erweiterte Einstellungen</string>\n    <string name=\"settings_advanced_description\">Ändere Download und Installation</string>\n    <string name=\"settings_channel\">Release-Kanal</string>\n    <string name=\"settings_mirror\">Download-Mirror</string>\n    <string name=\"settings_auto_clear_cache\">Cache automatisch leeren</string>\n    <string name=\"settings_auto_clear_cache_description\">Cache leeren, wenn Discord aktualisiert wird</string>\n    <string name=\"settings_developer\">Entwicklereinstellungen</string>\n    <string name=\"settings_developer_description\">Diese Einstellungen können Dinge beschädigen, falls Sie falsch genutzt werden</string>\n    <string name=\"settings_module_location\">Modulspeicherort</string>\n    <string name=\"settings_module_location_description\">Für Xposed-Modul-Entwicklung. SEI VORSICHTIG</string>\n    <string name=\"settings_module_location_reset\">Modulspeicherort zurücksetzen</string>\n    <string name=\"settings_package_name\">Paketname</string>\n    <string name=\"settings_version\">Discord Version</string>\n    <string name=\"settings_debuggable\">Debugfähig</string>\n    <string name=\"settings_debuggable_description\">Aktiviert das \\\"debuggable\\\" Attribut im Manifest</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny-Manager Version %1$s ist jetzt verfügbar!</string>\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Besonderen Dank an</string>\n    <string name=\"label_translate\">Übersetzung</string>\n    <string name=\"version_latest\">Neueste Version: %1$s</string>\n    <string name=\"version_target\">Zielversion: %1$s</string>\n    <string name=\"version_current\">Aktuelle Version: %1$s</string>\n    <string name=\"install_method\">Installationsmethode</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-el-rGR/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Επιτυχής εκκαθάριση προσωρινής μνήμης</string>\n    <string name=\"msg_load_fail\">Αποτυχία φόρτωσης των ρυθμίσεων</string>\n    <string name=\"msg_coming_soon\">Έρχεται σύντομα</string>\n    <string name=\"msg_invalid_version\">Μη έγκυρη έκδοση Discord</string>\n    <string name=\"msg_seven_left\">7 ακόμα πατήματα</string>\n    <string name=\"msg_five_left\">5 ακόμα πατήματα</string>\n    <string name=\"msg_two_left\">2 ακόμα πατήματα</string>\n    <string name=\"msg_loading\">Φόρτωση…</string>\n    <string name=\"msg_downgrade_disallowed\">Αδυναμία υποβάθμισης, δοκιμάστε πρώτα την απεγκατάσταση</string>\n    <string name=\"msg_unlocked\">Είστε πλέον προγραμματιστής</string>\n    <string name=\"msg_permission_grant\">Για να λειτουργήσει ο Bunny Manager, απαιτούνται δικαιώματα αρχείων. Δεδομένου ότι τα κοινόχρηστα δεδομένα αποθηκεύονται στο ~/Bunny, απαιτούνται δικαιώματα πρόσβασης σε αυτά.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Θα θέλατε να δοκιμάσετε ξανά χρησιμοποιώντας έναν καθρέφτη λήψης;</string>\n    <string name=\"msg_invalid_apk\">Το APK ήταν κατεστραμμένο, προσπαθήστε να καθαρίσετε την προσωρινή μνήμη και έπειτα να επανεγκαταστήσετε</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Λήψη APK</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Γίνεται εγκατάσταση</string>\n    <string name=\"step_dl_base\">Λήψη βασικού apk</string>\n    <string name=\"step_dl_lib\">Λήψη libraries apk</string>\n    <string name=\"step_dl_lang\">Λήψη language apk</string>\n    <string name=\"step_dl_res\">Λήψη resources apk</string>\n    <string name=\"step_dl_vd\">Λήψη πακέτου Bunny</string>\n    <string name=\"step_change_icon\">Αλλαγή εικονιδίου εφαρμογής</string>\n    <string name=\"step_patch_manifests\">Ενημέρωση manifests τής εφαρμογής</string>\n    <string name=\"step_add_vd\">Ενσωμάτωση Bunny</string>\n    <string name=\"step_signing\">Συγχρονισμός των APKs</string>\n    <string name=\"step_installing\">Εγκατάσταση APKs</string>\n    <string name=\"installer_success\">Εγκαταστάθηκε επιτυχώς</string>\n    <string name=\"installer_aborted\">Η εγκατάσταση ακυρώθηκε</string>\n    <string name=\"install_fail_generic\">Αποτυχία εγκατάστασης: Άγνωστος λόγος</string>\n    <string name=\"install_fail_blocked\">Η εγκατάσταση αποκλείστηκε</string>\n    <string name=\"install_fail_invalid\">Ένα ή περισσότερα APKs ήταν άκυρα ή κατεστραμμένα</string>\n    <string name=\"install_fail_conflict\">Συγκρούσεις με μια υπάρχουσα εφαρμογή, συνήθως λόγω αναντιστοιχίας υπογραφών</string>\n    <string name=\"install_fail_storage\">Δεν υπάρχει αρκετός διαθέσιμος χώρος για εγκατάσταση</string>\n    <string name=\"install_fail_incompatible\">Η εφαρμογή δεν είναι συμβατή με αυτήν τη συσκευή</string>\n    <string name=\"install_fail_timeout\">Το χρονικό όριο εγκατάστασης έληξε</string>\n    <string name=\"status_ongoing\">Σε εξέλιξη</string>\n    <string name=\"status_successful\">Επιτυχής</string>\n    <string name=\"status_fail\">Αποτυχία</string>\n    <string name=\"status_queued\">Σε αναμονή</string>\n    <string name=\"action_collapse\">Σύμπτυξη</string>\n    <string name=\"action_expand\">Ανάπτυξη</string>\n    <string name=\"action_back\">Επιστροφή</string>\n    <string name=\"action_copy_logs\">Αντιγραφή καταγραφών</string>\n    <string name=\"action_clear_cache\">Εκκαθάριση προσωρινής μνήμης</string>\n    <string name=\"action_confirm\">Επιβεβαίωση</string>\n    <string name=\"action_start_update\">Έναρξη ενημέρωσης</string>\n    <string name=\"action_install\">Εγκατάσταση</string>\n    <string name=\"action_update\">Ενημέρωση</string>\n    <string name=\"action_reinstall\">Επανεγκατάσταση</string>\n    <string name=\"action_launch\">Άνοιγμα</string>\n    <string name=\"action_uninstall\">Απεγκατάσταση</string>\n    <string name=\"action_info\">Πληροφορίες</string>\n    <string name=\"action_retry\">Επανάληψη</string>\n    <string name=\"action_reload\">Ανανέωση</string>\n    <string name=\"action_open_about\">Άνοιγμα σχετικά με</string>\n    <string name=\"action_open_settings\">Άνοιγμα ρυθμίσεων</string>\n    <string name=\"action_tap_to_install\">Πατήστε για να εγκαταστήσετε το Bunny για το Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Έξοδος ούτως ή άλλως</string>\n    <string name=\"action_dismiss_nevermind\">Δεν πειράζει</string>\n    <string name=\"action_dismiss_no_thanks\">Όχι, ευχαριστώ</string>\n    <string name=\"action_try_again\">Προσπάθησε ξανά</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Η έξοδος από το πρόγραμμα εγκατάστασης πριν από την ολοκλήρωση του θα μπορούσε να καταστρέψει τα κατεβασμένα αρχεία, είστε σίγουροι ότι θέλετε να το κάνετε αυτό;</string>\n    <string name=\"installer_cached\">Στη προσωρινή μνήμη</string>\n    <string name=\"title_installer\">Εγκαταστάτης</string>\n    <string name=\"title_home\">Αρχική</string>\n    <string name=\"title_settings\">Ρυθμίσεις</string>\n    <string name=\"title_update\">Διαθέσιμη ενημέρωση!</string>\n    <string name=\"title_about\">Σχετικά με</string>\n    <string name=\"title_permission_grant\">Εκχώρηση Δικαιωμάτων</string>\n    <string name=\"title_update_available\">Νέα ενημέρωση για το Discord είναι διαθέσιμη!</string>\n    <string name=\"title_warning\">Προσοχή</string>\n    <string name=\"title_dl_failed\">Αποτυχία λήψης</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Σύστημα</string>\n    <string name=\"theme_light\">Ανοιχτό</string>\n    <string name=\"theme_dark\">Σκούρο</string>\n    <string name=\"duration_disabled\">Πότε</string>\n    <string name=\"duration_fifteen_min\">Ανά 15 λεπτά</string>\n    <string name=\"duration_half_hour\">Ανά μισή ώρα</string>\n    <string name=\"duration_hourly\">Ανά μία ώρα</string>\n    <string name=\"duration_bihourly\">Ανά 2 ώρες</string>\n    <string name=\"duration_twice_daily\">Δύο φορές την ημέρα</string>\n    <string name=\"duration_daily\">Καθημερινά</string>\n    <string name=\"duration_weekly\">Εβδομαδιαία</string>\n    <string name=\"settings_appearance\">Εμφάνιση</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Δυναμικό χρώμα</string>\n    <string name=\"settings_dynamic_color_description\">Διαθέσιμο μόνο για Android 12 και άνω</string>\n    <string name=\"settings_theme\">Θέμα</string>\n    <string name=\"settings_check_updates\">Έλεγχος για ενημερώσεις του Discord</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">Όνομα εφαρμογής</string>\n    <string name=\"settings_app_icon\">Αντικατάσταση εικονιδίου εφαρμογής</string>\n    <string name=\"settings_app_icon_description\">Χρησιμοποίηση του εικονιδίου Bunny αντί του Discord</string>\n    <string name=\"settings_advanced\">Για προχωρημένους</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Κανάλι κυκλοφορίας</string>\n    <string name=\"settings_mirror\">Λήψη mirror</string>\n    <string name=\"settings_auto_clear_cache\">Αυτόματη εκκαθάριση προσωρινής μνήμης</string>\n    <string name=\"settings_auto_clear_cache_description\">Καθαρίζει την προσωρινή μνήμη όταν το Discord λαμβάνει μια ενημέρωση</string>\n    <string name=\"settings_developer\">Μόνο για προγραμματιστές</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Τοποθεσία module</string>\n    <string name=\"settings_module_location_description\">Για χρήση με την ανάπτυξη του Xposed module. ΝΑ ΕΊΣΤΕ ΠΡΟΣΕΚΤΙΚΟΊ</string>\n    <string name=\"settings_module_location_reset\">Επαναφορά τοποθεσίας module</string>\n    <string name=\"settings_package_name\">Όνομα πακέτου</string>\n    <string name=\"settings_version\">Έκδοση Discord</string>\n    <string name=\"settings_debuggable\">Αποσφαλματώσιμο</string>\n    <string name=\"settings_debuggable_description\">Ενεργοποίηση σημαίας αποσφαλμάτωσης</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Η έκδοση %1$s του Bunny Manager είναι τώρα διαθέσιμη!</string>\n    <string name=\"channel_stable\">Σταθερή</string>\n    <string name=\"channel_beta\">Δοκιμαστική</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Ομάδα</string>\n    <string name=\"label_special_thanks\">Ιδιαίτερες ευχαριστίες</string>\n    <string name=\"label_translate\">Μετάφραση</string>\n    <string name=\"version_latest\">Πρόσφατο: %1$s</string>\n    <string name=\"version_target\">Στόχος: %1$s</string>\n    <string name=\"version_current\">Τρέχουσα: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-en-rUS/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cache cleared successfully</string>\n    <string name=\"msg_load_fail\">Failed to load commits</string>\n    <string name=\"msg_coming_soon\">Never coming out</string>\n    <string name=\"msg_invalid_version\">Invalid Discord version</string>\n    <string name=\"msg_seven_left\">7 more taps</string>\n    <string name=\"msg_five_left\">5 more taps</string>\n    <string name=\"msg_two_left\">2 more taps</string>\n    <string name=\"msg_loading\">Loading…</string>\n    <string name=\"msg_downgrade_disallowed\">Cannot downgrade, try uninstalling first</string>\n    <string name=\"msg_unlocked\">You are now a developer</string>\n    <string name=\"msg_permission_grant\">In order for Bunny Manager to function, file permissions are required. Since shared data is stored in ~/Bunny, permissions are required in order to access it.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Download APKs</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Installing</string>\n    <string name=\"step_dl_base\">Downloading base APK</string>\n    <string name=\"step_dl_lib\">Downloading libraries APK</string>\n    <string name=\"step_dl_lang\">Downloading language APK</string>\n    <string name=\"step_dl_res\">Downloading resources APK</string>\n    <string name=\"step_dl_vd\">Downloading Bunny module</string>\n    <string name=\"step_change_icon\">Changing app icon</string>\n    <string name=\"step_patch_manifests\">Patching app manifests</string>\n    <string name=\"step_add_vd\">Injecting Bunny</string>\n    <string name=\"step_signing\">Signing APKs</string>\n    <string name=\"step_installing\">Installing APKs</string>\n    <string name=\"installer_success\">Installed successfully</string>\n    <string name=\"installer_aborted\">Install canceled</string>\n    <string name=\"install_fail_generic\">Failed to install: Unknown reason</string>\n    <string name=\"install_fail_blocked\">Installation was blocked</string>\n    <string name=\"install_fail_invalid\">One or more APKs were invalid or corrupt</string>\n    <string name=\"install_fail_conflict\">Conflicts with an existing app, usually due to mismatched signatures</string>\n    <string name=\"install_fail_storage\">Not enough available storage to install</string>\n    <string name=\"install_fail_incompatible\">Application is incompatible with this device</string>\n    <string name=\"install_fail_timeout\">Installation timed out</string>\n    <string name=\"status_ongoing\">Ongoing</string>\n    <string name=\"status_successful\">Successful</string>\n    <string name=\"status_fail\">Failed</string>\n    <string name=\"status_queued\">Queued</string>\n    <string name=\"action_collapse\">Collapse</string>\n    <string name=\"action_expand\">Expand</string>\n    <string name=\"action_back\">Go back</string>\n    <string name=\"action_copy_logs\">Copy logs</string>\n    <string name=\"action_clear_cache\">Clear cache</string>\n    <string name=\"action_confirm\">Confirm</string>\n    <string name=\"action_start_update\">Start update</string>\n    <string name=\"action_install\">Install</string>\n    <string name=\"action_update\">Update</string>\n    <string name=\"action_reinstall\">Reinstall</string>\n    <string name=\"action_launch\">Launch</string>\n    <string name=\"action_uninstall\">Uninstall</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Retry</string>\n    <string name=\"action_reload\">Reload</string>\n    <string name=\"action_open_about\">Open about</string>\n    <string name=\"action_open_settings\">Open settings</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Never mind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">Cached</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Settings</string>\n    <string name=\"title_update\">Update available!</string>\n    <string name=\"title_about\">About</string>\n    <string name=\"title_permission_grant\">Grant Permissions</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Light</string>\n    <string name=\"theme_dark\">Dark</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">Appearance</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamic color</string>\n    <string name=\"settings_dynamic_color_description\">Only available on Android 12 and up</string>\n    <string name=\"settings_theme\">Theme</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">App name</string>\n    <string name=\"settings_app_icon\">Replace app icon</string>\n    <string name=\"settings_app_icon_description\">Uses the Bunny icon instead of Discord\\'s</string>\n    <string name=\"settings_advanced\">Advanced</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Release channel</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">Developer only</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Package name</string>\n    <string name=\"settings_version\">Discord version</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Enable debuggable flag</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager version %1$s is now available!</string>\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Special thanks</string>\n    <string name=\"label_translate\">Translate</string>\n    <string name=\"version_latest\">Latest: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Current: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-es-rES/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Caché borrado con éxito</string>\n    <string name=\"msg_load_fail\">Error al cargar commits</string>\n    <string name=\"msg_coming_soon\">Próximamente</string>\n    <string name=\"msg_invalid_version\">Versión inválida de Discord</string>\n    <string name=\"msg_seven_left\">7 toques más</string>\n    <string name=\"msg_five_left\">5 toques más</string>\n    <string name=\"msg_two_left\">2 toques más</string>\n    <string name=\"msg_loading\">Cargando…</string>\n    <string name=\"msg_downgrade_disallowed\">No se puede desactualizar, intente desinstalándolo primero</string>\n    <string name=\"msg_unlocked\">Ahora eres un desarrollador</string>\n    <string name=\"msg_permission_grant\">Para que Bunny Manager funcione, se requieren permisos de archivos. Dado que los datos compartidos se almacenan en ~/Bunny, se requieren permisos para acceder a ellos.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">¿Te gustaría volver a intentar usando un servidor réplica de descarga?</string>\n    <string name=\"msg_invalid_apk\">APK estaba dañado, intente borrar la caché y vuelva a instalar</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Descargar APKs</string>\n    <string name=\"group_patch\">Parcheando</string>\n    <string name=\"group_installing\">Instalando</string>\n    <string name=\"step_dl_base\">Descargando apk base</string>\n    <string name=\"step_dl_lib\">Descargando apk de librerías</string>\n    <string name=\"step_dl_lang\">Descargando apk de idiomas</string>\n    <string name=\"step_dl_res\">Descargando apk de recursos</string>\n    <string name=\"step_dl_vd\">Descargando módulo Bunny</string>\n    <string name=\"step_change_icon\">Cambiando icono de la aplicación</string>\n    <string name=\"step_patch_manifests\">Parcheando manifiestos de aplicación</string>\n    <string name=\"step_add_vd\">Inyectando Bunny</string>\n    <string name=\"step_signing\">Firmando APKs</string>\n    <string name=\"step_installing\">Instalando APKs</string>\n    <string name=\"installer_success\">Instalado con éxito</string>\n    <string name=\"installer_aborted\">Instalación cancelada</string>\n    <string name=\"install_fail_generic\">Error al instalar: Razón desconocida</string>\n    <string name=\"install_fail_blocked\">La instalación fue bloqueada</string>\n    <string name=\"install_fail_invalid\">Uno o más APKs no son válidos o están corruptos</string>\n    <string name=\"install_fail_conflict\">Conflictos con una aplicación existente, generalmente debido a firmas inadecuadas</string>\n    <string name=\"install_fail_storage\">No hay suficiente almacenamiento disponible para instalar</string>\n    <string name=\"install_fail_incompatible\">La aplicación es incompatible con este dispositivo</string>\n    <string name=\"install_fail_timeout\">Tiempo de instalación agotado</string>\n    <string name=\"status_ongoing\">En progreso</string>\n    <string name=\"status_successful\">Éxito</string>\n    <string name=\"status_fail\">Fallido</string>\n    <string name=\"status_queued\">En cola</string>\n    <string name=\"action_collapse\">Colapsar</string>\n    <string name=\"action_expand\">Expandir</string>\n    <string name=\"action_back\">Volver atrás</string>\n    <string name=\"action_copy_logs\">Copiar logs</string>\n    <string name=\"action_clear_cache\">Limpiar caché</string>\n    <string name=\"action_confirm\">Confirmar</string>\n    <string name=\"action_start_update\">Iniciar actualización</string>\n    <string name=\"action_install\">Instalar</string>\n    <string name=\"action_update\">Actualizar</string>\n    <string name=\"action_reinstall\">Reinstalar</string>\n    <string name=\"action_launch\">Iniciar</string>\n    <string name=\"action_uninstall\">Desinstalar</string>\n    <string name=\"action_info\">Información</string>\n    <string name=\"action_retry\">Reintentar</string>\n    <string name=\"action_reload\">Actualizar</string>\n    <string name=\"action_open_about\">Abrir \\\"acerca de\\\"</string>\n    <string name=\"action_open_settings\">Abrir configuración</string>\n    <string name=\"action_tap_to_install\">Toca para instalar Bunny para Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Salir de todos modos</string>\n    <string name=\"action_dismiss_nevermind\">Mejor no</string>\n    <string name=\"action_dismiss_no_thanks\">No, gracias</string>\n    <string name=\"action_try_again\">Intentar de nuevo</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Salir del instalador antes de que finalice podría corromper los archivos descargados, ¿está seguro de que quieres hacerlo?</string>\n    <string name=\"installer_cached\">En caché</string>\n    <string name=\"title_installer\">Instalador</string>\n    <string name=\"title_home\">Inicio</string>\n    <string name=\"title_settings\">Configuración</string>\n    <string name=\"title_update\">¡Actualización disponible!</string>\n    <string name=\"title_about\">Acerca de</string>\n    <string name=\"title_permission_grant\">Otorgar Permisos</string>\n    <string name=\"title_update_available\">¡Nueva actualización de Discord disponible!</string>\n    <string name=\"title_warning\">Advertencia</string>\n    <string name=\"title_dl_failed\">Descarga fallida</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Sistema</string>\n    <string name=\"theme_light\">Claro</string>\n    <string name=\"theme_dark\">Oscuro</string>\n    <string name=\"duration_disabled\">Deshabilitado</string>\n    <string name=\"duration_fifteen_min\">Cada 15 minutos</string>\n    <string name=\"duration_half_hour\">Cada media hora</string>\n    <string name=\"duration_hourly\">Cada hora</string>\n    <string name=\"duration_bihourly\">Cada dos horas</string>\n    <string name=\"duration_twice_daily\">Dos veces al día</string>\n    <string name=\"duration_daily\">Cada día</string>\n    <string name=\"duration_weekly\">Semanalmente</string>\n    <string name=\"settings_appearance\">Apariencia</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Color dinámico</string>\n    <string name=\"settings_dynamic_color_description\">Sólo disponible en Android 12 y superior</string>\n    <string name=\"settings_theme\">Tema</string>\n    <string name=\"settings_check_updates\">Comprobar actualizaciones de Discord</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">Nombre de la aplicación</string>\n    <string name=\"settings_app_icon\">Reemplazar el icono de la app</string>\n    <string name=\"settings_app_icon_description\">Usa el ícono de Bunny en lugar de Discord</string>\n    <string name=\"settings_advanced\">Avanzado</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Canal de lanzamientos</string>\n    <string name=\"settings_mirror\">Descargar desde servidor réplica</string>\n    <string name=\"settings_auto_clear_cache\">Borrar caché automáticamente</string>\n    <string name=\"settings_auto_clear_cache_description\">Limpiar el caché cuando Discord recibe una actualización</string>\n    <string name=\"settings_developer\">Sólo desarrolladores</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Ubicación del módulo</string>\n    <string name=\"settings_module_location_description\">Para el uso con el desarrollo del módulo Xposed. SE CUIDADOSO</string>\n    <string name=\"settings_module_location_reset\">Restablecer la ubicación del módulo</string>\n    <string name=\"settings_package_name\">Nombre del paquete</string>\n    <string name=\"settings_version\">Versión de Discord</string>\n    <string name=\"settings_debuggable\">Depurable</string>\n    <string name=\"settings_debuggable_description\">Activar modo de depuración</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">¡La versión %1$s de Bunny Manager está disponible!</string>\n    <string name=\"channel_stable\">Estable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alfa</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Equipo</string>\n    <string name=\"label_special_thanks\">Agradecimientos especiales</string>\n    <string name=\"label_translate\">Traducir</string>\n    <string name=\"version_latest\">Más reciente: %1$s</string>\n    <string name=\"version_target\">Selección: %1$s</string>\n    <string name=\"version_current\">Actual: %1$s</string>\n    <string name=\"install_method\">Método de instalación</string>\n    <string name=\"default_installer\">Por defecto (recomendado)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-fi-rFI/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cache cleared successfully</string>\n    <string name=\"msg_load_fail\">Failed to load commits</string>\n    <string name=\"msg_coming_soon\">Coming soon</string>\n    <string name=\"msg_invalid_version\">Invalid Discord version</string>\n    <string name=\"msg_seven_left\">7 more taps</string>\n    <string name=\"msg_five_left\">5 more taps</string>\n    <string name=\"msg_two_left\">2 more taps</string>\n    <string name=\"msg_loading\">Loading…</string>\n    <string name=\"msg_downgrade_disallowed\">Cannot downgrade, try uninstalling first</string>\n    <string name=\"msg_unlocked\">You are now a developer</string>\n    <string name=\"msg_permission_grant\">In order for Bunny Manager to function, file permissions are required. Since shared data is stored in ~/Bunny, permissions are required in order to access it.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Download APKs</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Installing</string>\n    <string name=\"step_dl_base\">Downloading base apk</string>\n    <string name=\"step_dl_lib\">Downloading libraries apk</string>\n    <string name=\"step_dl_lang\">Downloading language apk</string>\n    <string name=\"step_dl_res\">Downloading resources apk</string>\n    <string name=\"step_dl_vd\">Downloading Bunny module</string>\n    <string name=\"step_change_icon\">Changing app icon</string>\n    <string name=\"step_patch_manifests\">Patching app manifests</string>\n    <string name=\"step_add_vd\">Injecting Bunny</string>\n    <string name=\"step_signing\">Signing APKs</string>\n    <string name=\"step_installing\">Installing APKs</string>\n    <string name=\"installer_success\">Installed successfully</string>\n    <string name=\"installer_aborted\">Install canceled</string>\n    <string name=\"install_fail_generic\">Failed to install: Unknown reason</string>\n    <string name=\"install_fail_blocked\">Installation was blocked</string>\n    <string name=\"install_fail_invalid\">One or more APKs were invalid or corrupt</string>\n    <string name=\"install_fail_conflict\">Conflicts with an existing app, usually due to mismatched signatures</string>\n    <string name=\"install_fail_storage\">Not enough available storage to install</string>\n    <string name=\"install_fail_incompatible\">Application is incompatible with this device</string>\n    <string name=\"install_fail_timeout\">Installation timed out</string>\n    <string name=\"status_ongoing\">Ongoing</string>\n    <string name=\"status_successful\">Successful</string>\n    <string name=\"status_fail\">Failed</string>\n    <string name=\"status_queued\">Queued</string>\n    <string name=\"action_collapse\">Collapse</string>\n    <string name=\"action_expand\">Expand</string>\n    <string name=\"action_back\">Go back</string>\n    <string name=\"action_copy_logs\">Copy logs</string>\n    <string name=\"action_clear_cache\">Clear cache</string>\n    <string name=\"action_confirm\">Confirm</string>\n    <string name=\"action_start_update\">Start update</string>\n    <string name=\"action_install\">Install</string>\n    <string name=\"action_update\">Update</string>\n    <string name=\"action_reinstall\">Reinstall</string>\n    <string name=\"action_launch\">Launch</string>\n    <string name=\"action_uninstall\">Uninstall</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Retry</string>\n    <string name=\"action_reload\">Reload</string>\n    <string name=\"action_open_about\">Open about</string>\n    <string name=\"action_open_settings\">Open settings</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">Cached</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Settings</string>\n    <string name=\"title_update\">Update available!</string>\n    <string name=\"title_about\">About</string>\n    <string name=\"title_permission_grant\">Grant Permissions</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Light</string>\n    <string name=\"theme_dark\">Dark</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">Appearance</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamic color</string>\n    <string name=\"settings_dynamic_color_description\">Only available on Android 12 and up</string>\n    <string name=\"settings_theme\">Theme</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">App name</string>\n    <string name=\"settings_app_icon\">Replace app icon</string>\n    <string name=\"settings_app_icon_description\">Uses the Bunny icon instead of Discord\\'s</string>\n    <string name=\"settings_advanced\">Advanced</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Release channel</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">Developer only</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Package name</string>\n    <string name=\"settings_version\">Discord version</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Enable debuggable flag</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager version %1$s is now available!</string>\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Special thanks</string>\n    <string name=\"label_translate\">Translate</string>\n    <string name=\"version_latest\">Latest: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Current: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-fil-rPH/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Manager ng Bunny</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Na-clear na ang cache</string>\n    <string name=\"msg_load_fail\">Nabigong i-load ang mga commit</string>\n    <string name=\"msg_coming_soon\">Parating na</string>\n    <string name=\"msg_invalid_version\">Hindi wastong bersyon ng Discord</string>\n    <string name=\"msg_seven_left\">7 pang mga tap</string>\n    <string name=\"msg_five_left\">5 pang mga tap</string>\n    <string name=\"msg_two_left\">2 pang mga tap</string>\n    <string name=\"msg_loading\">Naglo-load…</string>\n    <string name=\"msg_downgrade_disallowed\">Hindi maka-downgrade, subukang mag-uninstall muna</string>\n    <string name=\"msg_unlocked\">Isa ka nang developer ngayon</string>\n    <string name=\"msg_permission_grant\">Upang gumana ang Bunny Manager, kinakailangan ang pahintulot ng file. Dahil nakaimbak ang nakabahaging data sa ~/Bunny, kailangan ng mga pahintulot para ma-access ito.</string>\n    <string name=\"msg_shizuku_denied\">Nabigong makuha ang mga pahintulot ng Shizuku</string>\n    <string name=\"msg_change_mirror\">Gusto mo bang subukan muli gamit ng download mirror?</string>\n    <string name=\"msg_invalid_apk\">Nasira ang APK, subukang i-clear ang cache at pag-reinstall</string>\n    <string name=\"msg_download_cancelled\">Na-abort ang pag-download</string>\n    <string name=\"msg_download_failed\">Nabigo ang pag-download</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">I-download ang mga APK</string>\n    <string name=\"group_patch\">Pina-patch</string>\n    <string name=\"group_installing\">Ini-install</string>\n    <string name=\"step_dl_base\">Dina-download ang base apk</string>\n    <string name=\"step_dl_lib\">Dina-download ang libraries apk</string>\n    <string name=\"step_dl_lang\">Dina-download ang language apk</string>\n    <string name=\"step_dl_res\">Dina-download ang resources apk</string>\n    <string name=\"step_dl_vd\">Dina-download ang Bunny module</string>\n    <string name=\"step_change_icon\">Pinapalitan ang app icon</string>\n    <string name=\"step_patch_manifests\">Pina-patch ang mga app manifest</string>\n    <string name=\"step_add_vd\">Ini-inject ang Bunny</string>\n    <string name=\"step_signing\">Sina-sign ang mga APK</string>\n    <string name=\"step_installing\">Ini-install ang mga APK</string>\n    <string name=\"installer_success\">Matagumpay na na-install</string>\n    <string name=\"installer_aborted\">Kinansela ang pag-install</string>\n    <string name=\"install_fail_generic\">Nabigong i-install: Hiindi alam na dahilan</string>\n    <string name=\"install_fail_blocked\">Na-block ang installation</string>\n    <string name=\"install_fail_invalid\">Ang isa o higit pang mga APK ay hindi wasto o sira</string>\n    <string name=\"install_fail_conflict\">Mga salungatan sa isang umiiral nang app, kadalasan dahil sa mga hindi tugmang signature</string>\n    <string name=\"install_fail_storage\">Walang sapat na available na storage para ma-install</string>\n    <string name=\"install_fail_incompatible\">Hindi compatible ang application sa device na ito</string>\n    <string name=\"install_fail_timeout\">Nag-time out ang installation</string>\n    <string name=\"status_ongoing\">Isinasagawa</string>\n    <string name=\"status_successful\">Matagumpay</string>\n    <string name=\"status_fail\">Nabigo</string>\n    <string name=\"status_queued\">Naka-queue</string>\n    <string name=\"action_collapse\">Itago</string>\n    <string name=\"action_expand\">Ipakita</string>\n    <string name=\"action_back\">Bumalik</string>\n    <string name=\"action_copy_logs\">Kopyahin ang mga log</string>\n    <string name=\"action_clear_cache\">I-clear ang cache</string>\n    <string name=\"action_confirm\">Kumpirmahin</string>\n    <string name=\"action_start_update\">Simulan ang update</string>\n    <string name=\"action_install\">I-install</string>\n    <string name=\"action_update\">I-update</string>\n    <string name=\"action_reinstall\">Muling i-install</string>\n    <string name=\"action_launch\">Buksan</string>\n    <string name=\"action_uninstall\">I-Uninstall</string>\n    <string name=\"action_info\">Impormasyon</string>\n    <string name=\"action_retry\">Muling subukan</string>\n    <string name=\"action_reload\">I-reload</string>\n    <string name=\"action_open_about\">Buksan ang about</string>\n    <string name=\"action_open_settings\">Buksan ang mga setting</string>\n    <string name=\"action_tap_to_install\">I-tap para i-install ang Bunny para sa Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Umalis na lang</string>\n    <string name=\"action_dismiss_nevermind\">Huwag na lang</string>\n    <string name=\"action_dismiss_no_thanks\">Hindi na, salamat</string>\n    <string name=\"action_try_again\">Subukan muli</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Ang pagalis sa installer bago matapos ay maaring mag-corrupt ng mga file, sigurado ka bang gusto mo yan gawin?</string>\n    <string name=\"installer_cached\">Naka-cache</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Mga Setting</string>\n    <string name=\"title_update\">Mayroong update!</string>\n    <string name=\"title_about\">Tungkol sa</string>\n    <string name=\"title_permission_grant\">Magbigay ng Mga Pahintulot</string>\n    <string name=\"title_update_available\">May bagong available na update sa Discord!</string>\n    <string name=\"title_warning\">Babala</string>\n    <string name=\"title_dl_failed\">Nabigo ang pag-download</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Sistema</string>\n    <string name=\"theme_light\">Maliwanag</string>\n    <string name=\"theme_dark\">Madilim</string>\n    <string name=\"duration_disabled\">Naka-disable</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Kalahating oras</string>\n    <string name=\"duration_hourly\">Oras-oras</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Dalawang beses araw-araw</string>\n    <string name=\"duration_daily\">Araw-araw</string>\n    <string name=\"duration_weekly\">Lingguhan</string>\n    <string name=\"settings_appearance\">Hitsura</string>\n    <string name=\"settings_appearance_description\">Baguhin ang hitsura ng app</string>\n    <string name=\"settings_dynamic_color\">Dinamika na kulay</string>\n    <string name=\"settings_dynamic_color_description\">Available lamang sa Android 12 o mas mataas</string>\n    <string name=\"settings_theme\">Tema</string>\n    <string name=\"settings_check_updates\">Mag-check ng mga bagong update sa Discord</string>\n    <string name=\"settings_customization\">Pag-customize</string>\n    <string name=\"settings_customization_description\">I-customize ang iyong Bunny install</string>\n    <string name=\"settings_app_name\">Pangalan ng app</string>\n    <string name=\"settings_app_icon\">Palitan ang app icon</string>\n    <string name=\"settings_app_icon_description\">Gamitin ang Bunny icon sa halip ng Discord</string>\n    <string name=\"settings_advanced\">Advanced</string>\n    <string name=\"settings_advanced_description\">Baguhin ang pag-download at pag-install</string>\n    <string name=\"settings_channel\">Release channel</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">I-clear ang cache ng awtomatiko</string>\n    <string name=\"settings_auto_clear_cache_description\">Iki-clear ang cache kapag nakakuha ng update ang Discord</string>\n    <string name=\"settings_developer\">Developer lamang</string>\n    <string name=\"settings_developer_description\">Maaring masira ang iba\\'t ibang bagay kapag hindi ginamit ng mabuti</string>\n    <string name=\"settings_module_location\">Lokasyon ng module</string>\n    <string name=\"settings_module_location_description\">Para sa paggamit sa pag-develop ng Xposed module. MAG-INGAT KA</string>\n    <string name=\"settings_module_location_reset\">I-reset ang lokasyon ng module</string>\n    <string name=\"settings_package_name\">Pangalan ng package</string>\n    <string name=\"settings_version\">Bersyon ng Discord</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Paganahin ang debuggable flag</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Available na ang Bunny Manager bersyon %1$s!</string>\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Koponan</string>\n    <string name=\"label_special_thanks\">Espesyal na Pasasalamat</string>\n    <string name=\"label_translate\">Isalin</string>\n    <string name=\"version_latest\">Pinakabago: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Kasalukuyan: %1$s</string>\n    <string name=\"install_method\">Paraan ng pag-install</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-fr-rFR/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Gestionnaire de Bunny</string>\n    <string name=\"cd_library_author\">Auteur: %1$s</string>\n    <string name=\"cd_library_license\">Licence : %1$s</string>\n    <string name=\"msg_cleared_cache\">Le cache a été supprimé avec succès</string>\n    <string name=\"msg_load_fail\">Échec lors du chargement des commits</string>\n    <string name=\"msg_coming_soon\">Bientôt disponible</string>\n    <string name=\"msg_invalid_version\">Version de Discord invalide</string>\n    <string name=\"msg_seven_left\">Appuyez encore 7 fois</string>\n    <string name=\"msg_five_left\">Appuyez encore 5 fois</string>\n    <string name=\"msg_two_left\">Appuyez encore 2 fois</string>\n    <string name=\"msg_loading\">Chargement en cours…</string>\n    <string name=\"msg_downgrade_disallowed\">Impossible de revenir à la version ultérieure, essayez d\\'abord de la désinstaller puis réessayez</string>\n    <string name=\"msg_unlocked\">Vous êtes maintenant un développeur</string>\n    <string name=\"msg_permission_grant\">Pour que le Gestionnaire de Bunny fonctionne correctement, la permission de stockage de fichier est requise. Les fichiers sont stockés dans le dossier Bunny, des autorisations sont nécessaires pour y accéder.</string>\n    <string name=\"msg_shizuku_denied\">Échec de l\\'obtention des permissions Shizuku</string>\n    <string name=\"msg_change_mirror\">Voulez-vous réessayer en utilisant un autre serveur de téléchargement ?</string>\n    <string name=\"msg_invalid_apk\">L\\'APK a été corrompu, essayez de vider le cache puis de réinstaller</string>\n    <string name=\"msg_download_cancelled\">Le téléchargement a été annulé</string>\n    <string name=\"msg_download_failed\">Téléchargements échoué</string>\n    <string name=\"msg_download_verify_failed\">Impossible de vérifier le fichier téléchargé, vérifiez les logs pour plus de détails</string>\n    <string name=\"msg_copied\">Copié dans le presse-papiers</string>\n    <string name=\"group_download\">Télécharger les APKs</string>\n    <string name=\"group_patch\">Patch en cours</string>\n    <string name=\"group_installing\">Installation en cours</string>\n    <string name=\"step_dl_base\">Téléchargement de l\\'APK de base</string>\n    <string name=\"step_dl_lib\">Téléchargement de l\\'APK de librairies</string>\n    <string name=\"step_dl_lang\">Téléchargement de l\\'APK de langue</string>\n    <string name=\"step_dl_res\">Téléchargement des ressources pour l\\'APK</string>\n    <string name=\"step_dl_vd\">Téléchargement du module Bunny</string>\n    <string name=\"step_change_icon\">Changement de l\\'icône de l\\'app</string>\n    <string name=\"step_patch_manifests\">Patch des manifests de l\\'app</string>\n    <string name=\"step_add_vd\">Injection de Bunny</string>\n    <string name=\"step_signing\">Signature des APKs</string>\n    <string name=\"step_installing\">Installation des APKs</string>\n    <string name=\"installer_success\">Installation réussie</string>\n    <string name=\"installer_aborted\">Installation annulée</string>\n    <string name=\"install_fail_generic\">Échec de l\\'installation : raison inconnue</string>\n    <string name=\"install_fail_blocked\">L\\'installation a été bloquée</string>\n    <string name=\"install_fail_invalid\">Un ou plusieurs APKs sont invalides ou corrompus</string>\n    <string name=\"install_fail_conflict\">Conflit avec une application existante, généralement à cause de signatures non identiques</string>\n    <string name=\"install_fail_storage\">Stockage insuffisant pour installer</string>\n    <string name=\"install_fail_incompatible\">L\\'application n\\'est pas compatible avec cet appareil</string>\n    <string name=\"install_fail_timeout\">Installation échouée : Temps limite dépassée</string>\n    <string name=\"status_ongoing\">En cours</string>\n    <string name=\"status_successful\">Succès</string>\n    <string name=\"status_fail\">Échec</string>\n    <string name=\"status_queued\">En file d\\'attente</string>\n    <string name=\"action_collapse\">Réduire</string>\n    <string name=\"action_expand\">Agrandir</string>\n    <string name=\"action_back\">Précédent</string>\n    <string name=\"action_copy_logs\">Copier les logs</string>\n    <string name=\"action_clear_cache\">Vider le cache</string>\n    <string name=\"action_confirm\">Confirmer</string>\n    <string name=\"action_start_update\">Démarrer la mise à jour</string>\n    <string name=\"action_install\">Installer</string>\n    <string name=\"action_update\">Mettre à jour</string>\n    <string name=\"action_reinstall\">Réinstaller</string>\n    <string name=\"action_launch\">Démarrer</string>\n    <string name=\"action_uninstall\">Désinstaller</string>\n    <string name=\"action_info\">Information</string>\n    <string name=\"action_retry\">Réessayer</string>\n    <string name=\"action_reload\">Recharger</string>\n    <string name=\"action_open_about\">Ouvrir la page « à propos »</string>\n    <string name=\"action_open_settings\">Ouvrir les paramètres</string>\n    <string name=\"action_tap_to_install\">Appuyez ici pour installer Bunny pour Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Quitter quand même</string>\n    <string name=\"action_dismiss_nevermind\">Jamais</string>\n    <string name=\"action_dismiss_no_thanks\">Non, merci</string>\n    <string name=\"action_try_again\">Réessayer</string>\n    <string name=\"action_previous_theme\">Voir le thème précédent</string>\n    <string name=\"action_next_theme\">Voir le thème suivant</string>\n    <string name=\"action_view_logs\">Voir les logs</string>\n    <string name=\"action_show_timestamp\">Afficher l\\'horodatage</string>\n    <string name=\"action_copy_log\">Copier les logs</string>\n    <string name=\"action_save_logs\">Enregistrer les logs dans un fichier</string>\n    <string name=\"action_share_logs\">Partager les logs</string>\n    <string name=\"action_more_options\">Plus d\\'options</string>\n    <string name=\"msg_back_warning\">Quitter le programme d\\'installation avant qu\\'il ne soit terminé pourrait corrompre les fichiers téléchargés. Êtes-vous sûr de vouloir le faire ?</string>\n    <string name=\"installer_cached\">Mis en cache</string>\n    <string name=\"title_installer\">Installateur</string>\n    <string name=\"title_home\">Accueil</string>\n    <string name=\"title_settings\">Paramètres</string>\n    <string name=\"title_update\">Mise à jour disponible !</string>\n    <string name=\"title_about\">À propos</string>\n    <string name=\"title_permission_grant\">Accorder les permissions</string>\n    <string name=\"title_update_available\">Une nouvelle mise à jour de Discord est disponible !</string>\n    <string name=\"title_warning\">Avertissement</string>\n    <string name=\"title_dl_failed\">Téléchargements échoué</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Bibliothèques open-source</string>\n    <string name=\"title_libraries\">Bibliothèques</string>\n    <string name=\"theme_system\">Système</string>\n    <string name=\"theme_light\">Clair</string>\n    <string name=\"theme_dark\">Sombre</string>\n    <string name=\"duration_disabled\">Désactivé</string>\n    <string name=\"duration_fifteen_min\">Chaque quart d\\'heure</string>\n    <string name=\"duration_half_hour\">Chaque demi-heure</string>\n    <string name=\"duration_hourly\">Chaque heure</string>\n    <string name=\"duration_bihourly\">Chaque deux heures</string>\n    <string name=\"duration_twice_daily\">Deux fois par jour</string>\n    <string name=\"duration_daily\">Quotidien</string>\n    <string name=\"duration_weekly\">Hebdomadaire</string>\n    <string name=\"settings_appearance\">Apparence</string>\n    <string name=\"settings_appearance_description\">Choisissez l\\'apparence de l\\'application</string>\n    <string name=\"settings_dynamic_color\">Couleur dynamique</string>\n    <string name=\"settings_dynamic_color_description\">Disponible uniquement sur Android 12 et plus</string>\n    <string name=\"settings_theme\">Thème</string>\n    <string name=\"settings_check_updates\">Vérifier les mises à jour pour Discord</string>\n    <string name=\"settings_customization\">Personnalisation</string>\n    <string name=\"settings_customization_description\">Personnalisez votre installation de Bunny</string>\n    <string name=\"settings_app_name\">Nom de l\\'appli</string>\n    <string name=\"settings_app_icon\">Remplacer l\\'icône de l\\'appli</string>\n    <string name=\"settings_app_icon_description\">Utiliser l\\'icône de Bunny au lieu de celle de Discord</string>\n    <string name=\"settings_advanced\">Avancé</string>\n    <string name=\"settings_advanced_description\">Modifier le téléchargement et l\\'installation</string>\n    <string name=\"settings_channel\">Type de version</string>\n    <string name=\"settings_mirror\">Serveur de téléchargement</string>\n    <string name=\"settings_auto_clear_cache\">Effacer automatiquement le cache</string>\n    <string name=\"settings_auto_clear_cache_description\">Effacer le cache lorsque Discord reçois une mise à jour</string>\n    <string name=\"settings_developer\">Développeur uniquement</string>\n    <string name=\"settings_developer_description\">Ces paramètres peuvent entraîner des dysfonctionnements s\\'ils sont utilisés de manière inappropriée</string>\n    <string name=\"settings_module_location\">Emplacement du module</string>\n    <string name=\"settings_module_location_description\">Pour une utilisation avec le développement du module Xposed. VEUILLEZ FAIRE ATTENTION</string>\n    <string name=\"settings_module_location_reset\">Réinitialiser l\\'emplacement du module</string>\n    <string name=\"settings_package_name\">Nom du package</string>\n    <string name=\"settings_version\">Version de Discord</string>\n    <string name=\"settings_debuggable\">Débogable</string>\n    <string name=\"settings_debuggable_description\">Activer le flag de débogage</string>\n    <string name=\"settings_logs_alternate_lines\">Lignes alternatives</string>\n    <string name=\"settings_logs_line_wrap\">Retour à la ligne automatique</string>\n    <string name=\"update_description\">La version %1$s du Gestionnaire de Bunny est maintenant disponible !</string>\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Bêta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Équipe</string>\n    <string name=\"label_special_thanks\">Remerciements</string>\n    <string name=\"label_translate\">Aidez-nous à traduire</string>\n    <string name=\"version_latest\">Dernière version : %1$s</string>\n    <string name=\"version_target\">Version cible : %1$s</string>\n    <string name=\"version_current\">Version actuelle : %1$s</string>\n    <string name=\"install_method\">Méthode d\\'installation</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-hu-rHU/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Kezelő</string>\n    <string name=\"cd_library_author\">Szerző: %1$s</string>\n    <string name=\"cd_library_license\">Licenc: %1$s</string>\n    <string name=\"msg_cleared_cache\">A gyorsítótár sikeresen törlődött</string>\n    <string name=\"msg_load_fail\">Nem sikerült betölteni a véglegesítéseket</string>\n    <string name=\"msg_coming_soon\">Hamarosan</string>\n    <string name=\"msg_invalid_version\">Érvénytelen Discord verzió</string>\n    <string name=\"msg_seven_left\">még 7 érintés</string>\n    <string name=\"msg_five_left\">még 5 érintés</string>\n    <string name=\"msg_two_left\">még 2 érintés</string>\n    <string name=\"msg_loading\">Betöltés…</string>\n    <string name=\"msg_downgrade_disallowed\">Nem lehet leminősíteni, próbálja meg először eltávolítani</string>\n    <string name=\"msg_unlocked\">Ön most már fejlesztő</string>\n    <string name=\"msg_permission_grant\">A Bunny Kezelő működéséhez fájlengedélyekre van szükség. Mivel a megosztott adatokat a ~/Bunny fájlban tárolja, a hozzáféréshez engedélyekre van szükség.</string>\n    <string name=\"msg_shizuku_denied\">Nem sikerült megszerezni Shizuku engedélyeit</string>\n    <string name=\"msg_change_mirror\">Szeretné újra megpróbálni egy letöltési mirror segítségével?</string>\n    <string name=\"msg_invalid_apk\">Az APK sérült, próbálja meg a gyorsítótár törlését, majd az újratelepítést</string>\n    <string name=\"msg_download_cancelled\">A letöltés megszakadt</string>\n    <string name=\"msg_download_failed\">Letöltés sikertelen</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Vágólapra másolva</string>\n    <string name=\"group_download\">APK-k letöltése</string>\n    <string name=\"group_patch\">Foltozás</string>\n    <string name=\"group_installing\">Telepítés folyamatban</string>\n    <string name=\"step_dl_base\">Alap apk letöltése</string>\n    <string name=\"step_dl_lib\">Könyvár apk letöltése</string>\n    <string name=\"step_dl_lang\">Nyelvi apk letöltése</string>\n    <string name=\"step_dl_res\">Források apk letöltése folyamatban</string>\n    <string name=\"step_dl_vd\">Bunny modul letöltése</string>\n    <string name=\"step_change_icon\">App ikon megváltoztatása</string>\n    <string name=\"step_patch_manifests\">Alkalmazás manifesztek javítása</string>\n    <string name=\"step_add_vd\">Bunny beépítése</string>\n    <string name=\"step_signing\">APK-k aláírása</string>\n    <string name=\"step_installing\">APK-k telepítése folyamatban</string>\n    <string name=\"installer_success\">Sikeresen telepítve</string>\n    <string name=\"installer_aborted\">Telepítés megszakítva</string>\n    <string name=\"install_fail_generic\">A telepítés sikertelen: Ismeretlen ok</string>\n    <string name=\"install_fail_blocked\">A telepítés blokkolva</string>\n    <string name=\"install_fail_invalid\">Egy vagy több APK érvénytelen vagy sérült</string>\n    <string name=\"install_fail_conflict\">Konfliktus egy meglévő alkalmazással, általában az aláírás eltérése miatt</string>\n    <string name=\"install_fail_storage\">Nincs elég hely a telepítéshez</string>\n    <string name=\"install_fail_incompatible\">Az alkalmazás nem kompatibilis ezzel az eszközzel</string>\n    <string name=\"install_fail_timeout\">A telepítés leállt</string>\n    <string name=\"status_ongoing\">Folyamatban</string>\n    <string name=\"status_successful\">Sikeresem</string>\n    <string name=\"status_fail\">Sikertelenül</string>\n    <string name=\"status_queued\">Várólistán</string>\n    <string name=\"action_collapse\">Összeomlott</string>\n    <string name=\"action_expand\">Kibontás</string>\n    <string name=\"action_back\">Vissza</string>\n    <string name=\"action_copy_logs\">Naplók másolása</string>\n    <string name=\"action_clear_cache\">Gyorsítótár törlése</string>\n    <string name=\"action_confirm\">Megerősítés</string>\n    <string name=\"action_start_update\">Frissítés most</string>\n    <string name=\"action_install\">Telepítés</string>\n    <string name=\"action_update\">Frissítés</string>\n    <string name=\"action_reinstall\">Újratelepítés</string>\n    <string name=\"action_launch\">Megnyitás</string>\n    <string name=\"action_uninstall\">Eltávolítás</string>\n    <string name=\"action_info\">Információ</string>\n    <string name=\"action_retry\">Újra</string>\n    <string name=\"action_reload\">Újratöltés</string>\n    <string name=\"action_open_about\">Rólunk megnyitása</string>\n    <string name=\"action_open_settings\">Beállítások megnyitása</string>\n    <string name=\"action_tap_to_install\">Érintse meg a Bunny A Discordhoz telepítéséhez %1$s</string>\n    <string name=\"action_confirm_exit\">Kilépés</string>\n    <string name=\"action_dismiss_nevermind\">Mindegy</string>\n    <string name=\"action_dismiss_no_thanks\">Nem, köszönöm</string>\n    <string name=\"action_try_again\">Próbáld újra</string>\n    <string name=\"action_previous_theme\">Lásd a korábbi témát</string>\n    <string name=\"action_next_theme\">Lásd a következő témát</string>\n    <string name=\"action_view_logs\">Naplók megtekintése</string>\n    <string name=\"action_show_timestamp\">Időbélyeg megjelenítése</string>\n    <string name=\"action_copy_log\">Napló másolása</string>\n    <string name=\"action_save_logs\">Naplófájlok mentése fáljba</string>\n    <string name=\"action_share_logs\">Napló megosztása</string>\n    <string name=\"action_more_options\">További beállítások</string>\n    <string name=\"msg_back_warning\">A telepítő befejezés előtti kilépésével sérülhetnek a letöltött fájlok, biztos, hogy ezt szeretné?</string>\n    <string name=\"installer_cached\">Gyorsítótárazott</string>\n    <string name=\"title_installer\">Telepítő</string>\n    <string name=\"title_home\">Kezdőlap</string>\n    <string name=\"title_settings\">Beállítások</string>\n    <string name=\"title_update\">Frissítés érhető el!</string>\n    <string name=\"title_about\">Rólunk</string>\n    <string name=\"title_permission_grant\">Engedélyek megadása</string>\n    <string name=\"title_update_available\">Új Discord frissítés elérhető!</string>\n    <string name=\"title_warning\">Figyelmeztetés</string>\n    <string name=\"title_dl_failed\">Sikertelen letöltés</string>\n    <string name=\"title_logs\">Naplók</string>\n    <string name=\"title_os_libraries\">Nyílt forráskódú könyvtárak</string>\n    <string name=\"title_libraries\">Könyvtárak</string>\n    <string name=\"theme_system\">Rendszer</string>\n    <string name=\"theme_light\">Világos</string>\n    <string name=\"theme_dark\">Sötét</string>\n    <string name=\"duration_disabled\">Kikapcsolva</string>\n    <string name=\"duration_fifteen_min\">Negyedóránként</string>\n    <string name=\"duration_half_hour\">Félóránként</string>\n    <string name=\"duration_hourly\">Óránként</string>\n    <string name=\"duration_bihourly\">Kétóránként</string>\n    <string name=\"duration_twice_daily\">Naponta kétszer</string>\n    <string name=\"duration_daily\">Naponta</string>\n    <string name=\"duration_weekly\">Hetente</string>\n    <string name=\"settings_appearance\">Megjelenés</string>\n    <string name=\"settings_appearance_description\">Az alkalmazás megjelenésének megváltoztatása</string>\n    <string name=\"settings_dynamic_color\">Rendszer szerinti színek</string>\n    <string name=\"settings_dynamic_color_description\">Csak Android 12+ rendszeren elérhető</string>\n    <string name=\"settings_theme\">Téma</string>\n    <string name=\"settings_check_updates\">Discord frissítések keresése</string>\n    <string name=\"settings_customization\">Testreszabás</string>\n    <string name=\"settings_customization_description\">A Bunny telepítésének testreszabása</string>\n    <string name=\"settings_app_name\">Alkalmazás neve</string>\n    <string name=\"settings_app_icon\">Alkalmazás ikon kicserélése</string>\n    <string name=\"settings_app_icon_description\">A Bunny ikon használata a Discord ikonja helyett</string>\n    <string name=\"settings_advanced\">Haladó</string>\n    <string name=\"settings_advanced_description\">Letöltés és telepítés módosítása</string>\n    <string name=\"settings_channel\">Kiadási csatorna</string>\n    <string name=\"settings_mirror\">Letöltési tükör</string>\n    <string name=\"settings_auto_clear_cache\">A gyorsítótár automatikus törlése</string>\n    <string name=\"settings_auto_clear_cache_description\">Törli a gyorsítótárat, amikor a Discordhoz elérhető frissítés</string>\n    <string name=\"settings_developer\">Csak fejlesztőknek</string>\n    <string name=\"settings_developer_description\">Ezek a beállítások tönkretehetik a dolgokat, ha helytelenül használja őket</string>\n    <string name=\"settings_module_location\">Modul helye</string>\n    <string name=\"settings_module_location_description\">Az Xposed modul fejlesztéséhez. LEGYEN ÓVATOS</string>\n    <string name=\"settings_module_location_reset\">A modul helyének visszaállítása</string>\n    <string name=\"settings_package_name\">Csomag neve</string>\n    <string name=\"settings_version\">Discord verzió</string>\n    <string name=\"settings_debuggable\">Debuggolható</string>\n    <string name=\"settings_debuggable_description\">Engedélyezze a debuggolható jelzőt</string>\n    <string name=\"settings_logs_alternate_lines\">Alternatív sorok</string>\n    <string name=\"settings_logs_line_wrap\">Felhúzott vonalak</string>\n    <string name=\"update_description\">A Bunny Manager %1$s verziója már elérhető!</string>\n    <string name=\"channel_stable\">Stabil</string>\n    <string name=\"channel_beta\">Béta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Csapat</string>\n    <string name=\"label_special_thanks\">Külön köszönet</string>\n    <string name=\"label_translate\">Fordítás</string>\n    <string name=\"version_latest\">Legújabb: %1$s</string>\n    <string name=\"version_target\">Cél: %1$s</string>\n    <string name=\"version_current\">Jelenlegi: %1$s</string>\n    <string name=\"install_method\">Telepítési módszer</string>\n    <string name=\"default_installer\">Alapértelmezett (ajánlott)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-in-rID/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Berkas singgahan (cache) berhasil dikosongkan</string>\n    <string name=\"msg_load_fail\">Failed to load commits</string>\n    <string name=\"msg_coming_soon\">Segera hadir</string>\n    <string name=\"msg_invalid_version\">Versi Discord tidak valid</string>\n    <string name=\"msg_seven_left\">7 ketukan lagi</string>\n    <string name=\"msg_five_left\">5 ketukan lagi</string>\n    <string name=\"msg_two_left\">2 ketukan lagi</string>\n    <string name=\"msg_loading\">Memuat…</string>\n    <string name=\"msg_downgrade_disallowed\">Tidak bisa menurunkan versi (downgrade), coba copot pemasangan dahulu</string>\n    <string name=\"msg_unlocked\">Kamu sekarang adalah seorang pengembang</string>\n    <string name=\"msg_permission_grant\">In order for Bunny Manager to function, file permissions are required. Since shared data is stored in ~/Bunny, permissions are required in order to access it.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Download APKs</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Installing</string>\n    <string name=\"step_dl_base\">Downloading base apk</string>\n    <string name=\"step_dl_lib\">Downloading libraries apk</string>\n    <string name=\"step_dl_lang\">Downloading language apk</string>\n    <string name=\"step_dl_res\">Downloading resources apk</string>\n    <string name=\"step_dl_vd\">Downloading Bunny module</string>\n    <string name=\"step_change_icon\">Changing app icon</string>\n    <string name=\"step_patch_manifests\">Patching app manifests</string>\n    <string name=\"step_add_vd\">Injecting Bunny</string>\n    <string name=\"step_signing\">Signing APKs</string>\n    <string name=\"step_installing\">Installing APKs</string>\n    <string name=\"installer_success\">Installed successfully</string>\n    <string name=\"installer_aborted\">Install canceled</string>\n    <string name=\"install_fail_generic\">Failed to install: Unknown reason</string>\n    <string name=\"install_fail_blocked\">Installation was blocked</string>\n    <string name=\"install_fail_invalid\">One or more APKs were invalid or corrupt</string>\n    <string name=\"install_fail_conflict\">Conflicts with an existing app, usually due to mismatched signatures</string>\n    <string name=\"install_fail_storage\">Not enough available storage to install</string>\n    <string name=\"install_fail_incompatible\">Application is incompatible with this device</string>\n    <string name=\"install_fail_timeout\">Installation timed out</string>\n    <string name=\"status_ongoing\">Ongoing</string>\n    <string name=\"status_successful\">Successful</string>\n    <string name=\"status_fail\">Failed</string>\n    <string name=\"status_queued\">Queued</string>\n    <string name=\"action_collapse\">Collapse</string>\n    <string name=\"action_expand\">Expand</string>\n    <string name=\"action_back\">Go back</string>\n    <string name=\"action_copy_logs\">Copy logs</string>\n    <string name=\"action_clear_cache\">Clear cache</string>\n    <string name=\"action_confirm\">Confirm</string>\n    <string name=\"action_start_update\">Start update</string>\n    <string name=\"action_install\">Install</string>\n    <string name=\"action_update\">Update</string>\n    <string name=\"action_reinstall\">Reinstall</string>\n    <string name=\"action_launch\">Launch</string>\n    <string name=\"action_uninstall\">Uninstall</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Retry</string>\n    <string name=\"action_reload\">Reload</string>\n    <string name=\"action_open_about\">Open about</string>\n    <string name=\"action_open_settings\">Open settings</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">Cached</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Settings</string>\n    <string name=\"title_update\">Update available!</string>\n    <string name=\"title_about\">About</string>\n    <string name=\"title_permission_grant\">Grant Permissions</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Light</string>\n    <string name=\"theme_dark\">Dark</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">Appearance</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamic color</string>\n    <string name=\"settings_dynamic_color_description\">Only available on Android 12 and up</string>\n    <string name=\"settings_theme\">Theme</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">App name</string>\n    <string name=\"settings_app_icon\">Replace app icon</string>\n    <string name=\"settings_app_icon_description\">Uses the Bunny icon instead of Discord\\'s</string>\n    <string name=\"settings_advanced\">Advanced</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Release channel</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">Developer only</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Package name</string>\n    <string name=\"settings_version\">Discord version</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Enable debuggable flag</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager version %1$s is now available!</string>\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Tim</string>\n    <string name=\"label_special_thanks\">Special thanks</string>\n    <string name=\"label_translate\">Translate</string>\n    <string name=\"version_latest\">Terkini: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Saat ini: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-it-rIT/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cache pulita con successo</string>\n    <string name=\"msg_load_fail\">Caricamento dei commit non riuscito</string>\n    <string name=\"msg_coming_soon\">A breve</string>\n    <string name=\"msg_invalid_version\">Versione Discord non valida</string>\n    <string name=\"msg_seven_left\">Altri 7 tocchi</string>\n    <string name=\"msg_five_left\">Altri 5 tocchi</string>\n    <string name=\"msg_two_left\">Altri 2 tocchi</string>\n    <string name=\"msg_loading\">Caricamento…</string>\n    <string name=\"msg_downgrade_disallowed\">Impossibile eseguire il downgrade, prova a disinstallare prima</string>\n    <string name=\"msg_unlocked\">Ora sei uno sviluppatore</string>\n    <string name=\"msg_permission_grant\">Affinché Bunny Manager possa funzionare, sono richiesti i permessi dei file. Dal momento che i dati condivisi sono memorizzati in ~/Bunny, sono necessari i permessi per accedervi.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Vuoi provare di nuovo usando un download alternativo?</string>\n    <string name=\"msg_invalid_apk\">L\\'APK è corrotto, prova a svuotare la cache e poi a reinstallarlo</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Download APKs</string>\n    <string name=\"group_patch\">Patch in corso</string>\n    <string name=\"group_installing\">Installazione</string>\n    <string name=\"step_dl_base\">Download apk base</string>\n    <string name=\"step_dl_lib\">Download apk librerie</string>\n    <string name=\"step_dl_lang\">Download apk lingua</string>\n    <string name=\"step_dl_res\">Download apk risorse</string>\n    <string name=\"step_dl_vd\">Download modulo Bunny</string>\n    <string name=\"step_change_icon\">Cambia icona dell\\'app</string>\n    <string name=\"step_patch_manifests\">Patch manifest dell\\'app</string>\n    <string name=\"step_add_vd\">Iniettando Bunny</string>\n    <string name=\"step_signing\">Firmando gli APK</string>\n    <string name=\"step_installing\">Installando APK</string>\n    <string name=\"installer_success\">Installato con successo</string>\n    <string name=\"installer_aborted\">Installazione annullata</string>\n    <string name=\"install_fail_generic\">Installazione non riuscita: Motivo sconosciuto</string>\n    <string name=\"install_fail_blocked\">L\\'installazione è stata bloccata</string>\n    <string name=\"install_fail_invalid\">Uno o più APK non erano validi o corrotti</string>\n    <string name=\"install_fail_conflict\">Conflitti con un\\'app esistente, di solito a causa di firme non corrispondenti</string>\n    <string name=\"install_fail_storage\">Spazio disponibile insufficiente per l\\'installazione</string>\n    <string name=\"install_fail_incompatible\">L\\'applicazione non è compatibile con questo dispositivo</string>\n    <string name=\"install_fail_timeout\">Tempo scaduto per l\\'installazione</string>\n    <string name=\"status_ongoing\">In corso</string>\n    <string name=\"status_successful\">Riuscito</string>\n    <string name=\"status_fail\">Non riuscito</string>\n    <string name=\"status_queued\">In coda</string>\n    <string name=\"action_collapse\">Minimizza</string>\n    <string name=\"action_expand\">Espandi</string>\n    <string name=\"action_back\">Indietro</string>\n    <string name=\"action_copy_logs\">Copia i log</string>\n    <string name=\"action_clear_cache\">Svuota cache</string>\n    <string name=\"action_confirm\">Conferma</string>\n    <string name=\"action_start_update\">Avvia l\\'aggiornamento</string>\n    <string name=\"action_install\">Installa</string>\n    <string name=\"action_update\">Aggiorna</string>\n    <string name=\"action_reinstall\">Reinstalla</string>\n    <string name=\"action_launch\">Avvia</string>\n    <string name=\"action_uninstall\">Disinstalla</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Riprova</string>\n    <string name=\"action_reload\">Aggiorna</string>\n    <string name=\"action_open_about\">Apri informazioni</string>\n    <string name=\"action_open_settings\">Apri impostazioni</string>\n    <string name=\"action_tap_to_install\">Tocca per installare Bunny per Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Esci comunque</string>\n    <string name=\"action_dismiss_nevermind\">Non importa</string>\n    <string name=\"action_dismiss_no_thanks\">No grazie</string>\n    <string name=\"action_try_again\">Riprova</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Uscire dal programma prima che abbia finito potrebbe danneggiare i file scaricati, sei sicuro di volerlo fare?</string>\n    <string name=\"installer_cached\">Memorizz. nella cache</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Impostazioni</string>\n    <string name=\"title_update\">Aggiornamento disponibile!</string>\n    <string name=\"title_about\">Informazioni</string>\n    <string name=\"title_permission_grant\">Concedi permessi</string>\n    <string name=\"title_update_available\">Nuovo aggiornamento di Discord disponibile!</string>\n    <string name=\"title_warning\">Attenzione</string>\n    <string name=\"title_dl_failed\">Download non riuscito</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Sistema</string>\n    <string name=\"theme_light\">Chiaro</string>\n    <string name=\"theme_dark\">Scuro</string>\n    <string name=\"duration_disabled\">Disabilitato</string>\n    <string name=\"duration_fifteen_min\">Ogni 15 minuti</string>\n    <string name=\"duration_half_hour\">Ogni 30 minuti</string>\n    <string name=\"duration_hourly\">Ogni ora</string>\n    <string name=\"duration_bihourly\">Ogni 2 ore</string>\n    <string name=\"duration_twice_daily\">Due volte al giorno</string>\n    <string name=\"duration_daily\">Giornalmente</string>\n    <string name=\"duration_weekly\">Settimanalmente</string>\n    <string name=\"settings_appearance\">Aspetto</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Colori dinamici</string>\n    <string name=\"settings_dynamic_color_description\">Disponibile solo su Android 12 e versioni successive</string>\n    <string name=\"settings_theme\">Tema</string>\n    <string name=\"settings_check_updates\">Controlla aggiornamenti di Discord</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">Nome app</string>\n    <string name=\"settings_app_icon\">Sostituisci l\\'icona dell\\'app</string>\n    <string name=\"settings_app_icon_description\">Utilizza l\\'icona di Bunny al posto di Discord</string>\n    <string name=\"settings_advanced\">Avanzate</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Canale di rilascio</string>\n    <string name=\"settings_mirror\">Download alternativo</string>\n    <string name=\"settings_auto_clear_cache\">Cancella la cache automaticamente</string>\n    <string name=\"settings_auto_clear_cache_description\">Cancella la cache quando Discord riceve un aggiornamento</string>\n    <string name=\"settings_developer\">Solo sviluppatori</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Percorso del modulo</string>\n    <string name=\"settings_module_location_description\">Da utilizzare con lo sviluppo del modulo Xposed. FA ATTENZIONE</string>\n    <string name=\"settings_module_location_reset\">Ripristina la posizione del modulo</string>\n    <string name=\"settings_package_name\">Nome pacchetto</string>\n    <string name=\"settings_version\">Versione Discord</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Abilita flag debug</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager versione %1$s è disponibile!</string>\n    <string name=\"channel_stable\">Stabile</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Ringraziamenti speciali</string>\n    <string name=\"label_translate\">Traduci</string>\n    <string name=\"version_latest\">Ultima versione: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Versione attuale: %1$s</string>\n    <string name=\"install_method\">Metodo d\\'installazione</string>\n    <string name=\"default_installer\">Predefinito (Consigliato)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-iw-rIL/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">מנהל Bunny</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">המטמון נוקה בהצלחה</string>\n    <string name=\"msg_load_fail\">טעינת שינוים נכשלה</string>\n    <string name=\"msg_coming_soon\">בקרוב</string>\n    <string name=\"msg_invalid_version\">גרסת דיסקורד לא נתמכת</string>\n    <string name=\"msg_seven_left\">עוד 7 לחיצות</string>\n    <string name=\"msg_five_left\">עוד 5 לחיצות</string>\n    <string name=\"msg_two_left\">עוד 2 לחיצות</string>\n    <string name=\"msg_loading\">טוען…</string>\n    <string name=\"msg_downgrade_disallowed\">לא ניתן לחזור גרסה, נסה קודם להסיר את האפליקציה</string>\n    <string name=\"msg_unlocked\">אתה כעת מפתח</string>\n    <string name=\"msg_permission_grant\">על מנת שמנהל Bunny יפעל, נדרשות הרשאות קובץ. מכיוון שהנתונים המשותפים מאוחסנים ב-~/Bunny, נדרשות הרשאות על מנת לגשת אליהם.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">האם תרצה לנסות שוב באמצעות קישור אחר?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">מוריד קבצים</string>\n    <string name=\"group_patch\">מנתח</string>\n    <string name=\"group_installing\">מתקין</string>\n    <string name=\"step_dl_base\">מוריד את ה-Apk הבסיסי</string>\n    <string name=\"step_dl_lib\">מוריד את ספריית ה-Apk</string>\n    <string name=\"step_dl_lang\">מוריד שפות האפליקציה</string>\n    <string name=\"step_dl_res\">מוריד את החומרים לאפליקציה</string>\n    <string name=\"step_dl_vd\">מוריד את מודל Bunny</string>\n    <string name=\"step_change_icon\">שינוי סמל האפליקציה</string>\n    <string name=\"step_patch_manifests\">תקן אפליקציית מניפסטים</string>\n    <string name=\"step_add_vd\">מכניס את Bunny</string>\n    <string name=\"step_signing\">חותם על APKs</string>\n    <string name=\"step_installing\">מתקין אפליקציות</string>\n    <string name=\"installer_success\">הותקן בהצלחה</string>\n    <string name=\"installer_aborted\">התקנה בוטלה</string>\n    <string name=\"install_fail_generic\">ההתקנה נכשלה: סיבה לא ידועה</string>\n    <string name=\"install_fail_blocked\">ההתקנה נחסמה</string>\n    <string name=\"install_fail_invalid\">APK אחד או יותר היו לא תקינים או פגומים</string>\n    <string name=\"install_fail_conflict\">מתנגשות עם אפליקציה קיימת, בדרך כלל עקב אי-התאמה של חתימות</string>\n    <string name=\"install_fail_storage\">אין מספיק שטח אחסון זמין להתקנה</string>\n    <string name=\"install_fail_incompatible\">האפליקציה אינה תומכת במכשיר זה</string>\n    <string name=\"install_fail_timeout\">ההתקנה איבדה תקשורת</string>\n    <string name=\"status_ongoing\">מתמשך</string>\n    <string name=\"status_successful\">הצליח</string>\n    <string name=\"status_fail\">נכשל</string>\n    <string name=\"status_queued\">בהמתנה</string>\n    <string name=\"action_collapse\">צמצום</string>\n    <string name=\"action_expand\">הרחב</string>\n    <string name=\"action_back\">חזור אחורה</string>\n    <string name=\"action_copy_logs\">העתק לוגים</string>\n    <string name=\"action_clear_cache\">נקה מטמון</string>\n    <string name=\"action_confirm\">אישור</string>\n    <string name=\"action_start_update\">התחל עדכון</string>\n    <string name=\"action_install\">התקן</string>\n    <string name=\"action_update\">עדכן</string>\n    <string name=\"action_reinstall\">התקן מחדש</string>\n    <string name=\"action_launch\">הפעל</string>\n    <string name=\"action_uninstall\">הסר התקנה</string>\n    <string name=\"action_info\">מידע</string>\n    <string name=\"action_retry\">נסה שוב</string>\n    <string name=\"action_reload\">רענון</string>\n    <string name=\"action_open_about\">פתח על</string>\n    <string name=\"action_open_settings\">פתח הגדרות</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">מוטמן</string>\n    <string name=\"title_installer\">מתקין</string>\n    <string name=\"title_home\">בית</string>\n    <string name=\"title_settings\">הגדרות</string>\n    <string name=\"title_update\">עדכון זמין!</string>\n    <string name=\"title_about\">אודות</string>\n    <string name=\"title_permission_grant\">הענקת הרשאות</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">מערכת</string>\n    <string name=\"theme_light\">בהיר</string>\n    <string name=\"theme_dark\">כהה</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">מראה</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">צבע דינמי</string>\n    <string name=\"settings_dynamic_color_description\">זמין לאנדרואיד 12 ומעלה בלבד</string>\n    <string name=\"settings_theme\">עיצוב</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">שם האפליקציה</string>\n    <string name=\"settings_app_icon\">החלף תמונת אפליקציה</string>\n    <string name=\"settings_app_icon_description\">השתמש בתמונה של Bunny במקום התמונה של דיסקורד</string>\n    <string name=\"settings_advanced\">הגדרות מתקדמות</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">ערוץ הפצה</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">מתכנתים בלבד</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">שם החבילה</string>\n    <string name=\"settings_version\">גרסת דיסקורד</string>\n    <string name=\"settings_debuggable\">ניתן לניפוי באגים</string>\n    <string name=\"settings_debuggable_description\">האפשרות ניתן לניפוי באגים הופעלה</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">הגרסה %1$s של מנהל Bunny זמינה כעת!</string>\n    <string name=\"channel_stable\">יציב</string>\n    <string name=\"channel_beta\">בטא</string>\n    <string name=\"channel_alpha\">אלפא</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">דיסקורד</string>\n    <string name=\"label_team\">צוות</string>\n    <string name=\"label_special_thanks\">תודות מיוחדות</string>\n    <string name=\"label_translate\">תרגם</string>\n    <string name=\"version_latest\">גרסה אחרונה: %1$s</string>\n    <string name=\"version_target\">מטרה: %1$s</string>\n    <string name=\"version_current\">נוכחי: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-ja-rJP/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">開発者: %1$s</string>\n    <string name=\"cd_library_license\">ライセンス: %1$s</string>\n    <string name=\"msg_cleared_cache\">キャッシュを消去しました</string>\n    <string name=\"msg_load_fail\">コミットの読み込みに失敗しました</string>\n    <string name=\"msg_coming_soon\">近日公開</string>\n    <string name=\"msg_invalid_version\">Discordのバージョンが無効です</string>\n    <string name=\"msg_seven_left\">あと7回タップしてください</string>\n    <string name=\"msg_five_left\">あと5回タップしてください</string>\n    <string name=\"msg_two_left\">あと2回タップしてください</string>\n    <string name=\"msg_loading\">読み込み中…</string>\n    <string name=\"msg_downgrade_disallowed\">ダウングレードできません。まずアンインストールを試してください</string>\n    <string name=\"msg_unlocked\">これで開発者になりました</string>\n    <string name=\"msg_permission_grant\">Bunny Manager を正しく動作させるためには、ファイルへのアクセスを許可する必要があります。\n~/Bunny に共有データが保存されるため、Manager を機能させるためには権限が必要です。</string>\n    <string name=\"msg_shizuku_denied\">Shizukuの権限を取得できませんでした</string>\n    <string name=\"msg_change_mirror\">ダウンロードミラーを使用して再試行しますか？</string>\n    <string name=\"msg_invalid_apk\">APK が破損しています。キャッシュを消去してから再インストールしてください。</string>\n    <string name=\"msg_download_cancelled\">ダウンロードが中止されました</string>\n    <string name=\"msg_download_failed\">ダウンロードに失敗しました</string>\n    <string name=\"msg_download_verify_failed\">ダウンロードされたファイルを検証できませんでした。詳細についてはログを確認してください。</string>\n    <string name=\"msg_copied\">クリップボードにコピーしました</string>\n    <string name=\"group_download\">APK のダウンロード</string>\n    <string name=\"group_patch\">パッチの適用</string>\n    <string name=\"group_installing\">インストール</string>\n    <string name=\"step_dl_base\">ベース APK のダウンロード</string>\n    <string name=\"step_dl_lib\">ライブラリ APK のダウンロード</string>\n    <string name=\"step_dl_lang\">言語 APK のダウンロード</string>\n    <string name=\"step_dl_res\">リソース APK のダウンロード</string>\n    <string name=\"step_dl_vd\">Bunny モジュールのダウンロード</string>\n    <string name=\"step_change_icon\">アプリアイコンの変更</string>\n    <string name=\"step_patch_manifests\">マニフェストにパッチを適用中</string>\n    <string name=\"step_add_vd\">Bunny をインジェクト中</string>\n    <string name=\"step_signing\">APK を署名中</string>\n    <string name=\"step_installing\">APK をインストール中</string>\n    <string name=\"installer_success\">正常にインストールされました</string>\n    <string name=\"installer_aborted\">インストールはキャンセルされました</string>\n    <string name=\"install_fail_generic\">インストールに失敗しました: 不明な理由</string>\n    <string name=\"install_fail_blocked\">インストールがブロックされました</string>\n    <string name=\"install_fail_invalid\">1つまたは複数の APK が無効または破損しています</string>\n    <string name=\"install_fail_conflict\">既存のアプリと競合します。通常、署名が一致しないことが原因です。</string>\n    <string name=\"install_fail_storage\">空き容量が不足しています。</string>\n    <string name=\"install_fail_incompatible\">アプリケーションはこのデバイスと互換性がありません</string>\n    <string name=\"install_fail_timeout\">インストールがタイムアウトしました</string>\n    <string name=\"status_ongoing\">進行中</string>\n    <string name=\"status_successful\">成功</string>\n    <string name=\"status_fail\">失敗</string>\n    <string name=\"status_queued\">処理待ち</string>\n    <string name=\"action_collapse\">閉じる</string>\n    <string name=\"action_expand\">展開する</string>\n    <string name=\"action_back\">戻る</string>\n    <string name=\"action_copy_logs\">ログをコピー</string>\n    <string name=\"action_clear_cache\">キャッシュを消去</string>\n    <string name=\"action_confirm\">確定</string>\n    <string name=\"action_start_update\">アップデートを開始</string>\n    <string name=\"action_install\">インストール</string>\n    <string name=\"action_update\">アップデート</string>\n    <string name=\"action_reinstall\">再インストール</string>\n    <string name=\"action_launch\">開く</string>\n    <string name=\"action_uninstall\">アンインストール</string>\n    <string name=\"action_info\">情報</string>\n    <string name=\"action_retry\">再試行</string>\n    <string name=\"action_reload\">再読み込み</string>\n    <string name=\"action_open_about\">概要を開く</string>\n    <string name=\"action_open_settings\">設定を開く</string>\n    <string name=\"action_tap_to_install\">タップして Discord %1$s にBunnyをインストールする</string>\n    <string name=\"action_confirm_exit\">とにかく終了</string>\n    <string name=\"action_dismiss_nevermind\">やめる</string>\n    <string name=\"action_dismiss_no_thanks\">いいえ</string>\n    <string name=\"action_try_again\">再試行</string>\n    <string name=\"action_previous_theme\">前のテーマを表示</string>\n    <string name=\"action_next_theme\">次のテーマを表示</string>\n    <string name=\"action_view_logs\">ログを表示</string>\n    <string name=\"action_show_timestamp\">タイムスタンプを表示</string>\n    <string name=\"action_copy_log\">ログをコピー</string>\n    <string name=\"action_save_logs\">ログをファイルで保存</string>\n    <string name=\"action_share_logs\">ログを共有</string>\n    <string name=\"action_more_options\">その他のオプション</string>\n    <string name=\"msg_back_warning\">インストールが完了する前にインストーラーを終了すると、ダウンロードしたファイルが破損する可能性があります。本当に実行しますか？</string>\n    <string name=\"installer_cached\">キャッシュ済み</string>\n    <string name=\"title_installer\">インストーラー</string>\n    <string name=\"title_home\">ホーム</string>\n    <string name=\"title_settings\">設定</string>\n    <string name=\"title_update\">アップデートがあります</string>\n    <string name=\"title_about\">概要</string>\n    <string name=\"title_permission_grant\">アクセス権限の付与</string>\n    <string name=\"title_update_available\">新しい Discord のアップデートが利用可能です！</string>\n    <string name=\"title_warning\">警告</string>\n    <string name=\"title_dl_failed\">ダウンロードに失敗しました</string>\n    <string name=\"title_logs\">ログ</string>\n    <string name=\"title_os_libraries\">オープンソースライブラリ</string>\n    <string name=\"title_libraries\">ライブラリ</string>\n    <string name=\"theme_system\">システム</string>\n    <string name=\"theme_light\">ライト</string>\n    <string name=\"theme_dark\">ダーク</string>\n    <string name=\"duration_disabled\">無効</string>\n    <string name=\"duration_fifteen_min\">15分</string>\n    <string name=\"duration_half_hour\">30分</string>\n    <string name=\"duration_hourly\">1時間</string>\n    <string name=\"duration_bihourly\">2時間</string>\n    <string name=\"duration_twice_daily\">12時間</string>\n    <string name=\"duration_daily\">1日</string>\n    <string name=\"duration_weekly\">7日</string>\n    <string name=\"settings_appearance\">外観</string>\n    <string name=\"settings_appearance_description\">アプリの外観と操作性を変更します</string>\n    <string name=\"settings_dynamic_color\">ダイナミック カラー</string>\n    <string name=\"settings_dynamic_color_description\">Android 12 以降でのみ利用可能です</string>\n    <string name=\"settings_theme\">テーマ</string>\n    <string name=\"settings_check_updates\">Discordのアップデートを確認</string>\n    <string name=\"settings_customization\">カスタマイズ</string>\n    <string name=\"settings_customization_description\">Bunnyのカスタマイズ</string>\n    <string name=\"settings_app_name\">アプリ名</string>\n    <string name=\"settings_app_icon\">アプリのアイコンを置き換え</string>\n    <string name=\"settings_app_icon_description\">Discordアイコンの代わりにBunnyアイコンを使用します</string>\n    <string name=\"settings_advanced\">高度な設定</string>\n    <string name=\"settings_advanced_description\">ダウンロードとインストールの変更</string>\n    <string name=\"settings_channel\">リリースチャンネル</string>\n    <string name=\"settings_mirror\">ダウンロードミラー</string>\n    <string name=\"settings_auto_clear_cache\">キャッシュを自動的にクリア</string>\n    <string name=\"settings_auto_clear_cache_description\">Discordの更新時にキャッシュをクリアします</string>\n    <string name=\"settings_developer\">開発者専用</string>\n    <string name=\"settings_developer_description\">これらの設定を不適切に使用すると、問題が発生する可能性があります</string>\n    <string name=\"settings_module_location\">モジュールの場所</string>\n    <string name=\"settings_module_location_description\">Xposed モジュールの開発に使用します。！！注意！！</string>\n    <string name=\"settings_module_location_reset\">モジュールの保存場所をリセット</string>\n    <string name=\"settings_package_name\">パッケージ名</string>\n    <string name=\"settings_version\">Discord バージョン</string>\n    <string name=\"settings_debuggable\">デバッグ可能</string>\n    <string name=\"settings_debuggable_description\">デバッグ可能フラグを有効化します</string>\n    <string name=\"settings_logs_alternate_lines\">代替の行</string>\n    <string name=\"settings_logs_line_wrap\">行を折り返す</string>\n    <string name=\"update_description\">Bunny Manager の新バージョン %1$s が利用可能です！</string>\n    <string name=\"channel_stable\">安定版</string>\n    <string name=\"channel_beta\">ベータ版</string>\n    <string name=\"channel_alpha\">アルファ版</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">チーム</string>\n    <string name=\"label_special_thanks\">スペシャルサンクス</string>\n    <string name=\"label_translate\">翻訳</string>\n    <string name=\"version_latest\">最新バージョン: %1$s</string>\n    <string name=\"version_target\">ターゲット: %1$s</string>\n    <string name=\"version_current\">インストール済み: %1$s</string>\n    <string name=\"install_method\">インストール方法</string>\n    <string name=\"default_installer\">Default (推奨)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-ko-rKR/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">제작자: %1$s</string>\n    <string name=\"cd_library_license\">라이센스: %1$s</string>\n    <string name=\"msg_cleared_cache\">캐시를 비웠어요</string>\n    <string name=\"msg_load_fail\">커밋을 불러오는 데 실패했어요</string>\n    <string name=\"msg_coming_soon\">출시 예정</string>\n    <string name=\"msg_invalid_version\">잘못된 Discord 버전</string>\n    <string name=\"msg_seven_left\">7번 더 누르세요</string>\n    <string name=\"msg_five_left\">5번 더 누르세요</string>\n    <string name=\"msg_two_left\">2번 더 누르세요</string>\n    <string name=\"msg_loading\">불러오는 중…</string>\n    <string name=\"msg_downgrade_disallowed\">다운그레이드하지 못했어요. 먼저 삭제해 보세요</string>\n    <string name=\"msg_unlocked\">개발자 모드가 활성화되었어요</string>\n    <string name=\"msg_permission_grant\">Bunny Manager가 정상적으로 작동하려면, 파일 권한을 부여해 주셔야 해요. 공유된 데이터가 ~/Bunny에 저장되기 때문에, Manager가 작동하려면 권한이 필요해요.</string>\n    <string name=\"msg_shizuku_denied\">Shizuku 권한을 얻지 못했어요.</string>\n    <string name=\"msg_change_mirror\">미러 버전을 다운로드해서 다시 시도할까요?</string>\n    <string name=\"msg_invalid_apk\">APK가 손상되었습니다. 캐시를 지운 후 다시 설치해 보세요.</string>\n    <string name=\"msg_download_cancelled\">다운로드 중단</string>\n    <string name=\"msg_download_failed\">다운로드 실패</string>\n    <string name=\"msg_download_verify_failed\">다운로드한 파일을 검증할 수 없어요. 자세한 내용은 로그를 확인하세요.</string>\n    <string name=\"msg_copied\">클립보드에 복사됨.</string>\n    <string name=\"group_download\">APK 다운로드</string>\n    <string name=\"group_patch\">패치 중</string>\n    <string name=\"group_installing\">설치 중</string>\n    <string name=\"step_dl_base\">기본 APK 다운로드 중</string>\n    <string name=\"step_dl_lib\">라이브러리 APK 다운로드 중</string>\n    <string name=\"step_dl_lang\">언어 APK 다운로드 중</string>\n    <string name=\"step_dl_res\">리소스 APK 다운로드 중</string>\n    <string name=\"step_dl_vd\">Bunny 모듈 다운로드 중</string>\n    <string name=\"step_change_icon\">앱 아이콘 변경 중</string>\n    <string name=\"step_patch_manifests\">앱 manifests 패치 중</string>\n    <string name=\"step_add_vd\">Bunny 인젝팅 중</string>\n    <string name=\"step_signing\">APK 서명 중</string>\n    <string name=\"step_installing\">APK 설치 중</string>\n    <string name=\"installer_success\">설치가 완료되었어요</string>\n    <string name=\"installer_aborted\">설치가 취소되었어요</string>\n    <string name=\"install_fail_generic\">알 수 없는 이유로 설치에 실패했어요</string>\n    <string name=\"install_fail_blocked\">설치가 차단되었어요</string>\n    <string name=\"install_fail_invalid\">하나 이상의 APK가 잘못되었거나 손상되었어요</string>\n    <string name=\"install_fail_conflict\">기존 앱과 충돌이 일어났어요. 주로 서명이 일치하지 않아서 발생해요.</string>\n    <string name=\"install_fail_storage\">설치 가능한 저장 공간이 부족해요</string>\n    <string name=\"install_fail_incompatible\">앱이 이 기기와 호환되지 않아요</string>\n    <string name=\"install_fail_timeout\">설치 시간이 초과되었어요</string>\n    <string name=\"status_ongoing\">진행 중</string>\n    <string name=\"status_successful\">성공</string>\n    <string name=\"status_fail\">실패</string>\n    <string name=\"status_queued\">대기 중</string>\n    <string name=\"action_collapse\">접기</string>\n    <string name=\"action_expand\">펼치기</string>\n    <string name=\"action_back\">돌아가기</string>\n    <string name=\"action_copy_logs\">로그 복사</string>\n    <string name=\"action_clear_cache\">캐시 비우기</string>\n    <string name=\"action_confirm\">확인</string>\n    <string name=\"action_start_update\">업데이트 시작하기</string>\n    <string name=\"action_install\">설치</string>\n    <string name=\"action_update\">업데이트</string>\n    <string name=\"action_reinstall\">재설치</string>\n    <string name=\"action_launch\">실행</string>\n    <string name=\"action_uninstall\">삭제</string>\n    <string name=\"action_info\">정보</string>\n    <string name=\"action_retry\">재시도</string>\n    <string name=\"action_reload\">새로고침</string>\n    <string name=\"action_open_about\">정보 보기</string>\n    <string name=\"action_open_settings\">설정 열기</string>\n    <string name=\"action_tap_to_install\">Discord %1$s의 Bunny를 설치하려면 누르세요</string>\n    <string name=\"action_confirm_exit\">그래도 종료하기</string>\n    <string name=\"action_dismiss_nevermind\">괜찮아요</string>\n    <string name=\"action_dismiss_no_thanks\">괜찮아요</string>\n    <string name=\"action_try_again\">다시 시도</string>\n    <string name=\"action_previous_theme\">이전 테마 보기</string>\n    <string name=\"action_next_theme\">다음 테마 보기</string>\n    <string name=\"action_view_logs\">로그 보기</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">로그 복사</string>\n    <string name=\"action_save_logs\">파일에 로그 저장</string>\n    <string name=\"action_share_logs\">로그 공유</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">완료되기 전 설치기를 벗어나면 다운로드한 파일이 손상될 수 있어요. 그래도 계속할까요?</string>\n    <string name=\"installer_cached\">캐시됨</string>\n    <string name=\"title_installer\">설치하기</string>\n    <string name=\"title_home\">홈</string>\n    <string name=\"title_settings\">설정</string>\n    <string name=\"title_update\">업데이트 가능!</string>\n    <string name=\"title_about\">정보</string>\n    <string name=\"title_permission_grant\">권한 부여</string>\n    <string name=\"title_update_available\">새 Discord 업데이트가 있어요!</string>\n    <string name=\"title_warning\">경고</string>\n    <string name=\"title_dl_failed\">다운로드 실패</string>\n    <string name=\"title_logs\">로그</string>\n    <string name=\"title_os_libraries\">오픈 소스 라이브러리</string>\n    <string name=\"title_libraries\">라이브러리</string>\n    <string name=\"theme_system\">시스템</string>\n    <string name=\"theme_light\">라이트 모드</string>\n    <string name=\"theme_dark\">다크 모드</string>\n    <string name=\"duration_disabled\">사용 안 함</string>\n    <string name=\"duration_fifteen_min\">15분마다</string>\n    <string name=\"duration_half_hour\">30분마다</string>\n    <string name=\"duration_hourly\">1시간마다</string>\n    <string name=\"duration_bihourly\">2시간마다</string>\n    <string name=\"duration_twice_daily\">2일마다</string>\n    <string name=\"duration_daily\">1일마다</string>\n    <string name=\"duration_weekly\">7일마다</string>\n    <string name=\"settings_appearance\">외관</string>\n    <string name=\"settings_appearance_description\">앱의 외형과 분위기를 변경합니다.</string>\n    <string name=\"settings_dynamic_color\">동적 색상</string>\n    <string name=\"settings_dynamic_color_description\">안드로이드 12 버전 이상에서만 사용 가능해요</string>\n    <string name=\"settings_theme\">테마</string>\n    <string name=\"settings_check_updates\">Discord 업데이트 확인</string>\n    <string name=\"settings_customization\">사용자 지정</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">앱 이름</string>\n    <string name=\"settings_app_icon\">앱 아이콘 변경</string>\n    <string name=\"settings_app_icon_description\">Discord 아이콘 대신 Bunny 아이콘을 사용해요</string>\n    <string name=\"settings_advanced\">고급</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">릴리스 채널</string>\n    <string name=\"settings_mirror\">미러 버전 다운로드</string>\n    <string name=\"settings_auto_clear_cache\">자동으로 캐시 비우기</string>\n    <string name=\"settings_auto_clear_cache_description\">Discord 업데이트가 있을 경우 자동으로 캐시를 비워요</string>\n    <string name=\"settings_developer\">개발자 전용</string>\n    <string name=\"settings_developer_description\">이러한 설정을 잘못 사용하면 문제가 발생할 수 있어요.</string>\n    <string name=\"settings_module_location\">모듈 위치</string>\n    <string name=\"settings_module_location_description\">Xposed 모듈를 사용하여 개발하는 경우 조심하세요</string>\n    <string name=\"settings_module_location_reset\">모듈 위치 초기화</string>\n    <string name=\"settings_package_name\">패키지 이름</string>\n    <string name=\"settings_version\">Discord 버전</string>\n    <string name=\"settings_debuggable\">디버그 가능</string>\n    <string name=\"settings_debuggable_description\">디버그 가능 플래그를 사용해요</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">지금 Bunny Manager 버전 %1$s이 사용 가능해요!</string>\n    <string name=\"channel_stable\">안정화 버전</string>\n    <string name=\"channel_beta\">베타 버전</string>\n    <string name=\"channel_alpha\">알파 버전</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">팀</string>\n    <string name=\"label_special_thanks\">도움 주신 분들</string>\n    <string name=\"label_translate\">번역</string>\n    <string name=\"version_latest\">최신 버전: %1$s</string>\n    <string name=\"version_target\">대상 버전: %1$s</string>\n    <string name=\"version_current\">현재 버전: %1$s</string>\n    <string name=\"install_method\">설치 방법</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-nl-rNL/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cache succesvol geleegd</string>\n    <string name=\"msg_load_fail\">Kan commits niet laden</string>\n    <string name=\"msg_coming_soon\">Binnenkort beschikbaar</string>\n    <string name=\"msg_invalid_version\">Ongeldige Discord-versie</string>\n    <string name=\"msg_seven_left\">Nog 7 tikken</string>\n    <string name=\"msg_five_left\">Nog 5 tikken</string>\n    <string name=\"msg_two_left\">Nog 2 tikken</string>\n    <string name=\"msg_loading\">Bezig met laden…</string>\n    <string name=\"msg_downgrade_disallowed\">Kan niet downgraden, probeer eerst te verwijderen</string>\n    <string name=\"msg_unlocked\">Je bent nu een ontwikkelaar</string>\n    <string name=\"msg_permission_grant\">Om Bunny Manager te laten werken, zijn bestandsrechten vereist. Aangezien gedeelde gegevens worden opgeslagen in ~/Bunny, zijn machtigingen vereist om er toegang toe te krijgen.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Download APKs</string>\n    <string name=\"group_patch\">Patchen</string>\n    <string name=\"group_installing\">Installeren</string>\n    <string name=\"step_dl_base\">Basis-APK downloaden</string>\n    <string name=\"step_dl_lib\">Bibliotheken-APK downloaden</string>\n    <string name=\"step_dl_lang\">Taal-APK downloaden</string>\n    <string name=\"step_dl_res\">Resources-APK downloaden</string>\n    <string name=\"step_dl_vd\">Bunny-module downloaden</string>\n    <string name=\"step_change_icon\">App-pictogram veranderen</string>\n    <string name=\"step_patch_manifests\">App-manifesten patchen</string>\n    <string name=\"step_add_vd\">Bunny injecteren</string>\n    <string name=\"step_signing\">APK\\'s ondertekenen</string>\n    <string name=\"step_installing\">APK\\'s installeren</string>\n    <string name=\"installer_success\">Succesvol geïnstalleerd</string>\n    <string name=\"installer_aborted\">Installatie geannuleerd</string>\n    <string name=\"install_fail_generic\">Kan niet installeren: onbekende reden</string>\n    <string name=\"install_fail_blocked\">Installatie geblokkeerd</string>\n    <string name=\"install_fail_invalid\">Een of meer APK\\'s waren ongeldig of corrupt</string>\n    <string name=\"install_fail_conflict\">Conflict met een bestaande app, meestal door verkeerde ondertekeningen</string>\n    <string name=\"install_fail_storage\">Niet genoeg opslagruimte beschikbaar om te installeren</string>\n    <string name=\"install_fail_incompatible\">Applicatie is niet compatibel met dit apparaat</string>\n    <string name=\"install_fail_timeout\">Installatie time-out</string>\n    <string name=\"status_ongoing\">Lopende</string>\n    <string name=\"status_successful\">Succesvol</string>\n    <string name=\"status_fail\">Mislukt</string>\n    <string name=\"status_queued\">In wachtrij</string>\n    <string name=\"action_collapse\">Inklappen</string>\n    <string name=\"action_expand\">Uitklappen</string>\n    <string name=\"action_back\">Ga terug</string>\n    <string name=\"action_copy_logs\">Logs kopiëren</string>\n    <string name=\"action_clear_cache\">Cache wissen</string>\n    <string name=\"action_confirm\">Bevestigen</string>\n    <string name=\"action_start_update\">Update starten</string>\n    <string name=\"action_install\">Installeren</string>\n    <string name=\"action_update\">Updaten</string>\n    <string name=\"action_reinstall\">Opnieuw installeren</string>\n    <string name=\"action_launch\">Starten</string>\n    <string name=\"action_uninstall\">Verwijder</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Opnieuw proberen</string>\n    <string name=\"action_reload\">Opnieuw laden</string>\n    <string name=\"action_open_about\">\\\"About\\\" openen</string>\n    <string name=\"action_open_settings\">Instellingen openen</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">Gecached</string>\n    <string name=\"title_installer\">Installateur</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Instellingen</string>\n    <string name=\"title_update\">Update beschikbaar!</string>\n    <string name=\"title_about\">Over</string>\n    <string name=\"title_permission_grant\">Toestemmingen verlenen</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Systeem</string>\n    <string name=\"theme_light\">Licht</string>\n    <string name=\"theme_dark\">Donker</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">Uiterlijk</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamische kleuren</string>\n    <string name=\"settings_dynamic_color_description\">Alleen beschikbaar op Android 12 en hoger</string>\n    <string name=\"settings_theme\">Thema</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">App naam</string>\n    <string name=\"settings_app_icon\">App-pictogram vervangen</string>\n    <string name=\"settings_app_icon_description\">Gebruik het Bunny pictogram in plaats van Discord\\'s</string>\n    <string name=\"settings_advanced\">Geavanceerd</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Releasekanaal</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">Alleen voor ontwikkelaars</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Pakketnaam</string>\n    <string name=\"settings_version\">Discord-versie</string>\n    <string name=\"settings_debuggable\">Foutopspoorbaar</string>\n    <string name=\"settings_debuggable_description\">Foutopspoorbaar-vlag inschakelen</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager versie %1$s is nu beschikbaar!</string>\n    <string name=\"channel_stable\">Stabiel</string>\n    <string name=\"channel_beta\">Bèta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Bijzondere dank aan:</string>\n    <string name=\"label_translate\">Vertalen</string>\n    <string name=\"version_latest\">Nieuwste: %1$s</string>\n    <string name=\"version_target\">Doel: %1$s</string>\n    <string name=\"version_current\">Huidig: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-no-rNO/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Hurtigminnet tømt</string>\n    <string name=\"msg_load_fail\">Failed to load commits</string>\n    <string name=\"msg_coming_soon\">Kommer snart</string>\n    <string name=\"msg_invalid_version\">Ugyldig Discord-versjon</string>\n    <string name=\"msg_seven_left\">7 flere trykk</string>\n    <string name=\"msg_five_left\">5 flere trykk</string>\n    <string name=\"msg_two_left\">2 flere trykk</string>\n    <string name=\"msg_loading\">Laster…</string>\n    <string name=\"msg_downgrade_disallowed\">Kan ikke nedgradere, prøv å avinstallere først</string>\n    <string name=\"msg_unlocked\">Du er utvikler nå</string>\n    <string name=\"msg_permission_grant\">For at Bunny Manager skal fungere, er filtillatelser påkrevd. Siden delte data lagres i ~/Bunny, kreves tillatelser for å få tilgang til den.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Last ned APK</string>\n    <string name=\"group_patch\">Oppdaterer</string>\n    <string name=\"group_installing\">Installing</string>\n    <string name=\"step_dl_base\">Downloading base apk</string>\n    <string name=\"step_dl_lib\">Downloading libraries apk</string>\n    <string name=\"step_dl_lang\">Downloading language apk</string>\n    <string name=\"step_dl_res\">Downloading resources apk</string>\n    <string name=\"step_dl_vd\">Downloading Bunny module</string>\n    <string name=\"step_change_icon\">Changing app icon</string>\n    <string name=\"step_patch_manifests\">Patching app manifests</string>\n    <string name=\"step_add_vd\">Injecting Bunny</string>\n    <string name=\"step_signing\">Signing APKs</string>\n    <string name=\"step_installing\">Installing APKs</string>\n    <string name=\"installer_success\">Installed successfully</string>\n    <string name=\"installer_aborted\">Install canceled</string>\n    <string name=\"install_fail_generic\">Failed to install: Unknown reason</string>\n    <string name=\"install_fail_blocked\">Installation was blocked</string>\n    <string name=\"install_fail_invalid\">One or more APKs were invalid or corrupt</string>\n    <string name=\"install_fail_conflict\">Conflicts with an existing app, usually due to mismatched signatures</string>\n    <string name=\"install_fail_storage\">Not enough available storage to install</string>\n    <string name=\"install_fail_incompatible\">Application is incompatible with this device</string>\n    <string name=\"install_fail_timeout\">Installation timed out</string>\n    <string name=\"status_ongoing\">Ongoing</string>\n    <string name=\"status_successful\">Successful</string>\n    <string name=\"status_fail\">Failed</string>\n    <string name=\"status_queued\">Queued</string>\n    <string name=\"action_collapse\">Collapse</string>\n    <string name=\"action_expand\">Expand</string>\n    <string name=\"action_back\">Go back</string>\n    <string name=\"action_copy_logs\">Copy logs</string>\n    <string name=\"action_clear_cache\">Clear cache</string>\n    <string name=\"action_confirm\">Confirm</string>\n    <string name=\"action_start_update\">Start update</string>\n    <string name=\"action_install\">Install</string>\n    <string name=\"action_update\">Update</string>\n    <string name=\"action_reinstall\">Reinstall</string>\n    <string name=\"action_launch\">Launch</string>\n    <string name=\"action_uninstall\">Uninstall</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Retry</string>\n    <string name=\"action_reload\">Reload</string>\n    <string name=\"action_open_about\">Open about</string>\n    <string name=\"action_open_settings\">Open settings</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">Cached</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Settings</string>\n    <string name=\"title_update\">Update available!</string>\n    <string name=\"title_about\">About</string>\n    <string name=\"title_permission_grant\">Grant Permissions</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Light</string>\n    <string name=\"theme_dark\">Dark</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">Appearance</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamic color</string>\n    <string name=\"settings_dynamic_color_description\">Only available on Android 12 and up</string>\n    <string name=\"settings_theme\">Theme</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">App name</string>\n    <string name=\"settings_app_icon\">Replace app icon</string>\n    <string name=\"settings_app_icon_description\">Uses the Bunny icon instead of Discord\\'s</string>\n    <string name=\"settings_advanced\">Advanced</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Release channel</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">Developer only</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Package name</string>\n    <string name=\"settings_version\">Discord version</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Enable debuggable flag</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager version %1$s is now available!</string>\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Special thanks</string>\n    <string name=\"label_translate\">Translate</string>\n    <string name=\"version_latest\">Latest: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Current: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-or-rIN/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cache cleared successfully</string>\n    <string name=\"msg_load_fail\">Failed to load commits</string>\n    <string name=\"msg_coming_soon\">ଯଥାଶୀଘ୍ର ଆସୁଅଛି</string>\n    <string name=\"msg_invalid_version\">ଅଵୈଧ Discord ସଂସ୍କରଣ</string>\n    <string name=\"msg_seven_left\">ଆଉ ୭ଟି ଟ୍ୟାପ୍</string>\n    <string name=\"msg_five_left\">ଆଉ ୫ଟି ଟ୍ୟାପ୍</string>\n    <string name=\"msg_two_left\">ଆଉ ୨ଟି ଟ୍ୟାପ୍</string>\n    <string name=\"msg_loading\">Loading…</string>\n    <string name=\"msg_downgrade_disallowed\">Cannot downgrade, try uninstalling first</string>\n    <string name=\"msg_unlocked\">You are now a developer</string>\n    <string name=\"msg_permission_grant\">In order for Bunny Manager to function, file permissions are required. Since shared data is stored in ~/Bunny, permissions are required in order to access it.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Download APKs</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Installing</string>\n    <string name=\"step_dl_base\">Downloading base apk</string>\n    <string name=\"step_dl_lib\">Downloading libraries apk</string>\n    <string name=\"step_dl_lang\">Downloading language apk</string>\n    <string name=\"step_dl_res\">Downloading resources apk</string>\n    <string name=\"step_dl_vd\">Downloading Bunny module</string>\n    <string name=\"step_change_icon\">Changing app icon</string>\n    <string name=\"step_patch_manifests\">Patching app manifests</string>\n    <string name=\"step_add_vd\">Injecting Bunny</string>\n    <string name=\"step_signing\">Signing APKs</string>\n    <string name=\"step_installing\">Installing APKs</string>\n    <string name=\"installer_success\">Installed successfully</string>\n    <string name=\"installer_aborted\">Install canceled</string>\n    <string name=\"install_fail_generic\">Failed to install: Unknown reason</string>\n    <string name=\"install_fail_blocked\">Installation was blocked</string>\n    <string name=\"install_fail_invalid\">One or more APKs were invalid or corrupt</string>\n    <string name=\"install_fail_conflict\">Conflicts with an existing app, usually due to mismatched signatures</string>\n    <string name=\"install_fail_storage\">Not enough available storage to install</string>\n    <string name=\"install_fail_incompatible\">Application is incompatible with this device</string>\n    <string name=\"install_fail_timeout\">Installation timed out</string>\n    <string name=\"status_ongoing\">Ongoing</string>\n    <string name=\"status_successful\">Successful</string>\n    <string name=\"status_fail\">Failed</string>\n    <string name=\"status_queued\">Queued</string>\n    <string name=\"action_collapse\">Collapse</string>\n    <string name=\"action_expand\">Expand</string>\n    <string name=\"action_back\">Go back</string>\n    <string name=\"action_copy_logs\">Copy logs</string>\n    <string name=\"action_clear_cache\">Clear cache</string>\n    <string name=\"action_confirm\">Confirm</string>\n    <string name=\"action_start_update\">Start update</string>\n    <string name=\"action_install\">Install</string>\n    <string name=\"action_update\">Update</string>\n    <string name=\"action_reinstall\">Reinstall</string>\n    <string name=\"action_launch\">Launch</string>\n    <string name=\"action_uninstall\">Uninstall</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Retry</string>\n    <string name=\"action_reload\">Reload</string>\n    <string name=\"action_open_about\">Open about</string>\n    <string name=\"action_open_settings\">Open settings</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">Cached</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Settings</string>\n    <string name=\"title_update\">Update available!</string>\n    <string name=\"title_about\">About</string>\n    <string name=\"title_permission_grant\">Grant Permissions</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Light</string>\n    <string name=\"theme_dark\">Dark</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">Appearance</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamic color</string>\n    <string name=\"settings_dynamic_color_description\">Only available on Android 12 and up</string>\n    <string name=\"settings_theme\">Theme</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">ଆପ୍ ନାମ</string>\n    <string name=\"settings_app_icon\">Replace app icon</string>\n    <string name=\"settings_app_icon_description\">Uses the Bunny icon instead of Discord\\'s</string>\n    <string name=\"settings_advanced\">Advanced</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Release channel</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">କେଵଳ ଵିକାଶକ</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Package name</string>\n    <string name=\"settings_version\">Discord version</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Enable debuggable flag</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager version %1$s is now available!</string>\n    <string name=\"channel_stable\">ସ୍ଥିର</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">ଦଳ</string>\n    <string name=\"label_special_thanks\">ଵିଶେଷ ଧନ୍ୟଵାଦ</string>\n    <string name=\"label_translate\">ଅନୁଵାଦ କରନ୍ତୁ</string>\n    <string name=\"version_latest\">ସଦ୍ୟତମ: %1$s</string>\n    <string name=\"version_target\">ଲକ୍ଷ୍ୟ: %1$s</string>\n    <string name=\"version_current\">ଚଳିତ: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-pl-rPL/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Menedżer Bunny</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Pamięć podręczna pomyślnie wyczyszczona</string>\n    <string name=\"msg_load_fail\">Nie udało się załadować commitów</string>\n    <string name=\"msg_coming_soon\">Już niedługo</string>\n    <string name=\"msg_invalid_version\">Nieprawidłowa wersja Discorda</string>\n    <string name=\"msg_seven_left\">Jeszcze 7 kliknięć</string>\n    <string name=\"msg_five_left\">Jeszcze 5 kliknięć</string>\n    <string name=\"msg_two_left\">Jeszcze 2 kliknięcia</string>\n    <string name=\"msg_loading\">Ładowanie…</string>\n    <string name=\"msg_downgrade_disallowed\">Nie można zainstalować starszej wersji, spróbuj najpierw odinstalować aktualnie zainstalowaną</string>\n    <string name=\"msg_unlocked\">Jesteś teraz deweloperem</string>\n    <string name=\"msg_permission_grant\">Aby Menadżer Bunny działał, wymagane są uprawnienia do plików. Ponieważ udostępnione dane są przechowywane w ~/Bunny, dostęp do nich wymaga uprawnień.</string>\n    <string name=\"msg_shizuku_denied\">Nie udało się uzyskać uprawnień Shizuku</string>\n    <string name=\"msg_change_mirror\">Czy chcesz spróbować ponownie, używając serwera lustrzanego pobierania?</string>\n    <string name=\"msg_invalid_apk\">Plik APK został uszkodzony, spróbuj wyczyścić pamięć podręczną i ponownie zainstalować Bunny</string>\n    <string name=\"msg_download_cancelled\">Pobieranie zostało przerwane</string>\n    <string name=\"msg_download_failed\">Pobieranie nieudane</string>\n    <string name=\"msg_download_verify_failed\">Nie można zweryfikować pobranego pliku, sprawdź logi po więcej szczegółów</string>\n    <string name=\"msg_copied\">Skopiowane do schowka</string>\n    <string name=\"group_download\">Pobieranie plików APK</string>\n    <string name=\"group_patch\">Łatanie</string>\n    <string name=\"group_installing\">Instalowanie</string>\n    <string name=\"step_dl_base\">Pobieranie base apk</string>\n    <string name=\"step_dl_lib\">Pobieranie libraries apk</string>\n    <string name=\"step_dl_lang\">Pobieranie language apk</string>\n    <string name=\"step_dl_res\">Pobieranie resources apk</string>\n    <string name=\"step_dl_vd\">Pobieranie modułu Bunny</string>\n    <string name=\"step_change_icon\">Zmienianie ikony aplikacji</string>\n    <string name=\"step_patch_manifests\">Patchowanie manifestów aplikacji</string>\n    <string name=\"step_add_vd\">Wgrywanie Bunny</string>\n    <string name=\"step_signing\">Podpisywanie plików APK</string>\n    <string name=\"step_installing\">Instalowanie plików APK</string>\n    <string name=\"installer_success\">Pomyślnie zainstalowano</string>\n    <string name=\"installer_aborted\">Instalacja przerwana</string>\n    <string name=\"install_fail_generic\">Błąd przy instalacji: nieznany powód</string>\n    <string name=\"install_fail_blocked\">Instalacja została zablokowana</string>\n    <string name=\"install_fail_invalid\">Co najmniej jeden lub więcej plików APK są nieprawidłowe lub uszkodzone</string>\n    <string name=\"install_fail_conflict\">Konflikty z istniejącą aplikacją, zazwyczaj z powodu niedopasowanych podpisów</string>\n    <string name=\"install_fail_storage\">Brak dostępnej pamięci do zainstalowania</string>\n    <string name=\"install_fail_incompatible\">Aplikacja jest niekompatybilna z tym urządzeniem</string>\n    <string name=\"install_fail_timeout\">Upłynął limit czasu instalacji</string>\n    <string name=\"status_ongoing\">W toku</string>\n    <string name=\"status_successful\">Sukces</string>\n    <string name=\"status_fail\">Niepowodzenie</string>\n    <string name=\"status_queued\">W kolejce</string>\n    <string name=\"action_collapse\">Zwiń</string>\n    <string name=\"action_expand\">Rozwiń</string>\n    <string name=\"action_back\">Powrót</string>\n    <string name=\"action_copy_logs\">Kopiuj logi</string>\n    <string name=\"action_clear_cache\">Wyczyść pamięć podręczną</string>\n    <string name=\"action_confirm\">Potwierdź</string>\n    <string name=\"action_start_update\">Rozpocznij aktualizację</string>\n    <string name=\"action_install\">Zainstaluj</string>\n    <string name=\"action_update\">Aktualizuj</string>\n    <string name=\"action_reinstall\">Reinstaluj</string>\n    <string name=\"action_launch\">Uruchom</string>\n    <string name=\"action_uninstall\">Odinstaluj</string>\n    <string name=\"action_info\">Informacje</string>\n    <string name=\"action_retry\">Ponów</string>\n    <string name=\"action_reload\">Odśwież</string>\n    <string name=\"action_open_about\">Otwórz o aplikacji</string>\n    <string name=\"action_open_settings\">Otwórz ustawienia</string>\n    <string name=\"action_tap_to_install\">Dotknij, aby zainstalować Bunny dla Discorda %1$s</string>\n    <string name=\"action_confirm_exit\">Wyjdź mimo to</string>\n    <string name=\"action_dismiss_nevermind\">Nieważne</string>\n    <string name=\"action_dismiss_no_thanks\">Nie, dziękuję</string>\n    <string name=\"action_try_again\">Spróbuj ponownie</string>\n    <string name=\"action_previous_theme\">Zobacz poprzedni motyw</string>\n    <string name=\"action_next_theme\">Zobacz następny motyw</string>\n    <string name=\"action_view_logs\">Pokaż logi</string>\n    <string name=\"action_show_timestamp\">Pokaż znacznik czasu</string>\n    <string name=\"action_copy_log\">Kopiuj logi</string>\n    <string name=\"action_save_logs\">Zapisz logi do pliku</string>\n    <string name=\"action_share_logs\">Udostępnij logi</string>\n    <string name=\"action_more_options\">Więcej opcji</string>\n    <string name=\"msg_back_warning\">Wyjście z instalatora przed zakończeniem instalacji może uszkodzić pobierane pliki, czy na pewno chcesz to zrobić?</string>\n    <string name=\"installer_cached\">w pamięci podręcznej</string>\n    <string name=\"title_installer\">Instalator</string>\n    <string name=\"title_home\">Strona główna</string>\n    <string name=\"title_settings\">Ustawienia</string>\n    <string name=\"title_update\">Dostępna aktualizacja!</string>\n    <string name=\"title_about\">O Aplikacji</string>\n    <string name=\"title_permission_grant\">Przyznaj uprawnienia</string>\n    <string name=\"title_update_available\">Dostępna jest nowa aktualizacja Discorda!</string>\n    <string name=\"title_warning\">Ostrzeżenie</string>\n    <string name=\"title_dl_failed\">Pobieranie nieudane</string>\n    <string name=\"title_logs\">Logi</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Jasny</string>\n    <string name=\"theme_dark\">Ciemny</string>\n    <string name=\"duration_disabled\">Wyłączony</string>\n    <string name=\"duration_fifteen_min\">Co kwartał</string>\n    <string name=\"duration_half_hour\">Półgodzinny</string>\n    <string name=\"duration_hourly\">Raz na godzinę</string>\n    <string name=\"duration_bihourly\">Co dwie godziny</string>\n    <string name=\"duration_twice_daily\">Dwa razy dziennie</string>\n    <string name=\"duration_daily\">Raz dziennie</string>\n    <string name=\"duration_weekly\">Raz w tygodniu</string>\n    <string name=\"settings_appearance\">Wygląd</string>\n    <string name=\"settings_appearance_description\">Zmień wygląd i styl aplikacji</string>\n    <string name=\"settings_dynamic_color\">Dynamiczny kolor</string>\n    <string name=\"settings_dynamic_color_description\">Dostępne tylko na Androidzie 12 i nowszym</string>\n    <string name=\"settings_theme\">Motyw</string>\n    <string name=\"settings_check_updates\">Sprawdź dostępność aktualizacji Discorda</string>\n    <string name=\"settings_customization\">Personalizacja</string>\n    <string name=\"settings_customization_description\">Dostosuj instalację Bunny</string>\n    <string name=\"settings_app_name\">Nazwa aplikacji</string>\n    <string name=\"settings_app_icon\">Zastąp ikonę aplikacji</string>\n    <string name=\"settings_app_icon_description\">Używa ikony Bunny zamiast Discorda</string>\n    <string name=\"settings_advanced\">Zaawansowane</string>\n    <string name=\"settings_advanced_description\">Modyfikuj pobieranie i instalację</string>\n    <string name=\"settings_channel\">Kanał wydania</string>\n    <string name=\"settings_mirror\">Serwer lustrzany pobierania</string>\n    <string name=\"settings_auto_clear_cache\">Automatycznie czyść pamięć podręczną</string>\n    <string name=\"settings_auto_clear_cache_description\">Czyści pamięć podręczną, kiedy Discord otrzymuje aktualizację</string>\n    <string name=\"settings_developer\">Tylko dla deweloperów</string>\n    <string name=\"settings_developer_description\">Te ustawienia mogą zaszkodzić, jeśli używane są nieprawidłowo</string>\n    <string name=\"settings_module_location\">Lokalizacja modułów</string>\n    <string name=\"settings_module_location_description\">Do użycia przy tworzeniu modułu Xposed. BĄDŹ OSTROŻNY</string>\n    <string name=\"settings_module_location_reset\">Zresetuj lokalizację modułu</string>\n    <string name=\"settings_package_name\">Nazwa pakietu</string>\n    <string name=\"settings_version\">Wersja Discorda</string>\n    <string name=\"settings_debuggable\">Debugowalne</string>\n    <string name=\"settings_debuggable_description\">Włącz flagę debugowania</string>\n    <string name=\"settings_logs_alternate_lines\">Alternatywne linie</string>\n    <string name=\"settings_logs_line_wrap\">Zawijaj wiersze</string>\n    <string name=\"update_description\">Menadżer Bunny w wersji %1$s jest teraz dostępny!</string>\n    <string name=\"channel_stable\">Stabilna</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Zespół</string>\n    <string name=\"label_special_thanks\">Specjalne podziękowania</string>\n    <string name=\"label_translate\">Przetłumacz</string>\n    <string name=\"version_latest\">Najnowsza: %1$s</string>\n    <string name=\"version_target\">Docelowa: %1$s</string>\n    <string name=\"version_current\">Zainstalowana: %1$s</string>\n    <string name=\"install_method\">Metoda instalacji</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-pt-rBR/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Autor: %1$s</string>\n    <string name=\"cd_library_license\">Licença: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cache limpo com êxito</string>\n    <string name=\"msg_load_fail\">Falha ao carregar commits</string>\n    <string name=\"msg_coming_soon\">Disponível em breve</string>\n    <string name=\"msg_invalid_version\">Versão inválida do Discord</string>\n    <string name=\"msg_seven_left\">Mais 7 toques</string>\n    <string name=\"msg_five_left\">Mais 5 toques</string>\n    <string name=\"msg_two_left\">Mais 2 toques</string>\n    <string name=\"msg_loading\">Carregando…</string>\n    <string name=\"msg_downgrade_disallowed\">Não é possível desatualizar, tente desinstalar primeiro</string>\n    <string name=\"msg_unlocked\">Você agora é um desenvolvedor</string>\n    <string name=\"msg_permission_grant\">Para o Gerenciador do Bunny funcionar corretamente, você precisa conceder as permissões de arquivos. Como os dados compartilhados são armazenados em ~/Bunny, as permissões são necessárias para acessa-los.</string>\n    <string name=\"msg_shizuku_denied\">Falha ao obter permissões Shizuku</string>\n    <string name=\"msg_change_mirror\">Gostaria de tentar novamente usando uma forma alternativa de download?</string>\n    <string name=\"msg_invalid_apk\">O APK estava corrompido, tente limpar o cache e reinstale-o</string>\n    <string name=\"msg_download_cancelled\">Download foi abortado</string>\n    <string name=\"msg_download_failed\">Falha no download</string>\n    <string name=\"msg_download_verify_failed\">Não foi possível verificar o arquivo baixado, verifique os logs para mais detalhes</string>\n    <string name=\"msg_copied\">Copiado para área de transferência</string>\n    <string name=\"group_download\">Baixar APKs</string>\n    <string name=\"group_patch\">Modificando</string>\n    <string name=\"group_installing\">Instalando</string>\n    <string name=\"step_dl_base\">Baixando apk base</string>\n    <string name=\"step_dl_lib\">Baixando bibliotecas apk</string>\n    <string name=\"step_dl_lang\">Baixando apk de idioma</string>\n    <string name=\"step_dl_res\">Baixando recursos de apk</string>\n    <string name=\"step_dl_vd\">Baixando módulo Bunny</string>\n    <string name=\"step_change_icon\">Alterando ícone do aplicativo</string>\n    <string name=\"step_patch_manifests\">Modificando manifestos do aplicativo</string>\n    <string name=\"step_add_vd\">Injetando Bunny</string>\n    <string name=\"step_signing\">Assinando APKs</string>\n    <string name=\"step_installing\">Instalando APKs</string>\n    <string name=\"installer_success\">Instalado com sucesso</string>\n    <string name=\"installer_aborted\">Instalação cancelada</string>\n    <string name=\"install_fail_generic\">Falha ao instalar: Razão desconhecida</string>\n    <string name=\"install_fail_blocked\">A instalação foi bloqueada</string>\n    <string name=\"install_fail_invalid\">Um ou mais APKs eram inválidos ou corrompidos</string>\n    <string name=\"install_fail_conflict\">Conflitos com um app existente, geralmente devido a assinaturas incompatíveis</string>\n    <string name=\"install_fail_storage\">Não há espaço disponível para instalar</string>\n    <string name=\"install_fail_incompatible\">O aplicativo é incompatível com esse dispositivo</string>\n    <string name=\"install_fail_timeout\">A instalação expirou</string>\n    <string name=\"status_ongoing\">Em andamento</string>\n    <string name=\"status_successful\">Concluído</string>\n    <string name=\"status_fail\">Falhou</string>\n    <string name=\"status_queued\">Na fila</string>\n    <string name=\"action_collapse\">Minimizar</string>\n    <string name=\"action_expand\">Expandir</string>\n    <string name=\"action_back\">Retornar</string>\n    <string name=\"action_copy_logs\">Copiar logs</string>\n    <string name=\"action_clear_cache\">Limpar cache</string>\n    <string name=\"action_confirm\">Confirmar</string>\n    <string name=\"action_start_update\">Iniciar atualização</string>\n    <string name=\"action_install\">Instalar</string>\n    <string name=\"action_update\">Atualizar</string>\n    <string name=\"action_reinstall\">Reinstalar</string>\n    <string name=\"action_launch\">Executar</string>\n    <string name=\"action_uninstall\">Desinstalar</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Repetir</string>\n    <string name=\"action_reload\">Recarregar</string>\n    <string name=\"action_open_about\">Abrir sobre</string>\n    <string name=\"action_open_settings\">Abrir as configurações</string>\n    <string name=\"action_tap_to_install\">Toque para instalar o Bunny para o Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Sair de qualquer jeito</string>\n    <string name=\"action_dismiss_nevermind\">Deixa para lá</string>\n    <string name=\"action_dismiss_no_thanks\">Não, obrigado</string>\n    <string name=\"action_try_again\">Tente novamente</string>\n    <string name=\"action_previous_theme\">Ver tema anterior</string>\n    <string name=\"action_next_theme\">Ver o próximo tema</string>\n    <string name=\"action_view_logs\">Ver logs</string>\n    <string name=\"action_show_timestamp\">Exibir marcações de tempo</string>\n    <string name=\"action_copy_log\">Copiar log</string>\n    <string name=\"action_save_logs\">Salvar logs como arquivo</string>\n    <string name=\"action_share_logs\">Compartilhar logs</string>\n    <string name=\"action_more_options\">Mais opções</string>\n    <string name=\"msg_back_warning\">Sair do instalador antes do seu término pode corromper os arquivos, você tem certeza que deseja fazer isso?</string>\n    <string name=\"installer_cached\">Em cache</string>\n    <string name=\"title_installer\">Instalador</string>\n    <string name=\"title_home\">Início</string>\n    <string name=\"title_settings\">Configurações</string>\n    <string name=\"title_update\">Atualização disponível!</string>\n    <string name=\"title_about\">Sobre</string>\n    <string name=\"title_permission_grant\">Conceder Permissões</string>\n    <string name=\"title_update_available\">Nova atualização do Discord disponível!</string>\n    <string name=\"title_warning\">Atenção</string>\n    <string name=\"title_dl_failed\">Falha no download</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Bibliotecas de código aberto</string>\n    <string name=\"title_libraries\">Bibliotecas</string>\n    <string name=\"theme_system\">Sistema</string>\n    <string name=\"theme_light\">Claro</string>\n    <string name=\"theme_dark\">Escuro</string>\n    <string name=\"duration_disabled\">Desativado</string>\n    <string name=\"duration_fifteen_min\">Trimestralmente</string>\n    <string name=\"duration_half_hour\">Meia hora</string>\n    <string name=\"duration_hourly\">A cada hora</string>\n    <string name=\"duration_bihourly\">A cada duas horas</string>\n    <string name=\"duration_twice_daily\">Duas vezes ao dia</string>\n    <string name=\"duration_daily\">Diaramente</string>\n    <string name=\"duration_weekly\">Semanalmente</string>\n    <string name=\"settings_appearance\">Aparência</string>\n    <string name=\"settings_appearance_description\">Altere a aparência do aplicativo</string>\n    <string name=\"settings_dynamic_color\">Cor dinâmica</string>\n    <string name=\"settings_dynamic_color_description\">Disponível somente no Android 12 ou superior</string>\n    <string name=\"settings_theme\">Tema</string>\n    <string name=\"settings_check_updates\">Verificar se há atualizações do Discord</string>\n    <string name=\"settings_customization\">Customização</string>\n    <string name=\"settings_customization_description\">Personalize sua instalação do Bunny</string>\n    <string name=\"settings_app_name\">Nome do aplicativo</string>\n    <string name=\"settings_app_icon\">Mudar ícone do aplicativo</string>\n    <string name=\"settings_app_icon_description\">Usa o ícone do Bunny ao invés do Discord</string>\n    <string name=\"settings_advanced\">Avançado</string>\n    <string name=\"settings_advanced_description\">Modificar download e instalação</string>\n    <string name=\"settings_channel\">Canal de lançamento</string>\n    <string name=\"settings_mirror\">Download alternativo</string>\n    <string name=\"settings_auto_clear_cache\">Limpar cache automaticamente</string>\n    <string name=\"settings_auto_clear_cache_description\">Limpa o cache quando o Discord receber uma atualização</string>\n    <string name=\"settings_developer\">Somente para Desenvolvedores</string>\n    <string name=\"settings_developer_description\">Estas configurações podem quebrar coisas se forem usadas incorretamente</string>\n    <string name=\"settings_module_location\">Localização do módulo</string>\n    <string name=\"settings_module_location_description\">Para uso com o desenvolvimento do módulo Xposed. TOME CUIDADO</string>\n    <string name=\"settings_module_location_reset\">Redefinir local do módulo</string>\n    <string name=\"settings_package_name\">Nome do pacote</string>\n    <string name=\"settings_version\">Versão do Discord</string>\n    <string name=\"settings_debuggable\">Depurável</string>\n    <string name=\"settings_debuggable_description\">Habilitar modo de depuração</string>\n    <string name=\"settings_logs_alternate_lines\">Linhas alternativas</string>\n    <string name=\"settings_logs_line_wrap\">Quebra automática de linha</string>\n    <string name=\"update_description\">A versão %1$s do Bunny Manager já está disponível!</string>\n    <string name=\"channel_stable\">Estável</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alfa</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Nossa Equipe</string>\n    <string name=\"label_special_thanks\">Agradecimentos especiais</string>\n    <string name=\"label_translate\">Traduzir</string>\n    <string name=\"version_latest\">Mais recente: %1$s</string>\n    <string name=\"version_target\">Alvo: %1$s</string>\n    <string name=\"version_current\">Atual: %1$s</string>\n    <string name=\"install_method\">Método de instalação</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-pt-rPT/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\"></string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\"></string>\n    <string name=\"msg_load_fail\">Failed to load commits</string>\n    <string name=\"msg_coming_soon\">Coming soon</string>\n    <string name=\"msg_invalid_version\">Invalid Discord version</string>\n    <string name=\"msg_seven_left\">7 more taps</string>\n    <string name=\"msg_five_left\">5 more taps</string>\n    <string name=\"msg_two_left\">2 more taps</string>\n    <string name=\"msg_loading\">Loading…</string>\n    <string name=\"msg_downgrade_disallowed\">Cannot downgrade, try uninstalling first</string>\n    <string name=\"msg_unlocked\">You are now a developer</string>\n    <string name=\"msg_permission_grant\">In order for Bunny Manager to function, file permissions are required. Since shared data is stored in ~/Bunny, permissions are required in order to access it.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Download APKs</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Installing</string>\n    <string name=\"step_dl_base\">Downloading base apk</string>\n    <string name=\"step_dl_lib\">Downloading libraries apk</string>\n    <string name=\"step_dl_lang\">Downloading language apk</string>\n    <string name=\"step_dl_res\">Downloading resources apk</string>\n    <string name=\"step_dl_vd\">Downloading Bunny module</string>\n    <string name=\"step_change_icon\">Changing app icon</string>\n    <string name=\"step_patch_manifests\">Patching app manifests</string>\n    <string name=\"step_add_vd\">Injecting Bunny</string>\n    <string name=\"step_signing\">Signing APKs</string>\n    <string name=\"step_installing\">Installing APKs</string>\n    <string name=\"installer_success\">Installed successfully</string>\n    <string name=\"installer_aborted\">Install canceled</string>\n    <string name=\"install_fail_generic\">Failed to install: Unknown reason</string>\n    <string name=\"install_fail_blocked\">Installation was blocked</string>\n    <string name=\"install_fail_invalid\">One or more APKs were invalid or corrupt</string>\n    <string name=\"install_fail_conflict\">Conflicts with an existing app, usually due to mismatched signatures</string>\n    <string name=\"install_fail_storage\">Not enough available storage to install</string>\n    <string name=\"install_fail_incompatible\">Application is incompatible with this device</string>\n    <string name=\"install_fail_timeout\">Installation timed out</string>\n    <string name=\"status_ongoing\">Ongoing</string>\n    <string name=\"status_successful\">Successful</string>\n    <string name=\"status_fail\">Failed</string>\n    <string name=\"status_queued\">Queued</string>\n    <string name=\"action_collapse\">Collapse</string>\n    <string name=\"action_expand\">Expand</string>\n    <string name=\"action_back\">Go back</string>\n    <string name=\"action_copy_logs\">Copy logs</string>\n    <string name=\"action_clear_cache\">Clear cache</string>\n    <string name=\"action_confirm\">Confirm</string>\n    <string name=\"action_start_update\">Start update</string>\n    <string name=\"action_install\">Install</string>\n    <string name=\"action_update\">Update</string>\n    <string name=\"action_reinstall\">Reinstall</string>\n    <string name=\"action_launch\">Launch</string>\n    <string name=\"action_uninstall\">Uninstall</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Retry</string>\n    <string name=\"action_reload\">Reload</string>\n    <string name=\"action_open_about\">Open about</string>\n    <string name=\"action_open_settings\">Open settings</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">Cached</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Settings</string>\n    <string name=\"title_update\">Update available!</string>\n    <string name=\"title_about\">About</string>\n    <string name=\"title_permission_grant\">Grant Permissions</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Light</string>\n    <string name=\"theme_dark\">Dark</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">Appearance</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamic color</string>\n    <string name=\"settings_dynamic_color_description\">Only available on Android 12 and up</string>\n    <string name=\"settings_theme\">Theme</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">App name</string>\n    <string name=\"settings_app_icon\">Replace app icon</string>\n    <string name=\"settings_app_icon_description\">Uses the Bunny icon instead of Discord\\'s</string>\n    <string name=\"settings_advanced\">Advanced</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Release channel</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">Developer only</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Package name</string>\n    <string name=\"settings_version\">Discord version</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Enable debuggable flag</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager version %1$s is now available!</string>\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Special thanks</string>\n    <string name=\"label_translate\">Translate</string>\n    <string name=\"version_latest\">Latest: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Current: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-ro-rRO/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Managerul Bunny</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Memoria cache a fost golita</string>\n    <string name=\"msg_load_fail\">Încărcarea setărilor eșuată</string>\n    <string name=\"msg_coming_soon\">În curând</string>\n    <string name=\"msg_invalid_version\">Versiune filtru nevalidă</string>\n    <string name=\"msg_seven_left\">încă 7 atingeri</string>\n    <string name=\"msg_five_left\">Încă 5 atingeri</string>\n    <string name=\"msg_two_left\">încă 2 atingeri</string>\n    <string name=\"msg_loading\">Încărcare…</string>\n    <string name=\"msg_downgrade_disallowed\">Imposibil de retrogradat, încercați să dezinstalați mai întâi</string>\n    <string name=\"msg_unlocked\">Ați devenit dezvoltator</string>\n    <string name=\"msg_permission_grant\">Pentru ca Bunny Manager să funcţioneze, sunt necesare permisiunile fişierelor. Deoarece datele partajate sunt stocate în ~/Bunny, sunt necesare permisiuni pentru a le accesa.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Descarcaţi fișier APK</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Se instalează</string>\n    <string name=\"step_dl_base\">Descărcarea apk-ului de bază</string>\n    <string name=\"step_dl_lib\">Se descarcă biblioteca %s</string>\n    <string name=\"step_dl_lang\">Se descarcă limba</string>\n    <string name=\"step_dl_res\">Se descarcă biblioteca %s</string>\n    <string name=\"step_dl_vd\">Se descarca modulul Bunny</string>\n    <string name=\"step_change_icon\">Schimbați pictograma aplicației</string>\n    <string name=\"step_patch_manifests\">Patcheaza manifestele aplicatiei</string>\n    <string name=\"step_add_vd\">Injectarea Bunny</string>\n    <string name=\"step_signing\">Semnare APK</string>\n    <string name=\"step_installing\">Se instalează APK</string>\n    <string name=\"installer_success\">Instalat cu succes</string>\n    <string name=\"installer_aborted\">Instalarea a fost anulată</string>\n    <string name=\"install_fail_generic\">Instalarea a eșuat: motiv necunoscut</string>\n    <string name=\"install_fail_blocked\">Instalarea a fost blocată</string>\n    <string name=\"install_fail_invalid\">Unul sau mai multe APK-uri au fost invalide sau corupte</string>\n    <string name=\"install_fail_conflict\">Conflicte cu o aplicație existentă, de obicei din cauza semnăturilor necorespunzătoare</string>\n    <string name=\"install_fail_storage\">Nu este suficient spațiu de stocare disponibil pentru instalare</string>\n    <string name=\"install_fail_incompatible\">Aplicația este incompatibilă cu acest dispozitiv</string>\n    <string name=\"install_fail_timeout\">Instalarea a expirat</string>\n    <string name=\"status_ongoing\">În desfășurare</string>\n    <string name=\"status_successful\">Succes</string>\n    <string name=\"status_fail\">Eșuat</string>\n    <string name=\"status_queued\">În așteptare</string>\n    <string name=\"action_collapse\">Restrânge</string>\n    <string name=\"action_expand\">Extinde</string>\n    <string name=\"action_back\">Mergi înapoi</string>\n    <string name=\"action_copy_logs\">Copiază jurnalele</string>\n    <string name=\"action_clear_cache\">Golește cache-ul</string>\n    <string name=\"action_confirm\">A confirma</string>\n    <string name=\"action_start_update\">Începe actualizarea</string>\n    <string name=\"action_install\">Instalare</string>\n    <string name=\"action_update\">Actualizare</string>\n    <string name=\"action_reinstall\">Reinstalare</string>\n    <string name=\"action_launch\">Lansați</string>\n    <string name=\"action_uninstall\">Dezinstalează</string>\n    <string name=\"action_info\">Informații</string>\n    <string name=\"action_retry\">Reîncearcă</string>\n    <string name=\"action_reload\">Reload</string>\n    <string name=\"action_open_about\">Open about</string>\n    <string name=\"action_open_settings\">Deschideți setările</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">Memorie cache</string>\n    <string name=\"title_installer\">Instalare</string>\n    <string name=\"title_home\">Acasă</string>\n    <string name=\"title_settings\">Setări</string>\n    <string name=\"title_update\">Actualizare disponibilă!</string>\n    <string name=\"title_about\">Despre</string>\n    <string name=\"title_permission_grant\">Acordă permisiuni</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Sistem</string>\n    <string name=\"theme_light\">Luminos</string>\n    <string name=\"theme_dark\">Întunecată</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">Aspect</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Culoare dinamică</string>\n    <string name=\"settings_dynamic_color_description\">Disponibil doar pe Android 12 și sus</string>\n    <string name=\"settings_theme\">Temă</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">Numele aplicației</string>\n    <string name=\"settings_app_icon\">Înlocuiţi pictograma aplicaţiei</string>\n    <string name=\"settings_app_icon_description\">Folosește icoana Bunny în loc de Discord</string>\n    <string name=\"settings_advanced\">Avansat</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Canal de lansare</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">Doar dezvoltatori</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Numele pachetului</string>\n    <string name=\"settings_version\">Versiune Discord</string>\n    <string name=\"settings_debuggable\">Depanare</string>\n    <string name=\"settings_debuggable_description\">Activează marcajul depanabil</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Versiunea Bunny Manager %1$s este acum disponibilă!</string>\n    <string name=\"channel_stable\">Stabil</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Echipă</string>\n    <string name=\"label_special_thanks\">Mulțumiri speciale</string>\n    <string name=\"label_translate\">Traduce</string>\n    <string name=\"version_latest\">Cel mai recent: %1$s</string>\n    <string name=\"version_target\">Tinta %1$s</string>\n    <string name=\"version_current\">Curent: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-ru-rRU/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Автор: %1$s</string>\n    <string name=\"cd_library_license\">Лицензия: %1$s</string>\n    <string name=\"msg_cleared_cache\">Кеш успешно очищен</string>\n    <string name=\"msg_load_fail\">Не удалось загрузить фиксации</string>\n    <string name=\"msg_coming_soon\">Скоро</string>\n    <string name=\"msg_invalid_version\">Некорректная Discord версия</string>\n    <string name=\"msg_seven_left\">Ещё 7 нажатий</string>\n    <string name=\"msg_five_left\">Ещё 5 нажатий</string>\n    <string name=\"msg_two_left\">Ещё 2 нажатия</string>\n    <string name=\"msg_loading\">Загрузка…</string>\n    <string name=\"msg_downgrade_disallowed\">Не удалось понизить версию, сначала попробуйте удалить</string>\n    <string name=\"msg_unlocked\">Вы стали разработчиком</string>\n    <string name=\"msg_permission_grant\">Чтобы Bunny Manager работал правильно, разрешения на доступ к файлам обязательны. Так как данные хранятся в ~/Bunny, выдача разрешений необходима для доступа к этому пути.</string>\n    <string name=\"msg_shizuku_denied\">Не удалось получить разрешения Shizuku</string>\n    <string name=\"msg_change_mirror\">Хотели бы вы попробовать еще раз, используя зеркало для скачивания?</string>\n    <string name=\"msg_invalid_apk\">Пакет был повреждён, попробуйте очистить кеш, а потом повторить установку</string>\n    <string name=\"msg_download_cancelled\">Скачивание было прервано</string>\n    <string name=\"msg_download_failed\">Скачивание не удалось</string>\n    <string name=\"msg_download_verify_failed\">Не удалось проверить загруженный файл, проверьте журналы для получения более подробной информации</string>\n    <string name=\"msg_copied\">Скопировано в буфер обмена</string>\n    <string name=\"group_download\">Скачивание пакетов</string>\n    <string name=\"group_patch\">Патчинг</string>\n    <string name=\"group_installing\">Установка</string>\n    <string name=\"step_dl_base\">Скачивание базового пакета</string>\n    <string name=\"step_dl_lib\">Скачивание библиотек пакета</string>\n    <string name=\"step_dl_lang\">Скачивание языкового пакета</string>\n    <string name=\"step_dl_res\">Скачивание ресурсных пакетов</string>\n    <string name=\"step_dl_vd\">Скачивание Bunny модуля</string>\n    <string name=\"step_change_icon\">Изменение значка приложения</string>\n    <string name=\"step_patch_manifests\">Патчинг манифестов приложения</string>\n    <string name=\"step_add_vd\">Внедрение Bunny</string>\n    <string name=\"step_signing\">Подписывание пакетов</string>\n    <string name=\"step_installing\">Установка пакетов</string>\n    <string name=\"installer_success\">Успешно установлено</string>\n    <string name=\"installer_aborted\">Установка отменена</string>\n    <string name=\"install_fail_generic\">Не удалось установить: Неизвестная причина</string>\n    <string name=\"install_fail_blocked\">Установка была заблокирована</string>\n    <string name=\"install_fail_invalid\">Один или несколько пакетов были недействительны или повреждены</string>\n    <string name=\"install_fail_conflict\">Конфликтует с уже установленным приложением, обычно из-за несоответствующих подписей</string>\n    <string name=\"install_fail_storage\">Недостаточно свободного места для установки</string>\n    <string name=\"install_fail_incompatible\">Приложение несовместимо с данным устройством</string>\n    <string name=\"install_fail_timeout\">Время ожидания установки истекло</string>\n    <string name=\"status_ongoing\">В процессе</string>\n    <string name=\"status_successful\">Успешно</string>\n    <string name=\"status_fail\">Не удалось</string>\n    <string name=\"status_queued\">В очереди</string>\n    <string name=\"action_collapse\">Свернуть</string>\n    <string name=\"action_expand\">Развернуть</string>\n    <string name=\"action_back\">Назад</string>\n    <string name=\"action_copy_logs\">Скопировать логи</string>\n    <string name=\"action_clear_cache\">Очистить кеш</string>\n    <string name=\"action_confirm\">Подтвердить</string>\n    <string name=\"action_start_update\">Начать обновление</string>\n    <string name=\"action_install\">Установить</string>\n    <string name=\"action_update\">Обновить</string>\n    <string name=\"action_reinstall\">Переустановить</string>\n    <string name=\"action_launch\">Запустить</string>\n    <string name=\"action_uninstall\">Удалить</string>\n    <string name=\"action_info\">Информация</string>\n    <string name=\"action_retry\">Повторить</string>\n    <string name=\"action_reload\">Перезагрузить</string>\n    <string name=\"action_open_about\">Открыть О приложении</string>\n    <string name=\"action_open_settings\">Открыть настройки</string>\n    <string name=\"action_tap_to_install\">Нажмите, чтобы установить Bunny для Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Всё равно выйти</string>\n    <string name=\"action_dismiss_nevermind\">Не сейчас</string>\n    <string name=\"action_dismiss_no_thanks\">Нет, спасибо</string>\n    <string name=\"action_try_again\">Попробовать снова</string>\n    <string name=\"action_previous_theme\">Увидеть предыдущую тему</string>\n    <string name=\"action_next_theme\">Увидеть следующую тему</string>\n    <string name=\"action_view_logs\">Посмотреть логи</string>\n    <string name=\"action_show_timestamp\">Показать временную метку</string>\n    <string name=\"action_copy_log\">Скопировать лог</string>\n    <string name=\"action_save_logs\">Сохранить логи в файл</string>\n    <string name=\"action_share_logs\">Поделиться логами</string>\n    <string name=\"action_more_options\">Дополнительные параметры</string>\n    <string name=\"msg_back_warning\">Выход из программы установки до её завершения может привести к повреждению загруженных файлов, вы уверены, что хотите это сделать?</string>\n    <string name=\"installer_cached\">Кешировано</string>\n    <string name=\"title_installer\">Установщик</string>\n    <string name=\"title_home\">Главная</string>\n    <string name=\"title_settings\">Настройки</string>\n    <string name=\"title_update\">Доступно обновление!</string>\n    <string name=\"title_about\">О приложении</string>\n    <string name=\"title_permission_grant\">Предоставить разрешения</string>\n    <string name=\"title_update_available\">Доступно новое обновление Discord!</string>\n    <string name=\"title_warning\">Предупреждение</string>\n    <string name=\"title_dl_failed\">Скачивание не удалось</string>\n    <string name=\"title_logs\">Логи</string>\n    <string name=\"title_os_libraries\">Библиотеки с открытым исходным кодом</string>\n    <string name=\"title_libraries\">Библиотеки</string>\n    <string name=\"theme_system\">Системная</string>\n    <string name=\"theme_light\">Светлая</string>\n    <string name=\"theme_dark\">Тёмная</string>\n    <string name=\"duration_disabled\">Отключено</string>\n    <string name=\"duration_fifteen_min\">Каждую четверть часа</string>\n    <string name=\"duration_half_hour\">Каждые полчаса</string>\n    <string name=\"duration_hourly\">Каждый час</string>\n    <string name=\"duration_bihourly\">Каждый второй час</string>\n    <string name=\"duration_twice_daily\">Дважды в день</string>\n    <string name=\"duration_daily\">Ежедневно</string>\n    <string name=\"duration_weekly\">Еженедельно</string>\n    <string name=\"settings_appearance\">Внешний вид</string>\n    <string name=\"settings_appearance_description\">Изменить внешний вид и ощущения от приложения</string>\n    <string name=\"settings_dynamic_color\">Динамический цвет</string>\n    <string name=\"settings_dynamic_color_description\">Доступно только на Android 12 и выше</string>\n    <string name=\"settings_theme\">Тема</string>\n    <string name=\"settings_check_updates\">Проверять на обновления Discord</string>\n    <string name=\"settings_customization\">Кастомизация</string>\n    <string name=\"settings_customization_description\">Кастомизируйте вашу Bunny установку</string>\n    <string name=\"settings_app_name\">Название приложения</string>\n    <string name=\"settings_app_icon\">Заменить значок приложения</string>\n    <string name=\"settings_app_icon_description\">Использует иконку Bunny вместо Discord</string>\n    <string name=\"settings_advanced\">Дополнительные</string>\n    <string name=\"settings_advanced_description\">Изменить скачивание и установку</string>\n    <string name=\"settings_channel\">Канал выпуска</string>\n    <string name=\"settings_mirror\">Зеркало скачивания</string>\n    <string name=\"settings_auto_clear_cache\">Очищать кеш автоматически</string>\n    <string name=\"settings_auto_clear_cache_description\">Очищает кеш, когда Discord получает обновление</string>\n    <string name=\"settings_developer\">Только для разработчика</string>\n    <string name=\"settings_developer_description\">Эти настройки могут сломать некоторые вещи, если их неправильно использовать</string>\n    <string name=\"settings_module_location\">Расположение модуля</string>\n    <string name=\"settings_module_location_description\">Для использования при разработке Xposed модуля. БУДЬТЕ ОСТОРОЖНЫ</string>\n    <string name=\"settings_module_location_reset\">Сбросить расположение модуля</string>\n    <string name=\"settings_package_name\">Название пакета</string>\n    <string name=\"settings_version\">Версия Discord</string>\n    <string name=\"settings_debuggable\">Отлаживаемый</string>\n    <string name=\"settings_debuggable_description\">Включить отладочный флаг</string>\n    <string name=\"settings_logs_alternate_lines\">Альтернативные строки</string>\n    <string name=\"settings_logs_line_wrap\">Перенос строк</string>\n    <string name=\"update_description\">Доступна версия %1$s для Bunny Manager!</string>\n    <string name=\"channel_stable\">Стабильный</string>\n    <string name=\"channel_beta\">Бета</string>\n    <string name=\"channel_alpha\">Альфа</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Команда</string>\n    <string name=\"label_special_thanks\">Особая благодарность</string>\n    <string name=\"label_translate\">Перевести</string>\n    <string name=\"version_latest\">Последняя: %1$s</string>\n    <string name=\"version_target\">Выбранная: %1$s</string>\n    <string name=\"version_current\">Текущая: %1$s</string>\n    <string name=\"install_method\">Метод установки</string>\n    <string name=\"default_installer\">По умолчанию (рекомендуется)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-sr-rSP/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cache cleared successfully</string>\n    <string name=\"msg_load_fail\">Failed to load commits</string>\n    <string name=\"msg_coming_soon\">Coming soon</string>\n    <string name=\"msg_invalid_version\">Invalid Discord version</string>\n    <string name=\"msg_seven_left\">7 more taps</string>\n    <string name=\"msg_five_left\">5 more taps</string>\n    <string name=\"msg_two_left\">2 more taps</string>\n    <string name=\"msg_loading\">Loading…</string>\n    <string name=\"msg_downgrade_disallowed\">Cannot downgrade, try uninstalling first</string>\n    <string name=\"msg_unlocked\">You are now a developer</string>\n    <string name=\"msg_permission_grant\">In order for Bunny Manager to function, file permissions are required. Since shared data is stored in ~/Bunny, permissions are required in order to access it.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Would you like to try again using a download mirror?</string>\n    <string name=\"msg_invalid_apk\">APK was corrupted, try clearing cache then reinstalling</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Download APKs</string>\n    <string name=\"group_patch\">Patching</string>\n    <string name=\"group_installing\">Installing</string>\n    <string name=\"step_dl_base\">Downloading base apk</string>\n    <string name=\"step_dl_lib\">Downloading libraries apk</string>\n    <string name=\"step_dl_lang\">Downloading language apk</string>\n    <string name=\"step_dl_res\">Downloading resources apk</string>\n    <string name=\"step_dl_vd\">Downloading Bunny module</string>\n    <string name=\"step_change_icon\">Changing app icon</string>\n    <string name=\"step_patch_manifests\">Patching app manifests</string>\n    <string name=\"step_add_vd\">Injecting Bunny</string>\n    <string name=\"step_signing\">Signing APKs</string>\n    <string name=\"step_installing\">Installing APKs</string>\n    <string name=\"installer_success\">Installed successfully</string>\n    <string name=\"installer_aborted\">Install canceled</string>\n    <string name=\"install_fail_generic\">Failed to install: Unknown reason</string>\n    <string name=\"install_fail_blocked\">Installation was blocked</string>\n    <string name=\"install_fail_invalid\">One or more APKs were invalid or corrupt</string>\n    <string name=\"install_fail_conflict\">Conflicts with an existing app, usually due to mismatched signatures</string>\n    <string name=\"install_fail_storage\">Not enough available storage to install</string>\n    <string name=\"install_fail_incompatible\">Application is incompatible with this device</string>\n    <string name=\"install_fail_timeout\">Installation timed out</string>\n    <string name=\"status_ongoing\">Ongoing</string>\n    <string name=\"status_successful\">Successful</string>\n    <string name=\"status_fail\">Failed</string>\n    <string name=\"status_queued\">Queued</string>\n    <string name=\"action_collapse\">Collapse</string>\n    <string name=\"action_expand\">Expand</string>\n    <string name=\"action_back\">Go back</string>\n    <string name=\"action_copy_logs\">Copy logs</string>\n    <string name=\"action_clear_cache\">Clear cache</string>\n    <string name=\"action_confirm\">Confirm</string>\n    <string name=\"action_start_update\">Start update</string>\n    <string name=\"action_install\">Install</string>\n    <string name=\"action_update\">Update</string>\n    <string name=\"action_reinstall\">Reinstall</string>\n    <string name=\"action_launch\">Launch</string>\n    <string name=\"action_uninstall\">Uninstall</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Retry</string>\n    <string name=\"action_reload\">Reload</string>\n    <string name=\"action_open_about\">Open about</string>\n    <string name=\"action_open_settings\">Open settings</string>\n    <string name=\"action_tap_to_install\">Tap to install Bunny for Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Exit anyways</string>\n    <string name=\"action_dismiss_nevermind\">Nevermind</string>\n    <string name=\"action_dismiss_no_thanks\">No thanks</string>\n    <string name=\"action_try_again\">Try again</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Exiting the installer before its finished could corrupt downloaded files, are you sure you want to do that?</string>\n    <string name=\"installer_cached\">Cached</string>\n    <string name=\"title_installer\">Installer</string>\n    <string name=\"title_home\">Home</string>\n    <string name=\"title_settings\">Settings</string>\n    <string name=\"title_update\">Update available!</string>\n    <string name=\"title_about\">About</string>\n    <string name=\"title_permission_grant\">Grant Permissions</string>\n    <string name=\"title_update_available\">New Discord update available!</string>\n    <string name=\"title_warning\">Warning</string>\n    <string name=\"title_dl_failed\">Download failed</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Light</string>\n    <string name=\"theme_dark\">Dark</string>\n    <string name=\"duration_disabled\">Disabled</string>\n    <string name=\"duration_fifteen_min\">Quarter hourly</string>\n    <string name=\"duration_half_hour\">Half hourly</string>\n    <string name=\"duration_hourly\">Hourly</string>\n    <string name=\"duration_bihourly\">Bi-hourly</string>\n    <string name=\"duration_twice_daily\">Twice daily</string>\n    <string name=\"duration_daily\">Daily</string>\n    <string name=\"duration_weekly\">Weekly</string>\n    <string name=\"settings_appearance\">Appearance</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Dynamic color</string>\n    <string name=\"settings_dynamic_color_description\">Only available on Android 12 and up</string>\n    <string name=\"settings_theme\">Theme</string>\n    <string name=\"settings_check_updates\">Check for Discord updates</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">App name</string>\n    <string name=\"settings_app_icon\">Replace app icon</string>\n    <string name=\"settings_app_icon_description\">Uses the Bunny icon instead of Discord\\'s</string>\n    <string name=\"settings_advanced\">Advanced</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Release channel</string>\n    <string name=\"settings_mirror\">Download mirror</string>\n    <string name=\"settings_auto_clear_cache\">Clear cache automatically</string>\n    <string name=\"settings_auto_clear_cache_description\">Clears cache when Discord gets an update</string>\n    <string name=\"settings_developer\">Developer only</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Module location</string>\n    <string name=\"settings_module_location_description\">For use with developing the Xposed module. BE CAREFUL</string>\n    <string name=\"settings_module_location_reset\">Reset module location</string>\n    <string name=\"settings_package_name\">Package name</string>\n    <string name=\"settings_version\">Discord version</string>\n    <string name=\"settings_debuggable\">Debuggable</string>\n    <string name=\"settings_debuggable_description\">Enable debuggable flag</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager version %1$s is now available!</string>\n    <string name=\"channel_stable\">Stable</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Special thanks</string>\n    <string name=\"label_translate\">Translate</string>\n    <string name=\"version_latest\">Latest: %1$s</string>\n    <string name=\"version_target\">Target: %1$s</string>\n    <string name=\"version_current\">Current: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-sv-rSE/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Hanteraren</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Cachen har lyckats rensats</string>\n    <string name=\"msg_load_fail\">Misslyckades att ladda comitter</string>\n    <string name=\"msg_coming_soon\">Kommer snart</string>\n    <string name=\"msg_invalid_version\">Ogiltig Discord version</string>\n    <string name=\"msg_seven_left\">7 tryck till</string>\n    <string name=\"msg_five_left\">5 tryck till</string>\n    <string name=\"msg_two_left\">2 tryck till</string>\n    <string name=\"msg_loading\">Laddar…</string>\n    <string name=\"msg_downgrade_disallowed\">Kan inte nedgradera, försök att avinstallera först</string>\n    <string name=\"msg_unlocked\">Du är nu en utvecklare</string>\n    <string name=\"msg_permission_grant\">För att Bunny Hanteraren ska kunna fungera så krävs filbehörigheter. Eftersom delad data lagras i ~/Bunny så krävs behörigheter för att komma åt den.</string>\n    <string name=\"msg_shizuku_denied\">Misslyckades med att få Shizuku-behörigheter</string>\n    <string name=\"msg_change_mirror\">Vill du försöka igen med hjälp av en speglad nedladdning?</string>\n    <string name=\"msg_invalid_apk\">APK:n blev korrupterad, försök att rensa cachen och sedan ominstallera</string>\n    <string name=\"msg_download_cancelled\">Nedladdningen avbröts</string>\n    <string name=\"msg_download_failed\">Nedladdning misslyckades</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Ladda ner APKer</string>\n    <string name=\"group_patch\">Patchar</string>\n    <string name=\"group_installing\">Installerar</string>\n    <string name=\"step_dl_base\">Laddar ner bas apk</string>\n    <string name=\"step_dl_lib\">Laddar ner programbiblioteks apk</string>\n    <string name=\"step_dl_lang\">Laddar ner språk apk</string>\n    <string name=\"step_dl_res\">Laddar ner resurs apk</string>\n    <string name=\"step_dl_vd\">Laddar ner Bunny modul</string>\n    <string name=\"step_change_icon\">Ändrar appikonen</string>\n    <string name=\"step_patch_manifests\">Patchar app manifester</string>\n    <string name=\"step_add_vd\">Injekterar Bunny</string>\n    <string name=\"step_signing\">Signerar APK:er</string>\n    <string name=\"step_installing\">Installerar APKer</string>\n    <string name=\"installer_success\">Installation klar</string>\n    <string name=\"installer_aborted\">Installeringen avbröts</string>\n    <string name=\"install_fail_generic\">Misslyckades att installera: Okänd orsak</string>\n    <string name=\"install_fail_blocked\">Installationen var blockerad</string>\n    <string name=\"install_fail_invalid\">En eller flera APK:er var ogiltiga eller korrupta</string>\n    <string name=\"install_fail_conflict\">Konflikter med en befintlig app, vanligtvis på grund av missmatchade signaturer</string>\n    <string name=\"install_fail_storage\">Inte tillräckligt med lagringsutrymme för att installera</string>\n    <string name=\"install_fail_incompatible\">Applikationen är inkompatibel med den här enheten</string>\n    <string name=\"install_fail_timeout\">Installationen tog för lång tid</string>\n    <string name=\"status_ongoing\">Pågående</string>\n    <string name=\"status_successful\">Lyckades</string>\n    <string name=\"status_fail\">Misslyckades</string>\n    <string name=\"status_queued\">Köad</string>\n    <string name=\"action_collapse\">Kollapsa</string>\n    <string name=\"action_expand\">Expandera</string>\n    <string name=\"action_back\">Gå tillbaka</string>\n    <string name=\"action_copy_logs\">Kopiera loggar</string>\n    <string name=\"action_clear_cache\">Rensa cache</string>\n    <string name=\"action_confirm\">Bekräfta</string>\n    <string name=\"action_start_update\">Starta uppdatering</string>\n    <string name=\"action_install\">Installera</string>\n    <string name=\"action_update\">Uppdatera</string>\n    <string name=\"action_reinstall\">Ominstallera</string>\n    <string name=\"action_launch\">Kör</string>\n    <string name=\"action_uninstall\">Avinstallera</string>\n    <string name=\"action_info\">Info</string>\n    <string name=\"action_retry\">Försök igen</string>\n    <string name=\"action_reload\">Ladda om</string>\n    <string name=\"action_open_about\">Öppna \\\"om\\\"</string>\n    <string name=\"action_open_settings\">Öppna inställningar</string>\n    <string name=\"action_tap_to_install\">Tryck för att installera Bunny för Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Gå ut ändå</string>\n    <string name=\"action_dismiss_nevermind\">Glöm det</string>\n    <string name=\"action_dismiss_no_thanks\">Nej tack</string>\n    <string name=\"action_try_again\">Försök igen</string>\n    <string name=\"action_previous_theme\">Visa föregående tema</string>\n    <string name=\"action_next_theme\">Visa nästa tema</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Att gå ur installationen innan den är klar kan korruptera nerladdade filer, är du säker på att du vill göra detta?</string>\n    <string name=\"installer_cached\">Cachad</string>\n    <string name=\"title_installer\">Installerare</string>\n    <string name=\"title_home\">Hem</string>\n    <string name=\"title_settings\">Inställningar</string>\n    <string name=\"title_update\">Uppdatering tillgänglig!</string>\n    <string name=\"title_about\">Om</string>\n    <string name=\"title_permission_grant\">Ge Behörigheter</string>\n    <string name=\"title_update_available\">Ny Discord-uppdatering tillgänglig!</string>\n    <string name=\"title_warning\">Varning</string>\n    <string name=\"title_dl_failed\">Nedladdning misslyckades</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">System</string>\n    <string name=\"theme_light\">Ljust</string>\n    <string name=\"theme_dark\">Mörkt</string>\n    <string name=\"duration_disabled\">Inaktiverad</string>\n    <string name=\"duration_fifteen_min\">Varje kvart</string>\n    <string name=\"duration_half_hour\">Varje halvtimme</string>\n    <string name=\"duration_hourly\">Varje timme</string>\n    <string name=\"duration_bihourly\">Varannan timme</string>\n    <string name=\"duration_twice_daily\">Två gånger om dagen</string>\n    <string name=\"duration_daily\">Dagligen</string>\n    <string name=\"duration_weekly\">Varje vecka</string>\n    <string name=\"settings_appearance\">Utseende</string>\n    <string name=\"settings_appearance_description\">Ändra appens utseende och känsla</string>\n    <string name=\"settings_dynamic_color\">Dynamisk färg</string>\n    <string name=\"settings_dynamic_color_description\">Endast tillgänglig på Android 12 och uppåt</string>\n    <string name=\"settings_theme\">Tema</string>\n    <string name=\"settings_check_updates\">Sök efter Discord-uppdateringar</string>\n    <string name=\"settings_customization\">Anpassningar</string>\n    <string name=\"settings_customization_description\">Skräddarsy din Bunny installation</string>\n    <string name=\"settings_app_name\">Namn på appen</string>\n    <string name=\"settings_app_icon\">Ersätt appikonen</string>\n    <string name=\"settings_app_icon_description\">Använder Bunnys ikon istället för Discords</string>\n    <string name=\"settings_advanced\">Avancerat</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Stabil kanal</string>\n    <string name=\"settings_mirror\">Speglad nedladdning</string>\n    <string name=\"settings_auto_clear_cache\">Rensa cache automatiskt</string>\n    <string name=\"settings_auto_clear_cache_description\">Rensar cachen när Discord får en uppdatering</string>\n    <string name=\"settings_developer\">Endast utvecklare</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Modulens plats</string>\n    <string name=\"settings_module_location_description\">För utveckling av Xposed modulen. VAR FÖRSIKTIG</string>\n    <string name=\"settings_module_location_reset\">Återställ modulens plats</string>\n    <string name=\"settings_package_name\">Namn på paket</string>\n    <string name=\"settings_version\">Discord-version</string>\n    <string name=\"settings_debuggable\">Felsökbar</string>\n    <string name=\"settings_debuggable_description\">Aktivera felsökbar flagga</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Bunny Manager version %1$s är nu tillgänglig!</string>\n    <string name=\"channel_stable\">Stabil</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Team</string>\n    <string name=\"label_special_thanks\">Särskilt tack</string>\n    <string name=\"label_translate\">Översätt</string>\n    <string name=\"version_latest\">Senaste: %1$s</string>\n    <string name=\"version_target\">Mål: %1$s</string>\n    <string name=\"version_current\">Nuvarande: %1$s</string>\n    <string name=\"install_method\">Installations metoder</string>\n    <string name=\"default_installer\">Standard (rekommenderad)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-tr-rTR/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">Yapan: %1$s</string>\n    <string name=\"cd_library_license\">Lisans: %1$s</string>\n    <string name=\"msg_cleared_cache\">Önbellek başarıyla temizlendi</string>\n    <string name=\"msg_load_fail\">İçerik yüklenemedi</string>\n    <string name=\"msg_coming_soon\">Yakında</string>\n    <string name=\"msg_invalid_version\">Geçersiz Discord sürümü</string>\n    <string name=\"msg_seven_left\">7 kez daha basın</string>\n    <string name=\"msg_five_left\">5 kez daha basın</string>\n    <string name=\"msg_two_left\">2 kez daha basın</string>\n    <string name=\"msg_loading\">Yükleniyor…</string>\n    <string name=\"msg_downgrade_disallowed\">Sürüm düşürülemiyor, önce kaldırmayı deneyin</string>\n    <string name=\"msg_unlocked\">Artık bir geliştiricisiniz</string>\n    <string name=\"msg_permission_grant\">Bunny Manager\\'ın düzgün çalışması için dosya izinleri gereklidir. Paylaşılan uygulama verileri ~/Bunny\\'da depolandığından, dosyalara erişim için izin gerekmektedir.</string>\n    <string name=\"msg_shizuku_denied\">Shizuku izinleri alınamadı</string>\n    <string name=\"msg_change_mirror\">Alternatif bir kaynak kullanarak tekrar denemek ister misiniz?</string>\n    <string name=\"msg_invalid_apk\">APK bozuk. Önbelleği temizleyip yeniden yüklemeyi deneyin</string>\n    <string name=\"msg_download_cancelled\">İndirme işlemi iptal edildi</string>\n    <string name=\"msg_download_failed\">İndirme işlemi başarısız oldu</string>\n    <string name=\"msg_download_verify_failed\">İndirilen dosya doğrulanamadı, daha fazla detay için günlükleri kontrol edin</string>\n    <string name=\"msg_copied\">Panoya kopyalandı</string>\n    <string name=\"group_download\">APK\\'ları indir</string>\n    <string name=\"group_patch\">Yamalanıyor</string>\n    <string name=\"group_installing\">Kuruluyor</string>\n    <string name=\"step_dl_base\">Temel apk indiriliyor</string>\n    <string name=\"step_dl_lib\">Kütüphane apk\\'ları indiriliyor</string>\n    <string name=\"step_dl_lang\">Dil apk\\'sı indiriliyor</string>\n    <string name=\"step_dl_res\">Kaynak apk\\'sı indiriliyor</string>\n    <string name=\"step_dl_vd\">Bunny modülü indiriliyor</string>\n    <string name=\"step_change_icon\">Uygulama simgesi değiştiriliyor</string>\n    <string name=\"step_patch_manifests\">Uygulama manifest\\'i yamalanıyor</string>\n    <string name=\"step_add_vd\">Bunny enjekte ediliyor</string>\n    <string name=\"step_signing\">APK\\'lar imzalanıyor</string>\n    <string name=\"step_installing\">APK\\'lar kuruluyor</string>\n    <string name=\"installer_success\">Başarıyla kuruldu</string>\n    <string name=\"installer_aborted\">Kurulum iptal edildi</string>\n    <string name=\"install_fail_generic\">Kurulum başarısız oldu: Bilinmeyen sebep</string>\n    <string name=\"install_fail_blocked\">Kurulum engellendi</string>\n    <string name=\"install_fail_invalid\">Bir ya da daha fazla APK geçersiz ya da bozuk</string>\n    <string name=\"install_fail_conflict\">Mevcut bir uygulamayla çakışıyor, genellikle uyumsuz imzalar sebep olur</string>\n    <string name=\"install_fail_storage\">Kurmak için yeterli depolama alanı yok</string>\n    <string name=\"install_fail_incompatible\">Uygulama bu cihaz ile uyumsuz</string>\n    <string name=\"install_fail_timeout\">Kurulum zaman aşımına uğradı</string>\n    <string name=\"status_ongoing\">Devam ediyor</string>\n    <string name=\"status_successful\">Başarılı</string>\n    <string name=\"status_fail\">Başarısız oldu</string>\n    <string name=\"status_queued\">Sıraya alındı</string>\n    <string name=\"action_collapse\">Daralt</string>\n    <string name=\"action_expand\">Genişlet</string>\n    <string name=\"action_back\">Geri dön</string>\n    <string name=\"action_copy_logs\">Günlükleri kopyala</string>\n    <string name=\"action_clear_cache\">Önbelleği temizle</string>\n    <string name=\"action_confirm\">Onayla</string>\n    <string name=\"action_start_update\">Güncellemeyi başlat</string>\n    <string name=\"action_install\">Kur</string>\n    <string name=\"action_update\">Güncelle</string>\n    <string name=\"action_reinstall\">Yeniden kur</string>\n    <string name=\"action_launch\">Başlat</string>\n    <string name=\"action_uninstall\">Kaldır</string>\n    <string name=\"action_info\">Bilgi</string>\n    <string name=\"action_retry\">Yeniden dene</string>\n    <string name=\"action_reload\">Yenile</string>\n    <string name=\"action_open_about\">Hakkındayı aç</string>\n    <string name=\"action_open_settings\">Ayarları aç</string>\n    <string name=\"action_tap_to_install\">Discord %1$s için Bunny\\'yı kurmak için dokunun</string>\n    <string name=\"action_confirm_exit\">Yine de çık</string>\n    <string name=\"action_dismiss_nevermind\">Boş ver</string>\n    <string name=\"action_dismiss_no_thanks\">Hayır teşekkürler</string>\n    <string name=\"action_try_again\">Tekrar deneyin</string>\n    <string name=\"action_previous_theme\">Önceki temayı göster</string>\n    <string name=\"action_next_theme\">Sonraki temayı göster</string>\n    <string name=\"action_view_logs\">Günlükleri göster</string>\n    <string name=\"action_show_timestamp\">Zamanı göster</string>\n    <string name=\"action_copy_log\">Günlüğü kopyala</string>\n    <string name=\"action_save_logs\">Günlükleri dosyaya kaydet</string>\n    <string name=\"action_share_logs\">Günlükleri paylaş</string>\n    <string name=\"action_more_options\">Diğer seçenekler</string>\n    <string name=\"msg_back_warning\">Yükleme bitmeden çıkmak indirilen dosyaları bozabilir, bunu yapmak istediğinizden emin misiniz?</string>\n    <string name=\"installer_cached\">Önbelleğe alındı</string>\n    <string name=\"title_installer\">Yükleyici</string>\n    <string name=\"title_home\">Ana Sayfa</string>\n    <string name=\"title_settings\">Ayarlar</string>\n    <string name=\"title_update\">Güncelleme mevcut!</string>\n    <string name=\"title_about\">Hakkında</string>\n    <string name=\"title_permission_grant\">İzinleri Ver</string>\n    <string name=\"title_update_available\">Yeni Discord güncellemesi mevcut!</string>\n    <string name=\"title_warning\">Uyarı</string>\n    <string name=\"title_dl_failed\">İndirme işlemi başarısız</string>\n    <string name=\"title_logs\">Günlükler</string>\n    <string name=\"title_os_libraries\">Açık kaynak kütüphaneleri</string>\n    <string name=\"title_libraries\">Kütüphaneler</string>\n    <string name=\"theme_system\">Sistem</string>\n    <string name=\"theme_light\">Açık</string>\n    <string name=\"theme_dark\">Koyu</string>\n    <string name=\"duration_disabled\">Devre dışı</string>\n    <string name=\"duration_fifteen_min\">15 dakikada bir</string>\n    <string name=\"duration_half_hour\">Yarım saatte bir</string>\n    <string name=\"duration_hourly\">Saatte bir</string>\n    <string name=\"duration_bihourly\">İki saatte bir</string>\n    <string name=\"duration_twice_daily\">Günde iki</string>\n    <string name=\"duration_daily\">Günde bir</string>\n    <string name=\"duration_weekly\">Haftada bir</string>\n    <string name=\"settings_appearance\">Görünüm</string>\n    <string name=\"settings_appearance_description\">Uygulamanın görünümünü ve havasını değiştirin</string>\n    <string name=\"settings_dynamic_color\">Dinamik renk</string>\n    <string name=\"settings_dynamic_color_description\">Sadece Android 12 ve üzerinde çalışır</string>\n    <string name=\"settings_theme\">Tema</string>\n    <string name=\"settings_check_updates\">Discord güncellemelerini denetle</string>\n    <string name=\"settings_customization\">Özelleştirme</string>\n    <string name=\"settings_customization_description\">Bunny kurulumunuzu özelleştirin</string>\n    <string name=\"settings_app_name\">Uygulama ismi</string>\n    <string name=\"settings_app_icon\">Uygulama simgesini değiştir</string>\n    <string name=\"settings_app_icon_description\">Discord\\'unki yerine Bunny\\'nın simgesini kullanır</string>\n    <string name=\"settings_advanced\">Gelişmiş</string>\n    <string name=\"settings_advanced_description\">İndirmeyi ve kurulumu ayarlayın</string>\n    <string name=\"settings_channel\">Yayın kanalı</string>\n    <string name=\"settings_mirror\">Alternatif indirme</string>\n    <string name=\"settings_auto_clear_cache\">Önbelleği otomatik olarak temizle</string>\n    <string name=\"settings_auto_clear_cache_description\">Discord güncelleme aldığında önbelleği temizler</string>\n    <string name=\"settings_developer\">Yalnızca geliştiriciler için</string>\n    <string name=\"settings_developer_description\">Bu ayarlar yanlış kullanıldığında bir şeyleri bozabilir</string>\n    <string name=\"settings_module_location\">Modül konumu</string>\n    <string name=\"settings_module_location_description\">Xposed modülünü geliştirmek içindir. DİKKATLİ OLUN</string>\n    <string name=\"settings_module_location_reset\">Modül konumunu sıfırla</string>\n    <string name=\"settings_package_name\">Paket ismi</string>\n    <string name=\"settings_version\">Discord sürümü</string>\n    <string name=\"settings_debuggable\">Hata ayıklanabilir</string>\n    <string name=\"settings_debuggable_description\">Hata ayıklanabilir yap</string>\n    <string name=\"settings_logs_alternate_lines\">Satırları ayır</string>\n    <string name=\"settings_logs_line_wrap\">Satırları kaydır</string>\n    <string name=\"update_description\">Bunny Manager sürüm %1$s yayınlandı!</string>\n    <string name=\"channel_stable\">Kararlı</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alfa</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Ekip</string>\n    <string name=\"label_special_thanks\">Özel teşekkürler</string>\n    <string name=\"label_translate\">Tercüme et</string>\n    <string name=\"version_latest\">En son: %1$s</string>\n    <string name=\"version_target\">Hedef: %1$s</string>\n    <string name=\"version_current\">Şu anki: %1$s</string>\n    <string name=\"install_method\">Kurulum yöntemi</string>\n    <string name=\"default_installer\">Varsayılan (önerilen)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-uk-rUA/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Менеджер Bunny</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Кеш успішно очищено</string>\n    <string name=\"msg_load_fail\">Не вдалося завантажити коміти</string>\n    <string name=\"msg_coming_soon\">Незабаром</string>\n    <string name=\"msg_invalid_version\">Невірна версія Discord</string>\n    <string name=\"msg_seven_left\">Ще 7 натисків</string>\n    <string name=\"msg_five_left\">Ще 5 натисків</string>\n    <string name=\"msg_two_left\">Ще 2 натиску</string>\n    <string name=\"msg_loading\">Завантаження…</string>\n    <string name=\"msg_downgrade_disallowed\">Неможливо понизити версію, спробуйте спочатку видалити</string>\n    <string name=\"msg_unlocked\">Тепер ви – розробник</string>\n    <string name=\"msg_permission_grant\">Для того, щоб Bunny Менеджер функціонував, потрібен доступ до файлів. Оскільки спільні дані зберігаються в ~/Bunny, для доступу необхіден дозвіл.</string>\n    <string name=\"msg_shizuku_denied\">Failed to obtain Shizuku permissions</string>\n    <string name=\"msg_change_mirror\">Бажаєте спробувати ще раз, використовуючи дзеркало завантаження?</string>\n    <string name=\"msg_invalid_apk\">APK-файл пошкоджений, спробуйте очистити кеш, а потім перевстановити</string>\n    <string name=\"msg_download_cancelled\">Download was aborted</string>\n    <string name=\"msg_download_failed\">Download failed</string>\n    <string name=\"msg_download_verify_failed\">Could not verify downloaded file, check logs for more details</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Завантаження APK-файлів</string>\n    <string name=\"group_patch\">Патчінг</string>\n    <string name=\"group_installing\">Встановлення</string>\n    <string name=\"step_dl_base\">Завантаження основного apk</string>\n    <string name=\"step_dl_lib\">Завантаження apk бібліотек</string>\n    <string name=\"step_dl_lang\">Завантаження мовних apk</string>\n    <string name=\"step_dl_res\">Завантаження ресурсних apk</string>\n    <string name=\"step_dl_vd\">Завантаження модуля Bunny</string>\n    <string name=\"step_change_icon\">Змінення іконки додатку</string>\n    <string name=\"step_patch_manifests\">Пропатчування маніфестів додатку</string>\n    <string name=\"step_add_vd\">Ін\\'єкція Bunny</string>\n    <string name=\"step_signing\">Сертифікація APK-файлів</string>\n    <string name=\"step_installing\">Встановлення APK-файлів</string>\n    <string name=\"installer_success\">Успішно встановлено</string>\n    <string name=\"installer_aborted\">Встановлення скасовано</string>\n    <string name=\"install_fail_generic\">Не вдалося встановити: невідома причина</string>\n    <string name=\"install_fail_blocked\">Встановлення було заблоковано</string>\n    <string name=\"install_fail_invalid\">Один чи декілька APK-файлів були невірні або пошкоджені</string>\n    <string name=\"install_fail_conflict\">Конфліктує з вже встановленою програмою, зазвичай з-за невідповідних сертифікацій</string>\n    <string name=\"install_fail_storage\">Недостатньо вільної пам\\'яті для встановлення</string>\n    <string name=\"install_fail_incompatible\">Додаток несумісний з цим пристроєм</string>\n    <string name=\"install_fail_timeout\">Час очікування встановлення закінчився</string>\n    <string name=\"status_ongoing\">Поточний</string>\n    <string name=\"status_successful\">Успішний</string>\n    <string name=\"status_fail\">Невдалий</string>\n    <string name=\"status_queued\">У черзі</string>\n    <string name=\"action_collapse\">Згорнути</string>\n    <string name=\"action_expand\">Розгорнути</string>\n    <string name=\"action_back\">Повернутися</string>\n    <string name=\"action_copy_logs\">Копіювати логи</string>\n    <string name=\"action_clear_cache\">Очистити кеш</string>\n    <string name=\"action_confirm\">Підтвердити</string>\n    <string name=\"action_start_update\">Почати оновлення</string>\n    <string name=\"action_install\">Встановити</string>\n    <string name=\"action_update\">Оновити</string>\n    <string name=\"action_reinstall\">Перевстановити</string>\n    <string name=\"action_launch\">Запустити</string>\n    <string name=\"action_uninstall\">Видалити</string>\n    <string name=\"action_info\">Інфо</string>\n    <string name=\"action_retry\">Повторити</string>\n    <string name=\"action_reload\">Оновити</string>\n    <string name=\"action_open_about\">Відкрити про</string>\n    <string name=\"action_open_settings\">Відкрити налаштування</string>\n    <string name=\"action_tap_to_install\">Натисни, щоб встановити Bunny до Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Вийти у будь-якому разі</string>\n    <string name=\"action_dismiss_nevermind\">Не зараз</string>\n    <string name=\"action_dismiss_no_thanks\">Ні дякую</string>\n    <string name=\"action_try_again\">Спробувати знову</string>\n    <string name=\"action_previous_theme\">See previous theme</string>\n    <string name=\"action_next_theme\">See next theme</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Вихід з програми установки перед її завершенням може зіпсуватися завантажені файли. Ви впевнені, що хочете це зробити?</string>\n    <string name=\"installer_cached\">Кешовано</string>\n    <string name=\"title_installer\">Встановлювач</string>\n    <string name=\"title_home\">Головна</string>\n    <string name=\"title_settings\">Налаштування</string>\n    <string name=\"title_update\">Доступне оновлення!</string>\n    <string name=\"title_about\">Про</string>\n    <string name=\"title_permission_grant\">Надати дозволи</string>\n    <string name=\"title_update_available\">Доступне нове оновлення Discord!</string>\n    <string name=\"title_warning\">Попередження</string>\n    <string name=\"title_dl_failed\">Помилка завантаження</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Системна</string>\n    <string name=\"theme_light\">Світла</string>\n    <string name=\"theme_dark\">Темна</string>\n    <string name=\"duration_disabled\">Вимкнено</string>\n    <string name=\"duration_fifteen_min\">Кожну чверть години</string>\n    <string name=\"duration_half_hour\">Кожні пів години</string>\n    <string name=\"duration_hourly\">Кожну годину</string>\n    <string name=\"duration_bihourly\">Кожну другу годину</string>\n    <string name=\"duration_twice_daily\">Двічі на день</string>\n    <string name=\"duration_daily\">Щодня</string>\n    <string name=\"duration_weekly\">Щотижня</string>\n    <string name=\"settings_appearance\">Оформлення</string>\n    <string name=\"settings_appearance_description\">Change the look and feel of the app</string>\n    <string name=\"settings_dynamic_color\">Динамічні кольори</string>\n    <string name=\"settings_dynamic_color_description\">Доступно лише для Android 12 та вище</string>\n    <string name=\"settings_theme\">Тема</string>\n    <string name=\"settings_check_updates\">Перевіряти на оновлення Discord</string>\n    <string name=\"settings_customization\">Customization</string>\n    <string name=\"settings_customization_description\">Customize your Bunny install</string>\n    <string name=\"settings_app_name\">Назва додатку</string>\n    <string name=\"settings_app_icon\">Замінити іконку додатку</string>\n    <string name=\"settings_app_icon_description\">Використовує іконку Bunny замість Discord</string>\n    <string name=\"settings_advanced\">Розширені</string>\n    <string name=\"settings_advanced_description\">Modify downloading and installation</string>\n    <string name=\"settings_channel\">Канал випуску</string>\n    <string name=\"settings_mirror\">Дзеркальне завантаження</string>\n    <string name=\"settings_auto_clear_cache\">Очищати кеш автоматично</string>\n    <string name=\"settings_auto_clear_cache_description\">Очищає кеш, коли Discord отримує оновлення</string>\n    <string name=\"settings_developer\">Тільки для розробників</string>\n    <string name=\"settings_developer_description\">These settings may break things if used improperly</string>\n    <string name=\"settings_module_location\">Розташування модуля</string>\n    <string name=\"settings_module_location_description\">Використовується для розробки Xposed модуля. БУДЬТЕ ОБЕРЕЖНІ</string>\n    <string name=\"settings_module_location_reset\">Відновити розташування модуля</string>\n    <string name=\"settings_package_name\">Назва пакету</string>\n    <string name=\"settings_version\">Версія Discord</string>\n    <string name=\"settings_debuggable\">Налагоджуваний</string>\n    <string name=\"settings_debuggable_description\">Увімкнути налагоджувальний прапорець</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Версія Bunny Менеджер %1$s вже доступна!</string>\n    <string name=\"channel_stable\">Стабільна</string>\n    <string name=\"channel_beta\">Бета</string>\n    <string name=\"channel_alpha\">Альфа</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Команда</string>\n    <string name=\"label_special_thanks\">Окрема подяка</string>\n    <string name=\"label_translate\">Перекласти</string>\n    <string name=\"version_latest\">Остання: %1$s</string>\n    <string name=\"version_target\">Цільова: %1$s</string>\n    <string name=\"version_current\">Поточна: %1$s</string>\n    <string name=\"install_method\">Install method</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-vi-rVN/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Trình quản lý Bunny</string>\n    <string name=\"cd_library_author\">Author: %1$s</string>\n    <string name=\"cd_library_license\">License: %1$s</string>\n    <string name=\"msg_cleared_cache\">Đã xóa bộ nhớ đệm thành công</string>\n    <string name=\"msg_load_fail\">Tải các cập nhật phiên bản thất bại</string>\n    <string name=\"msg_coming_soon\">Sắp ra mắt</string>\n    <string name=\"msg_invalid_version\">Phiên bản Discord không hợp lệ</string>\n    <string name=\"msg_seven_left\">Nhấn thêm 7 lần nữa</string>\n    <string name=\"msg_five_left\">Nhấn thêm 5 lần nữa</string>\n    <string name=\"msg_two_left\">Nhấn thêm 2 lần nữa</string>\n    <string name=\"msg_loading\">Đang tải…</string>\n    <string name=\"msg_downgrade_disallowed\">Không thể hạ cấp, hãy thử gỡ cài đặt trước</string>\n    <string name=\"msg_unlocked\">Bạn hiện là nhà phát triển</string>\n    <string name=\"msg_permission_grant\">Để Trình quản lý Bunny hoạt động, bạn cần cấp quyền truy cập tệp. Do dữ liệu chia sẻ được lưu trữ trong ~/Bunny, nên cần có quyền để truy cập dữ liệu đó.</string>\n    <string name=\"msg_shizuku_denied\">Nhận quyền của Shizuku thất bại</string>\n    <string name=\"msg_change_mirror\">Bạn có muốn thử lại bằng cách sử dụng máy chủ tải xuống khác không?</string>\n    <string name=\"msg_invalid_apk\">APK bị hỏng, hãy thử xóa bộ nhớ đệm rồi cài đặt lại</string>\n    <string name=\"msg_download_cancelled\">Tải xuống đã bị hủy bỏ</string>\n    <string name=\"msg_download_failed\">Tải xuống thất bại</string>\n    <string name=\"msg_download_verify_failed\">Không thể xác minh tệp đã tải, hãy kiểm tra nhật ký để biết thêm chi tiết</string>\n    <string name=\"msg_copied\">Copied to clipboard</string>\n    <string name=\"group_download\">Tải xuống APKs</string>\n    <string name=\"group_patch\">Đang vá</string>\n    <string name=\"group_installing\">Đang cài đặt</string>\n    <string name=\"step_dl_base\">Đang tải xuống base.apk</string>\n    <string name=\"step_dl_lib\">Đang tải xuống các thư viện apk</string>\n    <string name=\"step_dl_lang\">Đang tải xuống ngôn ngữ apk</string>\n    <string name=\"step_dl_res\">Đang tải xuống tài nguyên apk</string>\n    <string name=\"step_dl_vd\">Đang tải xuống mô-đun Bunny</string>\n    <string name=\"step_change_icon\">Đang thay đổi biểu tượng app</string>\n    <string name=\"step_patch_manifests\">Đang vá tệp kê khai ứng dụng</string>\n    <string name=\"step_add_vd\">Đang triển khai Bunny</string>\n    <string name=\"step_signing\">Đang ký tệp APK</string>\n    <string name=\"step_installing\">Đang cài đặt APKs</string>\n    <string name=\"installer_success\">Đã cài đặt thành công</string>\n    <string name=\"installer_aborted\">Đã hủy cài đặt</string>\n    <string name=\"install_fail_generic\">Cài đặt thất bại: Không rõ lý do</string>\n    <string name=\"install_fail_blocked\">Cài đặt đã bị chặn</string>\n    <string name=\"install_fail_invalid\">Một hoặc nhiều tệp APK không hợp lệ hoặc bị hỏng</string>\n    <string name=\"install_fail_conflict\">Xung đột với ứng dụng hiện có, thường là do chữ ký không trùng khớp</string>\n    <string name=\"install_fail_storage\">Không đủ bộ nhớ khả dụng để cài đặt</string>\n    <string name=\"install_fail_incompatible\">Ứng dụng không tương thích với thiết bị này</string>\n    <string name=\"install_fail_timeout\">Hết thời gian chờ cho cài đặt</string>\n    <string name=\"status_ongoing\">Đang thực hiện</string>\n    <string name=\"status_successful\">Thành công</string>\n    <string name=\"status_fail\">Đã thất bại</string>\n    <string name=\"status_queued\">Trong hàng chờ</string>\n    <string name=\"action_collapse\">Thu gọn</string>\n    <string name=\"action_expand\">Mở rộng</string>\n    <string name=\"action_back\">Quay lại</string>\n    <string name=\"action_copy_logs\">Sao chép nhật ký</string>\n    <string name=\"action_clear_cache\">Xóa bộ nhớ đệm</string>\n    <string name=\"action_confirm\">Xác nhận</string>\n    <string name=\"action_start_update\">Bắt đầu cập nhật</string>\n    <string name=\"action_install\">Cài đặt</string>\n    <string name=\"action_update\">Cập nhật</string>\n    <string name=\"action_reinstall\">Cài đặt lại</string>\n    <string name=\"action_launch\">Khởi chạy</string>\n    <string name=\"action_uninstall\">Gỡ cài đặt</string>\n    <string name=\"action_info\">Thông tin</string>\n    <string name=\"action_retry\">Thử lại</string>\n    <string name=\"action_reload\">Tải lại</string>\n    <string name=\"action_open_about\">Mở về</string>\n    <string name=\"action_open_settings\">Mở cài đặt</string>\n    <string name=\"action_tap_to_install\">Nhấn để cài đặt Bunny cho Discord %1$s</string>\n    <string name=\"action_confirm_exit\">Vẫn thoát</string>\n    <string name=\"action_dismiss_nevermind\">Bỏ qua</string>\n    <string name=\"action_dismiss_no_thanks\">Không, cảm ơn</string>\n    <string name=\"action_try_again\">Thử lại</string>\n    <string name=\"action_previous_theme\">Xem chủ đề trước</string>\n    <string name=\"action_next_theme\">Xem chủ đề tiếp theo</string>\n    <string name=\"action_view_logs\">View logs</string>\n    <string name=\"action_show_timestamp\">Show timestamp</string>\n    <string name=\"action_copy_log\">Copy log</string>\n    <string name=\"action_save_logs\">Save logs to file</string>\n    <string name=\"action_share_logs\">Share logs</string>\n    <string name=\"action_more_options\">More options</string>\n    <string name=\"msg_back_warning\">Việc thoát khỏi trình cài đặt trước khi hoàn tất có thể làm hỏng các tệp đã tải, bạn có chắc muốn làm điều đó?</string>\n    <string name=\"installer_cached\">Đã lưu trong bộ nhớ đệm</string>\n    <string name=\"title_installer\">Trình cài đặt</string>\n    <string name=\"title_home\">Trang chủ</string>\n    <string name=\"title_settings\">Cài đặt</string>\n    <string name=\"title_update\">Đã có bản cập nhật mới!</string>\n    <string name=\"title_about\">Về chúng tôi</string>\n    <string name=\"title_permission_grant\">Cấp quyền</string>\n    <string name=\"title_update_available\">Discord đã có bản cập nhật mới!</string>\n    <string name=\"title_warning\">Cảnh báo</string>\n    <string name=\"title_dl_failed\">Tải xuống thất bại</string>\n    <string name=\"title_logs\">Logs</string>\n    <string name=\"title_os_libraries\">Open source libraries</string>\n    <string name=\"title_libraries\">Libraries</string>\n    <string name=\"theme_system\">Hệ thống</string>\n    <string name=\"theme_light\">Sáng</string>\n    <string name=\"theme_dark\">Tối</string>\n    <string name=\"duration_disabled\">Tắt</string>\n    <string name=\"duration_fifteen_min\">Mỗi 15 phút</string>\n    <string name=\"duration_half_hour\">Thời gian nửa giờ</string>\n    <string name=\"duration_hourly\">Mỗi giờ</string>\n    <string name=\"duration_bihourly\">Mỗi 2 giờ</string>\n    <string name=\"duration_twice_daily\">Hai lần mỗi ngày</string>\n    <string name=\"duration_daily\">Hàng ngày</string>\n    <string name=\"duration_weekly\">Hằng tuần</string>\n    <string name=\"settings_appearance\">Giao diện</string>\n    <string name=\"settings_appearance_description\">Thay đổi cái nhìn và cảm nhận của ứng dụng</string>\n    <string name=\"settings_dynamic_color\">Màu động</string>\n    <string name=\"settings_dynamic_color_description\">Chỉ khả dụng trên Android 12 trở lên</string>\n    <string name=\"settings_theme\">Chủ đề</string>\n    <string name=\"settings_check_updates\">Kiểm tra bản cập nhật Discord</string>\n    <string name=\"settings_customization\">Tuỳ biến</string>\n    <string name=\"settings_customization_description\">Tùy chỉnh cài đặt Bunny của bạn</string>\n    <string name=\"settings_app_name\">Tên ứng dụng</string>\n    <string name=\"settings_app_icon\">Thay thế biểu tượng ứng dụng</string>\n    <string name=\"settings_app_icon_description\">Sử dụng biểu tượng Bunny thay vì của Discord</string>\n    <string name=\"settings_advanced\">Nâng cao</string>\n    <string name=\"settings_advanced_description\">Sửa đổi tải xuống và cài đặt</string>\n    <string name=\"settings_channel\">Kênh phát hành</string>\n    <string name=\"settings_mirror\">Máy chủ tải xuống</string>\n    <string name=\"settings_auto_clear_cache\">Xóa bộ nhớ đệm tự động</string>\n    <string name=\"settings_auto_clear_cache_description\">Xóa bộ đệm khi Discord có bản cập nhật</string>\n    <string name=\"settings_developer\">Chỉ dành cho nhà phát triển</string>\n    <string name=\"settings_developer_description\">Những cài đặt này có thể làm hỏng mọi thứ nếu dùng không đúng cách</string>\n    <string name=\"settings_module_location\">Vị trí mô-đun</string>\n    <string name=\"settings_module_location_description\">Để sử dụng để phát triển mô-đun Xposed. HÃY CẨN THẬN</string>\n    <string name=\"settings_module_location_reset\">Đặt lại vị trí mô-đun</string>\n    <string name=\"settings_package_name\">Tên gói</string>\n    <string name=\"settings_version\">Phiên bản Discord</string>\n    <string name=\"settings_debuggable\">Gỡ lỗi</string>\n    <string name=\"settings_debuggable_description\">Bật tùy chọn gỡ lỗi</string>\n    <string name=\"settings_logs_alternate_lines\">Alternate lines</string>\n    <string name=\"settings_logs_line_wrap\">Wrap lines</string>\n    <string name=\"update_description\">Trình quản lý Bunny phiên bản %1$s đang khả dụng!</string>\n    <string name=\"channel_stable\">Ổn định</string>\n    <string name=\"channel_beta\">Beta</string>\n    <string name=\"channel_alpha\">Alpha</string>\n    <string name=\"label_github\">Github</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">Nhóm</string>\n    <string name=\"label_special_thanks\">Đặc biệt cảm ơn</string>\n    <string name=\"label_translate\">Dịch bởi</string>\n    <string name=\"version_latest\">Mới nhất: %1$s</string>\n    <string name=\"version_target\">Mục tiêu: %1$s</string>\n    <string name=\"version_current\">Hiện tại: %1$s</string>\n    <string name=\"install_method\">Cách thức cài đặt</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-zh-rCN/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny 管理器</string>\n    <string name=\"cd_library_author\">作者：%1$s</string>\n    <string name=\"cd_library_license\">许可证：%1$s</string>\n    <string name=\"msg_cleared_cache\">缓存清除成功</string>\n    <string name=\"msg_load_fail\">无法加载提交</string>\n    <string name=\"msg_coming_soon\">敬请期待</string>\n    <string name=\"msg_invalid_version\">无效的 Discord 版本</string>\n    <string name=\"msg_seven_left\">请再点击 7 次</string>\n    <string name=\"msg_five_left\">请再点击 5 次</string>\n    <string name=\"msg_two_left\">请再点击 2 次</string>\n    <string name=\"msg_loading\">载入中…</string>\n    <string name=\"msg_downgrade_disallowed\">无法降级，请先尝试卸载</string>\n    <string name=\"msg_unlocked\">您现在已成为开发者</string>\n    <string name=\"msg_permission_grant\">为了使 Bunny Manager 正常运作，您需要授予「管理所有文件」权限。由于数据存储在 ~/Bunny 中，因此需要权限才能读取它。</string>\n    <string name=\"msg_shizuku_denied\">无法获取Shizuku权限</string>\n    <string name=\"msg_change_mirror\">您想使用下载镜像再试一次吗？</string>\n    <string name=\"msg_invalid_apk\">APK已损坏，请尝试清除缓存后再重新安装</string>\n    <string name=\"msg_download_cancelled\">下载已中止</string>\n    <string name=\"msg_download_failed\">下载失败</string>\n    <string name=\"msg_download_verify_failed\">无法校验下载的文件，请检查日志以了解详细信息</string>\n    <string name=\"msg_copied\">复制到剪贴板</string>\n    <string name=\"group_download\">下载 APK</string>\n    <string name=\"group_patch\">补丁中</string>\n    <string name=\"group_installing\">安装中</string>\n    <string name=\"step_dl_base\">正在下载基础 apk</string>\n    <string name=\"step_dl_lib\">正在下载函式库 apk</string>\n    <string name=\"step_dl_lang\">正在下载语言 apk</string>\n    <string name=\"step_dl_res\">正在下载资源 apk</string>\n    <string name=\"step_dl_vd\">正在下载 Bunny 模块</string>\n    <string name=\"step_change_icon\">正在变更应用程序图标</string>\n    <string name=\"step_patch_manifests\">正在安装补丁应用程序清单</string>\n    <string name=\"step_add_vd\">正在注入 Bunny</string>\n    <string name=\"step_signing\">正在签署 apk</string>\n    <string name=\"step_installing\">正在安装 apk</string>\n    <string name=\"installer_success\">安装成功</string>\n    <string name=\"installer_aborted\">已取消安装</string>\n    <string name=\"install_fail_generic\">安装失败：未知的原因</string>\n    <string name=\"install_fail_blocked\">安装已被阻止</string>\n    <string name=\"install_fail_invalid\">一个或多个 apk 损坏或无效</string>\n    <string name=\"install_fail_conflict\">与现有应用程序冲突，通常是因为签署名不相符造成的</string>\n    <string name=\"install_fail_storage\">您没有足够的存储空间来安装</string>\n    <string name=\"install_fail_incompatible\">此应用程序与您的设备不兼容</string>\n    <string name=\"install_fail_timeout\">安装超时</string>\n    <string name=\"status_ongoing\">进行中</string>\n    <string name=\"status_successful\">成功</string>\n    <string name=\"status_fail\">失败</string>\n    <string name=\"status_queued\">待处理</string>\n    <string name=\"action_collapse\">折迭</string>\n    <string name=\"action_expand\">展开</string>\n    <string name=\"action_back\">返回</string>\n    <string name=\"action_copy_logs\">复制日志</string>\n    <string name=\"action_clear_cache\">清除缓存</string>\n    <string name=\"action_confirm\">确认</string>\n    <string name=\"action_start_update\">开始更新</string>\n    <string name=\"action_install\">安装</string>\n    <string name=\"action_update\">更新</string>\n    <string name=\"action_reinstall\">重新安装</string>\n    <string name=\"action_launch\">启动</string>\n    <string name=\"action_uninstall\">卸载</string>\n    <string name=\"action_info\">信息</string>\n    <string name=\"action_retry\">重试</string>\n    <string name=\"action_reload\">刷新</string>\n    <string name=\"action_open_about\">打开关于</string>\n    <string name=\"action_open_settings\">打开设置</string>\n    <string name=\"action_tap_to_install\">点击为 Discord 安装 Bunny Manager %1$s</string>\n    <string name=\"action_confirm_exit\">坚持推出</string>\n    <string name=\"action_dismiss_nevermind\">没关系</string>\n    <string name=\"action_dismiss_no_thanks\">残忍拒绝</string>\n    <string name=\"action_try_again\">重试</string>\n    <string name=\"action_previous_theme\">查看上一个主题</string>\n    <string name=\"action_next_theme\">查看下一个主题</string>\n    <string name=\"action_view_logs\">查看日志</string>\n    <string name=\"action_show_timestamp\">显示时间戳</string>\n    <string name=\"action_copy_log\">复制日志</string>\n    <string name=\"action_save_logs\">将日志保存到文件目录</string>\n    <string name=\"action_share_logs\">分享日志</string>\n    <string name=\"action_more_options\">更多选项</string>\n    <string name=\"msg_back_warning\">在安装程序完成之前退出可能会损坏下载的文件，您确定要这样做吗？</string>\n    <string name=\"installer_cached\">已缓存</string>\n    <string name=\"title_installer\">安装器</string>\n    <string name=\"title_home\">首页</string>\n    <string name=\"title_settings\">设置</string>\n    <string name=\"title_update\">更新可供使用！</string>\n    <string name=\"title_about\">关于</string>\n    <string name=\"title_permission_grant\">授予权限</string>\n    <string name=\"title_update_available\">有新的 Discord 更新可用！</string>\n    <string name=\"title_warning\">警告</string>\n    <string name=\"title_dl_failed\">下载失败</string>\n    <string name=\"title_logs\">日志</string>\n    <string name=\"title_os_libraries\">开源库</string>\n    <string name=\"title_libraries\">库</string>\n    <string name=\"theme_system\">系统</string>\n    <string name=\"theme_light\">浅色</string>\n    <string name=\"theme_dark\">深色</string>\n    <string name=\"duration_disabled\">停用</string>\n    <string name=\"duration_fifteen_min\">每 15 分钟</string>\n    <string name=\"duration_half_hour\">每半小时</string>\n    <string name=\"duration_hourly\">每小时</string>\n    <string name=\"duration_bihourly\">每两小时</string>\n    <string name=\"duration_twice_daily\">每天两次</string>\n    <string name=\"duration_daily\">每天</string>\n    <string name=\"duration_weekly\">每周</string>\n    <string name=\"settings_appearance\">外观</string>\n    <string name=\"settings_appearance_description\">更改应用程序的外观。</string>\n    <string name=\"settings_dynamic_color\">动态颜色</string>\n    <string name=\"settings_dynamic_color_description\">仅适用于 Android 12 及更高的版本</string>\n    <string name=\"settings_theme\">主题</string>\n    <string name=\"settings_check_updates\">检测 Discord 更新</string>\n    <string name=\"settings_customization\">个性化</string>\n    <string name=\"settings_customization_description\">自定义您的 Bunny 安装</string>\n    <string name=\"settings_app_name\">应用名称</string>\n    <string name=\"settings_app_icon\">更换应用程示图标</string>\n    <string name=\"settings_app_icon_description\">使用 Bunny 图标代替 Discord 图标</string>\n    <string name=\"settings_advanced\">高级</string>\n    <string name=\"settings_advanced_description\">修改下载和安装</string>\n    <string name=\"settings_channel\">发布通道</string>\n    <string name=\"settings_mirror\">下载镜像</string>\n    <string name=\"settings_auto_clear_cache\">自动清除缓存</string>\n    <string name=\"settings_auto_clear_cache_description\">当 Discord 更新时清除缓存</string>\n    <string name=\"settings_developer\">仅限开发者</string>\n    <string name=\"settings_developer_description\">这些设置如果使用不当可能会破坏内容</string>\n    <string name=\"settings_module_location\">模块位置</string>\n    <string name=\"settings_module_location_description\">用于开发 Xposed 模块, 请小心</string>\n    <string name=\"settings_module_location_reset\">重置模块位置</string>\n    <string name=\"settings_package_name\">包名</string>\n    <string name=\"settings_version\">Discord 版本</string>\n    <string name=\"settings_debuggable\">可调试</string>\n    <string name=\"settings_debuggable_description\">启用调试标志</string>\n    <string name=\"settings_logs_alternate_lines\">备用路线</string>\n    <string name=\"settings_logs_line_wrap\">Wrap路线</string>\n    <string name=\"update_description\">Bunny Manager 版本 %1$s 已可供使用！</string>\n    <string name=\"channel_stable\">稳定版</string>\n    <string name=\"channel_beta\">测试版</string>\n    <string name=\"channel_alpha\">早期开发版</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">我们的团队</string>\n    <string name=\"label_special_thanks\">特别感谢</string>\n    <string name=\"label_translate\">协助翻译</string>\n    <string name=\"version_latest\">最新版本：%1$s</string>\n    <string name=\"version_target\">目标：%1$s</string>\n    <string name=\"version_current\">目前版本：%1$s</string>\n    <string name=\"install_method\">选择安装方法</string>\n    <string name=\"default_installer\">软件包安装程序 (推荐)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-zh-rTW/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources xmlns:tools=\"http://schemas.android.com/tools\" tools:ignore=\"MissingTranslation\">\n    <string name=\"app_name\">Bunny Manager</string>\n    <string name=\"cd_library_author\">作者：%1$s</string>\n    <string name=\"cd_library_license\">協議：%1$s</string>\n    <string name=\"msg_cleared_cache\">快取清除完成</string>\n    <string name=\"msg_load_fail\">無法載入提交</string>\n    <string name=\"msg_coming_soon\">敬請期待</string>\n    <string name=\"msg_invalid_version\">無效的 Discord 版本</string>\n    <string name=\"msg_seven_left\">再點擊 7 次</string>\n    <string name=\"msg_five_left\">再點擊 5 次</string>\n    <string name=\"msg_two_left\">再點擊 2 次</string>\n    <string name=\"msg_loading\">載入中…</string>\n    <string name=\"msg_downgrade_disallowed\">無法降級，請先嘗試解除安裝</string>\n    <string name=\"msg_unlocked\">您現在已成為開發人員</string>\n    <string name=\"msg_permission_grant\">為了使 Bunny Manager 正常運作，您需要授予「管理所有檔案」權限。由於資料儲存在 ~/Bunny 中，因此需要權限才能讀取它。</string>\n    <string name=\"msg_shizuku_denied\">取得 Shizuku 權限失敗</string>\n    <string name=\"msg_change_mirror\">您想使用下載鏡像再試一次嗎？</string>\n    <string name=\"msg_invalid_apk\">APK 已損壞，請嘗試清除快取然後重新安裝</string>\n    <string name=\"msg_download_cancelled\">下載中斷</string>\n    <string name=\"msg_download_failed\">下載失敗</string>\n    <string name=\"msg_download_verify_failed\">無法驗證已下載的檔案，檢視記錄檔以獲得更多詳細資訊</string>\n    <string name=\"msg_copied\">已複製到剪貼簿</string>\n    <string name=\"group_download\">下載 APK</string>\n    <string name=\"group_patch\">安裝修補工具中</string>\n    <string name=\"group_installing\">安裝中</string>\n    <string name=\"step_dl_base\">正在下載基礎 apk</string>\n    <string name=\"step_dl_lib\">正在下載函式庫 apk</string>\n    <string name=\"step_dl_lang\">正在下載語言 apk</string>\n    <string name=\"step_dl_res\">正在下載資源 apk</string>\n    <string name=\"step_dl_vd\">正在下載 Bunny 模組</string>\n    <string name=\"step_change_icon\">正在變更應用程式圖示</string>\n    <string name=\"step_patch_manifests\">正在安裝應用程式修補工具</string>\n    <string name=\"step_add_vd\">正在注入 Bunny</string>\n    <string name=\"step_signing\">正在簽署 apk</string>\n    <string name=\"step_installing\">正在安裝 apk</string>\n    <string name=\"installer_success\">成功安裝</string>\n    <string name=\"installer_aborted\">已取消安裝</string>\n    <string name=\"install_fail_generic\">安裝失敗：未知的原因</string>\n    <string name=\"install_fail_blocked\">安裝已被阻止</string>\n    <string name=\"install_fail_invalid\">一個或多個 apk 損壞或無效</string>\n    <string name=\"install_fail_conflict\">與現有應用程式衝突，通常是因為簽署名不相符造成的</string>\n    <string name=\"install_fail_storage\">您沒有足夠的儲存空間來安裝</string>\n    <string name=\"install_fail_incompatible\">此應用程式與您的裝置不相容</string>\n    <string name=\"install_fail_timeout\">安裝超時</string>\n    <string name=\"status_ongoing\">進行中</string>\n    <string name=\"status_successful\">成功</string>\n    <string name=\"status_fail\">失敗</string>\n    <string name=\"status_queued\">待處理</string>\n    <string name=\"action_collapse\">折疊</string>\n    <string name=\"action_expand\">展開</string>\n    <string name=\"action_back\">返回</string>\n    <string name=\"action_copy_logs\">複製記錄檔</string>\n    <string name=\"action_clear_cache\">清除快取</string>\n    <string name=\"action_confirm\">確定</string>\n    <string name=\"action_start_update\">開始更新</string>\n    <string name=\"action_install\">安裝</string>\n    <string name=\"action_update\">更新</string>\n    <string name=\"action_reinstall\">重新安裝</string>\n    <string name=\"action_launch\">啟動</string>\n    <string name=\"action_uninstall\">解除安裝</string>\n    <string name=\"action_info\">資訊</string>\n    <string name=\"action_retry\">重試</string>\n    <string name=\"action_reload\">重新整理</string>\n    <string name=\"action_open_about\">開啟關於</string>\n    <string name=\"action_open_settings\">開啟設定</string>\n    <string name=\"action_tap_to_install\">點擊為 Discord 安裝 Bunny Manager %1$s</string>\n    <string name=\"action_confirm_exit\">無論如何都要退出</string>\n    <string name=\"action_dismiss_nevermind\">沒關係</string>\n    <string name=\"action_dismiss_no_thanks\">不用</string>\n    <string name=\"action_try_again\">重試</string>\n    <string name=\"action_previous_theme\">看上一個主題</string>\n    <string name=\"action_next_theme\">看下一個主題</string>\n    <string name=\"action_view_logs\">檢視記錄檔</string>\n    <string name=\"action_show_timestamp\">顯示更新時間</string>\n    <string name=\"action_copy_log\">複製記錄檔</string>\n    <string name=\"action_save_logs\">儲存記錄檔到檔案</string>\n    <string name=\"action_share_logs\">分享記錄檔</string>\n    <string name=\"action_more_options\">更多選項</string>\n    <string name=\"msg_back_warning\">在安裝程序完成之前退出可能會損壞下載的檔案，您確定要這樣做嗎？</string>\n    <string name=\"installer_cached\">已快取</string>\n    <string name=\"title_installer\">安裝程式</string>\n    <string name=\"title_home\">首頁</string>\n    <string name=\"title_settings\">設定</string>\n    <string name=\"title_update\">有可供使用的更新！</string>\n    <string name=\"title_about\">關於</string>\n    <string name=\"title_permission_grant\">授予權限</string>\n    <string name=\"title_update_available\">有可供使用的新 Discord 更新！</string>\n    <string name=\"title_warning\">警告</string>\n    <string name=\"title_dl_failed\">下載失敗</string>\n    <string name=\"title_logs\">記錄檔</string>\n    <string name=\"title_os_libraries\">開放原始碼函式庫</string>\n    <string name=\"title_libraries\">函式庫</string>\n    <string name=\"theme_system\">系統</string>\n    <string name=\"theme_light\">淺色</string>\n    <string name=\"theme_dark\">深色</string>\n    <string name=\"duration_disabled\">停用</string>\n    <string name=\"duration_fifteen_min\">每 15 分鐘</string>\n    <string name=\"duration_half_hour\">每半小時</string>\n    <string name=\"duration_hourly\">每小時</string>\n    <string name=\"duration_bihourly\">每兩小時</string>\n    <string name=\"duration_twice_daily\">每天兩次</string>\n    <string name=\"duration_daily\">每天</string>\n    <string name=\"duration_weekly\">每週</string>\n    <string name=\"settings_appearance\">外觀</string>\n    <string name=\"settings_appearance_description\">變更應用程式的外觀</string>\n    <string name=\"settings_dynamic_color\">動態顏色</string>\n    <string name=\"settings_dynamic_color_description\">僅適用於 Android 12 及更高的版本</string>\n    <string name=\"settings_theme\">主題</string>\n    <string name=\"settings_check_updates\">檢查 Discord 更新</string>\n    <string name=\"settings_customization\">客製化</string>\n    <string name=\"settings_customization_description\">客製化安裝您的 Bunny</string>\n    <string name=\"settings_app_name\">應用程式名稱</string>\n    <string name=\"settings_app_icon\">更換應用程示圖示</string>\n    <string name=\"settings_app_icon_description\">使用 Bunny 圖示代替 Discord 圖示</string>\n    <string name=\"settings_advanced\">進階</string>\n    <string name=\"settings_advanced_description\">修改下載與安裝</string>\n    <string name=\"settings_channel\">發布通道</string>\n    <string name=\"settings_mirror\">下載鏡像</string>\n    <string name=\"settings_auto_clear_cache\">自動清除快取</string>\n    <string name=\"settings_auto_clear_cache_description\">當 Discord 更新時清除快取</string>\n    <string name=\"settings_developer\">僅限開發人員</string>\n    <string name=\"settings_developer_description\">如果使用不當，可能會損壞這些設定</string>\n    <string name=\"settings_module_location\">模組位置</string>\n    <string name=\"settings_module_location_description\">請小心，此用於開發 Xposed 模組。</string>\n    <string name=\"settings_module_location_reset\">重設模組位置</string>\n    <string name=\"settings_package_name\">套件名稱</string>\n    <string name=\"settings_version\">Discord 版本</string>\n    <string name=\"settings_debuggable\">除錯模式</string>\n    <string name=\"settings_debuggable_description\">啟用除錯模式</string>\n    <string name=\"settings_logs_alternate_lines\">取代行線</string>\n    <string name=\"settings_logs_line_wrap\">換行線</string>\n    <string name=\"update_description\">Bunny Manager 版本 %1$s 已可供使用！</string>\n    <string name=\"channel_stable\">穩定版（Stable）</string>\n    <string name=\"channel_beta\">測試版（Beta）</string>\n    <string name=\"channel_alpha\">早期開發版（Alpha）</string>\n    <string name=\"label_github\">GitHub</string>\n    <string name=\"label_discord\">Discord</string>\n    <string name=\"label_team\">團隊</string>\n    <string name=\"label_special_thanks\">特別感謝</string>\n    <string name=\"label_translate\">協助翻譯</string>\n    <string name=\"version_latest\">最新版本：%1$s</string>\n    <string name=\"version_target\">目標：%1$s</string>\n    <string name=\"version_current\">目前版本：%1$s</string>\n    <string name=\"install_method\">安裝方法</string>\n    <string name=\"default_installer\">Default (recommended)</string>\n    <string name=\"shizuku_installer\">Shizuku</string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/xml/backup_rules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n   Sample backup rules file; uncomment and customize as necessary.\n   See https://developer.android.com/guide/topics/data/autobackup\n   for details.\n   Note: This file is ignored for devices older that API 31\n   See https://developer.android.com/about/versions/12/backup-restore\n-->\n<full-backup-content>\n    <!--\n   <include domain=\"sharedpref\" path=\".\"/>\n   <exclude domain=\"sharedpref\" path=\"device.xml\"/>\n-->\n</full-backup-content>"
  },
  {
    "path": "app/src/main/res/xml/data_extraction_rules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n   Sample data extraction rules file; uncomment and customize as necessary.\n   See https://developer.android.com/about/versions/12/backup-restore#xml-changes\n   for details.\n-->\n<data-extraction-rules>\n    <cloud-backup>\n        <!-- TODO: Use <include> and <exclude> to control what is backed up.\n        <include .../>\n        <exclude .../>\n        -->\n    </cloud-backup>\n    <!--\n    <device-transfer>\n        <include .../>\n        <exclude .../>\n    </device-transfer>\n    -->\n</data-extraction-rules>"
  },
  {
    "path": "app/src/main/res/xml/locales_config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<locale-config xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <locale android:name=\"af-ZA\"/>\n    <locale android:name=\"ar-SA\"/>\n    <locale android:name=\"ca-ES\"/>\n    <locale android:name=\"cs-CZ\"/>\n    <locale android:name=\"da-DK\"/>\n    <locale android:name=\"de-DE\"/>\n    <locale android:name=\"el-GR\"/>\n    <locale android:name=\"en-US\"/>\n    <locale android:name=\"es-ES\"/>\n    <locale android:name=\"fi-FI\"/>\n    <locale android:name=\"fil-PH\"/>\n    <locale android:name=\"fr-FR\"/>\n    <locale android:name=\"hu-HU\"/>\n    <locale android:name=\"it-IT\"/>\n    <locale android:name=\"iw-IL\"/>\n    <locale android:name=\"ja-JP\"/>\n    <locale android:name=\"ko-KR\"/>\n    <locale android:name=\"nl-NL\"/>\n    <locale android:name=\"no-NO\"/>\n    <locale android:name=\"pl-PL\"/>\n    <locale android:name=\"pt-BR\"/>\n    <locale android:name=\"pt-PT\"/>\n    <locale android:name=\"ro-RO\"/>\n    <locale android:name=\"ru-RU\"/>\n    <locale android:name=\"sr-SP\"/>\n    <locale android:name=\"sv-SE\"/>\n    <locale android:name=\"tr-TR\"/>\n    <locale android:name=\"uk-UA\"/>\n    <locale android:name=\"vi-VN\"/>\n    <locale android:name=\"zh-CN\"/>\n    <locale android:name=\"zh-TW\"/>\n    <locale android:name=\"or-IN\"/>\n</locale-config>"
  },
  {
    "path": "app/src/main/res/xml/provider_paths.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<paths>\n    <files-path name=\"temp_logs\" path=\"logsTmp/\"/>\n</paths>"
  },
  {
    "path": "build.gradle.kts",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nplugins {\n    alias(libs.plugins.aboutlibraries) apply false\n    alias(libs.plugins.android.application) apply false\n    alias(libs.plugins.android.library) apply false\n    alias(libs.plugins.kotlin.android) apply false\n    alias(libs.plugins.compose.compiler) apply false\n}\n\ntasks.withType<Copy>().all {\n    duplicatesStrategy = DuplicatesStrategy.INCLUDE\n}\n\nallprojects {\n    repositories {\n        google()\n        mavenCentral()\n        maven(\"https://maven.aliucord.com/snapshots\")\n        maven(\"https://jitpack.io\")\n    }\n}"
  },
  {
    "path": "gradle/libs.versions.toml",
    "content": "[versions]\n# Plugins\nagp = \"8.8.1\"\nkotlin = \"2.0.21\"\n\n# AndroidX\nandroidx-core-ktx = \"1.15.0\"\nandroidx-core-splashscreen = \"1.0.1\"\nandroidx-lifecycle-runtime = \"2.8.7\"\nandroidx-paging-compose = \"3.3.4\"\nandroidx-work-runtime = \"2.10.0\"\n\n# Compose\ncompose-activity = \"1.9.3\"\ncompose-bom = \"2024.11.00\"\n\n# Misc.\naboutlibraries = \"11.1.3\"\naccompanist = \"0.36.0\"\nbinary-resources = \"2.0.0\"\ncoil = \"2.7.0\"\nkoin = \"4.0.0\"\nkotlinx-datetime = \"0.6.1\"\nkotlinx-collections = \"0.3.8\"\nktor = \"3.0.1\"\nshizuku = \"13.1.0\"\nvoyager = \"1.1.0-beta03\"\nzip-android = \"2.1.1\"\n\n[libraries]\n\n# Accompanist\naccompanist-pager = { group = \"com.google.accompanist\", name = \"accompanist-pager\", version.ref = \"accompanist\" }\naccompanist-permissions = { group = \"com.google.accompanist\", name = \"accompanist-permissions\", version.ref = \"accompanist\" }\naccompanist-systemuicontroller = { group = \"com.google.accompanist\", name = \"accompanist-systemuicontroller\", version.ref = \"accompanist\" }\n\n# AndroidX\nandroidx-core-ktx = { group = \"androidx.core\", name = \"core-ktx\", version.ref = \"androidx-core-ktx\" }\nandroidx-core-splashscreen = { group = \"androidx.core\", name = \"core-splashscreen\", version.ref = \"androidx-core-splashscreen\" }\nandroidx-lifecycle-runtime = { group = \"androidx.lifecycle\", name = \"lifecycle-runtime-ktx\", version.ref = \"androidx-lifecycle-runtime\" }\nandroidx-paging-compose = { group = \"androidx.paging\", name = \"paging-compose\", version.ref = \"androidx-paging-compose\" }\nandroidx-work-runtime = { group = \"androidx.work\", name = \"work-runtime-ktx\", version.ref = \"androidx-work-runtime\" }\n\n# Coil\ncoil = { group = \"io.coil-kt\", name = \"coil\", version.ref = \"coil\" }\ncoil-compose = { group = \"io.coil-kt\", name = \"coil-compose\", version.ref = \"coil\" }\n\n# Compose\ncompose-activity = { group = \"androidx.activity\", name = \"activity-compose\", version.ref = \"compose-activity\" }\ncompose-bom = { group = \"androidx.compose\", name = \"compose-bom\", version.ref = \"compose-bom\" }\ncompose-material3 = { group = \"androidx.compose.material3\", name = \"material3\" }\ncompose-material-icons-extended = { group = \"androidx.compose.material\", name = \"material-icons-extended\" }\ncompose-ui = { group = \"androidx.compose.ui\", name = \"ui\" }\ncompose-ui-graphics = { group = \"androidx.compose.ui\", name = \"ui-graphics\" }\ncompose-ui-tooling-preview = { group = \"androidx.compose.ui\", name = \"ui-tooling-preview\" }\n\n# Koin\nkoin-android = { group = \"io.insert-koin\", name = \"koin-android\", version.ref = \"koin\" }\nkoin-androidx-compose = { group = \"io.insert-koin\", name = \"koin-androidx-compose\", version.ref = \"koin\" }\nkoin-core = { group = \"io.insert-koin\", name = \"koin-core\", version.ref = \"koin\" }\n\n# Ktor\nktor-client-core = { group = \"io.ktor\", name = \"ktor-client-core\", version.ref = \"ktor\" }\nktor-client-cio = { group = \"io.ktor\", name = \"ktor-client-cio\", version.ref = \"ktor\" }\nktor-client-content-negotiation = { group = \"io.ktor\", name = \"ktor-client-content-negotiation\", version.ref = \"ktor\" }\nktor-serialization-kotlinx-json = { group = \"io.ktor\", name = \"ktor-serialization-kotlinx-json\", version.ref = \"ktor\" }\nktor-client-logging = { group = \"io.ktor\", name = \"ktor-client-logging\", version.ref = \"ktor\" }\n\n# Shizuku\nshizuku-api = { group = \"dev.rikka.shizuku\", name = \"api\", version.ref = \"shizuku\" }\nshizuku-provider = { group = \"dev.rikka.shizuku\", name = \"provider\", version.ref = \"shizuku\" }\n\n# Voyager\nvoyager-navigator = { group = \"cafe.adriel.voyager\", name = \"voyager-navigator\", version.ref = \"voyager\" }\nvoyager-screenmodel = { group = \"cafe.adriel.voyager\", name = \"voyager-screenmodel\", version.ref = \"voyager\" }\nvoyager-tab-navigator = { group = \"cafe.adriel.voyager\", name = \"voyager-tab-navigator\", version.ref = \"voyager\" }\nvoyager-transitions = { group = \"cafe.adriel.voyager\", name = \"voyager-transitions\", version.ref = \"voyager\" }\nvoyager-koin = { group = \"cafe.adriel.voyager\", name = \"voyager-koin\", version.ref = \"voyager\" }\n\n# Misc.\naboutlibraries-core = { group = \"com.mikepenz\", name = \"aboutlibraries\", version.ref = \"aboutlibraries\" }\nbinaryResources = { module = \"com.aliucord:binary-resources\", version.ref = \"binary-resources\" }\nkotlinx-datetime = { group = \"org.jetbrains.kotlinx\", name = \"kotlinx-datetime\", version.ref = \"kotlinx-datetime\" }\nkotlinx-collections = { group = \"org.jetbrains.kotlinx\", name = \"kotlinx-collections-immutable\", version.ref = \"kotlinx-collections\" }\nzip-android = { group = \"io.github.diamondminer88\", name = \"zip-android\", version.ref = \"zip-android\" }\n\n[bundles]\naccompanist = [\"accompanist-pager\", \"accompanist-permissions\", \"accompanist-systemuicontroller\"]\nandroidx = [\"androidx-work-runtime\", \"androidx-paging-compose\", \"androidx-lifecycle-runtime\", \"androidx-core-splashscreen\", \"androidx-core-ktx\"]\ncoil = [\"coil\", \"coil-compose\"]\ncompose = [\"compose-activity\", \"compose-material-icons-extended\", \"compose-material3\", \"compose-ui\", \"compose-ui-graphics\", \"compose-ui-tooling-preview\"]\nkoin = [\"koin-android\", \"koin-androidx-compose\", \"koin-core\"]\nktor = [\"ktor-client-cio\", \"ktor-client-content-negotiation\", \"ktor-client-core\", \"ktor-client-logging\", \"ktor-serialization-kotlinx-json\"]\nshizuku = [\"shizuku-api\", \"shizuku-provider\"]\nvoyager = [\"voyager-koin\", \"voyager-navigator\", \"voyager-tab-navigator\", \"voyager-transitions\", \"voyager-screenmodel\"]\n\n[plugins]\naboutlibraries = { id = \"com.mikepenz.aboutlibraries.plugin\", version.ref = \"aboutlibraries\"}\nandroid-application = { id = \"com.android.application\", version.ref = \"agp\" }\nandroid-library = { id = \"com.android.library\", version.ref = \"agp\" }\nkotlin-android = { id = \"org.jetbrains.kotlin.android\", version.ref = \"kotlin\" }\ncompose-compiler = { id = \"org.jetbrains.kotlin.plugin.compose\", version.ref = \"kotlin\" }\nkotlin-serialization = { id = \"org.jetbrains.kotlin.plugin.serialization\", version.ref = \"kotlin\" }"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Wed Aug 09 19:03:47 EDT 2023\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.10.2-bin.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n# AndroidX package structure to make it clearer which packages are bundled with the\n# Android operating system, and which are packaged with your app's APK\n# https://developer.android.com/topic/libraries/support-library/androidx-rn\nandroid.useAndroidX=true\n# Kotlin code style for this project: \"official\" or \"obsolete\":\nkotlin.code.style=official\n# Enables namespacing of each library's R class so that its R class includes only the\n# resources declared in the library itself and none from the library's dependencies,\n# thereby reducing the size of the R class for that library\nandroid.nonTransitiveRClass=true\n# Enable R8 full mode.\nandroid.enableR8.fullMode=true"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif [ \"$cygwin\" = \"true\" -o \"$msys\" = \"true\" ] ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=`expr $i + 1`\n    done\n    case $i in\n        0) set -- ;;\n        1) set -- \"$args0\" ;;\n        2) set -- \"$args0\" \"$args1\" ;;\n        3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=`save \"$@\"`\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "settings.gradle.kts",
    "content": "pluginManagement {\n    repositories {\n        google()\n        mavenCentral()\n        gradlePluginPortal()\n    }\n}\n\nrootProject.name = \"Bunny Manager\"\ninclude(\":app\")\n"
  }
]