From fec13ad15bb8ce7a2b3e8995352af4583e869c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ho=C3=A0ng=20Gia=20B=E1=BA=A3o?= <70064328+YT-Advanced@users.noreply.github.com> Date: Sat, 22 Mar 2025 08:32:46 +0700 Subject: [PATCH 01/77] fix(YouTube - Spoof app version): Remove broken spoof targets that YouTube no longer supports (#145) * Drop support for `v18.xx.xx` * fix: Apply code review suggestions * fix: Apply code review suggestions * fix: Apply code review suggestions --------- Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com> --- .../extension/youtube/settings/Settings.java | 12 ++++ .../spoofappversion/SpoofAppVersionPatch.kt | 58 +++++++++++-------- .../DescriptionComponentsPatch.kt | 5 +- .../player/descriptions/Fingerprints.kt | 2 +- .../youtube/utils/compatibility/Constants.kt | 4 -- .../utils/playservice/VersionCheckPatch.kt | 8 ++- .../youtube/settings/host/values/strings.xml | 3 +- 7 files changed, 58 insertions(+), 34 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 6ea0ffe24..4042cdf78 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -28,6 +28,8 @@ import app.revanced.extension.shared.settings.LongSetting; import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.settings.StringSetting; import app.revanced.extension.shared.settings.preference.SharedPrefCategory; +import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.patches.alternativethumbnails.AlternativeThumbnailsPatch.DeArrowAvailability; import app.revanced.extension.youtube.patches.alternativethumbnails.AlternativeThumbnailsPatch.StillImagesAvailability; import app.revanced.extension.youtube.patches.alternativethumbnails.AlternativeThumbnailsPatch.ThumbnailOption; @@ -637,6 +639,16 @@ public class Settings extends BaseSettings { static { // region Migration initialized + + // Old spoof versions that no longer work reliably. + String spoofAppVersionTarget = SPOOF_APP_VERSION_TARGET.get(); + if (spoofAppVersionTarget.compareTo(SPOOF_APP_VERSION_TARGET.defaultValue) < 0) { + Utils.showToastShort(str("revanced_spoof_app_version_target_invalid_toast", spoofAppVersionTarget)); + Utils.showToastShort(str("revanced_extended_reset_to_default_toast")); + Logger.printInfo(() -> "Resetting spoof app version target"); + SPOOF_APP_VERSION_TARGET.resetToDefault(); + } + // Categories were previously saved without a 'sb_' key prefix, so they need an additional adjustment. Set> sbCategories = new HashSet<>(Arrays.asList( SB_CATEGORY_SPONSOR, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt index 5177e36c7..ae0259731 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/spoofappversion/SpoofAppVersionPatch.kt @@ -16,7 +16,7 @@ import app.revanced.patches.youtube.utils.patch.PatchList.SPOOF_APP_VERSION import app.revanced.patches.youtube.utils.playservice.is_18_34_or_greater import app.revanced.patches.youtube.utils.playservice.is_18_39_or_greater import app.revanced.patches.youtube.utils.playservice.is_18_49_or_greater -import app.revanced.patches.youtube.utils.playservice.is_19_17_or_greater +import app.revanced.patches.youtube.utils.playservice.is_19_01_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_23_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_28_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater @@ -45,6 +45,15 @@ private val spoofAppVersionBytecodePatch = bytecodePatch( dependsOn(versionCheckPatch) execute { + if (is_19_01_or_greater) { + findMethodOrThrow(PATCH_STATUS_CLASS_DESCRIPTOR) { + name == "SpoofAppVersionDefaultString" + }.replaceInstruction( + 0, + "const-string v0, \"19.01.34\"" + ) + } + if (!is_19_23_or_greater) { return@execute } @@ -72,13 +81,6 @@ private val spoofAppVersionBytecodePatch = bytecodePatch( """, ExternalLabel("ignore", getInstruction(jumpIndex)) ) } - - findMethodOrThrow(PATCH_STATUS_CLASS_DESCRIPTOR) { - name == "SpoofAppVersionDefaultString" - }.replaceInstruction( - 0, - "const-string v0, \"18.38.45\"" - ) } } @@ -108,35 +110,43 @@ val spoofAppVersionPatch = resourcePatch( SPOOF_APP_VERSION ) - if (!is_19_17_or_greater) { + // TODO: Remove this when the legacy code for YouTube 18.xx is cleaned up. + if (!is_19_01_or_greater) { appendAppVersion("17.41.37") appendAppVersion("18.05.40") appendAppVersion("18.17.43") - if (!is_18_34_or_greater) { + + if (is_18_34_or_greater) { + appendAppVersion("18.33.40") + } else { return@execute } - appendAppVersion("18.33.40") - } - if (!is_18_39_or_greater) { + if (is_18_39_or_greater) { + appendAppVersion("18.38.45") + } else { + return@execute + } + + if (is_18_49_or_greater) { + appendAppVersion("18.48.39") + } + return@execute } - appendAppVersion("18.38.45") - if (!is_18_49_or_greater) { + appendAppVersion("19.01.34") + + if (is_19_28_or_greater) { + appendAppVersion("19.26.42") + } else { return@execute } - appendAppVersion("18.48.39") - if (!is_19_28_or_greater) { + if (is_19_34_or_greater) { + appendAppVersion("19.33.37") + } else { return@execute } - appendAppVersion("19.26.42") - - if (!is_19_34_or_greater) { - return@execute - } - appendAppVersion("19.33.37") - } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/DescriptionComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/DescriptionComponentsPatch.kt index 12be08c50..ac753a6fe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/DescriptionComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/DescriptionComponentsPatch.kt @@ -15,7 +15,7 @@ import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_CLASS_DESCR import app.revanced.patches.youtube.utils.patch.PatchList.DESCRIPTION_COMPONENTS import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch import app.revanced.patches.youtube.utils.playservice.is_18_49_or_greater -import app.revanced.patches.youtube.utils.playservice.is_19_02_or_greater +import app.revanced.patches.youtube.utils.playservice.is_19_05_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverHook import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverPatch @@ -93,8 +93,7 @@ val descriptionComponentsPatch = bytecodePatch( // region patch for disable video description interaction and expand video description - // since these patches are still A/B tested, they are classified as 'Experimental flags'. - if (is_19_02_or_greater) { + if (is_19_05_or_greater) { textViewComponentFingerprint.methodOrThrow().apply { val insertIndex = indexOfTextIsSelectableInstruction(this) val insertInstruction = getInstruction(insertIndex) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/Fingerprints.kt index 0fccda3a4..dd98d2908 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/descriptions/Fingerprints.kt @@ -9,7 +9,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference /** * This fingerprint is compatible with YouTube v18.35.xx~ - * Nonetheless, the patch works in YouTube v19.02.xx~ + * Nonetheless, the patch works in YouTube v19.05.xx~ */ internal val textViewComponentFingerprint = legacyFingerprint( name = "textViewComponentFingerprint", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt index 0ac2b447c..81fe49258 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt @@ -9,10 +9,6 @@ internal object Constants { val COMPATIBLE_PACKAGE: Pair?> = Pair( YOUTUBE_PACKAGE_NAME, setOf( - "18.29.38", // This is the last version where the 'Zoomed to fill' setting works. - "18.33.40", // This is the last version that do not use litho components in Shorts. - "18.38.44", // This is the last version with no delay in applying video quality on the server side. - "18.48.39", // This is the last version that do not use Rolling Number. "19.05.36", // This is the last version with the least YouTube experimental flag. "19.16.39", // This is the last version where the 'Restore old seekbar thumbnails' setting works. "19.44.39", // This is the latest version supported by the RVX patch. diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt index ef0ca18fa..bdbf30c72 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt @@ -15,10 +15,14 @@ var is_18_42_or_greater = false private set var is_18_49_or_greater = false private set +var is_19_01_or_greater = false + private set var is_19_02_or_greater = false private set var is_19_04_or_greater = false private set +var is_19_05_or_greater = false + private set var is_19_09_or_greater = false private set var is_19_15_or_greater = false @@ -83,8 +87,10 @@ val versionCheckPatch = resourcePatch( is_18_39_or_greater = 234000000 <= playStoreServicesVersion is_18_42_or_greater = 234302000 <= playStoreServicesVersion is_18_49_or_greater = 235000000 <= playStoreServicesVersion - is_19_02_or_greater = 240204000 < playStoreServicesVersion + is_19_01_or_greater = 240204000 < playStoreServicesVersion + is_19_02_or_greater = 240299000 < playStoreServicesVersion is_19_04_or_greater = 240502000 <= playStoreServicesVersion + is_19_05_or_greater = 240602000 <= playStoreServicesVersion is_19_09_or_greater = 241002000 <= playStoreServicesVersion is_19_15_or_greater = 241602000 <= playStoreServicesVersion is_19_16_or_greater = 241702000 <= playStoreServicesVersion diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index b174045f1..7809e27e0 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -477,8 +477,10 @@ If later turned off, it is recommended to clear the app data to prevent UI bugs. 18.33.40 - Restore old Shorts action bar 18.38.45 - Restore old default video quality behavior 18.48.39 - Disable views and likes from being updated in real time + 19.01.34 - Disable video description interaction 19.26.42 - Disable Cairo icon in navigation and toolbar 19.33.37 - Restore old playback speed flyout panel + Invalid spoof app version: %s. Account menu @@ -1510,7 +1512,6 @@ Info: "Custom actions are enabled in flyout menu. Limitations: -• Does not work if app version is spoofed to 18.49.37 or earlier. • Does not work with live stream." Custom actions are disabled in flyout menu. Enable custom actions in toolbar From c85816bbe9759e5fe5fc1a5b7a712cf48e78a894 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 22 Mar 2025 11:37:46 +0900 Subject: [PATCH 02/77] fix(YouTube - Shorts components): `Autoplay` option of `Change Shorts repeat state` not working (20.09+) --- .../shorts/ShortsRepeatStatePatch.java | 45 +++-- .../youtube/shorts/components/Fingerprints.kt | 36 ++++ .../shorts/components/ShortsComponentPatch.kt | 166 +++++++++++++----- .../patches/youtube/utils/Fingerprints.kt | 25 +++ .../utils/playservice/VersionCheckPatch.kt | 3 + .../youtube/video/information/Fingerprints.kt | 24 --- .../information/VideoInformationPatch.kt | 1 + .../youtube/settings/host/values/arrays.xml | 2 - 8 files changed, 223 insertions(+), 79 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/ShortsRepeatStatePatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/ShortsRepeatStatePatch.java index 50933c1f7..f8fa0890b 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/ShortsRepeatStatePatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/ShortsRepeatStatePatch.java @@ -2,6 +2,8 @@ package app.revanced.extension.youtube.patches.shorts; import android.app.Activity; +import androidx.annotation.Nullable; + import java.lang.ref.WeakReference; import java.util.Objects; @@ -28,11 +30,16 @@ public class ShortsRepeatStatePatch { END_SCREEN; static void setYTEnumValue(Enum ytBehavior) { + String ytName = ytBehavior.name(); for (ShortsLoopBehavior rvBehavior : values()) { - if (ytBehavior.name().endsWith(rvBehavior.name())) { - rvBehavior.ytEnumValue = ytBehavior; - - Logger.printDebug(() -> rvBehavior + " set to YT enum: " + ytBehavior.name()); + if (ytName.endsWith(rvBehavior.name())) { + if (rvBehavior.ytEnumValue != null) { + Logger.printException(() -> "Conflicting behavior names: " + rvBehavior + + " ytBehavior: " + ytName); + } else { + rvBehavior.ytEnumValue = ytBehavior; + Logger.printDebug(() -> rvBehavior + " set to YT enum: " + ytName); + } return; } } @@ -77,25 +84,39 @@ public class ShortsRepeatStatePatch { /** * Injection point. */ - public static Enum changeShortsRepeatBehavior(Enum original) { + @Nullable + public static Enum changeShortsRepeatBehavior(@Nullable Enum original) { try { - final ShortsLoopBehavior behavior = ExtendedUtils.IS_19_34_OR_GREATER && + if (original == null) { + Logger.printDebug(() -> "Original is null, returning null"); + return null; + } + + ShortsLoopBehavior behavior = ExtendedUtils.IS_19_34_OR_GREATER && isAppInBackgroundPiPMode() ? Settings.CHANGE_SHORTS_BACKGROUND_REPEAT_STATE.get() : Settings.CHANGE_SHORTS_REPEAT_STATE.get(); + Enum overrideBehavior = behavior.ytEnumValue; - if (behavior != ShortsLoopBehavior.UNKNOWN && behavior.ytEnumValue != null) { - Logger.printDebug(() -> behavior.ytEnumValue == original - ? "Changing Shorts repeat behavior from: " + original.name() + " to: " + behavior.ytEnumValue - : "Behavior setting is same as original. Using original: " + original.name() + if (overrideBehavior != null) { + Logger.printDebug(() -> overrideBehavior == original + ? "Behavior setting is same as original. Using original: " + original.name() + : "Changing Shorts repeat behavior from: " + original.name() + " to: " + overrideBehavior.name() ); - return behavior.ytEnumValue; + return overrideBehavior; } } catch (Exception ex) { - Logger.printException(() -> "changeShortsRepeatState failure", ex); + Logger.printException(() -> "changeShortsRepeatBehavior failure", ex); } return original; } + + /** + * Injection point. + */ + public static boolean isAutoPlay(@Nullable Enum original) { + return original != null && ShortsLoopBehavior.SINGLE_PLAY.ytEnumValue == original; + } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt index 00f4cc521..633d8c019 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt @@ -20,6 +20,7 @@ import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference import kotlin.collections.listOf @@ -71,6 +72,41 @@ internal val reelEnumStaticFingerprint = legacyFingerprint( returnType = "L" ) +/** + * YouTube 18.49.36 ~ + */ +internal val reelPlaybackRepeatFingerprint = legacyFingerprint( + name = "reelPlaybackRepeatFingerprint", + returnType = "V", + parameters = listOf("L"), + strings = listOf("YoutubePlayerState is in throwing an Error.") +) + +internal val reelPlaybackFingerprint = legacyFingerprint( + name = "reelPlaybackFingerprint", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("J"), + returnType = "V", + customFingerprint = { method, _ -> + indexOfMilliSecondsInstruction(method) >= 0 && + indexOfInitializationInstruction(method) >= 0 + } +) + +private fun indexOfMilliSecondsInstruction(method: Method) = + method.indexOfFirstInstruction { + getReference()?.name == "MILLISECONDS" + } + +internal fun indexOfInitializationInstruction(method: Method) = + method.indexOfFirstInstruction { + val reference = getReference() + opcode == Opcode.INVOKE_DIRECT && + reference?.name == "" && + reference.parameterTypes.size == 3 && + reference.parameterTypes.firstOrNull() == "I" + } + internal const val SHORTS_HUD_FEATURE_FLAG = 45644023L /** diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt index e327d3e75..cc33f254b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt @@ -33,10 +33,12 @@ import app.revanced.patches.youtube.utils.patch.PatchList.SHORTS_COMPONENTS import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch import app.revanced.patches.youtube.utils.playservice.is_18_31_or_greater import app.revanced.patches.youtube.utils.playservice.is_18_34_or_greater +import app.revanced.patches.youtube.utils.playservice.is_18_49_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_02_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_25_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_28_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater +import app.revanced.patches.youtube.utils.playservice.is_20_09_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverHook import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverPatch @@ -60,6 +62,7 @@ import app.revanced.patches.youtube.utils.settings.ResourceUtils.getContext import app.revanced.patches.youtube.utils.settings.settingsPatch import app.revanced.patches.youtube.utils.toolbar.hookToolBar import app.revanced.patches.youtube.utils.toolbar.toolBarHookPatch +import app.revanced.patches.youtube.utils.videoIdFingerprintShorts import app.revanced.patches.youtube.video.information.hookShortsVideoInformation import app.revanced.patches.youtube.video.information.videoInformationPatch import app.revanced.patches.youtube.video.playbackstart.PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR @@ -71,11 +74,11 @@ import app.revanced.patches.youtube.video.videoid.hookPlayerResponseVideoId import app.revanced.patches.youtube.video.videoid.videoIdPatch import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.ResourceGroup +import app.revanced.util.addEntryValues import app.revanced.util.cloneMutable import app.revanced.util.copyResources import app.revanced.util.findMethodOrThrow import app.revanced.util.findMutableMethodOf -import app.revanced.util.fingerprint.definingClassOrThrow import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall import app.revanced.util.fingerprint.matchOrThrow import app.revanced.util.fingerprint.methodOrThrow @@ -94,6 +97,7 @@ import app.revanced.util.or import app.revanced.util.replaceLiteralInstructionCall import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction @@ -403,9 +407,7 @@ private val shortsRepeatPatch = bytecodePatch( "setMainActivity" ) - val reelEnumClass = reelEnumConstructorFingerprint.definingClassOrThrow() - - reelEnumConstructorFingerprint.methodOrThrow().apply { + val endScreenReference = with (reelEnumConstructorFingerprint.methodOrThrow()) { val insertIndex = indexOfFirstInstructionOrThrow(Opcode.RETURN_VOID) addInstructions( @@ -413,7 +415,7 @@ private val shortsRepeatPatch = bytecodePatch( """ # Pass the first enum value to extension. # Any enum value of this type will work. - sget-object v0, $reelEnumClass->a:$reelEnumClass + sget-object v0, $definingClass->a:$definingClass invoke-static { v0 }, $EXTENSION_REPEAT_STATE_CLASS_DESCRIPTOR->setYTShortsRepeatEnum(Ljava/lang/Enum;)V """, ) @@ -422,50 +424,132 @@ private val shortsRepeatPatch = bytecodePatch( indexOfFirstStringInstructionOrThrow("REEL_LOOP_BEHAVIOR_END_SCREEN") val endScreenReferenceIndex = indexOfFirstInstructionOrThrow(endScreenStringIndex, Opcode.SPUT_OBJECT) - val endScreenReference = - getInstruction(endScreenReferenceIndex).reference.toString() - val enumMethod = reelEnumStaticFingerprint.methodOrThrow(reelEnumConstructorFingerprint) + getInstruction(endScreenReferenceIndex).reference.toString() + } + + lateinit var insertMethod: MutableMethod + var insertMethodFound = false + + if (is_18_49_or_greater) { + insertMethod = reelPlaybackRepeatFingerprint.methodOrThrow() + } else { + val isInsertMethod: Method.() -> Boolean = { + parameters.size == 1 && + parameterTypes.first().startsWith("L") && + returnType == "V" && + indexOfFirstInstruction { + getReference()?.toString() == endScreenReference + } >= 0 + } classes.forEach { classDef -> - classDef.methods.filter { method -> - method.parameters.size == 1 && - method.parameters[0].startsWith("L") && - method.returnType == "V" && - method.indexOfFirstInstruction { - getReference()?.toString() == endScreenReference - } >= 0 - }.forEach { targetMethod -> - proxy(classDef) - .mutableClass - .findMutableMethodOf(targetMethod) - .apply { - implementation!!.instructions - .withIndex() - .filter { (_, instruction) -> - val reference = - (instruction as? ReferenceInstruction)?.reference - reference is MethodReference && - MethodUtil.methodSignaturesMatch(enumMethod, reference) - } - .map { (index, _) -> index } - .reversed() - .forEach { index -> - val register = - getInstruction(index + 1).registerA - - addInstructions( - index + 2, """ - invoke-static {v$register}, $EXTENSION_REPEAT_STATE_CLASS_DESCRIPTOR->changeShortsRepeatBehavior(Ljava/lang/Enum;)Ljava/lang/Enum; - move-result-object v$register - """ - ) - } + if (!insertMethodFound) { + classDef.methods.forEach { method -> + if (method.isInsertMethod()) { + insertMethodFound = true + insertMethod = proxy(classDef) + .mutableClass + .findMutableMethodOf(method) } + } } } } + val enumMethod = reelEnumStaticFingerprint.methodOrThrow(reelEnumConstructorFingerprint) + + insertMethod.apply { + implementation!!.instructions + .withIndex() + .filter { (_, instruction) -> + val reference = + (instruction as? ReferenceInstruction)?.reference + reference is MethodReference && + MethodUtil.methodSignaturesMatch(enumMethod, reference) + } + .map { (index, _) -> index } + .reversed() + .forEach { index -> + val register = + getInstruction(index + 1).registerA + + addInstructions( + index + 2, """ + invoke-static {v$register}, $EXTENSION_REPEAT_STATE_CLASS_DESCRIPTOR->changeShortsRepeatBehavior(Ljava/lang/Enum;)Ljava/lang/Enum; + move-result-object v$register + """ + ) + } + } + + // As of YouTube 20.09, Google has removed the code for 'Autoplay' and 'Pause' from this method. + // Manually add the 'Autoplay' code that Google removed. + // Tested on YouTube 20.10. + // TODO: add the 'Pause' code that Google removed. + if (is_20_09_or_greater) { + val (directReference, virtualReference) = with (reelPlaybackFingerprint.methodOrThrow(videoIdFingerprintShorts)) { + val directIndex = indexOfInitializationInstruction(this) + val virtualIndex = indexOfFirstInstructionOrThrow(directIndex) { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.parameterTypes?.size == 1 + } + + Pair( + getInstruction(directIndex).reference as MethodReference, + getInstruction(virtualIndex).reference as MethodReference + ) + } + + insertMethod.apply { + val extensionIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.INVOKE_STATIC && + getReference()?.definingClass == EXTENSION_REPEAT_STATE_CLASS_DESCRIPTOR + } + val enumRegister = getInstruction(extensionIndex + 1).registerA + val freeIndex = indexOfFirstInstructionOrThrow(extensionIndex) { + opcode == Opcode.SGET_OBJECT && + getReference()?.name != "a" + } + val freeRegister = getInstruction(freeIndex).registerA + val getIndex = indexOfFirstInstructionOrThrow(extensionIndex) { + val reference = getReference() + opcode == Opcode.IGET_OBJECT && + reference?.definingClass == definingClass && + reference.type == virtualReference.definingClass + } + val getReference = getInstruction(getIndex).reference + + addInstructionsWithLabels( + extensionIndex + 2, """ + invoke-static {v$enumRegister}, $EXTENSION_REPEAT_STATE_CLASS_DESCRIPTOR->isAutoPlay(Ljava/lang/Enum;)Z + move-result v$freeRegister + if-eqz v$freeRegister, :ignore + new-instance v0, ${directReference.definingClass} + const/4 v1, 0x3 + const/4 v2, 0x0 + invoke-direct {v0, v1, v2, v2}, $directReference + iget-object v3, p0, $getReference + invoke-virtual {v3, v0}, $virtualReference + return-void + :ignore + nop + """ + ) + } + } else { + getContext().apply { + addEntryValues( + "revanced_change_shorts_repeat_state_entries", + "@string/revanced_change_shorts_repeat_state_entry_pause", + ) + addEntryValues( + "revanced_change_shorts_repeat_state_entry_values", + "END_SCREEN", + ) + } + } + if (is_19_34_or_greater) { shortsHUDFeatureFingerprint.injectLiteralInstructionBooleanCall( SHORTS_HUD_FEATURE_FLAG, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt index 7488b3d1e..6792d46bf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt @@ -16,6 +16,7 @@ import app.revanced.patches.youtube.utils.resourceid.totalTime import app.revanced.patches.youtube.utils.resourceid.varispeedUnavailableTitle import app.revanced.patches.youtube.utils.resourceid.videoQualityBottomSheet import app.revanced.patches.youtube.utils.sponsorblock.sponsorBlockBytecodePatch +import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction @@ -23,6 +24,7 @@ import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference internal val bottomSheetMenuItemBuilderFingerprint = legacyFingerprint( @@ -219,6 +221,29 @@ internal val videoEndFingerprint = legacyFingerprint( literals = listOf(45368273L), ) +/** + * This fingerprint is compatible with all versions of YouTube starting from v18.29.38 to supported versions. + * This method is invoked only in Shorts. + * Accurate video information is invoked even when the user moves Shorts upward or downward. + */ +internal val videoIdFingerprintShorts = legacyFingerprint( + name = "videoIdFingerprintShorts", + returnType = "V", + parameters = listOf(PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR), + opcodes = listOf( + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT_OBJECT + ), + customFingerprint = custom@{ method, _ -> + if (method.containsLiteralInstruction(45365621L)) + return@custom true + + method.indexOfFirstInstruction { + getReference()?.name == "reelWatchEndpoint" + } >= 0 + } +) + /** * Several instructions are added to this method by different patches. * Therefore, patches using this fingerprint should not use the [Opcode] pattern, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt index bdbf30c72..bb4baa8da 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt @@ -65,6 +65,8 @@ var is_20_03_or_greater = false private set var is_20_05_or_greater = false private set +var is_20_09_or_greater = false + private set var is_20_10_or_greater = false private set @@ -112,6 +114,7 @@ val versionCheckPatch = resourcePatch( is_20_02_or_greater = 250299000 <= playStoreServicesVersion is_20_03_or_greater = 250405000 <= playStoreServicesVersion is_20_05_or_greater = 250605000 <= playStoreServicesVersion + is_20_09_or_greater = 251006000 <= playStoreServicesVersion is_20_10_or_greater = 251105000 <= playStoreServicesVersion } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt index 9c2e47803..c8648d9d9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/Fingerprints.kt @@ -3,7 +3,6 @@ package app.revanced.patches.youtube.video.information import app.revanced.patches.youtube.utils.PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.resourceid.notificationBigPictureIconWidth import app.revanced.patches.youtube.utils.resourceid.qualityAuto -import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction @@ -133,29 +132,6 @@ fun indexOfPlayerResponseModelInterfaceInstruction(methodDef: Method) = getReference()?.definingClass == PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR } -/** - * This fingerprint is compatible with all versions of YouTube starting from v18.29.38 to supported versions. - * This method is invoked only in Shorts. - * Accurate video information is invoked even when the user moves Shorts upward or downward. - */ -internal val videoIdFingerprintShorts = legacyFingerprint( - name = "videoIdFingerprintShorts", - returnType = "V", - parameters = listOf(PLAYER_RESPONSE_MODEL_CLASS_DESCRIPTOR), - opcodes = listOf( - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT - ), - customFingerprint = custom@{ method, _ -> - if (method.containsLiteralInstruction(45365621L)) - return@custom true - - method.indexOfFirstInstruction { - getReference()?.name == "reelWatchEndpoint" - } >= 0 - } -) - internal val videoQualityListFingerprint = legacyFingerprint( name = "videoQualityListFingerprint", returnType = "V", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt index fa9d1075c..52683bdd5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt @@ -19,6 +19,7 @@ import app.revanced.patches.youtube.utils.extension.Constants.SHARED_PATH import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.youtube.utils.videoEndFingerprint +import app.revanced.patches.youtube.utils.videoIdFingerprintShorts import app.revanced.patches.youtube.video.playerresponse.Hook import app.revanced.patches.youtube.video.playerresponse.addPlayerResponseMethodHook import app.revanced.patches.youtube.video.playerresponse.playerResponseMethodHookPatch diff --git a/patches/src/main/resources/youtube/settings/host/values/arrays.xml b/patches/src/main/resources/youtube/settings/host/values/arrays.xml index 9ca518f23..cfb11f881 100644 --- a/patches/src/main/resources/youtube/settings/host/values/arrays.xml +++ b/patches/src/main/resources/youtube/settings/host/values/arrays.xml @@ -98,13 +98,11 @@ @string/revanced_change_shorts_repeat_state_entry_default @string/revanced_change_shorts_repeat_state_entry_repeat @string/revanced_change_shorts_repeat_state_entry_auto_play - @string/revanced_change_shorts_repeat_state_entry_pause UNKNOWN REPEAT SINGLE_PLAY - END_SCREEN @string/quality_auto From 84b122f628ccc96877afda52b92b494cbb1569de Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 20:13:36 +0900 Subject: [PATCH 03/77] fix(YouTube - Settings): System navigation bar is located above the settings ui on Android 15+ https://github.com/ReVanced/revanced-patches/issues/4606 --- .../preference/ReVancedPreferenceFragment.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index 5eab38ba7..4e54475cf 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -205,11 +205,24 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { .findViewById(android.R.id.content) .getParent(); - // Fix required for Android 15 + // Edge-to-edge is enforced if the following conditions are met: + // 1. targetSDK is 35 or greater (YouTube 19.44.39 or greater). + // 2. user is using Android 15 or greater. + // + // Related Issues: + // https://github.com/ReVanced/revanced-patches/issues/3976 + // https://github.com/ReVanced/revanced-patches/issues/4606 + // + // Docs: + // https://developer.android.com/develop/ui/views/layout/edge-to-edge#system-bars-insets + // + // Since ReVanced Settings Activity do not use AndroidX libraries, + // You will need to manually fix the layout breakage caused by edge-to-edge. if (isSDKAbove(35)) { rootView.setOnApplyWindowInsetsListener((v, insets) -> { Insets statusInsets = insets.getInsets(WindowInsets.Type.statusBars()); - v.setPadding(0, statusInsets.top, 0, 0); + Insets navInsets = insets.getInsets(WindowInsets.Type.navigationBars()); + v.setPadding(0, statusInsets.top, 0, navInsets.bottom); return insets; }); } From 872db64da1111336a52285103e38855d621c7d9c Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 20:36:32 +0900 Subject: [PATCH 04/77] fix(YouTube - Settings): Add a listener only if edge-to-edge display is supported --- .../extension/shared/utils/PackageUtils.java | 26 ++++++++++++++++--- .../ReVancedPreferenceFragment.java | 5 +++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java index dcfd46864..e6539fa8b 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java @@ -30,9 +30,9 @@ public class PackageUtils extends Utils { } public static boolean isPackageEnabled(@NonNull String packageName) { - try { - return getContext().getPackageManager().getApplicationInfo(packageName, 0).enabled; - } catch (PackageManager.NameNotFoundException ignored) { + ApplicationInfo applicationInfo = getApplicationInfo(packageName); + if (applicationInfo != null) { + return applicationInfo.enabled; } return false; @@ -47,6 +47,26 @@ public class PackageUtils extends Utils { } // utils + @Nullable + public static Integer getTargetSDKVersion(@NonNull String packageName) { + ApplicationInfo applicationInfo = getApplicationInfo(packageName); + if (applicationInfo != null) { + return applicationInfo.targetSdkVersion; + } + + return null; + } + + @Nullable + private static ApplicationInfo getApplicationInfo(@NonNull String packageName) { + try { + return getContext().getPackageManager().getApplicationInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + Logger.printException(() -> "Failed to get application Info!" + e); + } + return null; + } + @Nullable private static PackageInfo getPackageInfo() { try { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index 4e54475cf..77bf67050 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -197,6 +197,9 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { } } + Integer targetSDKVersion = ExtendedUtils.getTargetSDKVersion(getContext().getPackageName()); + boolean isEdgeToEdgeSupported = isSDKAbove(35) && targetSDKVersion != null && targetSDKVersion >= 35; + for (PreferenceScreen mPreferenceScreen : preferenceScreenMap.values()) { mPreferenceScreen.setOnPreferenceClickListener( preferenceScreen -> { @@ -218,7 +221,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { // // Since ReVanced Settings Activity do not use AndroidX libraries, // You will need to manually fix the layout breakage caused by edge-to-edge. - if (isSDKAbove(35)) { + if (isEdgeToEdgeSupported) { rootView.setOnApplyWindowInsetsListener((v, insets) -> { Insets statusInsets = insets.getInsets(WindowInsets.Type.statusBars()); Insets navInsets = insets.getInsets(WindowInsets.Type.navigationBars()); From c3d05fd01db21301493ee4123474938decdd2328 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 20:43:35 +0900 Subject: [PATCH 05/77] chore: Lint code --- .../extension/shared/utils/PackageUtils.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java index e6539fa8b..c2f147dcf 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/PackageUtils.java @@ -29,6 +29,16 @@ public class PackageUtils extends Utils { } } + @Nullable + public static Integer getTargetSDKVersion(@NonNull String packageName) { + ApplicationInfo applicationInfo = getApplicationInfo(packageName); + if (applicationInfo != null) { + return applicationInfo.targetSdkVersion; + } + + return null; + } + public static boolean isPackageEnabled(@NonNull String packageName) { ApplicationInfo applicationInfo = getApplicationInfo(packageName); if (applicationInfo != null) { @@ -47,16 +57,6 @@ public class PackageUtils extends Utils { } // utils - @Nullable - public static Integer getTargetSDKVersion(@NonNull String packageName) { - ApplicationInfo applicationInfo = getApplicationInfo(packageName); - if (applicationInfo != null) { - return applicationInfo.targetSdkVersion; - } - - return null; - } - @Nullable private static ApplicationInfo getApplicationInfo(@NonNull String packageName) { try { From 98f2e990618713b4ee824e61785f0b185627c64c Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 20:49:17 +0900 Subject: [PATCH 06/77] fix(YouTube - Spoof streaming data): Remove `iOS` client https://github.com/inotia00/revanced-patches/pull/141 --- .../extension/shared/patches/client/YouTubeAppClient.kt | 7 +++---- .../main/resources/youtube/settings/host/values/arrays.xml | 2 -- .../main/resources/youtube/settings/xml/revanced_prefs.xml | 6 ------ 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeAppClient.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeAppClient.kt index 8723b8297..f32c1b425 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeAppClient.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeAppClient.kt @@ -213,7 +213,7 @@ object YouTubeAppClient { } fun availableClientTypes(preferredClient: ClientType): Array { - val availableClientTypes = ClientType.CLIENT_ORDER_TO_USE_YOUTUBE + val availableClientTypes = ClientType.CLIENT_ORDER_TO_USE if (ArrayUtils.contains(availableClientTypes, preferredClient)) { val clientToUse: Array = arrayOfNulls(availableClientTypes.size) @@ -230,7 +230,7 @@ object YouTubeAppClient { } } - @Suppress("DEPRECATION") + @Suppress("DEPRECATION", "unused") enum class ClientType( /** * [YouTube client type](https://github.com/zerodytrash/YouTube-Internal-Clients?tab=readme-ov-file#clients) @@ -381,12 +381,11 @@ object YouTubeAppClient { ); companion object { - val CLIENT_ORDER_TO_USE_YOUTUBE: Array = arrayOf( + val CLIENT_ORDER_TO_USE: Array = arrayOf( ANDROID_VR_NO_AUTH, ANDROID_UNPLUGGED, ANDROID_CREATOR, IOS_UNPLUGGED, - IOS, ANDROID_VR, ) } diff --git a/patches/src/main/resources/youtube/settings/host/values/arrays.xml b/patches/src/main/resources/youtube/settings/host/values/arrays.xml index cfb11f881..b9d357e7f 100644 --- a/patches/src/main/resources/youtube/settings/host/values/arrays.xml +++ b/patches/src/main/resources/youtube/settings/host/values/arrays.xml @@ -398,14 +398,12 @@ @string/revanced_spoof_streaming_data_type_entry_android_vr_no_auth @string/revanced_spoof_streaming_data_type_entry_android_unplugged @string/revanced_spoof_streaming_data_type_entry_ios_unplugged - @string/revanced_spoof_streaming_data_type_entry_ios ANDROID_VR ANDROID_VR_NO_AUTH ANDROID_UNPLUGGED IOS_UNPLUGGED - IOS diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 136f93c31..3915effdd 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -838,12 +838,6 @@ Ads From fd32e4a854111312fe889037a8aa92be8e9a5f3f Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 21:14:59 +0900 Subject: [PATCH 11/77] feat(Universal): Add `Disable edge-to-edge display` patch https://github.com/inotia00/ReVanced_Extended/issues/2859 --- .../edgetoedge/EdgeToEdgeDisplayPatch.kt | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/all/misc/display/edgetoedge/EdgeToEdgeDisplayPatch.kt diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/display/edgetoedge/EdgeToEdgeDisplayPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/display/edgetoedge/EdgeToEdgeDisplayPatch.kt new file mode 100644 index 000000000..a3ae247a1 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/display/edgetoedge/EdgeToEdgeDisplayPatch.kt @@ -0,0 +1,38 @@ +package app.revanced.patches.all.misc.display.edgetoedge + +import app.revanced.patcher.patch.resourcePatch +import app.revanced.util.Utils.printWarn +import app.revanced.util.getNode +import org.w3c.dom.Element + +@Suppress("unused") +val edgeToEdgeDisplayPatch = resourcePatch( + name = "Disable edge-to-edge display", + description = "Disable forced edge-to-edge display on Android 15+ by changing the app's target SDK version. " + + "This patch does not work if the app is installed by mounting.", + use = false, +) { + execute { + document("AndroidManifest.xml").use { document -> + // Ideally, the patch should only be applied when targetSdkVersion is 35 or greater. + // Since ApkTool does not add targetSdkVersion to AndroidManifest, there is no way to check targetSdkVersion. + // Instead, it checks compileSdkVersion and prints a warning. + try { + val manifestElement = document.getNode("manifest") as Element + val compileSdkVersion = Integer.parseInt(manifestElement.getAttribute("android:compileSdkVersion")) + if (compileSdkVersion < 35) { + printWarn("This app may not be forcing edge to edge display (compileSdkVersion: $compileSdkVersion)") + } + } catch (_: Exception) { + printWarn("Failed to check compileSdkVersion") + } + + // Change targetSdkVersion to 34. + document.getElementsByTagName("manifest").item(0).also { + it.appendChild(it.ownerDocument.createElement("uses-sdk").also { element -> + element.setAttribute("android:targetSdkVersion", "34") + }) + } + } + } +} From 529e0163ccea7ae6e8cbf6e422df956d6fd0273b Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 21:23:46 +0900 Subject: [PATCH 12/77] fix(YouTube - Player components): `Speed overlay value` only works when set to 1.0 or higher https://github.com/inotia00/ReVanced_Extended/issues/2849 --- .../youtube/patches/player/PlayerPatch.java | 6 ++ .../youtube/player/components/Fingerprints.kt | 4 +- .../components/PlayerComponentsPatch.kt | 84 +++++++++++++++---- .../utils/playservice/VersionCheckPatch.kt | 3 + 4 files changed, 81 insertions(+), 16 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java index 00d74d8c5..287ed6992 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java @@ -518,6 +518,12 @@ public class PlayerPatch { return SPEED_OVERLAY_VALUE; } + public static float speedOverlayRelativeValue(float original) { + return SPEED_OVERLAY_VALUE != 2.0f + ? 0f + : original; + } + public static boolean hideChannelWatermark(boolean original) { return !Settings.HIDE_CHANNEL_WATERMARK.get() && original; } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt index a36f776ab..303b05170 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt @@ -88,6 +88,8 @@ internal val speedOverlayFingerprint = legacyFingerprint( literals = listOf(SPEED_OVERLAY_FEATURE_FLAG), ) +internal const val SPEED_OVERLAY_LEGACY_FEATURE_FLAG = 45411328L + /** * This value is the key for the playback speed overlay value. * Deprecated in YouTube v19.18.41+. @@ -97,7 +99,7 @@ internal val speedOverlayFloatValueFingerprint = legacyFingerprint( returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, opcodes = listOf(Opcode.DOUBLE_TO_FLOAT), - literals = listOf(45411328L), + literals = listOf(SPEED_OVERLAY_LEGACY_FEATURE_FLAG), ) internal val speedOverlayTextValueFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt index 8cc9ce104..81d9579d5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt @@ -24,9 +24,11 @@ import app.revanced.patches.youtube.utils.engagement.engagementPanelIdRegister import app.revanced.patches.youtube.utils.extension.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.extension.Constants.SPANS_PATH +import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch import app.revanced.patches.youtube.utils.fix.suggestedvideoendscreen.suggestedVideoEndScreenPatch import app.revanced.patches.youtube.utils.patch.PatchList.PLAYER_COMPONENTS import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch +import app.revanced.patches.youtube.utils.playservice.is_19_18_or_greater import app.revanced.patches.youtube.utils.playservice.is_20_02_or_greater import app.revanced.patches.youtube.utils.playservice.is_20_03_or_greater import app.revanced.patches.youtube.utils.playservice.is_20_05_or_greater @@ -45,23 +47,27 @@ import app.revanced.patches.youtube.video.information.videoInformationPatch import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.Utils.printWarn import app.revanced.util.findMethodOrThrow +import app.revanced.util.findMutableMethodOf import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall import app.revanced.util.fingerprint.injectLiteralInstructionViewCall import app.revanced.util.fingerprint.matchOrThrow import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.fingerprint.mutableClassOrThrow -import app.revanced.util.fingerprint.resolvable import app.revanced.util.getReference import app.revanced.util.getWalkerMethod import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow +import app.revanced.util.or +import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ThreeRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference @@ -70,7 +76,11 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference private val speedOverlayPatch = bytecodePatch( description = "speedOverlayPatch" ) { - dependsOn(sharedResourceIdPatch) + dependsOn( + sharedExtensionPatch, + sharedResourceIdPatch, + versionCheckPatch, + ) execute { fun MutableMethod.hookSpeedOverlay( @@ -87,11 +97,19 @@ private val speedOverlayPatch = bytecodePatch( ) } - val resolvable = restoreSlideToSeekBehaviorFingerprint.resolvable() && - speedOverlayFingerprint.resolvable() && - speedOverlayFloatValueFingerprint.resolvable() + fun MutableMethod.hookRelativeSpeedValue(startIndex: Int) { + val relativeIndex = indexOfFirstInstructionOrThrow(startIndex, Opcode.CMPL_FLOAT) + val relativeRegister = getInstruction(relativeIndex).registerB - if (resolvable) { + addInstructions( + relativeIndex, """ + invoke-static {v$relativeRegister}, $PLAYER_CLASS_DESCRIPTOR->speedOverlayRelativeValue(F)F + move-result v$relativeRegister + """ + ) + } + + if (!is_19_18_or_greater) { // Used on YouTube 18.29.38 ~ YouTube 19.17.41 // region patch for Disable speed overlay (Enable slide to seek) @@ -110,17 +128,51 @@ private val speedOverlayPatch = bytecodePatch( // region patch for Custom speed overlay float value - speedOverlayFloatValueFingerprint.matchOrThrow().let { - it.method.apply { - val index = it.patternMatch!!.startIndex - val register = getInstruction(index).registerA + val speedFieldReference = with (speedOverlayFloatValueFingerprint.methodOrThrow()) { + val literalIndex = indexOfFirstLiteralInstructionOrThrow(SPEED_OVERLAY_LEGACY_FEATURE_FLAG) + val floatIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.DOUBLE_TO_FLOAT) + val floatRegister = getInstruction(floatIndex).registerA - addInstructions( - index + 1, """ - invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->speedOverlayValue(F)F - move-result v$register + addInstructions( + floatIndex + 1, """ + invoke-static {v$floatRegister}, $PLAYER_CLASS_DESCRIPTOR->speedOverlayValue(F)F + move-result v$floatRegister """ - ) + ) + + val speedFieldIndex = indexOfFirstInstructionOrThrow(literalIndex) { + opcode == Opcode.IPUT && + getReference()?.type == "F" + } + + getInstruction(speedFieldIndex).reference.toString() + } + + fun indexOfFirstSpeedFieldInstruction(method: Method) = + method.indexOfFirstInstruction { + opcode == Opcode.IGET && + getReference()?.toString() == speedFieldReference + } + + val isSyntheticMethod: Method.() -> Boolean = { + name == "run" && + accessFlags == AccessFlags.PUBLIC or AccessFlags.FINAL && + parameterTypes.isEmpty() && + indexOfFirstSpeedFieldInstruction(this) >= 0 && + indexOfFirstInstruction(Opcode.CMPL_FLOAT) >= 0 + } + + classes.forEach { classDef -> + classDef.methods.forEach { method -> + if (method.isSyntheticMethod()) { + proxy(classDef) + .mutableClass + .findMutableMethodOf(method) + .apply { + val speedFieldIndex = indexOfFirstSpeedFieldInstruction(this) + hookRelativeSpeedValue(speedFieldIndex) + } + } } } @@ -241,6 +293,8 @@ private val speedOverlayPatch = bytecodePatch( move-result v$speedOverlayFloatValueRegister """ ) + + hookRelativeSpeedValue(speedOverlayFloatValueIndex) } // Removed in YouTube 20.03+ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt index bb4baa8da..97966f6b9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt @@ -31,6 +31,8 @@ var is_19_16_or_greater = false private set var is_19_17_or_greater = false private set +var is_19_18_or_greater = false + private set var is_19_23_or_greater = false private set var is_19_25_or_greater = false @@ -97,6 +99,7 @@ val versionCheckPatch = resourcePatch( is_19_15_or_greater = 241602000 <= playStoreServicesVersion is_19_16_or_greater = 241702000 <= playStoreServicesVersion is_19_17_or_greater = 241802000 <= playStoreServicesVersion + is_19_18_or_greater = 241902000 <= playStoreServicesVersion is_19_23_or_greater = 242402000 <= playStoreServicesVersion is_19_25_or_greater = 242599000 <= playStoreServicesVersion is_19_26_or_greater = 242705000 <= playStoreServicesVersion From 8666d14297ea58262e6f509ef10325b291d9aac6 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 21:26:57 +0900 Subject: [PATCH 13/77] feat(YouTube): Replace with a fingerprint that supports a wider range of versions (..20.12) --- .../youtube/ads/general/Fingerprints.kt | 2 - .../general/components/Fingerprints.kt | 9 +- .../components/LayoutComponentsPatch.kt | 23 ++-- .../general/toolbar/ToolBarComponentsPatch.kt | 5 +- .../youtube/player/components/Fingerprints.kt | 49 +++++++- .../components/PlayerComponentsPatch.kt | 77 +++++++++--- .../player/flyoutmenu/hide/Fingerprints.kt | 41 +++---- .../flyoutmenu/hide/PlayerFlyoutMenuPatch.kt | 7 +- .../miniplayer/general/MiniplayerPatch.kt | 12 +- .../youtube/player/seekbar/Fingerprints.kt | 36 +++--- .../player/seekbar/SeekbarComponentsPatch.kt | 114 ++++++++++-------- .../patches/youtube/utils/Fingerprints.kt | 35 +++--- .../fix/splash/DarkModeSplashScreenPatch.kt | 25 ++-- .../utils/playservice/VersionCheckPatch.kt | 3 + .../utils/resourceid/SharedResourceIdPatch.kt | 24 +++- .../returnyoutubedislike/Fingerprints.kt | 10 +- .../youtube/video/playback/Fingerprints.kt | 16 ++- .../youtube/video/videoid/Fingerprints.kt | 2 +- 18 files changed, 301 insertions(+), 189 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/Fingerprints.kt index 315b1d9ac..c8aa32933 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ads/general/Fingerprints.kt @@ -57,8 +57,6 @@ internal val showDialogCommandFingerprint = legacyFingerprint( name = "showDialogCommandFingerprint", returnType = "V", opcodes = listOf( - Opcode.IF_EQ, - Opcode.IGET_OBJECT, Opcode.INVOKE_VIRTUAL, Opcode.IGET, // get dialog code ), diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/Fingerprints.kt index e9e4a2e29..8782607c6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/Fingerprints.kt @@ -6,6 +6,7 @@ import app.revanced.patches.youtube.utils.resourceid.compactListItem import app.revanced.patches.youtube.utils.resourceid.editSettingsAction import app.revanced.patches.youtube.utils.resourceid.fab import app.revanced.patches.youtube.utils.resourceid.toolTipContentView +import app.revanced.patches.youtube.utils.resourceid.ytCallToAction import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionReversed @@ -19,13 +20,7 @@ internal val accountListFingerprint = legacyFingerprint( name = "accountListFingerprint", returnType = "V", accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL or AccessFlags.SYNTHETIC, - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET - ) + literals = listOf(ytCallToAction), ) internal val accountListParentFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt index 7782e7741..003903a3f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt @@ -20,6 +20,7 @@ import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.resourceid.accountSwitcherAccessibility import app.revanced.patches.youtube.utils.resourceid.fab import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch +import app.revanced.patches.youtube.utils.resourceid.ytCallToAction import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall @@ -122,17 +123,19 @@ val layoutComponentsPatch = bytecodePatch( // region patch for hide account menu // for you tab - accountListFingerprint.matchOrThrow(accountListParentFingerprint).let { - it.method.apply { - val targetIndex = it.patternMatch!!.startIndex + 3 - val targetInstruction = getInstruction(targetIndex) - - addInstruction( - targetIndex, - "invoke-static {v${targetInstruction.registerC}, v${targetInstruction.registerD}}, " + - "$GENERAL_CLASS_DESCRIPTOR->hideAccountList(Landroid/view/View;Ljava/lang/CharSequence;)V" - ) + accountListFingerprint.methodOrThrow(accountListParentFingerprint).apply { + val literalIndex = indexOfFirstLiteralInstructionOrThrow(ytCallToAction) + val targetIndex = indexOfFirstInstructionOrThrow(literalIndex) { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "setText" } + val targetInstruction = getInstruction(targetIndex) + + addInstruction( + targetIndex, + "invoke-static {v${targetInstruction.registerC}, v${targetInstruction.registerD}}, " + + "$GENERAL_CLASS_DESCRIPTOR->hideAccountList(Landroid/view/View;Ljava/lang/CharSequence;)V" + ) } // for tablet and old clients diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt index f928fd94d..e701162e8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt @@ -272,10 +272,11 @@ val toolBarComponentsPatch = bytecodePatch( opcode == Opcode.IGET_OBJECT && getReference()?.type == "Landroid/widget/ImageView;" } - val jumpIndex = indexOfFirstInstructionOrThrow(replaceIndex) { + val uriIndex = indexOfFirstInstructionOrThrow(replaceIndex) { opcode == Opcode.INVOKE_STATIC && getReference()?.toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" - } + 4 + } + val jumpIndex = indexOfFirstInstructionOrThrow(uriIndex, Opcode.CONST_4) val replaceIndexInstruction = getInstruction(replaceIndex) val freeRegister = replaceIndexInstruction.registerA val classRegister = replaceIndexInstruction.registerB diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt index 303b05170..cd274c9dc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt @@ -10,11 +10,12 @@ import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutCircl import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutIcon import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutVideo import app.revanced.patches.youtube.utils.resourceid.offlineActionsVideoDeletedUndoSnackbarText -import app.revanced.patches.youtube.utils.resourceid.scrubbing +import app.revanced.patches.youtube.utils.resourceid.verticalTouchOffsetToEnterFineScrubbing import app.revanced.patches.youtube.utils.resourceid.seekEasyHorizontalTouchOffsetToStartScrubbing import app.revanced.patches.youtube.utils.resourceid.suggestedAction import app.revanced.patches.youtube.utils.resourceid.tapBloomView import app.revanced.patches.youtube.utils.resourceid.touchArea +import app.revanced.patches.youtube.utils.resourceid.verticalTouchOffsetToStartFineScrubbing import app.revanced.patches.youtube.utils.resourceid.videoZoomSnapIndicator import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.getReference @@ -126,6 +127,9 @@ internal val crowdfundingBoxFingerprint = legacyFingerprint( literals = listOf(donationCompanion), ) +/** + * ~ YouTube 20.11 + */ internal val filmStripOverlayConfigFingerprint = legacyFingerprint( name = "filmStripOverlayConfigFingerprint", returnType = "Z", @@ -140,11 +144,48 @@ internal val filmStripOverlayInteractionFingerprint = legacyFingerprint( parameters = listOf("L") ) -internal val filmStripOverlayParentFingerprint = legacyFingerprint( - name = "filmStripOverlayParentFingerprint", +internal val filmStripOverlayEnterParentFingerprint = legacyFingerprint( + name = "filmStripOverlayEnterParentFingerprint", returnType = "V", accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, - literals = listOf(scrubbing), + literals = listOf(verticalTouchOffsetToEnterFineScrubbing), +) + +/** + * YouTube 20.12 ~ + */ +internal val filmStripOverlayMotionEventPrimaryFingerprint = legacyFingerprint( + name = "filmStripOverlayMotionEventPrimaryFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Landroid/view/MotionEvent;"), + opcodes = listOf( + Opcode.IGET_OBJECT, + Opcode.INVOKE_INTERFACE, + ), +) + +/** + * YouTube 20.12 ~ + */ +internal val filmStripOverlayMotionEventSecondaryFingerprint = legacyFingerprint( + name = "filmStripOverlayMotionEventSecondaryFingerprint", + returnType = "Z", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Landroid/view/MotionEvent;"), + opcodes = listOf( + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + Opcode.IF_EQZ, + Opcode.NEG_FLOAT, + ), +) + +internal val filmStripOverlayStartParentFingerprint = legacyFingerprint( + name = "filmStripOverlayStartParentFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + literals = listOf(verticalTouchOffsetToStartFineScrubbing), ) internal val filmStripOverlayPreviewFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt index 81d9579d5..c3c3b5b21 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt @@ -32,6 +32,7 @@ import app.revanced.patches.youtube.utils.playservice.is_19_18_or_greater import app.revanced.patches.youtube.utils.playservice.is_20_02_or_greater import app.revanced.patches.youtube.utils.playservice.is_20_03_or_greater import app.revanced.patches.youtube.utils.playservice.is_20_05_or_greater +import app.revanced.patches.youtube.utils.playservice.is_20_12_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.resourceid.darkBackground import app.revanced.patches.youtube.utils.resourceid.fadeDurationFast @@ -399,18 +400,6 @@ val playerComponentsPatch = bytecodePatch( return "" } - fun MutableMethod.hookFilmstripOverlay() { - addInstructionsWithLabels( - 0, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideFilmstripOverlay()Z - move-result v0 - if-eqz v0, :shown - const/4 v0, 0x0 - return v0 - """, ExternalLabel("shown", getInstruction(0)) - ) - } - // region patch for custom player overlay opacity youtubeControlsOverlayFingerprint.methodOrThrow().apply { @@ -581,12 +570,68 @@ val playerComponentsPatch = bytecodePatch( // region patch for hide filmstrip overlay - arrayOf( - filmStripOverlayConfigFingerprint, + fun MutableMethod.hookFilmstripOverlay( + index: Int = 0, + register: Int = 0 + ) { + val stringInstructions = if (returnType == "Z") + """ + const/4 v$register, 0x0 + return v$register + """ + else if (returnType == "V") + """ + return-void + """ + else + throw Exception("This case should never happen.") + + addInstructionsWithLabels( + index, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->hideFilmstripOverlay()Z + move-result v$register + if-eqz v$register, :shown + """ + stringInstructions + """ + :shown + nop + """ + ) + } + + val filmStripOverlayFingerprints = mutableListOf( filmStripOverlayInteractionFingerprint, filmStripOverlayPreviewFingerprint - ).forEach { fingerprint -> - fingerprint.methodOrThrow(filmStripOverlayParentFingerprint).hookFilmstripOverlay() + ) + + if (is_20_12_or_greater) { + filmStripOverlayMotionEventPrimaryFingerprint.matchOrThrow(filmStripOverlayStartParentFingerprint).let { + it.method.apply { + val index = it.patternMatch!!.startIndex + val register = getInstruction(index).registerA + + hookFilmstripOverlay(index, register) + } + } + + filmStripOverlayMotionEventSecondaryFingerprint.matchOrThrow(filmStripOverlayStartParentFingerprint).let { + it.method.apply { + val index = it.patternMatch!!.startIndex + 2 + val register = getInstruction(index).registerA + + addInstructions( + index, """ + invoke-static {v$register}, $PLAYER_CLASS_DESCRIPTOR->hideFilmstripOverlay(Z)Z + move-result v$register + """ + ) + } + } + } else { + filmStripOverlayFingerprints += filmStripOverlayConfigFingerprint + } + + filmStripOverlayFingerprints.forEach { fingerprint -> + fingerprint.methodOrThrow(filmStripOverlayEnterParentFingerprint).hookFilmstripOverlay() } // Removed in YouTube 20.05+ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/Fingerprints.kt index 19470906e..70d3db075 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/Fingerprints.kt @@ -1,8 +1,10 @@ package app.revanced.patches.youtube.player.flyoutmenu.hide +import app.revanced.patches.youtube.utils.indexOfAddHeaderViewInstruction import app.revanced.patches.youtube.utils.resourceid.bottomSheetFooterText import app.revanced.patches.youtube.utils.resourceid.subtitleMenuSettingsFooterInfo import app.revanced.patches.youtube.utils.resourceid.videoQualityBottomSheet +import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction @@ -18,33 +20,18 @@ internal val advancedQualityBottomSheetFingerprint = legacyFingerprint( returnType = "L", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("L", "L", "L"), - opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_STATIC, - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_16, - Opcode.INVOKE_VIRTUAL, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IGET_OBJECT, - Opcode.CONST_STRING - ), - literals = listOf(videoQualityBottomSheet), + customFingerprint = custom@{ method, _ -> + if (!method.containsLiteralInstruction(videoQualityBottomSheet)) { + return@custom false + } + if (indexOfAddHeaderViewInstruction(method) < 0) { + return@custom false + } + val implementation = method.implementation + ?: return@custom false + + implementation.instructions.elementAt(0).opcode == Opcode.IGET_OBJECT + } ) internal val captionsBottomSheetFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt index 07c2df304..8f7ea6837 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/flyoutmenu/hide/PlayerFlyoutMenuPatch.kt @@ -10,6 +10,7 @@ import app.revanced.patches.shared.litho.lithoFilterPatch import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.extension.Constants.COMPONENTS_PATH import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.indexOfAddHeaderViewInstruction import app.revanced.patches.youtube.utils.patch.PatchList.HIDE_PLAYER_FLYOUT_MENU import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch import app.revanced.patches.youtube.utils.playservice.is_18_39_or_greater @@ -25,7 +26,6 @@ import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall import app.revanced.util.fingerprint.injectLiteralInstructionViewCall import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction @@ -75,10 +75,7 @@ val playerFlyoutMenuPatch = bytecodePatch( qualityMenuViewInflateFingerprint ).forEach { fingerprint -> fingerprint.methodOrThrow().apply { - val insertIndex = indexOfFirstInstructionOrThrow { - opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.name == "addHeaderView" - } + val insertIndex = indexOfAddHeaderViewInstruction(this) val insertRegister = getInstruction(insertIndex).registerD addInstructions( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/MiniplayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/MiniplayerPatch.kt index bdd835f99..a5d331118 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/MiniplayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/MiniplayerPatch.kt @@ -50,6 +50,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstructio import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.TypeReference import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter @@ -145,10 +146,15 @@ val miniplayerPatch = bytecodePatch( // region Legacy tablet Miniplayer hooks. miniplayerOverrideFingerprint.matchOrThrow().let { - val appNameStringIndex = it.stringMatches!!.first().index + 2 - it.method.apply { - val walkerMethod = getWalkerMethod(appNameStringIndex) + val stringIndex = it.stringMatches!!.first().index + val walkerIndex = indexOfFirstInstructionOrThrow(stringIndex) { + val reference = getReference() + reference?.returnType == "Z" && + reference.parameterTypes.size == 1 && + reference.parameterTypes.firstOrNull() == "Landroid/content/Context;" + } + val walkerMethod = getWalkerMethod(walkerIndex) walkerMethod.apply { findReturnIndicesReversed().forEach { index -> diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt index 22584d1ab..d0e9eac5c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt @@ -7,9 +7,13 @@ import app.revanced.patches.youtube.utils.resourceid.ytTextSecondary import app.revanced.patches.youtube.utils.resourceid.ytYoutubeMagenta import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionReversed import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.MethodReference import kotlin.collections.listOf internal val shortsSeekbarColorFingerprint = legacyFingerprint( @@ -113,27 +117,21 @@ internal val seekbarTappingFingerprint = legacyFingerprint( name = "seekbarTappingFingerprint", returnType = "Z", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters = listOf("L"), - opcodes = listOf( - Opcode.IPUT_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INT_TO_FLOAT, - Opcode.INT_TO_FLOAT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ - ), - customFingerprint = { method, _ -> method.name == "onTouchEvent" } + parameters = listOf("Landroid/view/MotionEvent;"), + customFingerprint = { method, classDef -> + classDef.interfaces.contains("Landroid/view/View${'$'}OnLayoutChangeListener;") && + classDef.fields.find { it.type == "[Lcom/google/android/libraries/youtube/player/features/overlay/timebar/TimelineMarker;" } != null && + method.name == "onTouchEvent" && + indexOfPointInstruction(method) >= 0 + } ) +internal fun indexOfPointInstruction(method: Method) = + method.indexOfFirstInstructionReversed { + opcode == Opcode.INVOKE_DIRECT && + getReference()?.toString() == "Landroid/graphics/Point;->(II)V" + } + internal val seekbarThumbnailsQualityFingerprint = legacyFingerprint( name = "seekbarThumbnailsQualityFingerprint", returnType = "Z", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt index 441ec5f4c..92bf1da06 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt @@ -132,60 +132,70 @@ val seekbarComponentsPatch = bytecodePatch( // region patch for enable seekbar tapping patch - seekbarTappingFingerprint.matchOrThrow().let { - it.method.apply { - val tapSeekIndex = it.patternMatch!!.startIndex + 1 - val tapSeekClass = getInstruction(tapSeekIndex) - .getReference()!! - .definingClass + seekbarTappingFingerprint.methodOrThrow().apply { + val pointIndex = indexOfPointInstruction(this) + val pointInstruction = getInstruction(pointIndex) + val freeRegister = pointInstruction.registerE + val xAxisRegister = pointInstruction.registerD - val tapSeekMethods = findMethodsOrThrow(tapSeekClass) - var pMethodCall = "" - var oMethodCall = "" - - for (method in tapSeekMethods) { - if (method.implementation == null) - continue - - val instructions = method.implementation!!.instructions - // here we make sure we actually find the method because it has more than 7 instructions - if (instructions.count() != 10) - continue - - // we know that the 7th instruction has the opcode CONST_4 - val instruction = instructions.elementAt(6) - if (instruction.opcode != Opcode.CONST_4) - continue - - // the literal for this instruction has to be either 1 or 2 - val literal = (instruction as NarrowLiteralInstruction).narrowLiteral - - // method founds - if (literal == 1) - pMethodCall = "${method.definingClass}->${method.name}(I)V" - else if (literal == 2) - oMethodCall = "${method.definingClass}->${method.name}(I)V" - } - - if (pMethodCall.isEmpty()) { - throw PatchException("pMethod not found") - } - if (oMethodCall.isEmpty()) { - throw PatchException("oMethod not found") - } - - val insertIndex = it.patternMatch!!.startIndex + 2 - - addInstructionsWithLabels( - insertIndex, """ - invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSeekbarTapping()Z - move-result v0 - if-eqz v0, :disabled - invoke-virtual { p0, v2 }, $pMethodCall - invoke-virtual { p0, v2 }, $oMethodCall - """, ExternalLabel("disabled", getInstruction(insertIndex)) - ) + val tapSeekIndex = indexOfFirstInstructionOrThrow(pointIndex) { + val reference = getReference() + opcode == Opcode.INVOKE_VIRTUAL && + reference?.returnType == "V" && + reference.parameterTypes.isEmpty() } + val thisInstanceRegister = getInstruction(tapSeekIndex).registerC + + val tapSeekClass = getInstruction(tapSeekIndex) + .getReference()!! + .definingClass + + val tapSeekMethods = findMethodsOrThrow(tapSeekClass) + var pMethodCall = "" + var oMethodCall = "" + + for (method in tapSeekMethods) { + if (method.implementation == null) + continue + + val instructions = method.implementation!!.instructions + // here we make sure we actually find the method because it has more than 7 instructions + if (instructions.count() != 10) + continue + + // we know that the 7th instruction has the opcode CONST_4 + val instruction = instructions.elementAt(6) + if (instruction.opcode != Opcode.CONST_4) + continue + + // the literal for this instruction has to be either 1 or 2 + val literal = (instruction as NarrowLiteralInstruction).narrowLiteral + + // method founds + if (literal == 1) + pMethodCall = "${method.definingClass}->${method.name}(I)V" + else if (literal == 2) + oMethodCall = "${method.definingClass}->${method.name}(I)V" + } + + if (pMethodCall.isEmpty()) { + throw PatchException("pMethod not found") + } + if (oMethodCall.isEmpty()) { + throw PatchException("oMethod not found") + } + + val insertIndex = tapSeekIndex + 1 + + addInstructionsWithLabels( + insertIndex, """ + invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSeekbarTapping()Z + move-result v$freeRegister + if-eqz v$freeRegister, :disabled + invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $pMethodCall + invoke-virtual { v$thisInstanceRegister, v$xAxisRegister }, $oMethodCall + """, ExternalLabel("disabled", getInstruction(insertIndex)) + ) } // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt index 6792d46bf..b7ecbe4cb 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/Fingerprints.kt @@ -109,25 +109,26 @@ internal val qualityMenuViewInflateFingerprint = legacyFingerprint( returnType = "L", accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("L", "L", "L"), - opcodes = listOf( - Opcode.INVOKE_SUPER, - Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CONST_16, - Opcode.INVOKE_VIRTUAL, - Opcode.CONST, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST - ), - literals = listOf(videoQualityBottomSheet), + customFingerprint = custom@{ method, _ -> + if (!method.containsLiteralInstruction(videoQualityBottomSheet)) { + return@custom false + } + if (indexOfAddHeaderViewInstruction(method) < 0) { + return@custom false + } + val implementation = method.implementation + ?: return@custom false + + implementation.instructions.elementAt(0).opcode == Opcode.INVOKE_SUPER + } ) +internal fun indexOfAddHeaderViewInstruction(method: Method) = + method.indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.name == "addHeaderView" + } + internal val rollingNumberTextViewAnimationUpdateFingerprint = legacyFingerprint( name = "rollingNumberTextViewAnimationUpdateFingerprint", returnType = "V", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt index 198a22138..f677f3965 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt @@ -8,25 +8,28 @@ import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.util.getBooleanOptionValue import org.w3c.dom.Element +/** + * Fix the splash screen dark mode background color. + * In earlier versions of the app this is white and makes no sense for dark mode. + * This is only required for 19.32 and greater, but is applied to all targets. + * Only dark mode needs this fix as light mode correctly uses the custom color. + * + * This is a bug in unpatched YouTube. + * Should always be applied even if the `Theme` patch is excluded. + */ val darkModeSplashScreenPatch = resourcePatch( description = "darkModeSplashScreenPatch" ) { dependsOn(versionCheckPatch) finalize { - val restoreOldSplashAnimationIncluded = is_19_32_or_greater && - CUSTOM_BRANDING_ICON_FOR_YOUTUBE.included == true && + if (!is_19_32_or_greater) { + return@finalize + } + + val restoreOldSplashAnimationIncluded = CUSTOM_BRANDING_ICON_FOR_YOUTUBE.included == true && customBrandingIconPatch.getBooleanOptionValue("restoreOldSplashAnimation").value == true - /** - * Fix the splash screen dark mode background color. - * In earlier versions of the app this is white and makes no sense for dark mode. - * This is only required for 19.32 and greater, but is applied to all targets. - * Only dark mode needs this fix as light mode correctly uses the custom color. - * - * This is a bug in unpatched YouTube. - * Should always be applied even if the `Theme` patch is excluded. - */ if (restoreOldSplashAnimationIncluded) { document("res/values-night/styles.xml").use { document -> val resourcesNode = document.getElementsByTagName("resources").item(0) as Element diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt index 97966f6b9..fa38cf1db 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt @@ -71,6 +71,8 @@ var is_20_09_or_greater = false private set var is_20_10_or_greater = false private set +var is_20_12_or_greater = false + private set val versionCheckPatch = resourcePatch( description = "versionCheckPatch", @@ -119,5 +121,6 @@ val versionCheckPatch = resourcePatch( is_20_05_or_greater = 250605000 <= playStoreServicesVersion is_20_09_or_greater = 251006000 <= playStoreServicesVersion is_20_10_or_greater = 251105000 <= playStoreServicesVersion + is_20_12_or_greater = 251305000 <= playStoreServicesVersion } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index b8598df1e..56194df98 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -193,8 +193,6 @@ var rightComment = -1L private set var scrimOverlay = -1L private set -var scrubbing = -1L - private set var seekEasyHorizontalTouchOffsetToStartScrubbing = -1L private set var seekUndoEduOverlayStub = -1L @@ -225,6 +223,10 @@ var videoQualityBottomSheet = -1L private set var varispeedUnavailableTitle = -1L private set +var verticalTouchOffsetToEnterFineScrubbing = -1L + private set +var verticalTouchOffsetToStartFineScrubbing = -1L + private set var videoQualityUnavailableAnnouncement = -1L private set var videoZoomSnapIndicator = -1L @@ -235,6 +237,8 @@ var youTubeControlsOverlaySubtitleButton = -1L private set var youTubeLogo = -1L private set +var ytCallToAction = -1L + private set var ytFillBell = -1L private set var ytOutlineLibrary = -1L @@ -620,10 +624,6 @@ internal val sharedResourceIdPatch = resourcePatch( ID, "scrim_overlay" ] - scrubbing = resourceMappings[ - DIMEN, - "vertical_touch_offset_to_enter_fine_scrubbing" - ] seekEasyHorizontalTouchOffsetToStartScrubbing = resourceMappings[ DIMEN, "seek_easy_horizontal_touch_offset_to_start_scrubbing" @@ -684,6 +684,14 @@ internal val sharedResourceIdPatch = resourcePatch( STRING, "varispeed_unavailable_title" ] + verticalTouchOffsetToEnterFineScrubbing = resourceMappings[ + DIMEN, + "vertical_touch_offset_to_enter_fine_scrubbing" + ] + verticalTouchOffsetToStartFineScrubbing = resourceMappings[ + DIMEN, + "vertical_touch_offset_to_start_fine_scrubbing" + ] videoQualityUnavailableAnnouncement = resourceMappings[ STRING, "video_quality_unavailable_announcement" @@ -704,6 +712,10 @@ internal val sharedResourceIdPatch = resourcePatch( ID, "youtube_logo" ] + ytCallToAction = resourceMappings[ + ATTR, + "ytCallToAction" + ] ytFillBell = resourceMappings[ DRAWABLE, "yt_fill_bell_black_24" diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/Fingerprints.kt index 0a8ea07c6..c7d6c602e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/returnyoutubedislike/Fingerprints.kt @@ -7,6 +7,7 @@ import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.iface.reference.StringReference /** * This fingerprint is compatible with YouTube v18.30.xx+ @@ -54,7 +55,14 @@ internal val rollingNumberMeasureTextParentFingerprint = legacyFingerprint( internal val rollingNumberSetterFingerprint = legacyFingerprint( name = "rollingNumberSetterFingerprint", opcodes = listOf(Opcode.CHECK_CAST), - literals = listOf(45427773L), + customFingerprint = { method, _ -> + method.indexOfFirstInstruction { + opcode == Opcode.CONST_STRING && + getReference() + ?.string.toString() + .startsWith("RollingNumberType required properties missing! Need") + } >= 0 + } ) internal val shortsTextViewFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt index 28ede6d2b..0b8282018 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt @@ -2,9 +2,12 @@ package app.revanced.patches.youtube.video.playback import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.reference.FieldReference internal val av1CodecFingerprint = legacyFingerprint( name = "av1CodecFingerprint", @@ -61,16 +64,17 @@ internal val playbackSpeedChangedFromRecyclerViewFingerprint = legacyFingerprint accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, parameters = listOf("L"), opcodes = listOf( - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, Opcode.INVOKE_INTERFACE, Opcode.MOVE_RESULT_OBJECT, Opcode.IGET, Opcode.INVOKE_VIRTUAL - ) + ), + customFingerprint = { method, _ -> + method.indexOfFirstInstruction { + opcode == Opcode.IGET && + getReference()?.type == "F" + } >= 0 + } ) internal val playbackSpeedInitializeFingerprint = legacyFingerprint( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt index 3567bf0fd..1a8979a08 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/videoid/Fingerprints.kt @@ -29,7 +29,7 @@ internal val videoIdFingerprint = legacyFingerprint( ?: return@custom false val instructions = implementation.instructions val instructionCount = instructions.count() - if (instructionCount < 30) { + if (instructionCount < 25) { return@custom false } From 7609b904d4122cacd53cba27510cb21ffb61f34e Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 21:30:25 +0900 Subject: [PATCH 14/77] feat(YouTube): Add support version `19.43.41` and `19.47.53` https://github.com/inotia00/ReVanced_Extended/issues/2859#issuecomment-2747926810 --- .../revanced/patches/youtube/utils/compatibility/Constants.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt index 81fe49258..f08e8b1d2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt @@ -11,7 +11,9 @@ internal object Constants { setOf( "19.05.36", // This is the last version with the least YouTube experimental flag. "19.16.39", // This is the last version where the 'Restore old seekbar thumbnails' setting works. - "19.44.39", // This is the latest version supported by the RVX patch. + "19.43.41", // This is the latest version where edge-to-edge display is not enforced on Android 15+. + "19.44.39", // This is the only version that has experimental shortcut icons. + "19.47.53", // This is the latest version supported by the RVX patch. ) ) } \ No newline at end of file From e7e011667e0c00d129831db251560e827ef2714d Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 21:33:11 +0900 Subject: [PATCH 15/77] feat(YouTube): Add `Disable layout updates` patch https://github.com/inotia00/ReVanced_Extended/issues/2863 --- .../youtube/patches/general/GeneralPatch.java | 28 +++++++++++ .../extension/youtube/settings/Settings.java | 1 + .../youtube/general/updates/Fingerprints.kt | 17 +++++++ .../general/updates/LayoutUpdatesPatch.kt | 50 +++++++++++++++++++ .../patches/youtube/utils/patch/PatchList.kt | 4 ++ .../youtube/settings/host/values/strings.xml | 14 ++++++ .../youtube/settings/xml/revanced_prefs.xml | 4 ++ 7 files changed, 118 insertions(+) create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/general/updates/Fingerprints.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/general/updates/LayoutUpdatesPatch.kt diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/GeneralPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/GeneralPatch.java index 8700b66d5..020012d82 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/GeneralPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/GeneralPatch.java @@ -106,6 +106,34 @@ public class GeneralPatch { // endregion + // region [Disable layout updates] patch + + private static final String[] REQUEST_HEADER_KEYS = { + "X-Youtube-Cold-Config-Data", + "X-Youtube-Cold-Hash-Data", + "X-Youtube-Hot-Config-Data", + "X-Youtube-Hot-Hash-Data" + }; + + private static final boolean DISABLE_LAYOUT_UPDATES = + Settings.DISABLE_LAYOUT_UPDATES.get(); + + /** + * @param key Keys to be added to the header of CronetBuilder. + * @param value Values to be added to the header of CronetBuilder. + * @return Empty value if setting is enabled. + */ + public static String disableLayoutUpdates(String key, String value) { + if (DISABLE_LAYOUT_UPDATES && StringUtils.equalsAny(key, REQUEST_HEADER_KEYS)) { + Logger.printDebug(() -> "Blocking: " + key); + return ""; + } + + return value; + } + + // endregion + // region [Disable splash animation] patch public static boolean disableSplashAnimation(boolean original) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index 4042cdf78..b9eda5de2 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -158,6 +158,7 @@ public class Settings extends BaseSettings { public static final EnumSetting CHANGE_FORM_FACTOR = new EnumSetting<>("revanced_change_form_factor", FormFactor.DEFAULT, true, "revanced_change_form_factor_user_dialog_message"); public static final BooleanSetting CHANGE_LIVE_RING_CLICK_ACTION = new BooleanSetting("revanced_change_live_ring_click_action", FALSE, true); + public static final BooleanSetting DISABLE_LAYOUT_UPDATES = new BooleanSetting("revanced_disable_layout_updates", false, true, "revanced_disable_layout_updates_user_dialog_message"); public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", false, true, "revanced_spoof_app_version_user_dialog_message"); public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", PatchStatus.SpoofAppVersionDefaultString(), true, parent(SPOOF_APP_VERSION)); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/updates/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/updates/Fingerprints.kt new file mode 100644 index 000000000..beffc631c --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/updates/Fingerprints.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.youtube.general.updates + +import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.or +import com.android.tools.smali.dexlib2.AccessFlags + +internal val cronetHeaderFingerprint = legacyFingerprint( + name = "cronetHeaderFingerprint", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Ljava/lang/String;", "Ljava/lang/String;"), + strings = listOf("Accept-Encoding"), + // In YouTube 19.16.39 or earlier, there are two methods with almost the same structure. + // Check the fields of the class to identify them correctly. + customFingerprint = { _, classDef -> + classDef.fields.find { it.type == "J" } != null + } +) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/updates/LayoutUpdatesPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/updates/LayoutUpdatesPatch.kt new file mode 100644 index 000000000..1543fc746 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/updates/LayoutUpdatesPatch.kt @@ -0,0 +1,50 @@ +package app.revanced.patches.youtube.general.updates + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE +import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR +import app.revanced.patches.youtube.utils.patch.PatchList.DISABLE_LAYOUT_UPDATES +import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference +import app.revanced.patches.youtube.utils.settings.settingsPatch +import app.revanced.util.fingerprint.matchOrThrow + +@Suppress("unused") +val layoutUpdatesPatch = bytecodePatch( + DISABLE_LAYOUT_UPDATES.title, + DISABLE_LAYOUT_UPDATES.summary, +) { + compatibleWith(COMPATIBLE_PACKAGE) + + dependsOn(settingsPatch) + + execute { + + cronetHeaderFingerprint.matchOrThrow().let { + it.method.apply { + val index = it.stringMatches!!.first().index + + addInstructions( + index, """ + invoke-static {p1, p2}, $GENERAL_CLASS_DESCRIPTOR->disableLayoutUpdates(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; + move-result-object p2 + """ + ) + } + } + + // region add settings + + addPreference( + arrayOf( + "PREFERENCE_SCREEN: GENERAL", + "PREFERENCE_CATEGORY: GENERAL_EXPERIMENTAL_FLAGS", + "SETTINGS: DISABLE_LAYOUT_UPDATES" + ), + DISABLE_LAYOUT_UPDATES + ) + + // endregion + + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/patch/PatchList.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/patch/PatchList.kt index c8dca6a6f..508b49496 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/patch/PatchList.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/patch/PatchList.kt @@ -81,6 +81,10 @@ internal enum class PatchList( "Disable haptic feedback", "Adds options to disable haptic feedback when swiping in the video player." ), + DISABLE_LAYOUT_UPDATES( + "Disable layout updates", + "Adds an option to disable layout updates by server." + ), DISABLE_RESUMING_MINIPLAYER_ON_STARTUP( "Disable resuming Miniplayer on startup", "Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup." diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 2f3c79735..3b18b2f2b 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -518,6 +518,20 @@ Automotive layout • Shorts open in the regular player. • Feed is organized by topics and channels. • Video description cannot be opened when 'Spoof streaming data' is turned off." + Disable layout updates + Layout will not be updated by the server. + Layout will be updated by the server. + "App layout reverts to the layout it was using when it was first installed. + +Some server-side layouts may not revert. + +Changes include: +• Components in the player flyout menu (or related settings) may not work. +• Rolling numbers are not animated. +• The Library tab is used. +• The Music section of video description may not work. +• Account switch button may not appear on the Library tab. Use the 'Enable wide search bar in You tab' setting." + Spoof app version Version spoofed Version not spoofed diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 3915effdd..8240aa8de 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -275,6 +275,9 @@ + + From c22391926b0a5b90566817adf62ca0fc077b87d8 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 22:03:28 +0900 Subject: [PATCH 18/77] feat(YouTube - Hook download actions, Overlay buttons): Add `Queue manager` setting (Experimental) --- extensions/shared/build.gradle.kts | 1 + .../patches/spoof/requests/PlayerRoutes.kt | 188 +++++++ .../patches/general/DownloadActionsPatch.java | 76 +-- .../overlaybutton/ExternalDownload.java | 11 +- .../youtube/patches/player/PlayerPatch.java | 4 + .../patches/shorts/CustomActionsPatch.java | 112 +--- .../youtube/patches/utils/PlaylistPatch.java | 495 ++++++++++++++++++ .../utils/requests/CreatePlaylistRequest.kt | 275 ++++++++++ .../utils/requests/DeletePlaylistRequest.kt | 197 +++++++ .../utils/requests/EditPlaylistRequest.kt | 233 +++++++++ .../utils/requests/GetPlaylistsRequest.kt | 236 +++++++++ .../utils/requests/SavePlaylistRequest.kt | 203 +++++++ .../extension/youtube/settings/Settings.java | 12 +- .../ReVancedSettingsPreference.java | 14 - .../youtube/utils/ExtendedUtils.java | 103 ++++ .../extension/youtube/utils/VideoUtils.java | 18 +- gradle/libs.versions.toml | 2 + .../general/downloads/DownloadActionsPatch.kt | 4 +- .../overlaybuttons/OverlayButtonsPatch.kt | 2 + .../youtube/utils/playlist/Fingerprints.kt | 54 ++ .../youtube/utils/playlist/PlaylistPatch.kt | 85 +++ .../youtube/settings/host/values/strings.xml | 40 +- .../youtube/settings/xml/revanced_prefs.xml | 2 + 23 files changed, 2212 insertions(+), 155 deletions(-) create mode 100644 extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaylistPatch.java create mode 100644 extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt create mode 100644 extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt create mode 100644 extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt create mode 100644 extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt create mode 100644 extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/Fingerprints.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt diff --git a/extensions/shared/build.gradle.kts b/extensions/shared/build.gradle.kts index 69641ab9e..d9511b8b8 100644 --- a/extensions/shared/build.gradle.kts +++ b/extensions/shared/build.gradle.kts @@ -26,6 +26,7 @@ android { dependencies { compileOnly(libs.annotation) compileOnly(libs.preference) + implementation(libs.collections4) implementation(libs.lang3) compileOnly(project(":extensions:shared:stub")) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt index bd99fc453..5ef4a4212 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt @@ -7,8 +7,10 @@ import app.revanced.extension.shared.requests.Route import app.revanced.extension.shared.requests.Route.CompiledRoute import app.revanced.extension.shared.settings.BaseSettings import app.revanced.extension.shared.utils.Logger +import app.revanced.extension.shared.utils.StringRef.str import app.revanced.extension.shared.utils.Utils import org.apache.commons.lang3.StringUtils +import org.json.JSONArray import org.json.JSONException import org.json.JSONObject import java.io.IOException @@ -20,6 +22,38 @@ import java.util.TimeZone @Suppress("deprecation") object PlayerRoutes { + @JvmField + val CREATE_PLAYLIST: CompiledRoute = Route( + Route.Method.POST, + "playlist/create" + + "?prettyPrint=false" + + "&fields=playlistId" + ).compile() + + @JvmField + val DELETE_PLAYLIST: CompiledRoute = Route( + Route.Method.POST, + "playlist/delete" + + "?prettyPrint=false" + ).compile() + + @JvmField + val EDIT_PLAYLIST: CompiledRoute = Route( + Route.Method.POST, + "browse/edit_playlist" + + "?prettyPrint=false" + + "&fields=status," + + "playlistEditResults" + ).compile() + + @JvmField + val GET_PLAYLISTS: CompiledRoute = Route( + Route.Method.POST, + "playlist/get_add_to_playlist" + + "?prettyPrint=false" + + "&fields=contents.addToPlaylistRenderer.playlists.playlistAddToOptionRenderer" + ).compile() + @JvmField val GET_CATEGORY: CompiledRoute = Route( Route.Method.POST, @@ -28,6 +62,16 @@ object PlayerRoutes { "&fields=microformat.playerMicroformatRenderer.category" ).compile() + @JvmField + val GET_SET_VIDEO_ID: CompiledRoute = Route( + Route.Method.POST, + "next" + + "?prettyPrint=false" + + "&fields=contents.singleColumnWatchNextResults." + + "playlist.playlist.contents.playlistPanelVideoRenderer." + + "playlistSetVideoId" + ).compile() + @JvmField val GET_PLAYLIST_PAGE: CompiledRoute = Route( Route.Method.POST, @@ -172,6 +216,150 @@ object PlayerRoutes { return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) } + private fun androidInnerTubeBody( + clientType: YouTubeAppClient.ClientType = YouTubeAppClient.ClientType.ANDROID + ): JSONObject { + val innerTubeBody = JSONObject() + + try { + val client = JSONObject() + client.put("deviceMake", clientType.deviceMake) + client.put("deviceModel", clientType.deviceModel) + client.put("clientName", clientType.clientName) + client.put("clientVersion", clientType.clientVersion) + client.put("osName", clientType.osName) + client.put("osVersion", clientType.osVersion) + client.put("androidSdkVersion", clientType.androidSdkVersion) + if (clientType.gmscoreVersionCode != null) { + client.put("gmscoreVersionCode", clientType.gmscoreVersionCode) + } + client.put( + "hl", + LOCALE_LANGUAGE + ) + client.put("gl", LOCALE_COUNTRY) + client.put("timeZone", TIME_ZONE_ID) + client.put("utcOffsetMinutes", "$UTC_OFFSET_MINUTES") + + val context = JSONObject() + context.put("client", client) + + innerTubeBody.put("context", context) + innerTubeBody.put("contentCheckOk", true) + innerTubeBody.put("racyCheckOk", true) + } catch (e: JSONException) { + Logger.printException({ "Failed to create android innerTubeBody" }, e) + } + + return innerTubeBody + } + + @JvmStatic + fun createPlaylistRequestBody( + videoId: String, + ): ByteArray { + val innerTubeBody = androidInnerTubeBody() + + try { + innerTubeBody.put("params", "CAQ%3D") + // TODO: Implement an AlertDialog that allows changing the title of the playlist. + innerTubeBody.put("title", str("revanced_queue_manager_queue")) + + val videoIds = JSONArray() + videoIds.put(0, videoId) + innerTubeBody.put("videoIds", videoIds) + } catch (e: JSONException) { + Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + } + + return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) + } + + @JvmStatic + fun deletePlaylistRequestBody( + playlistId: String, + ): ByteArray { + val innerTubeBody = androidInnerTubeBody() + + try { + innerTubeBody.put("playlistId", playlistId) + } catch (e: JSONException) { + Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + } + + return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) + } + + @JvmStatic + fun editPlaylistRequestBody( + videoId: String, + playlistId: String, + setVideoId: String?, + ): ByteArray { + val innerTubeBody = androidInnerTubeBody() + + try { + innerTubeBody.put("playlistId", playlistId) + + val actionsObject = JSONObject() + if (setVideoId != null && setVideoId.isNotEmpty()) { + actionsObject.put("action", "ACTION_REMOVE_VIDEO") + actionsObject.put("setVideoId", setVideoId) + } else { + actionsObject.put("action", "ACTION_ADD_VIDEO") + actionsObject.put("addedVideoId", videoId) + } + + val actionsArray = JSONArray() + actionsArray.put(0, actionsObject) + innerTubeBody.put("actions", actionsArray) + } catch (e: JSONException) { + Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + } + + return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) + } + + @JvmStatic + fun getPlaylistsRequestBody( + playlistId: String, + ): ByteArray { + val innerTubeBody = androidInnerTubeBody() + + try { + innerTubeBody.put("playlistId", playlistId) + innerTubeBody.put("excludeWatchLater", false) + } catch (e: JSONException) { + Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + } + + return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) + } + + @JvmStatic + fun savePlaylistRequestBody( + playlistId: String, + libraryId: String, + ): ByteArray { + val innerTubeBody = androidInnerTubeBody() + + try { + innerTubeBody.put("playlistId", playlistId) + + val actionsObject = JSONObject() + actionsObject.put("action", "ACTION_ADD_PLAYLIST") + actionsObject.put("addedFullListId", libraryId) + + val actionsArray = JSONArray() + actionsArray.put(0, actionsObject) + innerTubeBody.put("actions", actionsArray) + } catch (e: JSONException) { + Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + } + + return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) + } + @JvmStatic fun getPlayerResponseConnectionFromRoute( route: CompiledRoute, diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/DownloadActionsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/DownloadActionsPatch.java index 0c1607561..ba818a3c8 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/DownloadActionsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/DownloadActionsPatch.java @@ -1,18 +1,34 @@ package app.revanced.extension.youtube.patches.general; -import app.revanced.extension.shared.settings.BooleanSetting; +import static app.revanced.extension.youtube.utils.VideoUtils.launchPlaylistExternalDownloader; +import static app.revanced.extension.youtube.utils.VideoUtils.launchVideoExternalDownloader; + +import android.view.View; + +import androidx.annotation.Nullable; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; + import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.youtube.patches.utils.PlaylistPatch; import app.revanced.extension.youtube.settings.Settings; -import app.revanced.extension.youtube.utils.VideoUtils; @SuppressWarnings("unused") -public final class DownloadActionsPatch extends VideoUtils { +public final class DownloadActionsPatch { - private static final BooleanSetting overrideVideoDownloadButton = - Settings.OVERRIDE_VIDEO_DOWNLOAD_BUTTON; + private static final boolean OVERRIDE_PLAYLIST_DOWNLOAD_BUTTON = + Settings.OVERRIDE_PLAYLIST_DOWNLOAD_BUTTON.get(); - private static final BooleanSetting overridePlaylistDownloadButton = - Settings.OVERRIDE_PLAYLIST_DOWNLOAD_BUTTON; + private static final boolean OVERRIDE_VIDEO_DOWNLOAD_BUTTON = + Settings.OVERRIDE_VIDEO_DOWNLOAD_BUTTON.get(); + + private static final boolean OVERRIDE_VIDEO_DOWNLOAD_BUTTON_QUEUE_MANAGER = + OVERRIDE_VIDEO_DOWNLOAD_BUTTON && Settings.OVERRIDE_VIDEO_DOWNLOAD_BUTTON_QUEUE_MANAGER.get(); + + private static final String ELEMENTS_SENDER_VIEW = + "com.google.android.libraries.youtube.rendering.elements.sender_view"; /** * Injection point. @@ -23,17 +39,21 @@ public final class DownloadActionsPatch extends VideoUtils { *

* Appears to always be called from the main thread. */ - public static boolean inAppVideoDownloadButtonOnClick(String videoId) { + public static boolean inAppVideoDownloadButtonOnClick(@Nullable Map map,Object offlineVideoEndpointOuterClass, + @Nullable String videoId) { try { - if (!overrideVideoDownloadButton.get()) { - return false; - } - if (videoId == null || videoId.isEmpty()) { - return false; - } - launchVideoExternalDownloader(videoId); + if (OVERRIDE_VIDEO_DOWNLOAD_BUTTON && StringUtils.isNotEmpty(videoId)) { + if (OVERRIDE_VIDEO_DOWNLOAD_BUTTON_QUEUE_MANAGER) { + if (map != null && map.get(ELEMENTS_SENDER_VIEW) instanceof View view) { + PlaylistPatch.setContext(view.getContext()); + } + PlaylistPatch.prepareDialogBuilder(videoId); + } else { + launchVideoExternalDownloader(videoId); + } - return true; + return true; + } } catch (Exception ex) { Logger.printException(() -> "inAppVideoDownloadButtonOnClick failure", ex); } @@ -49,15 +69,10 @@ public final class DownloadActionsPatch extends VideoUtils { */ public static String inAppPlaylistDownloadButtonOnClick(String playlistId) { try { - if (!overridePlaylistDownloadButton.get()) { - return playlistId; + if (OVERRIDE_PLAYLIST_DOWNLOAD_BUTTON && StringUtils.isNotEmpty(playlistId)) { + launchPlaylistExternalDownloader(playlistId); + return ""; } - if (playlistId == null || playlistId.isEmpty()) { - return playlistId; - } - launchPlaylistExternalDownloader(playlistId); - - return ""; } catch (Exception ex) { Logger.printException(() -> "inAppPlaylistDownloadButtonOnClick failure", ex); } @@ -73,15 +88,10 @@ public final class DownloadActionsPatch extends VideoUtils { */ public static boolean inAppPlaylistDownloadMenuOnClick(String playlistId) { try { - if (!overridePlaylistDownloadButton.get()) { - return false; + if (OVERRIDE_PLAYLIST_DOWNLOAD_BUTTON && StringUtils.isNotEmpty(playlistId)) { + launchPlaylistExternalDownloader(playlistId); + return true; } - if (playlistId == null || playlistId.isEmpty()) { - return false; - } - launchPlaylistExternalDownloader(playlistId); - - return true; } catch (Exception ex) { Logger.printException(() -> "inAppPlaylistDownloadMenuOnClick failure", ex); } @@ -92,7 +102,7 @@ public final class DownloadActionsPatch extends VideoUtils { * Injection point. */ public static boolean overridePlaylistDownloadButtonVisibility() { - return overridePlaylistDownloadButton.get(); + return OVERRIDE_PLAYLIST_DOWNLOAD_BUTTON; } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/overlaybutton/ExternalDownload.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/overlaybutton/ExternalDownload.java index e6a572af6..450ee50f9 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/overlaybutton/ExternalDownload.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/overlaybutton/ExternalDownload.java @@ -6,7 +6,9 @@ import android.view.ViewGroup; import androidx.annotation.Nullable; import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.youtube.patches.utils.PlaylistPatch; import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.shared.VideoInformation; import app.revanced.extension.youtube.utils.VideoUtils; @SuppressWarnings("unused") @@ -19,7 +21,14 @@ public class ExternalDownload extends BottomControlButton { bottomControlsViewGroup, "external_download_button", Settings.OVERLAY_BUTTON_EXTERNAL_DOWNLOADER, - view -> VideoUtils.launchVideoExternalDownloader(), + view -> { + if (Settings.OVERLAY_BUTTON_EXTERNAL_DOWNLOADER_QUEUE_MANAGER.get()) { + PlaylistPatch.setContext(view.getContext()); + PlaylistPatch.prepareDialogBuilder(VideoInformation.getVideoId()); + } else { + VideoUtils.launchVideoExternalDownloader(); + } + }, null ); } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java index 287ed6992..ef1bf3800 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java @@ -546,6 +546,10 @@ public class PlayerPatch { return Settings.HIDE_FILMSTRIP_OVERLAY.get(); } + public static boolean hideFilmstripOverlay(boolean original) { + return !Settings.HIDE_FILMSTRIP_OVERLAY.get() && original; + } + public static boolean hideInfoCard(boolean original) { return !Settings.HIDE_INFO_CARDS.get() && original; } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java index 4bf010129..9b76a935c 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java @@ -1,25 +1,14 @@ package app.revanced.extension.youtube.patches.shorts; import static app.revanced.extension.shared.utils.ResourceUtils.getString; -import static app.revanced.extension.shared.utils.Utils.dpToPx; import static app.revanced.extension.youtube.patches.components.ShortsCustomActionsFilter.isShortsFlyoutMenuVisible; import static app.revanced.extension.youtube.utils.ExtendedUtils.isSpoofingToLessThan; -import android.app.AlertDialog; import android.content.Context; -import android.graphics.ColorFilter; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffColorFilter; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.StateListDrawable; import android.support.v7.widget.RecyclerView; -import android.view.Gravity; import android.view.View; import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ScrollView; @@ -42,7 +31,7 @@ import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.patches.components.ShortsCustomActionsFilter; import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.shared.ShortsPlayerState; -import app.revanced.extension.youtube.utils.ThemeUtils; +import app.revanced.extension.youtube.utils.ExtendedUtils; import app.revanced.extension.youtube.utils.VideoUtils; @SuppressWarnings("unused") @@ -90,105 +79,28 @@ public final class CustomActionsPatch { }), 0); } - private static void showMoreButtonDialog(Context context) { - ScrollView scrollView = new ScrollView(context); - LinearLayout container = new LinearLayout(context); + private static void showMoreButtonDialog(Context mContext) { + ScrollView mScrollView = new ScrollView(mContext); + LinearLayout mLinearLayout = new LinearLayout(mContext); + mLinearLayout.setOrientation(LinearLayout.VERTICAL); + mLinearLayout.setPadding(0, 0, 0, 0); - container.setOrientation(LinearLayout.VERTICAL); - container.setPadding(0, 0, 0, 0); - - Map toolbarMap = new LinkedHashMap<>(arrSize); + Map actionsMap = new LinkedHashMap<>(arrSize); for (CustomAction customAction : CustomAction.values()) { if (customAction.settings.get()) { String title = customAction.getLabel(); int iconId = customAction.getDrawableId(); Runnable action = customAction.getOnClickAction(); - LinearLayout itemLayout = createItemLayout(context, title, iconId); - toolbarMap.putIfAbsent(itemLayout, action); - container.addView(itemLayout); + LinearLayout itemLayout = ExtendedUtils.createItemLayout(mContext, title, iconId); + actionsMap.putIfAbsent(itemLayout, action); + mLinearLayout.addView(itemLayout); } } - scrollView.addView(container); + mScrollView.addView(mLinearLayout); - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setView(scrollView); - - AlertDialog dialog = builder.create(); - dialog.show(); - - toolbarMap.forEach((view, action) -> - view.setOnClickListener(v -> { - action.run(); - dialog.dismiss(); - }) - ); - toolbarMap.clear(); - - Window window = dialog.getWindow(); - if (window == null) { - return; - } - - // round corners - GradientDrawable dialogBackground = new GradientDrawable(); - dialogBackground.setCornerRadius(32); - window.setBackgroundDrawable(dialogBackground); - - // fit screen width - int dialogWidth = (int) (context.getResources().getDisplayMetrics().widthPixels * 0.95); - window.setLayout(dialogWidth, ViewGroup.LayoutParams.WRAP_CONTENT); - - // move dialog to bottom - WindowManager.LayoutParams layoutParams = window.getAttributes(); - layoutParams.gravity = Gravity.BOTTOM; - - // adjust the vertical offset - layoutParams.y = dpToPx(5); - - window.setAttributes(layoutParams); - } - - private static LinearLayout createItemLayout(Context context, String title, int iconId) { - // Item Layout - LinearLayout itemLayout = new LinearLayout(context); - itemLayout.setOrientation(LinearLayout.HORIZONTAL); - itemLayout.setPadding(dpToPx(16), dpToPx(12), dpToPx(16), dpToPx(12)); - itemLayout.setGravity(Gravity.CENTER_VERTICAL); - itemLayout.setClickable(true); - itemLayout.setFocusable(true); - - // Create a StateListDrawable for the background - StateListDrawable background = new StateListDrawable(); - ColorDrawable pressedDrawable = new ColorDrawable(ThemeUtils.getPressedElementColor()); - ColorDrawable defaultDrawable = new ColorDrawable(ThemeUtils.getBackgroundColor()); - background.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable); - background.addState(new int[]{}, defaultDrawable); - itemLayout.setBackground(background); - - // Icon - ColorFilter cf = new PorterDuffColorFilter(ThemeUtils.getForegroundColor(), PorterDuff.Mode.SRC_ATOP); - ImageView iconView = new ImageView(context); - iconView.setImageResource(iconId); - iconView.setColorFilter(cf); - LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams(dpToPx(24), dpToPx(24)); - iconParams.setMarginEnd(dpToPx(16)); - iconView.setLayoutParams(iconParams); - itemLayout.addView(iconView); - - // Text container - LinearLayout textContainer = new LinearLayout(context); - textContainer.setOrientation(LinearLayout.VERTICAL); - TextView titleView = new TextView(context); - titleView.setText(title); - titleView.setTextSize(16); - titleView.setTextColor(ThemeUtils.getForegroundColor()); - textContainer.addView(titleView); - - itemLayout.addView(textContainer); - - return itemLayout; + ExtendedUtils.showBottomSheetDialog(mContext, mScrollView, actionsMap); } private static boolean isMoreButton(String enumString) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaylistPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaylistPatch.java new file mode 100644 index 000000000..d33a55441 --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaylistPatch.java @@ -0,0 +1,495 @@ +package app.revanced.extension.youtube.patches.utils; + +import android.content.Context; +import android.view.KeyEvent; +import android.widget.LinearLayout; +import android.widget.ScrollView; + +import androidx.annotation.GuardedBy; +import androidx.annotation.NonNull; + +import org.apache.commons.collections4.BidiMap; +import org.apache.commons.collections4.bidimap.DualHashBidiMap; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.Nullable; + +import java.util.LinkedHashMap; +import java.util.Map; + +import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.shared.utils.ResourceUtils; +import app.revanced.extension.shared.utils.Utils; +import app.revanced.extension.youtube.patches.utils.requests.CreatePlaylistRequest; +import app.revanced.extension.youtube.patches.utils.requests.DeletePlaylistRequest; +import app.revanced.extension.youtube.patches.utils.requests.EditPlaylistRequest; +import app.revanced.extension.youtube.patches.utils.requests.GetPlaylistsRequest; +import app.revanced.extension.youtube.patches.utils.requests.SavePlaylistRequest; +import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.utils.ExtendedUtils; +import app.revanced.extension.youtube.utils.VideoUtils; +import kotlin.Pair; + +// TODO: Implement sync queue and clean up code. +@SuppressWarnings({"unused", "StaticFieldLeak"}) +public class PlaylistPatch extends VideoUtils { + private static final String AUTHORIZATION_HEADER = "Authorization"; + private static final String[] REQUEST_HEADER_KEYS = { + AUTHORIZATION_HEADER, + "X-GOOG-API-FORMAT-VERSION", + "X-Goog-Visitor-Id" + }; + private static final boolean QUEUE_MANAGER = + Settings.OVERLAY_BUTTON_EXTERNAL_DOWNLOADER_QUEUE_MANAGER.get() + || Settings.OVERRIDE_VIDEO_DOWNLOAD_BUTTON_QUEUE_MANAGER.get(); + + private static Context mContext; + private static volatile String authorization = ""; + private static volatile boolean isIncognito = false; + private static volatile Map requestHeader; + private static volatile String playlistId = ""; + private static volatile String videoId = ""; + + private static final String checkFailedAuth = + ResourceUtils.getString("revanced_queue_manager_check_failed_auth"); + private static final String checkFailedPlaylistId = + ResourceUtils.getString("revanced_queue_manager_check_failed_playlist_id"); + private static final String checkFailedQueue = + ResourceUtils.getString("revanced_queue_manager_check_failed_queue"); + private static final String checkFailedVideoId = + ResourceUtils.getString("revanced_queue_manager_check_failed_video_id"); + private static final String checkFailedGeneric = + ResourceUtils.getString("revanced_queue_manager_check_failed_generic"); + + private static final String fetchFailedAdd = + ResourceUtils.getString("revanced_queue_manager_fetch_failed_add"); + private static final String fetchFailedCreate = + ResourceUtils.getString("revanced_queue_manager_fetch_failed_create"); + private static final String fetchFailedDelete = + ResourceUtils.getString("revanced_queue_manager_fetch_failed_delete"); + private static final String fetchFailedRemove = + ResourceUtils.getString("revanced_queue_manager_fetch_failed_remove"); + private static final String fetchFailedSave = + ResourceUtils.getString("revanced_queue_manager_fetch_failed_save"); + + private static final String fetchSucceededAdd = + ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_add"); + private static final String fetchSucceededCreate = + ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_create"); + private static final String fetchSucceededDelete = + ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_delete"); + private static final String fetchSucceededRemove = + ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_remove"); + private static final String fetchSucceededSave = + ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_save"); + + @GuardedBy("itself") + private static final BidiMap lastVideoIds = new DualHashBidiMap<>(); + + /** + * Injection point. + */ + public static boolean onKeyLongPress(int keyCode) { + if (!QUEUE_MANAGER || keyCode != KeyEvent.KEYCODE_BACK) { + return false; + } + if (mContext == null) { + handleCheckError(checkFailedQueue); + return false; + } + prepareDialogBuilder(""); + return true; + } + + /** + * Injection point. + */ + public static void removeFromQueue(@Nullable String setVideoId) { + if (StringUtils.isNotEmpty(setVideoId)) { + synchronized (lastVideoIds) { + String videoId = lastVideoIds.inverseBidiMap().get(setVideoId); + if (videoId != null) { + lastVideoIds.remove(videoId, setVideoId); + EditPlaylistRequest.clearVideoId(videoId); + } + } + } + } + + /** + * Injection point. + */ + public static void setIncognitoStatus(boolean incognito) { + if (QUEUE_MANAGER) { + isIncognito = incognito; + } + } + + /** + * Injection point. + */ + public static void setRequestHeaders(String url, Map requestHeaders) { + if (QUEUE_MANAGER) { + try { + // Save requestHeaders whenever an account is switched. + String auth = requestHeaders.get(AUTHORIZATION_HEADER); + if (auth == null || authorization.equals(auth)) { + return; + } + for (String key : REQUEST_HEADER_KEYS) { + if (requestHeaders.get(key) == null) { + return; + } + } + authorization = auth; + requestHeader = requestHeaders; + } catch (Exception ex) { + Logger.printException(() -> "setRequestHeaders failure", ex); + } + } + } + + /** + * Invoked by extension. + */ + public static void setContext(Context context) { + mContext = context; + } + + /** + * Invoked by extension. + */ + public static void prepareDialogBuilder(@NonNull String currentVideoId) { + if (authorization.isEmpty() || isIncognito) { + handleCheckError(checkFailedAuth); + return; + } + if (currentVideoId.isEmpty()) { + buildBottomSheetDialog(QueueManager.noVideoIdQueueEntries); + } else { + videoId = currentVideoId; + synchronized (lastVideoIds) { + QueueManager[] customActionsEntries = playlistId.isEmpty() || lastVideoIds.get(currentVideoId) == null + ? QueueManager.addToQueueEntries + : QueueManager.removeFromQueueEntries; + + buildBottomSheetDialog(customActionsEntries); + } + } + } + + private static void buildBottomSheetDialog(QueueManager[] queueManagerEntries) { + ScrollView mScrollView = new ScrollView(mContext); + LinearLayout mLinearLayout = new LinearLayout(mContext); + mLinearLayout.setOrientation(LinearLayout.VERTICAL); + mLinearLayout.setPadding(0, 0, 0, 0); + + Map actionsMap = new LinkedHashMap<>(queueManagerEntries.length); + + for (QueueManager queueManager : queueManagerEntries) { + String title = queueManager.label; + int iconId = queueManager.drawableId; + Runnable action = queueManager.onClickAction; + LinearLayout itemLayout = ExtendedUtils.createItemLayout(mContext, title, iconId); + actionsMap.putIfAbsent(itemLayout, action); + mLinearLayout.addView(itemLayout); + } + + mScrollView.addView(mLinearLayout); + + ExtendedUtils.showBottomSheetDialog(mContext, mScrollView, actionsMap); + } + + private static void fetchQueue(boolean remove, boolean openPlaylist, boolean openVideo) { + try { + String currentPlaylistId = playlistId; + String currentVideoId = videoId; + synchronized (lastVideoIds) { + if (currentPlaylistId.isEmpty()) { // Queue is empty, create new playlist. + CreatePlaylistRequest.fetchRequestIfNeeded(currentVideoId, requestHeader); + runOnMainThreadDelayed(() -> { + CreatePlaylistRequest request = CreatePlaylistRequest.getRequestForVideoId(currentVideoId); + if (request != null) { + Pair playlistIds = request.getPlaylistId(); + if (playlistIds != null) { + String createdPlaylistId = playlistIds.getFirst(); + String setVideoId = playlistIds.getSecond(); + if (createdPlaylistId != null && setVideoId != null) { + playlistId = createdPlaylistId; + lastVideoIds.putIfAbsent(currentVideoId, setVideoId); + showToast(fetchSucceededCreate); + Logger.printDebug(() -> "Queue successfully created, playlistId: " + createdPlaylistId + ", setVideoId: " + setVideoId); + if (openPlaylist) { + openQueue(currentVideoId, openVideo); + } + return; + } + } + } + showToast(fetchFailedCreate); + }, 1000); + } else { // Queue is not empty, add or remove video. + String setVideoId = lastVideoIds.get(currentVideoId); + EditPlaylistRequest.fetchRequestIfNeeded(currentVideoId, currentPlaylistId, setVideoId, requestHeader); + + runOnMainThreadDelayed(() -> { + EditPlaylistRequest request = EditPlaylistRequest.getRequestForVideoId(currentVideoId); + if (request != null) { + String fetchedSetVideoId = request.getResult(); + Logger.printDebug(() -> "fetchedSetVideoId: " + fetchedSetVideoId); + if (remove) { // Remove from queue. + if (StringUtils.isEmpty(fetchedSetVideoId)) { + lastVideoIds.remove(currentVideoId, setVideoId); + showToast(fetchSucceededRemove); + if (openPlaylist) { + openQueue(currentVideoId, openVideo); + } + return; + } + showToast(fetchFailedRemove); + } else { // Add to queue. + if (StringUtils.isNotEmpty(fetchedSetVideoId)) { + lastVideoIds.putIfAbsent(currentVideoId, fetchedSetVideoId); + showToast(fetchSucceededAdd); + Logger.printDebug(() -> "Video successfully added, setVideoId: " + fetchedSetVideoId); + if (openPlaylist) { + openQueue(currentVideoId, openVideo); + } + return; + } + showToast(fetchFailedAdd); + } + } + }, 1000); + } + } + } catch (Exception ex) { + Logger.printException(() -> "fetchQueue failure", ex); + } + } + + private static void saveToPlaylist() { + String currentPlaylistId = playlistId; + if (currentPlaylistId.isEmpty()) { + handleCheckError(checkFailedQueue); + return; + } + try { + GetPlaylistsRequest.fetchRequestIfNeeded(currentPlaylistId, requestHeader); + runOnMainThreadDelayed(() -> { + GetPlaylistsRequest request = GetPlaylistsRequest.getRequestForPlaylistId(currentPlaylistId); + if (request != null) { + Pair[] playlists = request.getPlaylists(); + if (playlists != null) { + ScrollView mScrollView = new ScrollView(mContext); + LinearLayout mLinearLayout = new LinearLayout(mContext); + mLinearLayout.setOrientation(LinearLayout.VERTICAL); + mLinearLayout.setPadding(0, 0, 0, 0); + + Map actionsMap = new LinkedHashMap<>(playlists.length); + + int libraryIconId = QueueManager.SAVE_QUEUE.drawableId; + + for (Pair playlist : playlists) { + String playlistId = playlist.getFirst(); + String title = playlist.getSecond(); + Runnable action = () -> saveToPlaylist(playlistId, title); + LinearLayout itemLayout = ExtendedUtils.createItemLayout(mContext, title, libraryIconId); + actionsMap.putIfAbsent(itemLayout, action); + mLinearLayout.addView(itemLayout); + } + + mScrollView.addView(mLinearLayout); + + ExtendedUtils.showBottomSheetDialog(mContext, mScrollView, actionsMap); + GetPlaylistsRequest.clear(); + } + } + }, 1000); + } catch (Exception ex) { + Logger.printException(() -> "saveToPlaylist failure", ex); + } + } + + private static void saveToPlaylist(@Nullable String libraryId, @Nullable String libraryTitle) { + try { + if (StringUtils.isEmpty(libraryId)) { + handleCheckError(checkFailedPlaylistId); + return; + } + SavePlaylistRequest.fetchRequestIfNeeded(playlistId, libraryId, requestHeader); + + runOnMainThreadDelayed(() -> { + SavePlaylistRequest request = SavePlaylistRequest.getRequestForLibraryId(libraryId); + if (request != null) { + Boolean result = request.getResult(); + if (BooleanUtils.isTrue(result)) { + showToast(String.format(fetchSucceededSave, libraryTitle)); + SavePlaylistRequest.clear(); + return; + } + showToast(fetchFailedSave); + } + }, 1000); + } catch (Exception ex) { + Logger.printException(() -> "saveToPlaylist failure", ex); + } + } + + private static void removeQueue() { + String currentPlaylistId = playlistId; + if (currentPlaylistId.isEmpty()) { + handleCheckError(checkFailedQueue); + return; + } + try { + DeletePlaylistRequest.fetchRequestIfNeeded(currentPlaylistId, requestHeader); + runOnMainThreadDelayed(() -> { + DeletePlaylistRequest request = DeletePlaylistRequest.getRequestForPlaylistId(currentPlaylistId); + if (request != null) { + Boolean result = request.getResult(); + if (BooleanUtils.isTrue(result)) { + playlistId = ""; + synchronized (lastVideoIds) { + lastVideoIds.clear(); + } + CreatePlaylistRequest.clear(); + DeletePlaylistRequest.clear(); + EditPlaylistRequest.clear(); + GetPlaylistsRequest.clear(); + SavePlaylistRequest.clear(); + showToast(fetchSucceededDelete); + return; + } + } + showToast(fetchFailedDelete); + }, 1000); + } catch (Exception ex) { + Logger.printException(() -> "removeQueue failure", ex); + } + } + + private static void downloadVideo() { + String currentVideoId = videoId; + launchVideoExternalDownloader(currentVideoId); + } + + private static void openQueue() { + openQueue("", false); + } + + private static void openQueue(String currentVideoId, boolean openVideo) { + String currentPlaylistId = playlistId; + if (currentPlaylistId.isEmpty()) { + handleCheckError(checkFailedQueue); + return; + } + if (openVideo) { + if (StringUtils.isEmpty(currentVideoId)) { + handleCheckError(checkFailedVideoId); + return; + } + // Open a video from a playlist + openPlaylist(currentPlaylistId, currentVideoId); + } else { + // Open a playlist + openPlaylist(currentPlaylistId); + } + } + + private static void handleCheckError(String reason) { + showToast(String.format(checkFailedGeneric, reason)); + } + + private static void showToast(String reason) { + Utils.showToastShort(reason); + } + + private enum QueueManager { + ADD_TO_QUEUE( + "revanced_queue_manager_add_to_queue", + "yt_outline_list_add_black_24", + () -> fetchQueue(false, false, false) + ), + ADD_TO_QUEUE_AND_OPEN_QUEUE( + "revanced_queue_manager_add_to_queue_and_open_queue", + "yt_outline_list_add_black_24", + () -> fetchQueue(false, true, false) + ), + ADD_TO_QUEUE_AND_PLAY_VIDEO( + "revanced_queue_manager_add_to_queue_and_play_video", + "yt_outline_list_play_arrow_black_24", + () -> fetchQueue(false, true, true) + ), + REMOVE_FROM_QUEUE( + "revanced_queue_manager_remove_from_queue", + "yt_outline_trash_can_black_24", + () -> fetchQueue(true, false, false) + ), + REMOVE_FROM_QUEUE_AND_OPEN_QUEUE( + "revanced_queue_manager_remove_from_queue_and_open_queue", + "yt_outline_trash_can_black_24", + () -> fetchQueue(true, true, false) + ), + OPEN_QUEUE( + "revanced_queue_manager_open_queue", + "yt_outline_list_view_black_24", + PlaylistPatch::openQueue + ), + // For some reason, the 'playlist/delete' endpoint is unavailable. + REMOVE_QUEUE( + "revanced_queue_manager_remove_queue", + "yt_outline_slash_circle_left_black_24", + PlaylistPatch::removeQueue + ), + SAVE_QUEUE( + "revanced_queue_manager_save_queue", + "yt_outline_bookmark_black_24", + PlaylistPatch::saveToPlaylist + ), + EXTERNAL_DOWNLOADER( + "revanced_queue_manager_external_downloader", + "yt_outline_download_black_24", + PlaylistPatch::downloadVideo + ); + + public final int drawableId; + + @NonNull + public final String label; + + @NonNull + public final Runnable onClickAction; + + QueueManager(@NonNull String label, @NonNull String icon, @NonNull Runnable onClickAction) { + this.drawableId = ResourceUtils.getDrawableIdentifier(icon); + this.label = ResourceUtils.getString(label); + this.onClickAction = onClickAction; + } + + public static final QueueManager[] addToQueueEntries = { + ADD_TO_QUEUE, + ADD_TO_QUEUE_AND_OPEN_QUEUE, + ADD_TO_QUEUE_AND_PLAY_VIDEO, + OPEN_QUEUE, + //REMOVE_QUEUE, + EXTERNAL_DOWNLOADER, + SAVE_QUEUE, + }; + + public static final QueueManager[] removeFromQueueEntries = { + REMOVE_FROM_QUEUE, + REMOVE_FROM_QUEUE_AND_OPEN_QUEUE, + OPEN_QUEUE, + //REMOVE_QUEUE, + EXTERNAL_DOWNLOADER, + SAVE_QUEUE, + }; + + public static final QueueManager[] noVideoIdQueueEntries = { + OPEN_QUEUE, + //REMOVE_QUEUE, + SAVE_QUEUE, + }; + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt new file mode 100644 index 000000000..bf72d8966 --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt @@ -0,0 +1,275 @@ +package app.revanced.extension.youtube.patches.utils.requests + +import androidx.annotation.GuardedBy +import app.revanced.extension.shared.patches.client.YouTubeAppClient +import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.requests.Requester +import app.revanced.extension.shared.utils.Logger +import app.revanced.extension.shared.utils.Utils +import app.revanced.extension.youtube.patches.utils.requests.CreatePlaylistRequest.Companion.HTTP_TIMEOUT_MILLISECONDS +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException +import java.net.SocketTimeoutException +import java.util.Collections +import java.util.Objects +import java.util.concurrent.ExecutionException +import java.util.concurrent.Future +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +class CreatePlaylistRequest private constructor( + private val videoId: String, + private val playerHeaders: Map, +) { + private val future: Future> = Utils.submitOnBackgroundThread { + fetch(videoId, playerHeaders) + } + + val playlistId: Pair? + get() { + try { + return future[MAX_MILLISECONDS_TO_WAIT_FOR_FETCH.toLong(), TimeUnit.MILLISECONDS] + } catch (ex: TimeoutException) { + Logger.printInfo( + { "getPlaylistId timed out" }, + ex + ) + } catch (ex: InterruptedException) { + Logger.printException( + { "getPlaylistId interrupted" }, + ex + ) + Thread.currentThread().interrupt() // Restore interrupt status flag. + } catch (ex: ExecutionException) { + Logger.printException( + { "getPlaylistId failure" }, + ex + ) + } + + return null + } + + companion object { + /** + * TCP connection and HTTP read timeout. + */ + private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 + + /** + * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] + */ + private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 + + @GuardedBy("itself") + val cache: MutableMap = Collections.synchronizedMap( + object : LinkedHashMap(100) { + private val CACHE_LIMIT = 50 + + override fun removeEldestEntry(eldest: Map.Entry): Boolean { + return size > CACHE_LIMIT // Evict the oldest entry if over the cache limit. + } + }) + + @JvmStatic + fun clear() { + synchronized(cache) { + cache.clear() + } + } + + @JvmStatic + fun fetchRequestIfNeeded(videoId: String, playerHeaders: Map) { + Objects.requireNonNull(videoId) + synchronized(cache) { + if (!cache.containsKey(videoId)) { + cache[videoId] = CreatePlaylistRequest(videoId, playerHeaders) + } + } + } + + @JvmStatic + fun getRequestForVideoId(videoId: String): CreatePlaylistRequest? { + synchronized(cache) { + return cache[videoId] + } + } + + private fun handleConnectionError(toastMessage: String, ex: Exception?) { + Logger.printInfo({ toastMessage }, ex) + } + + private val REQUEST_HEADER_KEYS = arrayOf( + "Authorization", // Available only to logged-in users. + "X-GOOG-API-FORMAT-VERSION", + "X-Goog-Visitor-Id" + ) + + private fun sendCreatePlaylistRequest(videoId: String, playerHeaders: Map): JSONObject? { + Objects.requireNonNull(videoId) + + val startTime = System.currentTimeMillis() + // 'playlist/create' request does not require PoToken. + val clientType = YouTubeAppClient.ClientType.ANDROID + val clientTypeName = clientType.name + Logger.printDebug { "Fetching create playlist request for: $videoId, using client: $clientTypeName" } + + try { + val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( + PlayerRoutes.CREATE_PLAYLIST, + clientType + ) + connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS + connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS + + for (key in REQUEST_HEADER_KEYS) { + var value = playerHeaders[key] + if (value != null) { + connection.setRequestProperty(key, value) + } + } + + val requestBody = + PlayerRoutes.createPlaylistRequestBody( + videoId = videoId + ) + + connection.setFixedLengthStreamingMode(requestBody.size) + connection.outputStream.write(requestBody) + + val responseCode = connection.responseCode + if (responseCode == 200) return Requester.parseJSONObject(connection) + + handleConnectionError( + (clientTypeName + " not available with response code: " + + responseCode + " message: " + connection.responseMessage), + null + ) + } catch (ex: SocketTimeoutException) { + handleConnectionError("Connection timeout", ex) + } catch (ex: IOException) { + handleConnectionError("Network error", ex) + } catch (ex: Exception) { + Logger.printException({ "sendCreatePlaylistRequest failed" }, ex) + } finally { + Logger.printDebug { "video: " + videoId + " took: " + (System.currentTimeMillis() - startTime) + "ms" } + } + + return null + } + + private fun sendSetVideoIdRequest(videoId: String, playlistId: String, playerHeaders: Map): JSONObject? { + Objects.requireNonNull(playlistId) + + val startTime = System.currentTimeMillis() + // 'playlist/create' request does not require PoToken. + val clientType = YouTubeAppClient.ClientType.ANDROID + val clientTypeName = clientType.name + Logger.printDebug { "Fetching set video id request for: $playlistId, using client: $clientTypeName" } + + try { + val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( + PlayerRoutes.GET_SET_VIDEO_ID, + clientType + ) + connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS + connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS + + for (key in REQUEST_HEADER_KEYS) { + var value = playerHeaders[key] + if (value != null) { + connection.setRequestProperty(key, value) + } + } + + val requestBody = + PlayerRoutes.createApplicationRequestBody( + clientType = clientType, + videoId = videoId, + playlistId = playlistId + ) + + connection.setFixedLengthStreamingMode(requestBody.size) + connection.outputStream.write(requestBody) + + val responseCode = connection.responseCode + if (responseCode == 200) return Requester.parseJSONObject(connection) + + handleConnectionError( + (clientTypeName + " not available with response code: " + + responseCode + " message: " + connection.responseMessage), + null + ) + } catch (ex: SocketTimeoutException) { + handleConnectionError("Connection timeout", ex) + } catch (ex: IOException) { + handleConnectionError("Network error", ex) + } catch (ex: Exception) { + Logger.printException({ "sendSetVideoIdRequest failed" }, ex) + } finally { + Logger.printDebug { "playlist: " + playlistId + " took: " + (System.currentTimeMillis() - startTime) + "ms" } + } + + return null + } + + private fun parseCreatePlaylistResponse(json: JSONObject): String? { + try { + return json.getString("playlistId") + } catch (e: JSONException) { + val jsonForMessage = json.toString() + Logger.printException( + { "Fetch failed while processing response data for response: $jsonForMessage" }, + e + ) + } + + return null + } + + private fun parseSetVideoIdResponse(json: JSONObject): String? { + try { + val secondaryContentsJsonObject = + json.getJSONObject("contents") + .getJSONObject("singleColumnWatchNextResults") + .getJSONObject("playlist") + .getJSONObject("playlist") + .getJSONArray("contents") + .get(0) + + if (secondaryContentsJsonObject is JSONObject) { + return secondaryContentsJsonObject + .getJSONObject("playlistPanelVideoRenderer") + .getString("playlistSetVideoId") + } + } catch (e: JSONException) { + val jsonForMessage = json.toString() + Logger.printException( + { "Fetch failed while processing response data for response: $jsonForMessage" }, + e + ) + } + + return null + } + + private fun fetch(videoId: String, playerHeaders: Map): Pair? { + val createPlaylistJson = sendCreatePlaylistRequest(videoId, playerHeaders) + if (createPlaylistJson != null) { + val playlistId = parseCreatePlaylistResponse(createPlaylistJson) + if (playlistId != null) { + val setVideoIdJson = sendSetVideoIdRequest(videoId, playlistId, playerHeaders) + if (setVideoIdJson != null) { + val setVideoId = parseSetVideoIdResponse(setVideoIdJson) + if (setVideoId != null) { + return Pair(playlistId, setVideoId) + } + } + } + } + + return null + } + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt new file mode 100644 index 000000000..7a0c8fc95 --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt @@ -0,0 +1,197 @@ +package app.revanced.extension.youtube.patches.utils.requests + +import androidx.annotation.GuardedBy +import app.revanced.extension.shared.patches.client.YouTubeAppClient +import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.requests.Requester +import app.revanced.extension.shared.utils.Logger +import app.revanced.extension.shared.utils.Utils +import app.revanced.extension.youtube.patches.utils.requests.DeletePlaylistRequest.Companion.HTTP_TIMEOUT_MILLISECONDS +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException +import java.net.SocketTimeoutException +import java.util.Collections +import java.util.Objects +import java.util.concurrent.ExecutionException +import java.util.concurrent.Future +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +class DeletePlaylistRequest private constructor( + private val playlistId: String, + private val playerHeaders: Map, +) { + private val future: Future = Utils.submitOnBackgroundThread { + fetch( + playlistId, + playerHeaders, + ) + } + + val result: Boolean? + get() { + try { + return future[MAX_MILLISECONDS_TO_WAIT_FOR_FETCH.toLong(), TimeUnit.MILLISECONDS] + } catch (ex: TimeoutException) { + Logger.printInfo( + { "getResult timed out" }, + ex + ) + } catch (ex: InterruptedException) { + Logger.printException( + { "getResult interrupted" }, + ex + ) + Thread.currentThread().interrupt() // Restore interrupt status flag. + } catch (ex: ExecutionException) { + Logger.printException( + { "getResult failure" }, + ex + ) + } + + return null + } + + companion object { + /** + * TCP connection and HTTP read timeout. + */ + private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 + + /** + * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] + */ + private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 + + @GuardedBy("itself") + val cache: MutableMap = Collections.synchronizedMap( + object : LinkedHashMap(100) { + private val CACHE_LIMIT = 50 + + override fun removeEldestEntry(eldest: Map.Entry): Boolean { + return size > CACHE_LIMIT // Evict the oldest entry if over the cache limit. + } + }) + + @JvmStatic + fun clear() { + synchronized(cache) { + cache.clear() + } + } + + @JvmStatic + fun fetchRequestIfNeeded( + playlistId: String, + playerHeaders: Map + ) { + Objects.requireNonNull(playlistId) + synchronized(cache) { + if (!cache.containsKey(playlistId)) { + cache[playlistId] = DeletePlaylistRequest( + playlistId, + playerHeaders + ) + } + } + } + + @JvmStatic + fun getRequestForPlaylistId(playlistId: String): DeletePlaylistRequest? { + synchronized(cache) { + return cache[playlistId] + } + } + + private fun handleConnectionError(toastMessage: String, ex: Exception?) { + Logger.printInfo({ toastMessage }, ex) + } + + private val REQUEST_HEADER_KEYS = arrayOf( + "Authorization", // Available only to logged-in users. + "X-GOOG-API-FORMAT-VERSION", + "X-Goog-Visitor-Id" + ) + + private fun sendRequest( + playlistId: String, + playerHeaders: Map + ): JSONObject? { + Objects.requireNonNull(playlistId) + + val startTime = System.currentTimeMillis() + // 'playlist/delete' request does not require PoToken. + val clientType = YouTubeAppClient.ClientType.ANDROID + val clientTypeName = clientType.name + Logger.printDebug { "Fetching delete playlist request, playlistId: $playlistId, using client: $clientTypeName" } + + try { + val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( + PlayerRoutes.DELETE_PLAYLIST, + clientType, + ) + connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS + connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS + + for (key in REQUEST_HEADER_KEYS) { + var value = playerHeaders[key] + if (value != null) { + connection.setRequestProperty(key, value) + } + } + + val requestBody = PlayerRoutes.deletePlaylistRequestBody(playlistId) + + connection.setFixedLengthStreamingMode(requestBody.size) + connection.outputStream.write(requestBody) + + val responseCode = connection.responseCode + if (responseCode == 200) return Requester.parseJSONObject(connection) + + handleConnectionError( + (clientTypeName + " not available with response code: " + + responseCode + " message: " + connection.responseMessage), + null + ) + } catch (ex: SocketTimeoutException) { + handleConnectionError("Connection timeout", ex) + } catch (ex: IOException) { + handleConnectionError("Network error", ex) + } catch (ex: Exception) { + Logger.printException({ "sendRequest failed" }, ex) + } finally { + Logger.printDebug { "playlist: " + playlistId + " took: " + (System.currentTimeMillis() - startTime) + "ms" } + } + + return null + } + + private fun parseResponse(json: JSONObject): Boolean? { + try { + return json.has("command") + } catch (e: JSONException) { + val jsonForMessage = json.toString() + Logger.printException( + { "Fetch failed while processing response data for response: $jsonForMessage" }, + e + ) + } + + return null + } + + private fun fetch( + playlistId: String, + playerHeaders: Map + ): Boolean? { + val json = sendRequest(playlistId, playerHeaders) + if (json != null) { + return parseResponse(json) + } + + return null + } + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt new file mode 100644 index 000000000..7372cb89a --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt @@ -0,0 +1,233 @@ +package app.revanced.extension.youtube.patches.utils.requests + +import androidx.annotation.GuardedBy +import app.revanced.extension.shared.patches.client.YouTubeAppClient +import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.requests.Requester +import app.revanced.extension.shared.utils.Logger +import app.revanced.extension.shared.utils.Utils +import app.revanced.extension.youtube.patches.utils.requests.EditPlaylistRequest.Companion.HTTP_TIMEOUT_MILLISECONDS +import org.apache.commons.lang3.StringUtils +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException +import java.net.SocketTimeoutException +import java.util.Collections +import java.util.Objects +import java.util.concurrent.ExecutionException +import java.util.concurrent.Future +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +class EditPlaylistRequest private constructor( + private val videoId: String, + private val playlistId: String, + private val setVideoId: String?, + private val playerHeaders: Map, +) { + private val future: Future = Utils.submitOnBackgroundThread { + fetch( + videoId, + playlistId, + setVideoId, + playerHeaders, + ) + } + + val result: String? + get() { + try { + return future[MAX_MILLISECONDS_TO_WAIT_FOR_FETCH.toLong(), TimeUnit.MILLISECONDS] + } catch (ex: TimeoutException) { + Logger.printInfo( + { "getResult timed out" }, + ex + ) + } catch (ex: InterruptedException) { + Logger.printException( + { "getResult interrupted" }, + ex + ) + Thread.currentThread().interrupt() // Restore interrupt status flag. + } catch (ex: ExecutionException) { + Logger.printException( + { "getResult failure" }, + ex + ) + } + + return null + } + + companion object { + /** + * TCP connection and HTTP read timeout. + */ + private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 + + /** + * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] + */ + private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 + + @GuardedBy("itself") + val cache: MutableMap = Collections.synchronizedMap( + object : LinkedHashMap(100) { + private val CACHE_LIMIT = 50 + + override fun removeEldestEntry(eldest: Map.Entry): Boolean { + return size > CACHE_LIMIT // Evict the oldest entry if over the cache limit. + } + }) + + @JvmStatic + fun clear() { + synchronized(cache) { + cache.clear() + } + } + + @JvmStatic + fun clearVideoId(videoId: String) { + synchronized(cache) { + cache.remove(videoId) + } + } + + @JvmStatic + fun fetchRequestIfNeeded( + videoId: String, + playlistId: String, + setVideoId: String?, + playerHeaders: Map + ) { + Objects.requireNonNull(videoId) + synchronized(cache) { + if (!cache.containsKey(videoId)) { + cache[videoId] = EditPlaylistRequest( + videoId, + playlistId, + setVideoId, + playerHeaders + ) + } + } + } + + @JvmStatic + fun getRequestForVideoId(videoId: String): EditPlaylistRequest? { + synchronized(cache) { + return cache[videoId] + } + } + + private fun handleConnectionError(toastMessage: String, ex: Exception?) { + Logger.printInfo({ toastMessage }, ex) + } + + private val REQUEST_HEADER_KEYS = arrayOf( + "Authorization", // Available only to logged-in users. + "X-GOOG-API-FORMAT-VERSION", + "X-Goog-Visitor-Id" + ) + + private fun sendRequest( + videoId: String, + playlistId: String, + setVideoId: String?, + playerHeaders: Map + ): JSONObject? { + Objects.requireNonNull(videoId) + + val startTime = System.currentTimeMillis() + // 'browse/edit_playlist' request does not require PoToken. + val clientType = YouTubeAppClient.ClientType.ANDROID + val clientTypeName = clientType.name + Logger.printDebug { "Fetching edit playlist request, videoId: $videoId, playlistId: $playlistId, setVideoId: $setVideoId, using client: $clientTypeName" } + + try { + val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( + PlayerRoutes.EDIT_PLAYLIST, + clientType + ) + connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS + connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS + + for (key in REQUEST_HEADER_KEYS) { + var value = playerHeaders[key] + if (value != null) { + connection.setRequestProperty(key, value) + } + } + + val requestBody = + PlayerRoutes.editPlaylistRequestBody( + videoId = videoId, + playlistId = playlistId, + setVideoId = setVideoId, + ) + + connection.setFixedLengthStreamingMode(requestBody.size) + connection.outputStream.write(requestBody) + + val responseCode = connection.responseCode + if (responseCode == 200) return Requester.parseJSONObject(connection) + + handleConnectionError( + (clientTypeName + " not available with response code: " + + responseCode + " message: " + connection.responseMessage), + null + ) + } catch (ex: SocketTimeoutException) { + handleConnectionError("Connection timeout", ex) + } catch (ex: IOException) { + handleConnectionError("Network error", ex) + } catch (ex: Exception) { + Logger.printException({ "sendRequest failed" }, ex) + } finally { + Logger.printDebug { "video: " + videoId + " took: " + (System.currentTimeMillis() - startTime) + "ms" } + } + + return null + } + + private fun parseResponse(json: JSONObject, remove: Boolean): String? { + try { + if (json.getString("status") == "STATUS_SUCCEEDED") { + if (remove) { + return "" + } + val playlistEditResultsJSONObject = json.getJSONArray("playlistEditResults").get(0) + + if (playlistEditResultsJSONObject is JSONObject) { + return playlistEditResultsJSONObject + .getJSONObject("playlistEditVideoAddedResultData") + .getString("setVideoId") + } + } + } catch (e: JSONException) { + val jsonForMessage = json.toString() + Logger.printException( + { "Fetch failed while processing response data for response: $jsonForMessage" }, + e + ) + } + + return null + } + + private fun fetch( + videoId: String, + playlistId: String, + setVideoId: String?, + playerHeaders: Map + ): String? { + val json = sendRequest(videoId, playlistId, setVideoId, playerHeaders) + if (json != null) { + return parseResponse(json, StringUtils.isNotEmpty(setVideoId)) + } + + return null + } + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt new file mode 100644 index 000000000..54f54f33c --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt @@ -0,0 +1,236 @@ +package app.revanced.extension.youtube.patches.utils.requests + +import androidx.annotation.GuardedBy +import app.revanced.extension.shared.patches.client.YouTubeAppClient +import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.requests.Requester +import app.revanced.extension.shared.utils.Logger +import app.revanced.extension.shared.utils.Utils +import app.revanced.extension.youtube.patches.utils.requests.GetPlaylistsRequest.Companion.HTTP_TIMEOUT_MILLISECONDS +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException +import java.net.SocketTimeoutException +import java.util.Collections +import java.util.Objects +import java.util.concurrent.ExecutionException +import java.util.concurrent.Future +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +class GetPlaylistsRequest private constructor( + private val playlistId: String, + private val playerHeaders: Map, +) { + private val future: Future>> = Utils.submitOnBackgroundThread { + fetch( + playlistId, + playerHeaders, + ) + } + + val playlists: Array>? + get() { + try { + return future[MAX_MILLISECONDS_TO_WAIT_FOR_FETCH.toLong(), TimeUnit.MILLISECONDS] + } catch (ex: TimeoutException) { + Logger.printInfo( + { "getPlaylists timed out" }, + ex + ) + } catch (ex: InterruptedException) { + Logger.printException( + { "getPlaylists interrupted" }, + ex + ) + Thread.currentThread().interrupt() // Restore interrupt status flag. + } catch (ex: ExecutionException) { + Logger.printException( + { "getPlaylists failure" }, + ex + ) + } + + return null + } + + companion object { + /** + * TCP connection and HTTP read timeout. + */ + private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 + + /** + * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] + */ + private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 + + @GuardedBy("itself") + val cache: MutableMap = Collections.synchronizedMap( + object : LinkedHashMap(100) { + private val CACHE_LIMIT = 50 + + override fun removeEldestEntry(eldest: Map.Entry): Boolean { + return size > CACHE_LIMIT // Evict the oldest entry if over the cache limit. + } + }) + + @JvmStatic + fun clear() { + synchronized(cache) { + cache.clear() + } + } + + @JvmStatic + fun fetchRequestIfNeeded( + playlistId: String, + playerHeaders: Map + ) { + Objects.requireNonNull(playlistId) + synchronized(cache) { + if (!cache.containsKey(playlistId)) { + cache[playlistId] = GetPlaylistsRequest( + playlistId, + playerHeaders + ) + } + } + } + + @JvmStatic + fun getRequestForPlaylistId(playlistId: String): GetPlaylistsRequest? { + synchronized(cache) { + return cache[playlistId] + } + } + + private fun handleConnectionError(toastMessage: String, ex: Exception?) { + Logger.printInfo({ toastMessage }, ex) + } + + private val REQUEST_HEADER_KEYS = arrayOf( + "Authorization", // Available only to logged-in users. + "X-GOOG-API-FORMAT-VERSION", + "X-Goog-Visitor-Id" + ) + + private fun sendRequest( + playlistId: String, + playerHeaders: Map + ): JSONObject? { + Objects.requireNonNull(playlistId) + + val startTime = System.currentTimeMillis() + // 'playlist/get_add_to_playlist' request does not require PoToken. + val clientType = YouTubeAppClient.ClientType.ANDROID + val clientTypeName = clientType.name + Logger.printDebug { "Fetching get playlists request, playlistId: $playlistId, using client: $clientTypeName" } + + try { + val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( + PlayerRoutes.GET_PLAYLISTS, + clientType + ) + connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS + connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS + + for (key in REQUEST_HEADER_KEYS) { + var value = playerHeaders[key] + if (value != null) { + connection.setRequestProperty(key, value) + } + } + + val requestBody = PlayerRoutes.getPlaylistsRequestBody(playlistId) + + connection.setFixedLengthStreamingMode(requestBody.size) + connection.outputStream.write(requestBody) + + val responseCode = connection.responseCode + if (responseCode == 200) return Requester.parseJSONObject(connection) + + handleConnectionError( + (clientTypeName + " not available with response code: " + + responseCode + " message: " + connection.responseMessage), + null + ) + } catch (ex: SocketTimeoutException) { + handleConnectionError("Connection timeout", ex) + } catch (ex: IOException) { + handleConnectionError("Network error", ex) + } catch (ex: Exception) { + Logger.printException({ "sendRequest failed" }, ex) + } finally { + Logger.printDebug { "playlist: " + playlistId + " took: " + (System.currentTimeMillis() - startTime) + "ms" } + } + + return null + } + + private fun parseResponse(json: JSONObject): Array>? { + try { + val addToPlaylistRendererJsonObject = + json.getJSONArray("contents").get(0) + + if (addToPlaylistRendererJsonObject is JSONObject) { + val playlistsJsonArray = + addToPlaylistRendererJsonObject + .getJSONObject("addToPlaylistRenderer") + .getJSONArray("playlists") + + val playlistsLength = playlistsJsonArray.length() + val playlists: Array?> = + arrayOfNulls(playlistsLength) + + for (i in 0..playlistsLength - 1) { + val elementsJsonObject = + playlistsJsonArray.get(i) + + if (elementsJsonObject is JSONObject) { + val playlistAddToOptionRendererJSONObject = + elementsJsonObject + .getJSONObject("playlistAddToOptionRenderer") + + val playlistId = playlistAddToOptionRendererJSONObject + .getString("playlistId") + val playlistTitle = + (playlistAddToOptionRendererJSONObject + .getJSONObject("title") + .getJSONArray("runs") + .get(0) as JSONObject) + .getString("text") + + playlists[i] = Pair(playlistId, playlistTitle) + } + } + + val finalPlaylists = playlists.filterNotNull().toTypedArray() + if (finalPlaylists.isNotEmpty()) { + return finalPlaylists + } + } + } catch (e: JSONException) { + val jsonForMessage = json.toString() + Logger.printException( + { "Fetch failed while processing response data for response: $jsonForMessage" }, + e + ) + } + + return null + } + + private fun fetch( + playlistId: String, + playerHeaders: Map + ): Array>? { + val json = sendRequest(playlistId, playerHeaders) + if (json != null) { + return parseResponse(json) + } + + return null + } + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt new file mode 100644 index 000000000..c5d3a611a --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt @@ -0,0 +1,203 @@ +package app.revanced.extension.youtube.patches.utils.requests + +import androidx.annotation.GuardedBy +import app.revanced.extension.shared.patches.client.YouTubeAppClient +import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.requests.Requester +import app.revanced.extension.shared.utils.Logger +import app.revanced.extension.shared.utils.Utils +import app.revanced.extension.youtube.patches.utils.requests.SavePlaylistRequest.Companion.HTTP_TIMEOUT_MILLISECONDS +import org.json.JSONException +import org.json.JSONObject +import java.io.IOException +import java.net.SocketTimeoutException +import java.util.Collections +import java.util.Objects +import java.util.concurrent.ExecutionException +import java.util.concurrent.Future +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeoutException + +class SavePlaylistRequest private constructor( + private val playlistId: String, + private val libraryId: String, + private val playerHeaders: Map, +) { + private val future: Future = Utils.submitOnBackgroundThread { + fetch( + playlistId, + libraryId, + playerHeaders, + ) + } + + val result: Boolean? + get() { + try { + return future[MAX_MILLISECONDS_TO_WAIT_FOR_FETCH.toLong(), TimeUnit.MILLISECONDS] + } catch (ex: TimeoutException) { + Logger.printInfo( + { "getResult timed out" }, + ex + ) + } catch (ex: InterruptedException) { + Logger.printException( + { "getResult interrupted" }, + ex + ) + Thread.currentThread().interrupt() // Restore interrupt status flag. + } catch (ex: ExecutionException) { + Logger.printException( + { "getResult failure" }, + ex + ) + } + + return null + } + + companion object { + /** + * TCP connection and HTTP read timeout. + */ + private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 + + /** + * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] + */ + private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 + + @GuardedBy("itself") + val cache: MutableMap = Collections.synchronizedMap( + object : LinkedHashMap(100) { + private val CACHE_LIMIT = 50 + + override fun removeEldestEntry(eldest: Map.Entry): Boolean { + return size > CACHE_LIMIT // Evict the oldest entry if over the cache limit. + } + }) + + @JvmStatic + fun clear() { + synchronized(cache) { + cache.clear() + } + } + + @JvmStatic + fun fetchRequestIfNeeded( + playlistId: String, + libraryId: String, + playerHeaders: Map + ) { + Objects.requireNonNull(playlistId) + synchronized(cache) { + cache[libraryId] = SavePlaylistRequest( + playlistId, + libraryId, + playerHeaders + ) + } + } + + @JvmStatic + fun getRequestForLibraryId(libraryId: String): SavePlaylistRequest? { + synchronized(cache) { + return cache[libraryId] + } + } + + private fun handleConnectionError(toastMessage: String, ex: Exception?) { + Logger.printInfo({ toastMessage }, ex) + } + + private val REQUEST_HEADER_KEYS = arrayOf( + "Authorization", // Available only to logged-in users. + "X-GOOG-API-FORMAT-VERSION", + "X-Goog-Visitor-Id" + ) + + private fun sendRequest( + playlistId: String, + libraryId: String, + playerHeaders: Map + ): JSONObject? { + Objects.requireNonNull(playlistId) + Objects.requireNonNull(libraryId) + + val startTime = System.currentTimeMillis() + // 'browse/edit_playlist' request does not require PoToken. + val clientType = YouTubeAppClient.ClientType.ANDROID + val clientTypeName = clientType.name + Logger.printDebug { "Fetching edit playlist request, playlistId: $playlistId, libraryId: $libraryId, using client: $clientTypeName" } + + try { + val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( + PlayerRoutes.EDIT_PLAYLIST, + clientType + ) + connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS + connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS + + for (key in REQUEST_HEADER_KEYS) { + var value = playerHeaders[key] + if (value != null) { + connection.setRequestProperty(key, value) + } + } + + val requestBody = + PlayerRoutes.savePlaylistRequestBody(libraryId, playlistId) + + connection.setFixedLengthStreamingMode(requestBody.size) + connection.outputStream.write(requestBody) + + val responseCode = connection.responseCode + if (responseCode == 200) return Requester.parseJSONObject(connection) + + handleConnectionError( + (clientTypeName + " not available with response code: " + + responseCode + " message: " + connection.responseMessage), + null + ) + } catch (ex: SocketTimeoutException) { + handleConnectionError("Connection timeout", ex) + } catch (ex: IOException) { + handleConnectionError("Network error", ex) + } catch (ex: Exception) { + Logger.printException({ "sendRequest failed" }, ex) + } finally { + Logger.printDebug { "playlistId: $playlistId libraryId: $libraryId took: ${(System.currentTimeMillis() - startTime)}ms" } + } + + return null + } + + private fun parseResponse(json: JSONObject): Boolean? { + try { + return json.getString("status") == "STATUS_SUCCEEDED" + } catch (e: JSONException) { + val jsonForMessage = json.toString() + Logger.printException( + { "Fetch failed while processing response data for response: $jsonForMessage" }, + e + ) + } + + return null + } + + private fun fetch( + playlistId: String, + libraryId: String, + playerHeaders: Map + ): Boolean? { + val json = sendRequest(playlistId, libraryId,playerHeaders) + if (json != null) { + return parseResponse(json) + } + + return null + } + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index b9eda5de2..f450f1974 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -182,12 +182,14 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_NAVIGATION_SUBSCRIPTIONS_BUTTON = new BooleanSetting("revanced_hide_navigation_subscriptions_button", FALSE, true); public static final BooleanSetting HIDE_NAVIGATION_LABEL = new BooleanSetting("revanced_hide_navigation_label", FALSE, true); public static final BooleanSetting SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON = new BooleanSetting("revanced_switch_create_with_notifications_button", TRUE, true, "revanced_switch_create_with_notifications_button_user_dialog_message"); - public static final BooleanSetting ENABLE_TRANSLUCENT_NAVIGATION_BAR = new BooleanSetting("revanced_enable_translucent_navigation_bar", FALSE, true, "revanced_enable_translucent_navigation_bar_user_dialog_message"); + public static final BooleanSetting ENABLE_TRANSLUCENT_NAVIGATION_BAR = new BooleanSetting("revanced_enable_translucent_navigation_bar", FALSE, true); public static final BooleanSetting HIDE_NAVIGATION_BAR = new BooleanSetting("revanced_hide_navigation_bar", FALSE, true); // PreferenceScreen: General - Override buttons - public static final BooleanSetting OVERRIDE_PLAYLIST_DOWNLOAD_BUTTON = new BooleanSetting("revanced_override_playlist_download_button", FALSE); - public static final BooleanSetting OVERRIDE_VIDEO_DOWNLOAD_BUTTON = new BooleanSetting("revanced_override_video_download_button", FALSE); + public static final BooleanSetting OVERRIDE_PLAYLIST_DOWNLOAD_BUTTON = new BooleanSetting("revanced_override_playlist_download_button", FALSE, true); + public static final BooleanSetting OVERRIDE_VIDEO_DOWNLOAD_BUTTON = new BooleanSetting("revanced_override_video_download_button", FALSE, true); + public static final BooleanSetting OVERRIDE_VIDEO_DOWNLOAD_BUTTON_QUEUE_MANAGER = new BooleanSetting("revanced_override_video_download_button_queue_manager", FALSE, true, + "revanced_queue_manager_user_dialog_message", parent(OVERRIDE_VIDEO_DOWNLOAD_BUTTON)); public static final StringSetting EXTERNAL_DOWNLOADER_PACKAGE_NAME_PLAYLIST = new StringSetting("revanced_external_downloader_package_name_playlist", "com.deniscerri.ytdl"); public static final StringSetting EXTERNAL_DOWNLOADER_PACKAGE_NAME_VIDEO = new StringSetting("revanced_external_downloader_package_name_video", "com.deniscerri.ytdl"); public static final BooleanSetting OVERRIDE_YOUTUBE_MUSIC_BUTTON = new BooleanSetting("revanced_override_youtube_music_button", FALSE, true @@ -335,7 +337,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_PLAYER_FLYOUT_MENU_YT_MUSIC = new BooleanSetting("revanced_hide_player_flyout_menu_listen_with_youtube_music", TRUE); // PreferenceScreen: Player - Fullscreen - public static final BooleanSetting DISABLE_ENGAGEMENT_PANEL = new BooleanSetting("revanced_disable_engagement_panel", FALSE); + public static final BooleanSetting DISABLE_ENGAGEMENT_PANEL = new BooleanSetting("revanced_disable_engagement_panel", FALSE, true); public static final BooleanSetting ENTER_FULLSCREEN = new BooleanSetting("revanced_enter_fullscreen", FALSE); public static final EnumSetting EXIT_FULLSCREEN = new EnumSetting<>("revanced_exit_fullscreen", FullscreenMode.DISABLED); public static final BooleanSetting SHOW_VIDEO_TITLE_SECTION = new BooleanSetting("revanced_show_video_title_section", TRUE, true, parent(DISABLE_ENGAGEMENT_PANEL)); @@ -397,6 +399,8 @@ public class Settings extends BaseSettings { public static final BooleanSetting OVERLAY_BUTTON_COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_overlay_button_copy_video_url_timestamp", FALSE); public static final BooleanSetting OVERLAY_BUTTON_MUTE_VOLUME = new BooleanSetting("revanced_overlay_button_mute_volume", FALSE); public static final BooleanSetting OVERLAY_BUTTON_EXTERNAL_DOWNLOADER = new BooleanSetting("revanced_overlay_button_external_downloader", FALSE); + public static final BooleanSetting OVERLAY_BUTTON_EXTERNAL_DOWNLOADER_QUEUE_MANAGER = new BooleanSetting("revanced_overlay_button_external_downloader_queue_manager", FALSE, true, + "revanced_queue_manager_user_dialog_message", parent(OVERLAY_BUTTON_EXTERNAL_DOWNLOADER)); public static final BooleanSetting OVERLAY_BUTTON_SPEED_DIALOG = new BooleanSetting("revanced_overlay_button_speed_dialog", FALSE); public static final BooleanSetting OVERLAY_BUTTON_PLAY_ALL = new BooleanSetting("revanced_overlay_button_play_all", FALSE); public static final EnumSetting OVERLAY_BUTTON_PLAY_ALL_TYPE = new EnumSetting<>("revanced_overlay_button_play_all_type", PlaylistIdPrefix.ALL_CONTENTS_WITH_TIME_DESCENDING); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java index c3c22520b..dfd02e7a7 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java @@ -2,7 +2,6 @@ package app.revanced.extension.youtube.settings.preference; import static app.revanced.extension.shared.utils.StringRef.str; import static app.revanced.extension.shared.utils.Utils.isSDKAbove; -import static app.revanced.extension.youtube.utils.ExtendedUtils.isSpoofingToLessThan; import android.preference.Preference; import android.preference.SwitchPreference; @@ -43,7 +42,6 @@ public class ReVancedSettingsPreference extends ReVancedPreferenceFragment { enableDisablePreferences(); AmbientModePreferenceLinks(); - ExternalDownloaderPreferenceLinks(); FullScreenPanelPreferenceLinks(); NavigationPreferenceLinks(); RYDPreferenceLinks(); @@ -65,18 +63,6 @@ public class ReVancedSettingsPreference extends ReVancedPreferenceFragment { ); } - /** - * Enable/Disable Preference for External downloader settings - */ - private static void ExternalDownloaderPreferenceLinks() { - // Override download button will not work if spoofed with YouTube 18.24.xx or earlier. - enableDisablePreferences( - isSpoofingToLessThan("18.24.00"), - Settings.OVERRIDE_VIDEO_DOWNLOAD_BUTTON, - Settings.OVERRIDE_PLAYLIST_DOWNLOAD_BUTTON - ); - } - /** * Enable/Disable Preferences not working in tablet layout */ diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/ExtendedUtils.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/ExtendedUtils.java index fae38500b..7713f1084 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/ExtendedUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/ExtendedUtils.java @@ -2,8 +2,27 @@ package app.revanced.extension.youtube.utils; import static app.revanced.extension.shared.utils.StringRef.str; +import android.app.AlertDialog; +import android.content.Context; +import android.graphics.ColorFilter; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.StateListDrawable; +import android.view.Gravity; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ScrollView; +import android.widget.TextView; + import androidx.annotation.NonNull; +import java.util.Map; + import app.revanced.extension.shared.settings.BooleanSetting; import app.revanced.extension.shared.settings.FloatSetting; import app.revanced.extension.shared.settings.IntegerSetting; @@ -114,4 +133,88 @@ public class ExtendedUtils extends PackageUtils { } return additionalSettingsEnabled; } + + public static void showBottomSheetDialog(Context mContext, ScrollView mScrollView, + Map actionsMap) { + runOnMainThreadDelayed(() -> { + AlertDialog.Builder builder = new AlertDialog.Builder(mContext); + builder.setView(mScrollView); + + AlertDialog dialog = builder.create(); + dialog.show(); + + actionsMap.forEach((view, action) -> + view.setOnClickListener(v -> { + action.run(); + dialog.dismiss(); + }) + ); + actionsMap.clear(); + + Window window = dialog.getWindow(); + if (window == null) { + return; + } + + // round corners + GradientDrawable dialogBackground = new GradientDrawable(); + dialogBackground.setCornerRadius(32); + window.setBackgroundDrawable(dialogBackground); + + // fit screen width + int dialogWidth = (int) (mContext.getResources().getDisplayMetrics().widthPixels * 0.95); + window.setLayout(dialogWidth, ViewGroup.LayoutParams.WRAP_CONTENT); + + // move dialog to bottom + WindowManager.LayoutParams layoutParams = window.getAttributes(); + layoutParams.gravity = Gravity.BOTTOM; + + // adjust the vertical offset + layoutParams.y = dpToPx(5); + + window.setAttributes(layoutParams); + }, 250); + } + + public static LinearLayout createItemLayout(Context mContext, String title, int iconId) { + // Item Layout + LinearLayout itemLayout = new LinearLayout(mContext); + itemLayout.setOrientation(LinearLayout.HORIZONTAL); + itemLayout.setPadding(dpToPx(16), dpToPx(12), dpToPx(16), dpToPx(12)); + itemLayout.setGravity(Gravity.CENTER_VERTICAL); + itemLayout.setClickable(true); + itemLayout.setFocusable(true); + + // Create a StateListDrawable for the background + StateListDrawable background = new StateListDrawable(); + ColorDrawable pressedDrawable = new ColorDrawable(ThemeUtils.getPressedElementColor()); + ColorDrawable defaultDrawable = new ColorDrawable(ThemeUtils.getBackgroundColor()); + background.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable); + background.addState(new int[]{}, defaultDrawable); + itemLayout.setBackground(background); + + // Icon + ColorFilter cf = new PorterDuffColorFilter(ThemeUtils.getForegroundColor(), PorterDuff.Mode.SRC_ATOP); + ImageView iconView = new ImageView(mContext); + iconView.setImageResource(iconId); + iconView.setColorFilter(cf); + LinearLayout.LayoutParams iconParams = new LinearLayout.LayoutParams(dpToPx(24), dpToPx(24)); + iconParams.setMarginEnd(dpToPx(16)); + iconView.setLayoutParams(iconParams); + itemLayout.addView(iconView); + + // Text container + LinearLayout textContainer = new LinearLayout(mContext); + textContainer.setOrientation(LinearLayout.VERTICAL); + TextView titleView = new TextView(mContext); + titleView.setText(title); + titleView.setTextSize(16); + titleView.setTextColor(ThemeUtils.getForegroundColor()); + textContainer.addView(titleView); + + itemLayout.addView(textContainer); + + return itemLayout; + } + } \ No newline at end of file diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java index 68f364829..5f614c62b 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java @@ -63,7 +63,7 @@ public class VideoUtils extends IntentUtils { return builder.toString(); } - private static String getVideoScheme(String videoId, boolean isShorts) { + public static String getVideoScheme(String videoId, boolean isShorts) { return String.format( Locale.ENGLISH, isShorts ? VIDEO_SCHEME_INTENT_FORMAT : VIDEO_SCHEME_LINK_FORMAT, @@ -128,6 +128,22 @@ public class VideoUtils extends IntentUtils { launchView(getChannelUrl(channelId), getContext().getPackageName()); } + public static void openPlaylist(@NonNull String playlistId) { + openPlaylist(playlistId, ""); + } + + public static void openPlaylist(@NonNull String playlistId, @NonNull String videoId) { + final StringBuilder sb = new StringBuilder(); + if (videoId.isEmpty()) { + sb.append(getPlaylistUrl(playlistId)); + } else { + sb.append(getVideoScheme(videoId, false)); + sb.append("&list="); + sb.append(playlistId); + } + launchView(sb.toString(), getContext().getPackageName()); + } + public static void openVideo() { openVideo(VideoInformation.getVideoId()); } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4376956d5..616c34f24 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,12 +6,14 @@ smali = "3.0.5" gson = "2.12.1" agp = "8.2.2" annotation = "1.9.1" +collections4 = "4.5.0-M3" lang3 = "3.17.0" preference = "1.2.1" [libraries] gson = { module = "com.google.code.gson:gson", version.ref = "gson" } annotation = { module = "androidx.annotation:annotation", version.ref = "annotation" } +collections4 = { module = "org.apache.commons:commons-collections4", version.ref = "collections4" } lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "lang3" } preference = { module = "androidx.preference:preference", version.ref = "preference" } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/downloads/DownloadActionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/downloads/DownloadActionsPatch.kt index d6f4d54b4..7a36adba1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/downloads/DownloadActionsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/downloads/DownloadActionsPatch.kt @@ -11,6 +11,7 @@ import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PAC import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_PATH import app.revanced.patches.youtube.utils.patch.PatchList.HOOK_DOWNLOAD_ACTIONS import app.revanced.patches.youtube.utils.pip.pipStateHookPatch +import app.revanced.patches.youtube.utils.playlist.playlistPatch import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch @@ -41,6 +42,7 @@ val downloadActionsPatch = bytecodePatch( dependsOn( pipStateHookPatch, + playlistPatch, sharedResourceIdPatch, settingsPatch, ) @@ -52,7 +54,7 @@ val downloadActionsPatch = bytecodePatch( offlineVideoEndpointFingerprint.methodOrThrow().apply { addInstructionsWithLabels( 0, """ - invoke-static/range {p3 .. p3}, $EXTENSION_CLASS_DESCRIPTOR->inAppVideoDownloadButtonOnClick(Ljava/lang/String;)Z + invoke-static/range {p1 .. p3}, $EXTENSION_CLASS_DESCRIPTOR->inAppVideoDownloadButtonOnClick(Ljava/util/Map;Ljava/lang/Object;Ljava/lang/String;)Z move-result v0 if-eqz v0, :show_native_downloader return-void diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt index 67ce333ab..b2134cfc3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt @@ -15,6 +15,7 @@ import app.revanced.patches.youtube.utils.patch.PatchList.OVERLAY_BUTTONS import app.revanced.patches.youtube.utils.pip.pipStateHookPatch import app.revanced.patches.youtube.utils.playercontrols.hookBottomControlButton import app.revanced.patches.youtube.utils.playercontrols.playerControlsPatch +import app.revanced.patches.youtube.utils.playlist.playlistPatch import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch @@ -74,6 +75,7 @@ val overlayButtonsPatch = resourcePatch( cfBottomUIPatch, pipStateHookPatch, playerControlsPatch, + playlistPatch, sharedResourceIdPatch, settingsPatch, ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/Fingerprints.kt new file mode 100644 index 000000000..109484f0e --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/Fingerprints.kt @@ -0,0 +1,54 @@ +package app.revanced.patches.youtube.utils.playlist + +import app.revanced.util.fingerprint.legacyFingerprint +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.or +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.reference.FieldReference + +internal val accountIdentityFingerprint = legacyFingerprint( + name = "accountIdentityFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + customFingerprint = { method, _ -> + method.definingClass.endsWith("${'$'}AutoValue_AccountIdentity;") + } +) + +internal val editPlaylistConstructorFingerprint = legacyFingerprint( + name = "editPlaylistConstructorFingerprint", + returnType = "V", + strings = listOf("browse/edit_playlist") +) + +internal val editPlaylistFingerprint = legacyFingerprint( + name = "editPlaylistFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Ljava/util/List;"), + opcodes = listOf( + Opcode.CHECK_CAST, + Opcode.IGET_OBJECT, + ), +) + +internal val playlistEndpointFingerprint = legacyFingerprint( + name = "playlistEndpointFingerprint", + returnType = "L", + parameters = listOf("L", "Ljava/lang/String;"), + customFingerprint = { method, _ -> + method.indexOfFirstInstruction { + opcode == Opcode.SGET_OBJECT && + getReference()?.name == "playlistEditEndpoint" + } >= 0 && indexOfSetVideoIdInstruction(method) >= 0 + } +) + +internal fun indexOfSetVideoIdInstruction(method: Method) = + method.indexOfFirstInstruction { + opcode == Opcode.IPUT_OBJECT && + getReference()?.type == "Ljava/lang/String;" + } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt new file mode 100644 index 000000000..ce2bcccf7 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt @@ -0,0 +1,85 @@ +package app.revanced.patches.youtube.utils.playlist + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.shared.mainactivity.getMainActivityMethod +import app.revanced.patches.youtube.utils.extension.Constants.UTILS_PATH +import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch +import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch +import app.revanced.patches.youtube.utils.request.buildRequestPatch +import app.revanced.patches.youtube.utils.request.hookBuildRequest +import app.revanced.util.fingerprint.matchOrThrow +import app.revanced.util.fingerprint.methodOrThrow +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference + +private const val EXTENSION_CLASS_DESCRIPTOR = + "$UTILS_PATH/PlaylistPatch;" + +val playlistPatch = bytecodePatch( + description = "playlistPatch", +) { + dependsOn( + sharedExtensionPatch, + mainActivityResolvePatch, + buildRequestPatch, + ) + + execute { + // In Incognito mode, sending a request always seems to fail. + accountIdentityFingerprint.methodOrThrow().addInstructions( + 1, + "invoke-static/range {p4 .. p4}, $EXTENSION_CLASS_DESCRIPTOR->setIncognitoStatus(Z)V" + ) + + // Get the header to use the auth token. + hookBuildRequest("$EXTENSION_CLASS_DESCRIPTOR->setRequestHeaders(Ljava/lang/String;Ljava/util/Map;)V") + + // Open the queue manager by pressing and holding the back button. + getMainActivityMethod("onKeyLongPress") + .addInstructionsWithLabels( + 0, """ + invoke-static/range {p1 .. p1}, $EXTENSION_CLASS_DESCRIPTOR->onKeyLongPress(I)Z + move-result v0 + if-eqz v0, :ignore + return v0 + :ignore + nop + """ + ) + + val setVideoIdReference = with (playlistEndpointFingerprint.methodOrThrow()) { + val setVideoIdIndex = indexOfSetVideoIdInstruction(this) + getInstruction(setVideoIdIndex).reference as FieldReference + } + + // Users deleted videos via YouTube's flyout menu. + editPlaylistFingerprint + .matchOrThrow(editPlaylistConstructorFingerprint) + .let { + it.method.apply { + val castIndex = it.patternMatch!!.startIndex + val castClass = getInstruction(castIndex).reference.toString() + + if (castClass != setVideoIdReference.definingClass) { + throw PatchException("Method signature parameter did not match: $castClass") + } + val castRegister = getInstruction(castIndex).registerA + val insertIndex = castIndex + 1 + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + iget-object v$insertRegister, v$castRegister, $setVideoIdReference + invoke-static {v$insertRegister}, $EXTENSION_CLASS_DESCRIPTOR->removeFromQueue(Ljava/lang/String;)V + """ + ) + } + } + } +} diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 3b18b2f2b..c1eddda0c 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -22,6 +22,40 @@ "%1$s is not installed. Please download %2$s from the website." %s is not installed. Please install it. + + Add to queue + Add to queue and open queue + Add to queue and play video + External downloader + Open queue + Queue + Remove from queue + Remove from queue and open queue + Remove queue + Save queue + "Instead of opening an external downloader, open the queue manager dialog. + +You can also open the queue manager by pressing and holding the back button on the navigation bar. + +This feature is still in progress, so most features may not work. + +Please use it for debugging purposes only." + Login required + Queue manager unavailable (%s). + Could not identify playlist + Queue is empty + Could not identify video + Failed to add video. + Failed to create queue. + Failed to delete queue. + Failed to remove video. + Failed to save queue. + Video successfully added. + Queue successfully created. + Queue successfully deleted. + Video successfully removed. + Queue successfully saved to \'%s\'. + RVX language App language "Amharic @@ -595,6 +629,9 @@ Some components may not be hidden." Override video download button Native video download button opens your external downloader. Native video download button opens the native in-app downloader. + Queue manager + Native video download button opens the queue manager. + Native video download button opens your external downloader. Playlist downloader package name Package name of your installed external downloader app, such as YTDLnis. @@ -652,7 +689,6 @@ If this setting do not take effect, try switching to Incognito mode." Enable translucent navigation bar Navigation bar is translucent. Navigation bar is opaque. - In certain YouTube versions, this setting can make the system navigation bar transparent or the layout can be broken in PIP mode. Hide navigation bar Navigation bar is hidden. Navigation bar is shown. @@ -1264,6 +1300,8 @@ Tap and hold to copy video timestamp." Tap to mute volume of the current video. Tap again to unmute. Show external downloader button Tap to launch external downloader. + Queue manager + Instead of launching an external downloader, open the queue manager. Show speed dialog button "Tap to open speed dialog. Tap and hold to reset playback speed to 1.0x. Tap and hold again to reset back to default speed." diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 8240aa8de..b869b7988 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -148,6 +148,7 @@ + SETTINGS: HOOK_DOWNLOAD_ACTIONS --> @@ -489,6 +490,7 @@ + From 0c5c3a87be442c16bf36537cfdbdf5df122bee4e Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 22:04:57 +0900 Subject: [PATCH 19/77] feat(YouTube Music): Remove `Spoof client` patch https://github.com/inotia00/ReVanced_Extended/issues/2832#issuecomment-2745941171 --- .../patches/music/utils/fix/client/SpoofClientPatch.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/fix/client/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/fix/client/SpoofClientPatch.kt index 840bf6be2..1cc9eb807 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/fix/client/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/fix/client/SpoofClientPatch.kt @@ -63,9 +63,11 @@ private const val CLIENT_INFO_CLASS_DESCRIPTOR = @Suppress("unused") val spoofClientPatch = bytecodePatch( - SPOOF_CLIENT.title, - SPOOF_CLIENT.summary, - false, + // Removed from the patch list to avoid user confusion: + // https://github.com/inotia00/ReVanced_Extended/issues/2832#issuecomment-2745941171 + // SPOOF_CLIENT.title, + // SPOOF_CLIENT.summary, + // false, ) { compatibleWith(COMPATIBLE_PACKAGE) From 227afa532ae60b46effbd1a00556443fb80e4607 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 22:05:49 +0900 Subject: [PATCH 20/77] fix build error --- .../layout/branding/icon/CustomBrandingIconPatch.kt | 3 +++ .../youtube/player/seekbar/SeekbarComponentsPatch.kt | 7 +------ .../youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt | 7 +------ .../patches/youtube/utils/settings/ResourceUtils.kt | 1 + 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt index a4cedb451..4b9b2b5cc 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt @@ -10,6 +10,7 @@ import app.revanced.patches.youtube.utils.playservice.is_19_17_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_32_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch +import app.revanced.patches.youtube.utils.settings.ResourceUtils.restoreOldSplashAnimationIncluded import app.revanced.patches.youtube.utils.settings.ResourceUtils.updatePatchStatusIcon import app.revanced.patches.youtube.utils.settings.getBytecodeContext import app.revanced.patches.youtube.utils.settings.settingsPatch @@ -208,6 +209,8 @@ val customBrandingIconPatch = resourcePatch( // Change splash screen. if (restoreOldSplashAnimationOption == true) { + restoreOldSplashAnimationIncluded = true + oldSplashAnimationResourceGroups.let { resourceGroups -> resourceGroups.forEach { copyResources("$appIconResourcePath/splash", it) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt index 92bf1da06..f549f9d0e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt @@ -11,14 +11,12 @@ import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.shared.drawable.addDrawableColorHook import app.revanced.patches.shared.drawable.drawableColorHookPatch import app.revanced.patches.shared.mainactivity.onCreateMethod -import app.revanced.patches.youtube.layout.branding.icon.customBrandingIconPatch import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.youtube.utils.extension.Constants.PATCH_STATUS_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_CLASS_DESCRIPTOR import app.revanced.patches.youtube.utils.extension.Constants.PLAYER_PATH import app.revanced.patches.youtube.utils.flyoutmenu.flyoutMenuHookPatch import app.revanced.patches.youtube.utils.mainactivity.mainActivityResolvePatch -import app.revanced.patches.youtube.utils.patch.PatchList.CUSTOM_BRANDING_ICON_FOR_YOUTUBE import app.revanced.patches.youtube.utils.patch.PatchList.SEEKBAR_COMPONENTS import app.revanced.patches.youtube.utils.playerButtonsResourcesFingerprint import app.revanced.patches.youtube.utils.playerButtonsVisibilityFingerprint @@ -37,6 +35,7 @@ import app.revanced.patches.youtube.utils.seekbarFingerprint import app.revanced.patches.youtube.utils.seekbarOnDrawFingerprint import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.ResourceUtils.getContext +import app.revanced.patches.youtube.utils.settings.ResourceUtils.restoreOldSplashAnimationIncluded import app.revanced.patches.youtube.utils.settings.settingsPatch import app.revanced.patches.youtube.utils.totalTimeFingerprint import app.revanced.patches.youtube.video.information.videoInformationPatch @@ -48,7 +47,6 @@ import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall import app.revanced.util.fingerprint.matchOrThrow import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.fingerprint.resolvable -import app.revanced.util.getBooleanOptionValue import app.revanced.util.getReference import app.revanced.util.getWalkerMethod import app.revanced.util.indexOfFirstInstructionOrThrow @@ -122,9 +120,6 @@ val seekbarComponentsPatch = bytecodePatch( execute { - val restoreOldSplashAnimationIncluded = CUSTOM_BRANDING_ICON_FOR_YOUTUBE.included == true && - customBrandingIconPatch.getBooleanOptionValue("restoreOldSplashAnimation").value == true - var settingArray = arrayOf( "PREFERENCE_SCREEN: PLAYER", "SETTINGS: SEEKBAR_COMPONENTS" diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt index f677f3965..5a193d9e6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt @@ -1,11 +1,9 @@ package app.revanced.patches.youtube.utils.fix.splash import app.revanced.patcher.patch.resourcePatch -import app.revanced.patches.youtube.layout.branding.icon.customBrandingIconPatch -import app.revanced.patches.youtube.utils.patch.PatchList.CUSTOM_BRANDING_ICON_FOR_YOUTUBE import app.revanced.patches.youtube.utils.playservice.is_19_32_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch -import app.revanced.util.getBooleanOptionValue +import app.revanced.patches.youtube.utils.settings.ResourceUtils.restoreOldSplashAnimationIncluded import org.w3c.dom.Element /** @@ -27,9 +25,6 @@ val darkModeSplashScreenPatch = resourcePatch( return@finalize } - val restoreOldSplashAnimationIncluded = CUSTOM_BRANDING_ICON_FOR_YOUTUBE.included == true && - customBrandingIconPatch.getBooleanOptionValue("restoreOldSplashAnimation").value == true - if (restoreOldSplashAnimationIncluded) { document("res/values-night/styles.xml").use { document -> val resourcesNode = document.getElementsByTagName("resources").item(0) as Element diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/ResourceUtils.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/ResourceUtils.kt index 7b84b5f93..43cd0c4f1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/ResourceUtils.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/settings/ResourceUtils.kt @@ -25,6 +25,7 @@ internal object ResourceUtils { const val RVX_PREFERENCE_PATH = "res/xml/revanced_prefs.xml" const val YOUTUBE_SETTINGS_PATH = "res/xml/settings_fragment.xml" + var restoreOldSplashAnimationIncluded = false var youtubeMusicPackageName = YOUTUBE_MUSIC_PACKAGE_NAME var youtubePackageName = YOUTUBE_PACKAGE_NAME From 9046d2d9592b75a0a60e516d310ec48b5de2736e Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 22:06:08 +0900 Subject: [PATCH 21/77] feat(Translations): Update translation --- .../layout/translations/TranslationsPatch.kt | 4 +- .../music/translations/el-rGR/strings.xml | 19 + .../music/translations/hu-rHU/strings.xml | 22 + .../music/translations/it-rIT/strings.xml | 76 ++++ .../music/translations/ko-rKR/strings.xml | 3 + .../music/translations/pl-rPL/strings.xml | 3 + .../music/translations/pt-rBR/strings.xml | 17 + .../music/translations/ru-rRU/strings.xml | 3 + .../music/translations/uk-rUA/strings.xml | 5 +- .../music/translations/vi-rVN/strings.xml | 3 + .../youtube/translations/ar/strings.xml | 55 +-- .../youtube/translations/bg-rBG/strings.xml | 51 --- .../youtube/translations/el-rGR/strings.xml | 186 +++++--- .../youtube/translations/es-rES/strings.xml | 214 +++++++--- .../youtube/translations/fr-rFR/strings.xml | 188 +++++--- .../youtube/translations/hu-rHU/strings.xml | 78 ++-- .../youtube/translations/id-rID/strings.xml | 400 ++++++++++++++++++ .../youtube/translations/in/strings.xml | 400 ++++++++++++++++++ .../youtube/translations/it-rIT/strings.xml | 191 ++++++--- .../youtube/translations/ja-rJP/strings.xml | 52 --- .../youtube/translations/ko-rKR/strings.xml | 243 ++++++++--- .../youtube/translations/pl-rPL/strings.xml | 182 +++++--- .../youtube/translations/pt-rBR/strings.xml | 77 ++-- .../youtube/translations/ru-rRU/strings.xml | 183 +++++--- .../youtube/translations/tr-rTR/strings.xml | 52 --- .../youtube/translations/uk-rUA/strings.xml | 215 +++++++--- .../youtube/translations/vi-rVN/strings.xml | 72 +--- .../youtube/translations/zh-rCN/strings.xml | 51 --- .../youtube/translations/zh-rTW/strings.xml | 76 ++-- 29 files changed, 2195 insertions(+), 926 deletions(-) create mode 100644 patches/src/main/resources/youtube/translations/id-rID/strings.xml create mode 100644 patches/src/main/resources/youtube/translations/in/strings.xml diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/translations/TranslationsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/translations/TranslationsPatch.kt index a72aa6957..a9b768e9d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/translations/TranslationsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/translations/TranslationsPatch.kt @@ -11,8 +11,8 @@ import app.revanced.patches.youtube.utils.settings.settingsPatch // Array of supported translations, each represented by its language code. private val SUPPORTED_TRANSLATIONS = setOf( - "ar", "bg-rBG", "de-rDE", "el-rGR", "es-rES", "fr-rFR", "hu-rHU", "it-rIT", "ja-rJP", "ko-rKR", - "pl-rPL", "pt-rBR", "ru-rRU", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW" + "ar", "bg-rBG", "de-rDE", "el-rGR", "es-rES", "fr-rFR", "hu-rHU", "id-rID", "in", "it-rIT", "ja-rJP", + "ko-rKR", "pl-rPL", "pt-rBR", "ru-rRU", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW" ) @Suppress("unused") diff --git a/patches/src/main/resources/music/translations/el-rGR/strings.xml b/patches/src/main/resources/music/translations/el-rGR/strings.xml index 44d4e10f7..ee606bd58 100644 --- a/patches/src/main/resources/music/translations/el-rGR/strings.xml +++ b/patches/src/main/resources/music/translations/el-rGR/strings.xml @@ -172,6 +172,8 @@ Απόκρυψη της ενότητας καρτών λίστας αναπαραγωγής στη ροή. Απόκρυψη ενότητας «Δείγματα» Απόκρυψη της ενότητας «Δείγματα» στη ροή. + Απόκρυψη κουμπιού αναζήτησης + Απόκρυψη του κουμπιού αναζήτησης στη γραμμή εργαλείων. Απόκρυψη κουμπιού ηχητικής αναζήτησης Απόκρυψη του κουμπιού ηχητικής αναζήτησης στην γραμμή αναζήτησης. Απόκρυψη κουμπιού «Πατήστε για ενημέρωση» @@ -192,6 +194,7 @@ Επιλέξτε την έκδοση εφαρμογής που θα χρησιμοποιηθεί. 6.42.55 - Απενεργοποίηση στίχων σε πραγματικό χρόνο 7.16.53 - Επαναφορά παλιάς γραμμής ενεργειών + Μη έγκυρη έκδοση για παραποίηση: %s. Γραμμή πλοήγησης Προσαρμοσμένο χρώμα γραμμής πλοήγησης @@ -213,6 +216,18 @@ Απόκρυψη της γραμμής πλοήγησης. Απόκρυψη ονομασιών γραμμής πλοήγησης Απόκρυψη ονομασιών των κουμπιών στη γραμμή πλοήγησης. + Αντικατάσταση κουμπιού «Δείγματα» + Αντικατάσταση του κουμπιού «Δείγματα» με το κουμπί «Αναζήτηση». + Αντικατάσταση κουμπιού «Αναβάθμιση» + Αντικατάσταση του κουμπιού «Αναβάθμιση» με το κουμπί «Ρυθμίσεις». + Σχετικά με την αντικατάσταση κουμπιού + "Αυτή η λειτουργία είναι πειραματική. +Υπάρχουν δομικοί περιορισμοί της τροποποίησης, καθώς ενέργειες όπως η Αναζήτηση και οι Ρυθμίσεις στο YouTube Music δεν είναι δημόσιες. + +Γνωστά προβλήματα: +• Όταν κλείνει μια αντικατασταθείσα ενέργεια, όπως η Αναζήτηση και οι Ρυθμίσεις, ανοίγει η αρχική σελίδα. + +Πατήστε για να ανοίξετε την ρύθμιση «Αλλαγή αρχικής σελίδας»." Οθόνη αναπαραγωγής Προσθήκη κουμπιού επόμενου κομματιού στην ελαχιστοποιημένη οθόνη αναπαραγωγής @@ -452,6 +467,10 @@ iOS Music 6.21 iOS Music 7.04 Παραποίηση παραμέτρου προγράμματος αναπαραγωγής + "Παραποίηση παραμέτρου του προγράμματος αναπαραγωγής για την αποφυγή προβλημάτων αναπαραγωγής. + +Περιορισμός: +• Μερικές φορές οι υπότιτλοι βρίσκονται στην κορυφή της οθόνης αναπαραγωγής αντί του κάτω μέρους." Τύπος ιστορικού παρακολούθησης "• Αρχικός: Ακολουθεί τις ρυθμίσεις ιστορικού παρακολούθησης του λογαριασμού Google σας, αλλά το ιστορικό παρακολούθησης μπορεί να μη λειτουργεί λόγω χρήσης VPN ή εναλλακτικού DNS. • Αντικατάσταση του domain: Ακολουθεί τις ρυθμίσεις ιστορικού παρακολούθησης του λογαριασμού Google σας. diff --git a/patches/src/main/resources/music/translations/hu-rHU/strings.xml b/patches/src/main/resources/music/translations/hu-rHU/strings.xml index 60fe87248..22191d3b8 100644 --- a/patches/src/main/resources/music/translations/hu-rHU/strings.xml +++ b/patches/src/main/resources/music/translations/hu-rHU/strings.xml @@ -20,6 +20,7 @@ Elrejti a Szolgáltatási feltételeket a fiókmenüben. Műveletsáv + Lejátszási gombok sorának mozgatása a lejátszás gomb alá. A tetszik és nem tetszik gombok elrejtése Elrejti a tetszik és nem tetszik gombokat. Nem működik a régi lejátszóval. Megjegyzés gomb elrejtése @@ -32,6 +33,7 @@ Elrejti a rádió gombot. Megosztás gomb elrejtése Elrejti a Megosztás gombot. + "Zene/Videó gomb elrejtése (Ez a gomb csak néhány felhasználónak elérhető)" Navigációs gombok címkéinek elrejtése Elrejti a címkéket az műveleti gombokon. Letöltés gomb felülírása @@ -49,6 +51,11 @@ Töltsd le a(z) %2$s weboldalról." Hirdetések Teljes képernyős hirdetések elrejtése + "Teljes képernyős hirdetések elrejtése. + +Limitáció; +•Néha lehet hogy csak fekete képet látsz a kezdő képernyő helyett." + Teljes képernyős hírdetések bezárva. Általános hirdetések elrejtése Elrejti az általános hirdetéseket. Zenei hirdetések elrejtése @@ -57,6 +64,7 @@ Töltsd le a(z) %2$s weboldalról." Elrejti a promóció címkét. Felugró prémium hírdetések elrejtése Elrejti a prémium promóciós felugró ablakokat. + A teljes képernyős hírdetések be lettek zárva. Prémium megújítás szalaghírdetés elrejtése Elrejti a prémium megújítás szalaghírdetést. Promóciós figyelmeztető banner elrejtése @@ -88,6 +96,7 @@ Korlátozások: Rész menü elrejtése Podcast menü elrejtése Súgó & visszajelzés menü elrejtése + A nem érdekel gomb elrejtése Fül elrejtése a Gyors elérés menüben Következő lejátszása menü elrejtése Minőség menü elrejtése @@ -201,8 +210,21 @@ Ez nem kerüli meg a korhatárkorlátozást. Csak automatikusan elfogadja azt."< Elrejti a navigációs sávot. Navigációs címkék elrejtése Elrejti a szöveget a navigációs gombok alatt. + Minták gomb kicserélése + Kicseréli a minták gombot egy kereső gombra. + Előfizetés gomb kicserélése + A létrehozás gombot beállítások gombra cseréli. + A kicserélés gombról + "Ez a funkció kísérleti jellegű. +A javításnak vannak strukturális korlátai, mivel az olyan tevékenységek, mint a keresés és a beállítások a youtube zenében nem nyilvánosak. + +Ismert problémák: +- Amikor egy helyettesített tevékenység, például a Keresés és a Beállítások bezárásra kerül, megnyílik a kezdőlap. + +Kattintson a 'Kezdőlap módosítása' beállítások megnyitásához." Lejátszó + Minilejátszó következő gomb engedélyezése Lejtászó gesztus letiltása Letiltja a zeneszámok váltását a lejátszóban. Zen mód bekapcsolása diff --git a/patches/src/main/resources/music/translations/it-rIT/strings.xml b/patches/src/main/resources/music/translations/it-rIT/strings.xml index 30f83dae9..df5a9d0e6 100644 --- a/patches/src/main/resources/music/translations/it-rIT/strings.xml +++ b/patches/src/main/resources/music/translations/it-rIT/strings.xml @@ -1,6 +1,7 @@ + Impostazioni RVX Resetta ai valori iniziali. Riavvia per caricare il layout normalmente @@ -14,16 +15,91 @@ Nascondi componente vuoto Nasconde i componenti vuoti nel menu dell\'account Nascondi l\'intestazione + Nasconde l\'handle nel menù dell\'account. Nascondi contenitore termini Nasconde il contenitore dei termini di servizio. + Action bar + Cambia la posizione della Action bar + Sposta l\'Action bar sotto il pulsante Play. + Nascondi pulsanti Mi Piace e Non Mi Piace + Non funziona con il vecchio layout del player. + Nascondi il pulsante Commenti + Nascondi il pulsante Commenti. + Nascondi il pulsante Salva + Nasconde il pulsante Salva. + Nascondi il pulsante Download + Nasconde il pulsante del download. + Nascondi pulsante Radio + Nasconde il pulsante Radio. + Nascondi il pulsante Condividi + Nasconde il pulsante Condividi. + Nascondi pulsante Brano / Video + "Nasconde il pulsante Brano / Video. (Il pulsante è visibile solo per alcuni utenti)" + Nascondi le etichette della barra delle azioni + Nasconde le etichette dei pulsanti di azione. + Sovrascrivi il pulsante di azione Download + "Il pulsante Download apre il downloader esterno. + +• Sovrascrive solo il pulsante Download nel player. +• Non sovrascrive il pulsante Download nel menu flyout o nella scheda Libreria." Nome del pacchetto downloader esterno Nome del pacchetto dell\'app downloader esterna installata, come NewPipe o Seal. + Downloader esterno + Attenzione + "%1$s non è installato. +Si prega di scaricare %2$s dal sito web." %s non è installato. Installalo. + Annunci + Nascondi gli annunci a schermo intero + "Nasconde gli annunci a schermo intero. + +Limitazioni: +• A volte potrebbe apparire una schermata nera invece della Home." + Annunci a schermo intero chiusi. + Nascondi annunci generici + Nasconde annunci generici. Nascondi le pubblicità musicali + Nasconde gli annunci durante la riproduzione. + Nascondi l\'etichetta della promozione a pagamento + Nasconde l\'etichetta della promozione a pagamento. + Nascondi popup promozionali premium + Nasconde popup promozionali premium. + I popup promozionali Premium sono chiusi. + Nascondi banner di rinnovo premium + Nasconde il banner di rinnovo premium. + Nascondi banner di avviso promozionale + Nasconde il banner di avviso promozionale. + Menù a comparsa + Aggiungi interruttore per tagliare le parti di silenzio + "Aggiunge un interruttore per tagliare le parti di silenzio, nel menù a comparsa della velocità di riproduzione. + +Info: +• Questa funzione è per i podcast. +• Questa funzione è ancora in fase di sviluppo, potrebbe essere instabile." Abilita dialogo compatto + "Abilita il menù a comparsa compatto sui telefoni. + +Limitazioni: +• Le copertine degli album nella scheda Raccolta diventano più piccole quando viene organizzata in una griglia. +• Il layout del timer di spegnimento può apparire insolito." + Nascondi pulsanti Mi Piace e Non Mi Piace + Nascondi componente a tre tasti + Nascondi il menù Aggiungi alla coda + Nascondi il menù Sottotitoli + Nascondi il menu Elimina playlist + Nascondi il menu Ignora coda + Nascondi menù Download + Nascondi il menù Modifica playlist + Nascondi il menu Vai all\'album + Nascondi il menu Vai all\'artista + Nascondi il menù Vai all\'episodio + Nascondi il menù Vai al podcast + Nascondi il menu Aiuto & feedback + Nascondi il menu Non interessato + Nascondi Aggiungi al menu Selezione rapida Disabilita i sottotitoli automatici forzati Sottotitoli automatici forzati disabilitati. diff --git a/patches/src/main/resources/music/translations/ko-rKR/strings.xml b/patches/src/main/resources/music/translations/ko-rKR/strings.xml index 6bdbd316c..b2dedc69d 100644 --- a/patches/src/main/resources/music/translations/ko-rKR/strings.xml +++ b/patches/src/main/resources/music/translations/ko-rKR/strings.xml @@ -172,6 +172,8 @@ 피드에서 재생목록 카드 선반을 숨깁니다. 샘플 선반 제거 피드에서 샘플 선반을 숨깁니다. + 검색 버튼 제거 + 툴바에서 검색 버튼을 숨깁니다. 노래 검색 버튼 제거 툴바에서 노래 검색 버튼을 숨깁니다. 탭하여 업데이트 버튼 제거 @@ -191,6 +193,7 @@ 변경할 앱 버전을 선택하세요. 6.42.55 - 실시간 가사를 비활성화합니다. 7.16.53 - 이전 액션바로 복원합니다. + 변경할 앱 버전이 잘못되었습니다: %s 하단바 사용자 정의 하단바 색상 활성화 diff --git a/patches/src/main/resources/music/translations/pl-rPL/strings.xml b/patches/src/main/resources/music/translations/pl-rPL/strings.xml index d69e52c5c..d0657797c 100644 --- a/patches/src/main/resources/music/translations/pl-rPL/strings.xml +++ b/patches/src/main/resources/music/translations/pl-rPL/strings.xml @@ -172,6 +172,8 @@ Ograniczenia: Ukrywa półkę z rekomendowanymi playlistami na stronie głównej. Ukryj półkę z samplami Ukrywa półke z samplami na stronie głównej. + Ukryj przycisk wyszukiwania + Ukrywa przycisk wyszukiwania w pasku narzędzi. Ukryj przycisk od rozpoznawania piosenek Ukrywa przycisk od rozpoznawania piosenek w pasku wyszukiwania. Ukryj przycisk \'Stuknij, aby zaktualizować\' @@ -192,6 +194,7 @@ Nie pomija to ograniczeń wiekowych, lecz akceptuje je automatycznie." Wybierz wersję, którą chcesz oszukiwać. 6.42.55 - Wyłącza teksty w czasie rzeczywistym 7.16.53 - Przywraca stary pasek akcji + Nieprawidłowa oszukiwana wersja aplikacji: %s. Pasek nawigacji Włącz niestandardowy kolor paska nawigacji diff --git a/patches/src/main/resources/music/translations/pt-rBR/strings.xml b/patches/src/main/resources/music/translations/pt-rBR/strings.xml index 356d67cc6..64f93b21a 100644 --- a/patches/src/main/resources/music/translations/pt-rBR/strings.xml +++ b/patches/src/main/resources/music/translations/pt-rBR/strings.xml @@ -213,6 +213,18 @@ Isso não ignora a restrição de idade, apenas aceita isso automaticamente."Oculta a barra de navegação. Ocultar rótulos de navegação Oculta o rótulo abaixo de cada botão de navegação. + Substituir botão Descobertas + Substitui o botão Descobertas pelo botão de Pesquisa. + Substituir botão Upgrade + Substitui o botão Upgrade pelo botão de Configurações. + Sobre a substituição de botão + "Este recurso é experimental. +Existem limitações estruturais do patch, pois atividades como Pesquisa e Configurações no YouTube Music não são públicas. + +Problemas conhecidos: +• Quando uma atividade substituída, como Pesquisa e Configurações é fechada, a página inicial se abre. + +Clique para abrir as configurações de 'Alterar página inicial'." Reprodutor Adicionar o botão próximo ao mini reprodutor @@ -453,6 +465,11 @@ Informações: Android Music 5.29.53 iOS Music 6.21 iOS Music 7.04 + Falsificação de parâmetro do reprodutor + "Falsificar o parâmetro de reprodutor para evitar problemas de reprodução. + +Efeito lateral: +• Às vezes as legendas estão localizadas na parte superior do reprodutor ao invés da parte inferior." Tipo de histórico de exibição "• Original: segue as configurações do histórico de exibição da conta do Google, mas o histórico de exibição pode não funcionar devido a DNS ou VPN. • Substituir domínio: segue as configurações do histórico de exibição da conta do Google. diff --git a/patches/src/main/resources/music/translations/ru-rRU/strings.xml b/patches/src/main/resources/music/translations/ru-rRU/strings.xml index 6272aedbb..edf5695ab 100644 --- a/patches/src/main/resources/music/translations/ru-rRU/strings.xml +++ b/patches/src/main/resources/music/translations/ru-rRU/strings.xml @@ -172,6 +172,8 @@ Скрывает полку с заставкой плейлиста в ленте. Скрыть полку \"Семплы\" Скрывает полку \"Семплы\" в ленте. + Скрыть кнопку поиска + Скрывает кнопку поиска на панели инструментов. Скрыть кнопку поиска звука Скрывает кнопку поиска звука в строке поиска. Скрыть кнопку \"Обновить\" @@ -192,6 +194,7 @@ Выберите целевую версию приложения для подмены. 6.42.55 - Отключает динамических текстов 7.16.53 - Восстановить старую панель действий + Неверная версия подмены: %s. Панель навигации Включить пользовательский цвет панели навигации diff --git a/patches/src/main/resources/music/translations/uk-rUA/strings.xml b/patches/src/main/resources/music/translations/uk-rUA/strings.xml index b1d6d001b..03ef478d6 100644 --- a/patches/src/main/resources/music/translations/uk-rUA/strings.xml +++ b/patches/src/main/resources/music/translations/uk-rUA/strings.xml @@ -165,13 +165,15 @@ Приховати плаваючу кнопку Приховує плаваючу кнопку у вкладці \"Бібліотека\". Приховати кнопку історії - Приховує кнопку історії на панелі інструментів вкладки \"Бібліотека\". + Приховує кнопку історії на панелі інструментів. Приховати кнопку сповіщень Приховує кнопку сповіщень на панелі інструментів. Приховати полицю карток списку відтворення Приховує полицю карток списку відтворення в стрічці. Приховати полицю \"Семпли\" Приховує полицю \"Семпли для вас\" у стрічці. + Приховати кнопку пошуку + Приховує кнопку пошуку на панелі інструментів. Приховати кнопку пошуку музики Приховує кнопку пошуку музики у панелі пошуку. Приховати кнопку оновлення @@ -192,6 +194,7 @@ Виберіть зі списку цільову версію для підміни. 6.42.55 - Вимкнення динамічних текстів 7.16.53 - Відновлення старої панелі дій + Невірна версія підміни: %s. Панель навігації Увімкнути користувацький колір панелі навігації diff --git a/patches/src/main/resources/music/translations/vi-rVN/strings.xml b/patches/src/main/resources/music/translations/vi-rVN/strings.xml index 5cd971de8..b410fe63d 100644 --- a/patches/src/main/resources/music/translations/vi-rVN/strings.xml +++ b/patches/src/main/resources/music/translations/vi-rVN/strings.xml @@ -171,6 +171,8 @@ Hạn chế: Ẩn kệ thẻ danh sách phát ở thẻ Trang chủ. Ẩn thẻ Đoạn nhạc Ẩn kệ Đoạn nhạc ở thẻ Trang chủ. + Ẩn nút Tìm kiếm + Ẩn nút Tìm kiếm khỏi thanh công cụ. Ẩn nút Tìm kiếm bằng âm thanh Ẩn nút Tìm kiếm bằng âm thanh kế bên thanh tìm kiếm. Ẩn nút Chạm để nâng cấp @@ -191,6 +193,7 @@ Hạn chế: Chọn phiên bản YouTube Music mà bạn muốn giả mạo. 6.42.55 - Tắt lời bài hát theo thời gian thực 7.16.53 - Khôi phục thanh thao tác kiểu cũ + Phiên bản ứng dụng đã chọn không hợp lệ: %s. Thanh điều hướng Màu thanh điều hướng tuỳ chỉnh diff --git a/patches/src/main/resources/youtube/translations/ar/strings.xml b/patches/src/main/resources/youtube/translations/ar/strings.xml index f2271ae74..e3bd5e2f6 100644 --- a/patches/src/main/resources/youtube/translations/ar/strings.xml +++ b/patches/src/main/resources/youtube/translations/ar/strings.xml @@ -21,57 +21,6 @@ %s لم يتم تثبيته. الرجاء تثبيته. لغة RVX لغة التطبيق - العربيّة - Azerbaijani - Bulgarian - Bengali - Catalan - Czech - Danish - German - Greek - English - Spanish - Estonian - فارسى - Finnish - French - Gujarati - Hindi - Croatian - Hungarian - Indonesian - Italian - Japanese - Kazakh - Korean - Lithuanian - Latvian - Macedonian - Mongolian - Marathi - Malay - Burmese - Dutch - Odia - Punjabi - Polish - Portugese - Romanian - Russian - Slovak - Slovene - Serbian - Swedish - Swahili - Tamil - Telugu - Thai - Turkish - Ukrainian - Urdu - Vietnamese - Chinese الإعلانات إخفاء لافتة شاشة المتجر النهائية @@ -446,8 +395,10 @@ 18.33.40 - استعادة شريط إجراءات Shorts القديم 18.38.45 - استعادة سلوك جودة الفيديو الافتراضي القديم 18.48.39 - تعطيل تحديث المشاهدات والإعجابات في الوقت الفعلي + 19.01.34 - تعطيل تفاعل وصف الفيديو 19.26.42 - تعطيل أيقونة Cairo في شريط التنقل وشريط الأدوات 19.33.37 - استعادة لوحة التحكم القديمة لسرعة التشغيل + إصدار التطبيق الوهمي غير صالح: %s. قائمة الحساب إخفاء أو عرض العناصر في قائمة الحساب وعلامة التبويب أنت. @@ -536,7 +487,6 @@ تمكين شريط التنقل الشفاف شريط التنقل شفاف. شريط التنقل غير شفاف. - في بعض إصدارات YouTube، قد يؤدي هذا الإعداد إلى جعل شريط التنقل في النظام شفافًا أو قد يتم كسر التخطيط في وضع صورة داخل صورة. إخفاء شريط التنقل تم إخفاء شريط التنقل. يتم عرض شريط التنقل. @@ -1414,7 +1364,6 @@ "تم تمكين الإجراءات المخصصة في القائمة المنبثقة. القيود: -• لا يعمل إذا تم تغيير إصدار التطبيق إلى 18.49.37 أو إصدار أقدم. • لا يعمل مع البث المباشر." تم تعطيل الإجراءات المخصصة في القائمة المنبثقة. تمكين الإجراءات المخصصة في شريط الأدوات diff --git a/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml b/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml index 5d43133aa..a495f4501 100644 --- a/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml +++ b/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml @@ -20,57 +20,6 @@ %s не е инсталирано. Моля инсталирайте го. RVX език Език на приложението - Арабски - Азербайджански - Български - Бенгалски - Каталонски - Чешки - Датски - Немски - Гръцки - Английски - Испански - Естонски - Персийски - Финландски - Френски - Гуджарати - Хинди - Хърватски - Унгарски - Индонезийски - Италиански - Японски - Казахстански - Корейски - Литовски - Латвийски - Македонски - Монголски - Маратхи - Малайски - Бирмански - Холандски - Ория - Пенджабски - Полски - Португалски - Румънски - Руски - Словашки - Словенски - Сръбски - Шведски - Суахили - Тамилски - Телугу - Тайландски - Турски - Украински - Урду - Виетнамски - Китайски Реклами Скриване на рекламите в режим на цял екран diff --git a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml index 4e88fed07..c22ab86c9 100644 --- a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml +++ b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml @@ -9,7 +9,7 @@ Έγινε επαναφορά στις προεπιλεγμένες τιμές. Πειραματικές λειτουργίες Θέλετε να συνεχίσετε; - Επανεκκίνηση ώστε να φορτωθεί σωστά η διεπαφή + Επανεκκίνηση ώστε να φορτωθεί σωστά η διάταξη Ανανέωση και επανεκκίνηση Κανονική Όνομα πακέτου προγράμματος λήψης βίντεο @@ -21,57 +21,116 @@ %s δεν έχει εγκατασταθεί. Παρακαλούμε εγκαταστήστε το. Γλώσσα ρυθμίσεων RVX Γλώσσα εφαρμογής - Αραβικά - Αζερική - Βουλγαρικά - Βεγγαλικά - Καταλανικά - Τσέχικα - Δανικά - Γερμανικά - Ελληνικά - Αγγλικά - Ισπανικά - Εσθονικά - Περσικά - Φινλανδικά - Γαλλικά - Γκουτζαρατικά - Χίντι - Κροατικά - Ουγγρικά - Ινδονησιακά - Ιταλικά - Ιαπωνικά - Καζακικά - Κορεάτικα - Λιθουανικά - Λετονικά - Σλαβομακεδονικά - Μογγολικά - Μαράτι - Μαλαισιανά - Βιρμανικά - Ολλανδικά - Οντία - Παντζάμπι - Πολωνικά - Πορτογαλικά - Ρουμανικά - Ρώσικα - Σλοβακικά - Σλοβενικά - Σέρβικα - Σουηδικά - Σουαχίλι - Ταμίλ - Τελούγκου - Ταϊλανδικά - Τούρκικα - Ουκρανικά - Ουρντού - Βιετναμέζικα - Κινέζικα + "Αμχαρικά +አማርኛ" + "Αραβικά +العربية" + "Αζερικά +Azərbaycan" + "Λευκορωσική +беларуская" + "Βουλγαρικά +Български" + "Βεγγαλικά +বাংলা" + "Καταλανικά +Català" + "Τσέχικα +Čeština" + "Δανέζικα +Dansk" + "Γερμανικά +Deutsch" + "Ελληνικά +Ελληνικά" + "Αγγλικά +English" + "Ισπανικά +Español" + "Εσθονικά +Eesti" + "Περσικά +فارسی" + "Φινλανδικά +Suomi" + "Γαλλικά +Français" + "Γκουτζαρατί +ગુજરાતી" + "Εβραϊκά +עברי" + "Ινδικά +हिन्दी" + "Κροατικά +Hrvatski" + "Ουγγρικά +Magyar" + "Ινδονησιακά +Indonesia" + "Ιταλικά +Italiano" + "Ιαπωνικά +日本語" + "Καζακική +Қазақ тілі" + "Κορεατική +한국어" + "Λιθουανικά +Lietuvių" + "Λετονικά +Latviešu" + "Βορειομακεδονικά +Македонски" + "Μογγολικά +Монгол" + "Μαράτι +मराठी" + "Μαλαϊκά +Melayu" + "Βιρμανικά +ဗမာ" + "Ολλανδικά +Nederlands" + "Οντία +ଓଡ଼ିଆ" + "Παντζαμικά +ਪੰਜਾਬੀ" + "Πολωνικά +Polski" + "Πορτογαλικά +Português" + "Ρουμανικά +Română" + "Ρωσικά +Русский" + "Σλοβακικά +Slovenčina" + "Αλβανικά +Shqip" + "Σλοβενικά +Slovenščina" + "Σερβικά +Српски" + "Σουηδικά +Svenska" + "Σουαχίλι +Kiswahili" + "Ταμίλ +தமிழ்" + "Τελούγκου +తెలుగు" + "Ταϊλανδέζικα +ไทย" + "Τουρκικά +Türkçe" + "Ουκρανικά +Українська" + "Ουρντού +اردو" + "Βιετναμέζικα +Tiếng Việt" + "Κινέζικα +中文" Διαφημίσεις Ετικέτα καταστήματος στην τελική οθόνη @@ -426,6 +485,18 @@ Playlists • Τα Shorts ανοίγουν στην κανονική οθόνη αναπαραγωγής. • Η ροή οργανώνεται ανά θέματα και κανάλια. • Η περιγραφή βίντεο δεν γίνεται να ανοιχτεί όταν η λειτουργία «Παραποίηση ροών βίντεο» είναι ενεργοποιημένη." + Απενεργοποίηση ενημερώσεων διάταξης + Η διάταξη δε θα ενημερώνεται από τον διακομιστή. + Η διάταξη θα ενημερώνεται από τον διακομιστή. + "Η διάταξη της εφαρμογής θα επαναφερθεί στη διάταξη που χρησιμοποιούσε όταν εγκαταστάθηκε για πρώτη φορά. + +Κάποιες διατάξεις από την πλευρά του διακομιστή ενδέχεται να μην αναιρεθούν. + +Οι αλλαγές περιλαμβάνουν: +• Τα στοιχεία στο αναδυόμενο μενού της οθόνης αναπαραγωγής ή οι σχετικές ρυθμίσεις τους μπορεί να μη λειτουργούν. +• Οι αριθμοί προβολών & «Μου αρέσει» δεν κινούνται αυξανόμενοι εκθετικά. +• Η καρτέλα «Βιβλιοθήκη» θα επαναφερθεί. +• Το κουμπί εναλλαγής λογαριασμού μπορεί να μην εμφανίζεται στην καρτέλα «Βιβλιοθήκη». Χρησιμοποιήστε την ρύθμιση «Ευρεία γραμμή αναζήτησης στο «Εσείς»»." Παραποίηση έκδοσης εφαρμογής Η έκδοση παραποιείται. Η έκδοση δεν παραποιείται. @@ -443,8 +514,10 @@ Playlists 18.33.40 - Επαναφορά γραμμής ενεργειών Shorts στο παλιό στυλ 18.38.45 - Επαναφορά της παλιάς συμπεριφοράς προεπιλεγμένης ποιότητας βίντεο 18.48.39 - Απενεργοποίηση ενημέρωσης των προβολών & αριθμού των «Μου αρέσει» σε πραγματικό χρόνο + 19.01.34 - Απενεργοποίηση αλληλεπίδρασης περιγραφής βίντεο 19.26.42 - Απενεργοποίηση εικονιδίων θέματος Cairo στις γραμμές πλοήγησης και εργαλείων 19.33.37 - Επαναφορά αναδυόμενου πίνακα ταχύτητας αναπαραγωγής παλιού στυλ + Μη έγκυρη έκδοση για παραποίηση: %s. Μενού λογαριασμού Απόκρυψη ή εμφάνιση στοιχείων στο μενού λογαριασμού και στην καρτέλα «Εσείς». @@ -533,7 +606,6 @@ Playlists Διαφανή γραμμή πλοήγησης Η γραμμή πλοήγησης είναι διαφανής. Η γραμμή πλοήγησης δεν είναι διαφανής. - Σε ορισμένες εκδόσεις YouTube, αυτή η ρύθμιση μπορεί να κάνει τη γραμμή πλοήγησης του συστήματος διάφανη ή να χαλάσει τη διάταξη σε λειτουργία PIP. Γραμμή πλοήγησης Κρυμμένη. Εμφανίζεται. @@ -1428,8 +1500,7 @@ Playlists "Οι προσαρμοσμένες ενέργειες είναι ενεργοποιημένες στο αναδυόμενο μενού. Περιορισμοί: -• Δεν λειτουργεί εάν η έκδοση της εφαρμογής παραποιείται σε 18.49.37 ή παλιότερη. -• Δεν λειτουργεί σε ζωντανές μεταδόσεις." +• Δε λειτουργεί σε ζωντανές μεταδόσεις." Οι προσαρμοσμένες ενέργειες είναι απενεργοποιημένες στο αναδυόμενο μενού. Προσαρμοσμένες ενέργειες στη γραμμή εργαλείων "Οι προσαρμοσμένες ενέργειες είναι ενεργοποιημένες στη γραμμή εργαλείων. @@ -1467,7 +1538,7 @@ Playlists Περιορισμοί: • Αυτή η ρύθμιση ενεργοποιεί όχι μόνο τις χρονοσφραγίδες, αλλά επιτρέπει την απόκρυψη των στοιχείων UI πατώντας στο φόντο της οθόνης αναπαραγωγής. -• Δεδομένου ότι αυτή είναι μια λειτουργία της Google που βρίσκεται ακόμη στο στάδιο ανάπτυξης, η διεπαφή μπορεί να χαλάσει." +• Δεδομένου ότι αυτή είναι μια λειτουργία της Google που βρίσκεται ακόμη στο στάδιο ανάπτυξης, η διάταξη μπορεί να χαλάσει." Οι χρονοσφραγίδες είναι απενεργοποιημένες. Ενέργεια πατήματος χρονοσφραγίδας Πατήστε παρατεταμένα την χρονοσφραγίδα για να αλλάξει η κατάσταση επανάληψης των Shorts. @@ -1944,7 +2015,8 @@ Playlists • Η λειτουργία «Απενεργοποίηση υποχρεωτικών κομματιών ήχου» δεν είναι διαθέσιμη. • Τα βίντεο για παιδιά ενδέχεται να μην αναπαράγονται αν είστε αποσυνδεμένοι ή σε λειτουργία ανώνυμης περιήγησης." • Ενδέχεται να υπάρχουν προβλήματα αναπαραγωγής (Απαιτείται αναγνωριστικό PoToken). - "• Οι ταινίες ή τα επί πληρωμή βίντεο ενδέχεται να μην αναπαράγονται. + "• Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη. +• Οι ταινίες ή τα επί πληρωμή βίντεο ενδέχεται να μην αναπαράγονται. • Τα βίντεο για παιδιά ενδέχεται να μην αναπαράγονται αν είστε αποσυνδεμένοι ή σε λειτουργία ανώνυμης περιήγησης." Εξαναγκασμός iOS AVC (H.264) Ο κωδικοποιητής βίντεο έχει οριστεί υποχρεωτικά σε AVC (H.264). diff --git a/patches/src/main/resources/youtube/translations/es-rES/strings.xml b/patches/src/main/resources/youtube/translations/es-rES/strings.xml index 059f0331f..4cff24e5b 100644 --- a/patches/src/main/resources/youtube/translations/es-rES/strings.xml +++ b/patches/src/main/resources/youtube/translations/es-rES/strings.xml @@ -19,59 +19,150 @@ "%1$s no está instalado. Por favor, descarga %2$s desde el sitio web." %s no está instalado. Por favor, instálalo. + Añadir a la cola + Añadir a la cola y abrir la cola + Añadir a la cola y reproducir vídeo + Descargador externo + Abrir cola + Cola + Eliminar de la cola + Eliminar de la cola y abrir la cola + Eliminar cola + Guardar cola + "En lugar de abrir un descargador externo, abre el diálogo del gestor de colas. + +También puedes abrir el gestor de colas manteniendo presionado el botón Atrás en la barra de navegación. + +Esta función aún está en desarrollo, por lo que es posible que la mayoría de las funciones no funcionen. + +Por favor, utilízala solo con fines de depuración." + Es necesario iniciar sesión + Gestor de colas no disponible (%s). + No se pudo identificar la lista + La cola está vacía + No se pudo identificar el vídeo + Error al añadir el vídeo. + Error al crear la cola. + Error al eliminar la cola. + Error al eliminar el vídeo. + Error al guardar la cola. + Vídeo añadido correctamente. + Cola creada correctamente. + Cola eliminada correctamente. + Vídeo eliminado correctamente. + Cola guardada correctamente en \'%s\'. Idioma de RVX Idioma de la app - Árabe - Azerbaiyano - Búlgaro - Bengalí - Catalán - Checo - Danés - Alemán - Griego - Inglés - Español - Estoniano - Persa - Finlandés - Francés - Guyaratí - Hindi - Croata - Húngaro - Indonesio - Italiano - Japonés - Kazajo - Coreano - Lituano - Letón - Macedonio - Mongol - Maratí - Malayo - Birmano - Holandés - Odia - Punyabí - Polaco - Portugués - Rumano - Ruso - Eslovaco - Esloveno - Serbio - Sueco - Suajili - Tamil - Télugu - Tailandés - Turco - Ucraniano - Urdu - Vietnamita - Chino + "Amárico +አማርኛ" + "Árabe +العربية" + "Azerbaiyano +Azərbaycan" + "Bielorruso +беларуская" + "Búlgaro +Български" + "Bengalí +বাংলা" + "Catalán +Català" + "Checo +Čeština" + "Danés +Dansk" + "Alemán +Deutsch" + "Griego +Ελληνικά" + "Inglés +English" + "Español +Español" + "Estonio +Eesti" + "Persa +فارسی" + "Finlandés +Suomi" + "Francés +Français" + "Gujarati +ગુજરાતી" + "Hebreo +עברי" + "Hindi +हिन्दी" + "Croata +Hrvatski" + "Húngaro +Magyar" + "Indonesio +Indonesia" + "Italiano +Italiano" + "Japonés +日本語" + "Kazajo +Қазақ тілі" + "Coreano +한국어" + "Lituano +Lietuvių" + "Letón +Latviešu" + "Macedonio +Македонски" + "Mongol +Монгол" + "Maratí +मराठी" + "Malayo +Melayu" + "Birmano +ဗမာ" + "Neerlandés +Nederlands" + "Odia +ଓଡ଼ିଆ" + "Punjabi +ਪੰਜਾਬੀ" + "Polaco +Polski" + "Portugués +Português" + "Rumano +Română" + "Ruso +Русский" + "Eslovaco +Slovenčina" + "Albanés +Shqip" + "Esloveno +Slovenščina" + "Serbio +Српски" + "Sueco +Svenska" + "Suajili +Kiswahili" + "Tamil +தமிழ்" + "Télugu +తెలుగు" + "Tailandés +ไทย" + "Turco +Türkçe" + "Ucraniano +Українська" + "Urdu +اردو" + "Vietnamita +Tiếng Việt" + "Chino +中文" Anuncios Ocultar banner de tienda de pantalla final @@ -425,6 +516,19 @@ Diseño para automóvil • Los Shorts se abren en el reproductor normal. • El feed está organizado por temas y canales. • La descripción del vídeo no se puede abrir cuando está desactivado \"Falsificar datos de transmisión\"." + Desactivar actualizaciones de diseño + El servidor no actualizará el diseño. + El servidor actualizará el diseño. + "El diseño de la aplicación vuelve al diseño que estaba usando cuando se instaló por primera vez. + +Es posible que algunos diseños del lado del servidor no se reviertan. + +Los cambios incluyen: +• Los componentes del menú desplegable del reproductor (o la configuración relacionada) pueden no funcionar. +• Los números rodantes no están animados. +• Se utiliza la pestaña Biblioteca. +• La sección Música de la descripción del vídeo puede no funcionar. +• El botón de cambio de cuenta puede no aparecer en la pestaña Biblioteca. Utilice la función 'Activar barra de búsqueda ancha en la pestaña Tú'." Falsificar versión de la app Versión falsificada Versión no falsificada @@ -442,8 +546,10 @@ Si se desactiva más tarde, se recomienda borrar los datos de la aplicación par 18.33.40 - Restaura la antigua barra de acción de Shorts 18.38.45 - Restaura el antiguo comportamiento de la calidad predeterminada de vídeo 18.48.39 - Desactiva la actualización en tiempo real de las visualizaciones y los me gusta + 19.01.34 - Desactivar la interacción con la descripción del vídeo 19.26.42 - Desactivar icono de Cairo en la barra de navegación y herramientas 19.33.37 - Restaurar el antiguo panel desplegable de velocidad de reproducción + Versión de aplicación falsa no válida: %s. Menú de cuenta Ocultar o mostrar elementos en el menú de la cuenta y la pestaña Tú. @@ -479,6 +585,9 @@ Algunos componentes pueden no estar ocultos." Reemplazar botón de descarga de vídeo El botón nativo de descarga de vídeo abre tu descargador externo. El botón nativo de descarga de vídeo abre el descargador nativo de la aplicación. + Gestor de colas + El botón nativo de descarga de vídeo abre el gestor de colas. + El botón nativo de descarga de vídeo abre tu descargador externo. Nombre del paquete del descargador de listas de reproducción Nombre del paquete de tu aplicación de descargas externas instalada, como YTDLnis. @@ -532,7 +641,6 @@ Si este ajuste no surte efecto, prueba a cambiar al modo incógnito." Activar barra de navegación translúcida La barra de navegación es translúcida. La barra de navegación es opaca. - En ciertas versiones de YouTube, este ajuste puede hacer transparente la barra de navegación del sistema o el diseño puede romperse en modo PIP. Ocultar barra de navegación La barra de navegación está oculta. La barra de navegación está visible. @@ -1111,6 +1219,8 @@ Mantén pulsado para copiar la marca de tiempo del vídeo." Pulsa para silenciar el volumen del vídeo actual. Pulsa de nuevo para reactivar el sonido. Mostrar botón de descarga externa Pulsa para iniciar el descargador externo. + Gestor de colas + En lugar de iniciar un descargador externo, abre el gestor de colas. Mostrar botón de diálogo de velocidad "Pulsa para abrir el diálogo de velocidad. Mantén pulsado para establecer la velocidad de reproducción en 1.0x." diff --git a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml index ffd512f00..128b6f4c9 100644 --- a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml +++ b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml @@ -21,57 +21,116 @@ Veuillez télécharger %2$s à partir du site web." %s n\'est pas installé. Veuillez l’installer. Langue RVX Langue de l\'application - Arabe - Azerbaïdjan - Bulgare - Bengali - Catalan - Tchèque - Danois - Allemand - Grec - Anglais - Espagnol - Estonien - Persan - Finlandais - Français - Gujarati - Hindou - Croate - Hongrois - Indonésien - Italien - Japonais - Kazakh - Coréen - Lithuanien - Letton - Macédonien - Mongol - Marathi - Malaisien - Birman - Néerlandais - Odia - Pendjabi - Polonais - Portugais - Roumain - Russe - Slovaque - Slovène - Serbe - Suédois - Swahili - Tamoul - Télougou - Thaïlandais - Turc - Ukrainien - Ourdou - Vietnamien - Chinois + "Amharique +አማርኛ" + "Arabe +العربية" + "Azerbaïdjanais +Azərbaycan" + "Biélorusse +беларуская" + "Bulgare +Български" + "Bengali +বাংলা" + "Catalan +Català" + "Tchèque +Čeština" + "Danois +Dansk" + "Allemand +Deutsch" + "Grec +Ελληνικά" + "Anglais +English" + "Espagnol +Español" + "Estonien +Eesti" + "Persan +فارسی" + "Finnois +Suomi" + "Français +Français" + "Gujarati +ગુજરાતી" + "Hébreu +עברי" + "Hindi +हिन्दी" + "Croate +Hrvatski" + "Hongrois +Magyar" + "Indonésien +Indonesia" + "Italien +Italiano" + "Japonais +日本語" + "Kazakh +Қазақ тілі" + "Coréen +한국어" + "Lituanien +Lietuvių" + "Letton +Latviešu" + "Macédonien +Македонски" + "Mongol +Монгол" + "Marathi +मराठी" + "Malais +Melayu" + "Birman +ဗမာ" + "Néerlandais +Nederlands" + "Odia +ଓଡ଼ିଆ" + "Panjabi +ਪੰਜਾਬੀ" + "Polonais +Polski" + "Portugais +Português" + "Roumain +Română" + "Russe +Română" + "Slovaque +Slovenčina" + "Albanais +Shqip" + "Slovène +Slovenščina" + "Serbe +Српски" + "Suédois +Svenska" + "Swahili +Kiswahili" + "Tamoul +தமிழ்" + "Télougou +తెలుగు" + "Siamois +ไทย" + "Turc +Türkçe" + "Ukrainien +Українська" + "Ourdou +اردو" + "Vietnamien +Tiếng Việt" + "Chinois +中文" Publicités Masquer la bannière de boutique de l\'écran de fin @@ -414,6 +473,22 @@ Cela ne contourne pas la restriction d'âge, mais le confirme automatiquement."< Limitation : Lorsque la diffusion en direct de Shorts est ouverte dans le lecteur normal en raison du paramètre \"Ouvrir Shorts dans le lecteur normal\", la chaîne ne s'ouvre pas." La diffusion en direct s\'ouvre lorsque vous cliquez sur le cercle \'En direct\'. + Format de mise en page + Par défaut + Téléphone + Téléphone (Max 480 dpi) + Tablette + Tablette (Min 600 dpi) + Automobile + "Les changements sont les suivants : + +Mise en page tablettes +- Les messages de la communauté sont masqués. + +Mise en page automobile +- Les Shorts s'ouvrent dans le lecteur normal. +- Le flux est organisé par thèmes et par chaînes. +- La description de la vidéo ne peut pas être ouverte lorsque l'option « Falsifier les données de diffusion en direct » est désactivée." Falsifier la version de l\'app Version falsifiée Version non falsifiée @@ -431,8 +506,10 @@ Si désactivé ultérieurement, il est recommandé d'effacer les données de l'a 18.33.40 - Restaure l\'ancienne barre d\'action Shorts 18.38.45 - Restaure l\'ancien menu de qualité vidéo 18.48.39 - Désactive les \'vues\' et \'j\'aime\' en temps réel + 19.01.34 - Désactiver l\'interaction des descriptions vidéo 19.26.42 - Désactiver l\'icône Cairo de la barre de navigation et d\'outils 19.33.37 - Restaure l\'ancien menu déroulant de vitesse de lecture du lecteur + Version de falsification de l\'app invalide : %s. Menu du compte Masque ou affiche des éléments dans le menu du compte et dans l\'onglet \'Vous\'. @@ -521,7 +598,6 @@ Si ce paramètre ne fait pas effet, essayer de passer en mode Incognito."Activer la barre de navigation translucide La barre de navigation est translucide. La barre de navigation est opaque. - Dans certaines versions de YouTube, ce paramètre peut rendre la barre de navigation du système transparente ou la disposition peut être cassée en mode PIP. Masquer la barre de navigation La barre de navigation est masqué. La barre de navigation est affichée. @@ -1922,6 +1998,14 @@ Cliquez sur le bouton Continuer et autorisez les modifications d'optimisations." "Activer ceci peut améliorer la durée de vie de la batterie et résoudre les problèmes de lecture saccadée. AVC a une résolution maximale de 1080p, le codec audio Opus n'est pas disponible et la lecture vidéo utilisera plus de données internet que VP9 ou AV1." + Passer le chiffrement de réponse Onesie + "Passer le chiffrement de réponse Onesie + +• Résout un nouveau type de problème de lecture que certains utilisateurs rencontrent. +• Le codec AV1 peut ne pas être disponible." + "Ne pas passer le chiffrement de réponse Onesie + +• Certains utilisateurs peuvent rencontrer un nouveau type de problème de lecture." Afficher dans \'Statistiques pour les nerds\' Le client utilisé pour récupérer les données de lecture en direct est affiché dans \'Statistiques pour les nerds\'. Le client utilisé pour récupérer les données de lecture en direct est masqué dans \'Statistiques pour les nerds\'. diff --git a/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml b/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml index e7c37a19e..bf38e1057 100644 --- a/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml +++ b/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml @@ -21,57 +21,6 @@ Töltsd le a(z) %2$s weboldalról." %s nincs telepítve. Kérlek telepítsd. RVX nyelve Alkalmazás nyelve - Arab - Azerbajdzsáni - Bolgár - Bengáli - Katalán - Cseh - Dán - Német - Görög - Angol - Spanyol - Észt - Perzsa - Finn - Francia - Gudzsaráti - Hindi - Horvát - Magyar - Indonéz - Olasz - Japán - Kazah - Koreai - Litván - Lett - Macedón - Mongol - Marathi - Maláj - Burmai - Holland - Odia - Pandzsábi - Lengyel - Portugál - Román - Orosz - Szlovák - Szlovén - Szerb - Svéd - Szuahéli - Tamil - Telugu - Thai - Török - Ukrán - Urdu - Vietnámi - Kínai Hirdetések Záróképernyő üzlet banner elrejtése @@ -412,7 +361,22 @@ Ez nem kerüli meg a korhatárt. Csak automatikusan fogadja el." Élő közvetítés ikon kattintás műveletének módosítása "A csatorna nyílik meg az ikonra kattintva." Az élő közvetítés nyílik meg az ikonra kattintva. + Elrendezési alaktényező Alapértelmezett + Telefon + Telefon (max 480 dpi) + Tablet + Tablet (min 600 dpi) + Autóipari + "A változások a következők: + +Táblagép elrendezés +• A közösségi bejegyzések el vannak rejtve. + +Autóipari elrendezés +• A shortok a normál lejátszóban nyílnak meg. +• A hírfolyam témák és csatornák szerint van rendezve. +• A videó leírása nem nyitható meg, ha az 'Adatfolyam hamisítása' ki van kapcsolva." Alkalmazásverzió hamisítása Verzió hamisítás Verzió nincs hamisítva @@ -520,7 +484,6 @@ Ha ez a beállítás nem működik, váltson inkognító módra." Átlátszó navigációs sáv engedélyezése A navigációs sáv átlátszó. A navigációs sáv nem átlátszó. - Egyes YouTube verziókban ez a beállítás átlátszóvá teheti a rendszer navigációs sávját, vagy kép a képben módban az elrendezés széteshet. Navigációs sáv elrejtése A navigációs sáv el van rejtve. A navigációs sáv látható. @@ -1912,7 +1875,8 @@ Kattintson a folytatás gombra és kapcsolja ki az akkumulátor optimalizáláso • A kényszerített automatikus hangsávok letiltása nem elérhető. • Előfordulhat, hogy a gyerekeknek szánt tartalmat nem lehet lejátszani, ha ki van jelentkezve vagy inkognitó módban van." • Lejátszási problémák lehetnek (PoToken szükséges). - "• Előfordulhat, hogy a filmeket vagy a fizetős videókat nem lehet lejátszani. + "• A stabil hangerő nem érhető el. +• Előfordulhat, hogy a filmeket vagy a fizetős videókat nem lehet lejátszani. • Előfordulhat, hogy a gyerekeknek szánt tartalmat nem lehet lejátszani, ha ki van jelentkezve vagy inkognitó módban van." Kényszerített iOS AVC (H.264) A kényszerített videó kodek az AVC (H.264). @@ -1920,6 +1884,14 @@ Kattintson a folytatás gombra és kapcsolja ki az akkumulátor optimalizáláso "Ennek engedélyezése javíthatja az akkumulátor élettartamát és javíthatja a lejátszás akadozását. Az AVC maximális felbontása 1080p, az Opus hangkodek nem érhető el, és a videolejátszás több adatforgalmat igényel, mint a VP9 vagy az AV1." + Onesie válasz titkosításának kihagyása + "A Onesie válasz titkosításának kihagyása. + +• Javítja az egyes felhasználók által tapasztalt új típusú lejátszási problémát. +• Előfordulhat, hogy az AV1 kodek nem elérhető." + "Ne hagyja ki a Onesie válasz titkosítását. + +• Egyes felhasználók új típusú lejátszási problémákat tapasztalhatnak." Megjelenítés a statisztikában kockáknak Az adatfolyam lekérésére használt kliens a statisztikában kockáknak látható. Az adatfolyam lekérésére használt kliens a statisztikában kockáknak nem látható. diff --git a/patches/src/main/resources/youtube/translations/id-rID/strings.xml b/patches/src/main/resources/youtube/translations/id-rID/strings.xml new file mode 100644 index 000000000..f8cda0f09 --- /dev/null +++ b/patches/src/main/resources/youtube/translations/id-rID/strings.xml @@ -0,0 +1,400 @@ + + + + Nyalakan kontrol aksesibilitas untuk pemutar video? + Kontrol anda telah dimodifikasi karena layanan aksesibilitas menyala. + + RVX + Cari %s + Atur ulang ke nilai default. + Fitur Experimental + Apakah Anda ingin melanjutkan? + Mulai ulang aplikasi untuk memuat tata ruang dengan normal + Perbarui tampilan dan mulai ulang + Biasa + Nama paket pengunduh video + Nama paket aplikasi pengunduh eksternal yang dipasang, misalnya NewPipe atau YTDLnis. + Pengunduh eksternal + Peringatan + "%1$s tidak terpasang +Silahkan unduh %2$s dari situs web." + %s tidak terpasang. Silakan pasang. + Bahasa RVX + Bahasa Aplikasi + + Iklan + Sembunyikan spanduk toko di layar akhir + Spanduk toko disembunyikan. + Spanduk toko ditampilkan. + Sembunyikan iklan yang memenuhi layar + Iklan ysng memenuhi layar disembunyikan. + Iklan yang memenuhi layar ditampilkan. + Iklan layar penuh ditutup. + Sembunyikan iklan umum + Iklan umum disembunyikan. + Iklan umum ditunjukkan. + Sembunyikan rak dagangan + Rak dagangan disembunyikan. + Rak dagangan ditunjukkan. + Sembunyikan label promosi berbayar + Label promosi berbayar disembunyikan. + Label promosi berbayar dotunjukkan. + Sembunyikan rak belanja pemutar + Rak belanja disembunyikan. + Rak belanja ditampilkan. + Sembunyikan spanduk peringatan promosi + Spanduk peringatan promosi disembunyikan. + Spanduk peringatan promosi ditampilkan. + Sembunyikan kartu yang disponsori sendiri + Kartu yang disponsori sendiri disembunyikan. + Kartu yang disponsori sendiri ditunjukkan. + Sembunyikan iklan video + Iklan video disembunyikan. + Iklan video ditunjukkan. + Sembunyikan tampilan spanduk produk + Tampilan spanduk produk disembunyikan. + Tampilan spanduk produk ditunjukkan. + Sembunyikan hasil pencarian web + Hasil pencarian web ditunjukkan. + Hasil pencarian web ditunjukkan. + Sembunyikan promosi YouTube Premium + Promosi YouTube Premium disembunyikan. + Promosi YouTube Premium ditunjukkan. + + Thumbnail alternatif + Tab beranda + Daftar putar pemutar, rekomendasi + Hasil pencarian + Tab langganan + Tab anda + Thumbnail asli + DeArrow & Thumbnail asli + DeArrow & Tangkapan diam + Tangkapan diam + DeArrow + "DeArrow menyediakan gambar mini yang bersumber dari banyak orang untuk video YouTube. Thumbnail ini sering kali lebih relevan dibandingkan thumbnail yang disediakan oleh YouTube. + +Jika diaktifkan, URL video akan dikirim ke server API dan tidak ada data lain yang dikirim. Jika video tidak memiliki thumbnail DeArrow, maka gambar asli atau gambar diam akan ditampilkan. + +Ketuk di sini untuk mempelajari lebih lanjut tentang DeArrow." + Tunjukkan peringatan jika API tidak tersedia + Peringatan ditunjukkan bila DeArrow tidak tersedia. + Peringatan tidak ditunjukkan bila DeArrow tidak tersedia. + Titik akhir API DeArrow + URL titik akhir cache thumbnail DeArrow. + URL APIK DeArrow tidak valid. + Tangkapan video diam + Tangkapan diam diambil dari awal, tengah, akhir setiap video. Gambar ini dibuat di YouTube dan tidak ada API eksternal yang digunakan. + Gunakan tangkapan diam cepat + Menggunakan tangkapan diam kualitas sedang. Thumbnail akan dimuat lebih cepat, tetapi siaran langsung, video yang belum dirilis, atau video yang sangat lama mungkin menampilkan thumbnail kosong. + Menggunakan tangkapan diam berkualitas tinggi. + Waktu video untuk mengambil gambar diam + Awal video + Tengah video + Akhir video + DeArrow sementara ini tidak tersedia (kode status: %s) + DeArrow sementara tidak tersedia. + + Pembatasan wilayah gambar + Abaikan pembatasan wilayah gambar + Menggunakan sumber gambar yt4.ggpht.com. + Menggunakan sumber gambar asli\n\nMengaktifkan ini akan memperbaiki gambar hilang yang diblokir di daerah tertentu. + + Feed + Sembunyikan kartu album + Kartu album disembunyikan. + Kartu album ditampilkan. + Sembunyikan tombol Teks + Tombol teks disembunyikan. + Tombol teks ditampilkan. + Sembunyikan rak carousel + "Rak carousel disembunyikan, seperti: +• Berita terbaru +• Lanjutkan menonton +• Jelajahi lebih banyak saluran +• Dengarkan lagi +• Belanja +• Tonton lagi" + Rak carousel ditampilkan. + Sembunyikan kepingan rak + Kepingan rak disembunyikan. + Kepingan rak ditampilkan. + Sembunyikan kepingan yang dapat diperluas di bawah video + Kepingan yang dapat diperluas disembunyikan. + Kepingan yang dapat diperluas ditampilkan. + Sembunyikan rak yang dapat diperluas + Rak yang dapat diperluas disembunyikan. + Rak yang dapat diperluas ditampilkan. + Sembunyikan tombol mengambang + Tombol mengambang disembunyikan. + Tombol mengambang ditampilkan. + Sembunyikan rak gambar + Rak gambar disembunyikan. + Rak gambar ditamoilkan. + Sembunyikan postingan terbaru + Postingan terbaru disembunyikan. + Postingan terbaru ditampilkan. + Sembunyikan tombol video terbaru + Tombol video terbaru disembunyikan. + Tombol video terbaru ditampilkan. + Sembunyikan daftar putar campuran + Daftar putar campuran disembunyikan. + Daftar putar campuran ditampilkan. + Sembunyikan rak film + Rak film disembunyikan. + Rak film ditampilkan. + Sembunyikan tombol Beri tahu saya + Tombol \'Ingatkan saya\' disembunyikan. + Tombol \'Ingatkan saya\' ditunjukkan. + Sembunyikan yang dapat diputar + Yang dapat diputar disembunyikan. + Yang dapat diputar ditunjukkan. + Sembunyikan kolom pencarian + Kolom pencarian disembunyikan. + Kolom pencarian disembunyikan. + Sembunyikan tombol \'Tunjukkan lebih banyak\' + Tombol \'Tunjukkan lebih banyak disembunyikan. + Tombol \'Tunjukkan lebih banyak\' ditunjukkan. + Sembunyikan carousel langganan + Carousel langganan disembunyikan. + Carousel langganan ditampilkan. + Sembunyikan survei + Survey disembunyikan. + Survey ditampilkan. + Sembunyikan rak tiket + Rak tiket disembunyikan. + Rak tiket ditunjukkan. + + Bilah kategori + Sembunyikan atau tampilkan bilah kategori di feed, pencarian, dan video terkait. + Sembunyikan di halaman utama + Disembunyikan di halaman utama. + Ditunjukkan di halaman utama. + Sembunyikan di video terkait + Disembunyikan di video terkait. + Ditampilkan di video terkait. + Sembunyikan di hasil pencarian + Disembunyikan di hasil pencarian. + Ditampilkan di hasil pencarian. + + Profil saluran + Sembunyikan atau tampilkan komponen dalam profil saluran. + Aktifkan bilah saring saluran + Bilah saring saluran diaktikan. + Bilah saring saluran dinonaktifkan. + Bilah saring saluran + Daftar nama bilah saluran yang akan disaring, dipisahkan oleh baris baru. + "Shorts +Daftar putar +Toko" + Sembunyikan rak anggota channel + Rak anggota channel disembunyikan. + Rak anggota channel ditampilkan. + Sembunyikan tautan profil saluran + Tautan di bagian atas profil saluran disembunyikan. + Tautan di bagian atas profil saluran ditampilkan. + Sembunyikan rak Untuk Anda + Rak Untuk Anda disembunyikan. + Rak Untuk Anda ditampilkan. + Sembunyikan tombol Kunjungi toko + Tombol kunjungi toko disembunyikan. + Tombol kunjungi toko ditampilkan. + + Postingan Komunitas + Sembunyikan atau tampilkan postingan komunitas di feed dan saluran. + Sembunyikan di saluran + Disembunyikan di saluran. + Ditampilkan di saluran. + Sembunyikan di feed beranda dan video terkait + Disembunyikan di feed beranda dan video terkait. + Ditampilkan di feed beranda dan video terkait. + Sembunyikan di feed langganan + Disembunyikan di feed langganan. + Ditampilkan di feed langganan. + + Menu flyout + Sembunyikan atau tampilkan komponen menu flyout di feed. + Aktifkan penyaring menu feed flyout + Filter menu feed flyout diaktifkan. + Filter menu feed flyout dinonaktifkan. + Jenis penyaring menu feed flyout + Saring jika berisi.<br><br>Untuk menyembunyikan menu <b>\'Putar berikutnya dalam antrean\'</b> Anda dapat menggunakan <b>\'Putar berikutnya\'</b> atau <b>\'dalam antrean\'</b> sebagai kata kunci. + Saring jika cocok.<br><br>Untuk menyembunyikan menu <b>\'Putar berikutnya dalam antrean\'</b> Anda hanya dapat menggunakan <b>\'Putar berikutnya dalam antrean\'</b> sebagai kata kunci. + Menu penyaring feed flyout + Daftar nama menu flyout yang disaring, dipisahkan dengan baris baru. + + Penyaring video + Sembunyikan video berdasarkan kata kunci atau penayangan. + + Penyaring kata kunci + Sembunyikan komentar berdasarkan kata kunci + Komentar disaring. + Komentar tidak disaring. + Sembunyikan video di beranda berdasarkan kata kunci + Video di feed beranda disaring. + Video di feed beranda tidak disaring. + Sembunyikan hasil pencarian berdasarkan kata kunci + Hasil pencarian disaring. + Hasil pencarian tidak disaring. + Sembunyikan video langganan berdasarkan kata kunci + Video di feed langganan disaring. + Video dalam feed langganan tidak difilter. + Kata kunci yang ingin disembunyikan + "Kata kunci dan frasa yang akan disembunyikan, dipisahkan dengan baris baru. + +Kata kunci dapat berupa nama saluran atau teks apa pun yang ditampilkan dalam judul video. + +Kata dengan huruf besar di tengah harus dimasukkan dengan huruf kecil (misalnya: iPhone, TikTok, LeBlanc)." + Tentang penyaringan kata kunci + "Beranda / Langganan / Hasil pencarian disaring untuk menyembunyikan konten yang cocok dengan frasa kata kunci. + +Keterbatasan: +• Shorts tidak dapat disembunyikan berdasarkan nama saluran. +• Beberapa komponen UI mungkin tidak dapat disembunyikan. +• Pencarian kata kunci mungkin tidak menampilkan hasil." + Cocokkan seluruh kata + Melingkupi kata kunci/frasa dengan tanda kutip ganda akan mencegah pencocokan sebagian judul video dan nama saluran.<br><br>Sebagai contoh,<br><b>\"ai\"</b> akan menyembunyikan video: <b>Bagaimana cara kerja AI?</b><br>namun tidak akan menyembunyikan: <b>Apa yang dimaksud Jakarta Fair?</b> + Tidak dapat menggunakan kata kunci: %s. + Tambahkan tanda kutip untuk menggunakan kata kunci: %s. + Kata kunci punya keterangan yang bertentangan: %s. + Kata kunci terlalu pendek & butuh tanda kutip: %s. + Kata kunci akan menyembunyikan semua video: %s. + + Video yang direkomendasikan + Sembunyikan video dengan penayangan rendah + "Sembunyikan video dengan kurang dari 1.000 penayangan dari feed beranda yang telah diunggah dari saluran yang tidak berlangganan. + +Filter ini mungkin tidak lagi berfungsi, gunakan 'Filter jumlah penayangan' sebagai gantinya." + Sembunyikan video yang direkomendasikan + "Menyembunyikan video yang direkomendasikan berikut ini: + +• Video dengan frasa seperti 'Orang-orang juga menonton' di bawahnya." + + Filter jumlah penayangan + Sembunyikan video beranda berdasarkan penayangan + Video di feed beranda difilter. + Video di feed beranda tidak difilter. + Sembunyikan hasil pencarian berdasarkan penayangan + Hasil pencarian difilter. + Hasil pencarian tidak difilter. + Sembunyikan video langganan berdasarkan penayangan + Video di feed langganan disaring. + Video dalam feed langganan tidak disaring. + Lebih besar dari penayangan + Video dengan jumlah penayangan yang lebih besar dari angka ini akan disembunyikan. + Kurang dari penayangan + Video dengan jumlah penayangan yang lebih kurang dari angka ini akan disembunyikan. + Lihat kunci + Tentukan templat bahasa Anda untuk jumlah tampilan yang ditampilkan di bawah setiap video di antarmuka pengguna. Setiap kunci (huruf/kata dalam bahasa Anda) -> nilai (yang berarti kunci) harus berada di baris baru. Kunci diletakkan sebelum tanda \"->\". Jika Anda mengubah bahasa aplikasi atau sistem, Anda perlu mengatur ulang pengaturan ini.\n\nContoh:\nInggris: 10K tayangan = K -> 1000, tayangan -> tayangan\nSpanyol: 10 K tayangan = K -> 1000, tayangan -> tayangan + K -> 1 000\nM -> 1 000 000\nB -> 1 000 000 000\ntayangan -> tayangan + Tentang penyaringan jumlah tayangan + "Beranda / Langganan / Hasil pencarian disaring untuk menyembunyikan video dengan jumlah penayangan kurang atau lebih besar dari jumlah yang ditentukan. + +Keterbatasan: +• Shorts tidak dapat disembunyikan. +• Video dengan 0 penayangan tidak disaring." + Sembunyikan video terkait + Video terkait disembunyikan. + Video terkait ditampilkan. + "Pengaturan ini membatasi jumlah maksimum tata letak yang dapat dimuat pada layar pemutar. + +Jika tata letak layar pemutar berubah karena perubahan di sisi server, tata letak yang tidak diinginkan mungkin disembunyikan di layar pemutar." + Offset + + Umum + Ganti halaman awal + Default + Semua langganan + Jelajahi saluran + Kursus / Pembelajaran + Jelajahi + Busana & Kecantikan + Gaming + Riwayat + Pustaka + Video disukai + Siaran Langsung + Film + Musik + Berita + Pemberitahuan + Daftar Putar + Podcast + Cari + Belanja + Shorts + Olahraga + Langganan + Sedang Populer + Realitas Virtual + Tonton nanti + Klip Anda + Ganti jenis halaman awal + "Halaman awal selalu berubah. + +Keterbatasan: Tombol Kembali pada bilah alat mungkin tidak berfungsi." + Halaman awal berubah hanya sekali. + Nonaktifkan trek audio otomatis yang dipaksakan + Trek audio otomatis yang dipaksakan dinonaktifkan. + Trek audio otomatis yang dipaksakan diaktifkan. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/patches/src/main/resources/youtube/translations/in/strings.xml b/patches/src/main/resources/youtube/translations/in/strings.xml new file mode 100644 index 000000000..f8cda0f09 --- /dev/null +++ b/patches/src/main/resources/youtube/translations/in/strings.xml @@ -0,0 +1,400 @@ + + + + Nyalakan kontrol aksesibilitas untuk pemutar video? + Kontrol anda telah dimodifikasi karena layanan aksesibilitas menyala. + + RVX + Cari %s + Atur ulang ke nilai default. + Fitur Experimental + Apakah Anda ingin melanjutkan? + Mulai ulang aplikasi untuk memuat tata ruang dengan normal + Perbarui tampilan dan mulai ulang + Biasa + Nama paket pengunduh video + Nama paket aplikasi pengunduh eksternal yang dipasang, misalnya NewPipe atau YTDLnis. + Pengunduh eksternal + Peringatan + "%1$s tidak terpasang +Silahkan unduh %2$s dari situs web." + %s tidak terpasang. Silakan pasang. + Bahasa RVX + Bahasa Aplikasi + + Iklan + Sembunyikan spanduk toko di layar akhir + Spanduk toko disembunyikan. + Spanduk toko ditampilkan. + Sembunyikan iklan yang memenuhi layar + Iklan ysng memenuhi layar disembunyikan. + Iklan yang memenuhi layar ditampilkan. + Iklan layar penuh ditutup. + Sembunyikan iklan umum + Iklan umum disembunyikan. + Iklan umum ditunjukkan. + Sembunyikan rak dagangan + Rak dagangan disembunyikan. + Rak dagangan ditunjukkan. + Sembunyikan label promosi berbayar + Label promosi berbayar disembunyikan. + Label promosi berbayar dotunjukkan. + Sembunyikan rak belanja pemutar + Rak belanja disembunyikan. + Rak belanja ditampilkan. + Sembunyikan spanduk peringatan promosi + Spanduk peringatan promosi disembunyikan. + Spanduk peringatan promosi ditampilkan. + Sembunyikan kartu yang disponsori sendiri + Kartu yang disponsori sendiri disembunyikan. + Kartu yang disponsori sendiri ditunjukkan. + Sembunyikan iklan video + Iklan video disembunyikan. + Iklan video ditunjukkan. + Sembunyikan tampilan spanduk produk + Tampilan spanduk produk disembunyikan. + Tampilan spanduk produk ditunjukkan. + Sembunyikan hasil pencarian web + Hasil pencarian web ditunjukkan. + Hasil pencarian web ditunjukkan. + Sembunyikan promosi YouTube Premium + Promosi YouTube Premium disembunyikan. + Promosi YouTube Premium ditunjukkan. + + Thumbnail alternatif + Tab beranda + Daftar putar pemutar, rekomendasi + Hasil pencarian + Tab langganan + Tab anda + Thumbnail asli + DeArrow & Thumbnail asli + DeArrow & Tangkapan diam + Tangkapan diam + DeArrow + "DeArrow menyediakan gambar mini yang bersumber dari banyak orang untuk video YouTube. Thumbnail ini sering kali lebih relevan dibandingkan thumbnail yang disediakan oleh YouTube. + +Jika diaktifkan, URL video akan dikirim ke server API dan tidak ada data lain yang dikirim. Jika video tidak memiliki thumbnail DeArrow, maka gambar asli atau gambar diam akan ditampilkan. + +Ketuk di sini untuk mempelajari lebih lanjut tentang DeArrow." + Tunjukkan peringatan jika API tidak tersedia + Peringatan ditunjukkan bila DeArrow tidak tersedia. + Peringatan tidak ditunjukkan bila DeArrow tidak tersedia. + Titik akhir API DeArrow + URL titik akhir cache thumbnail DeArrow. + URL APIK DeArrow tidak valid. + Tangkapan video diam + Tangkapan diam diambil dari awal, tengah, akhir setiap video. Gambar ini dibuat di YouTube dan tidak ada API eksternal yang digunakan. + Gunakan tangkapan diam cepat + Menggunakan tangkapan diam kualitas sedang. Thumbnail akan dimuat lebih cepat, tetapi siaran langsung, video yang belum dirilis, atau video yang sangat lama mungkin menampilkan thumbnail kosong. + Menggunakan tangkapan diam berkualitas tinggi. + Waktu video untuk mengambil gambar diam + Awal video + Tengah video + Akhir video + DeArrow sementara ini tidak tersedia (kode status: %s) + DeArrow sementara tidak tersedia. + + Pembatasan wilayah gambar + Abaikan pembatasan wilayah gambar + Menggunakan sumber gambar yt4.ggpht.com. + Menggunakan sumber gambar asli\n\nMengaktifkan ini akan memperbaiki gambar hilang yang diblokir di daerah tertentu. + + Feed + Sembunyikan kartu album + Kartu album disembunyikan. + Kartu album ditampilkan. + Sembunyikan tombol Teks + Tombol teks disembunyikan. + Tombol teks ditampilkan. + Sembunyikan rak carousel + "Rak carousel disembunyikan, seperti: +• Berita terbaru +• Lanjutkan menonton +• Jelajahi lebih banyak saluran +• Dengarkan lagi +• Belanja +• Tonton lagi" + Rak carousel ditampilkan. + Sembunyikan kepingan rak + Kepingan rak disembunyikan. + Kepingan rak ditampilkan. + Sembunyikan kepingan yang dapat diperluas di bawah video + Kepingan yang dapat diperluas disembunyikan. + Kepingan yang dapat diperluas ditampilkan. + Sembunyikan rak yang dapat diperluas + Rak yang dapat diperluas disembunyikan. + Rak yang dapat diperluas ditampilkan. + Sembunyikan tombol mengambang + Tombol mengambang disembunyikan. + Tombol mengambang ditampilkan. + Sembunyikan rak gambar + Rak gambar disembunyikan. + Rak gambar ditamoilkan. + Sembunyikan postingan terbaru + Postingan terbaru disembunyikan. + Postingan terbaru ditampilkan. + Sembunyikan tombol video terbaru + Tombol video terbaru disembunyikan. + Tombol video terbaru ditampilkan. + Sembunyikan daftar putar campuran + Daftar putar campuran disembunyikan. + Daftar putar campuran ditampilkan. + Sembunyikan rak film + Rak film disembunyikan. + Rak film ditampilkan. + Sembunyikan tombol Beri tahu saya + Tombol \'Ingatkan saya\' disembunyikan. + Tombol \'Ingatkan saya\' ditunjukkan. + Sembunyikan yang dapat diputar + Yang dapat diputar disembunyikan. + Yang dapat diputar ditunjukkan. + Sembunyikan kolom pencarian + Kolom pencarian disembunyikan. + Kolom pencarian disembunyikan. + Sembunyikan tombol \'Tunjukkan lebih banyak\' + Tombol \'Tunjukkan lebih banyak disembunyikan. + Tombol \'Tunjukkan lebih banyak\' ditunjukkan. + Sembunyikan carousel langganan + Carousel langganan disembunyikan. + Carousel langganan ditampilkan. + Sembunyikan survei + Survey disembunyikan. + Survey ditampilkan. + Sembunyikan rak tiket + Rak tiket disembunyikan. + Rak tiket ditunjukkan. + + Bilah kategori + Sembunyikan atau tampilkan bilah kategori di feed, pencarian, dan video terkait. + Sembunyikan di halaman utama + Disembunyikan di halaman utama. + Ditunjukkan di halaman utama. + Sembunyikan di video terkait + Disembunyikan di video terkait. + Ditampilkan di video terkait. + Sembunyikan di hasil pencarian + Disembunyikan di hasil pencarian. + Ditampilkan di hasil pencarian. + + Profil saluran + Sembunyikan atau tampilkan komponen dalam profil saluran. + Aktifkan bilah saring saluran + Bilah saring saluran diaktikan. + Bilah saring saluran dinonaktifkan. + Bilah saring saluran + Daftar nama bilah saluran yang akan disaring, dipisahkan oleh baris baru. + "Shorts +Daftar putar +Toko" + Sembunyikan rak anggota channel + Rak anggota channel disembunyikan. + Rak anggota channel ditampilkan. + Sembunyikan tautan profil saluran + Tautan di bagian atas profil saluran disembunyikan. + Tautan di bagian atas profil saluran ditampilkan. + Sembunyikan rak Untuk Anda + Rak Untuk Anda disembunyikan. + Rak Untuk Anda ditampilkan. + Sembunyikan tombol Kunjungi toko + Tombol kunjungi toko disembunyikan. + Tombol kunjungi toko ditampilkan. + + Postingan Komunitas + Sembunyikan atau tampilkan postingan komunitas di feed dan saluran. + Sembunyikan di saluran + Disembunyikan di saluran. + Ditampilkan di saluran. + Sembunyikan di feed beranda dan video terkait + Disembunyikan di feed beranda dan video terkait. + Ditampilkan di feed beranda dan video terkait. + Sembunyikan di feed langganan + Disembunyikan di feed langganan. + Ditampilkan di feed langganan. + + Menu flyout + Sembunyikan atau tampilkan komponen menu flyout di feed. + Aktifkan penyaring menu feed flyout + Filter menu feed flyout diaktifkan. + Filter menu feed flyout dinonaktifkan. + Jenis penyaring menu feed flyout + Saring jika berisi.<br><br>Untuk menyembunyikan menu <b>\'Putar berikutnya dalam antrean\'</b> Anda dapat menggunakan <b>\'Putar berikutnya\'</b> atau <b>\'dalam antrean\'</b> sebagai kata kunci. + Saring jika cocok.<br><br>Untuk menyembunyikan menu <b>\'Putar berikutnya dalam antrean\'</b> Anda hanya dapat menggunakan <b>\'Putar berikutnya dalam antrean\'</b> sebagai kata kunci. + Menu penyaring feed flyout + Daftar nama menu flyout yang disaring, dipisahkan dengan baris baru. + + Penyaring video + Sembunyikan video berdasarkan kata kunci atau penayangan. + + Penyaring kata kunci + Sembunyikan komentar berdasarkan kata kunci + Komentar disaring. + Komentar tidak disaring. + Sembunyikan video di beranda berdasarkan kata kunci + Video di feed beranda disaring. + Video di feed beranda tidak disaring. + Sembunyikan hasil pencarian berdasarkan kata kunci + Hasil pencarian disaring. + Hasil pencarian tidak disaring. + Sembunyikan video langganan berdasarkan kata kunci + Video di feed langganan disaring. + Video dalam feed langganan tidak difilter. + Kata kunci yang ingin disembunyikan + "Kata kunci dan frasa yang akan disembunyikan, dipisahkan dengan baris baru. + +Kata kunci dapat berupa nama saluran atau teks apa pun yang ditampilkan dalam judul video. + +Kata dengan huruf besar di tengah harus dimasukkan dengan huruf kecil (misalnya: iPhone, TikTok, LeBlanc)." + Tentang penyaringan kata kunci + "Beranda / Langganan / Hasil pencarian disaring untuk menyembunyikan konten yang cocok dengan frasa kata kunci. + +Keterbatasan: +• Shorts tidak dapat disembunyikan berdasarkan nama saluran. +• Beberapa komponen UI mungkin tidak dapat disembunyikan. +• Pencarian kata kunci mungkin tidak menampilkan hasil." + Cocokkan seluruh kata + Melingkupi kata kunci/frasa dengan tanda kutip ganda akan mencegah pencocokan sebagian judul video dan nama saluran.<br><br>Sebagai contoh,<br><b>\"ai\"</b> akan menyembunyikan video: <b>Bagaimana cara kerja AI?</b><br>namun tidak akan menyembunyikan: <b>Apa yang dimaksud Jakarta Fair?</b> + Tidak dapat menggunakan kata kunci: %s. + Tambahkan tanda kutip untuk menggunakan kata kunci: %s. + Kata kunci punya keterangan yang bertentangan: %s. + Kata kunci terlalu pendek & butuh tanda kutip: %s. + Kata kunci akan menyembunyikan semua video: %s. + + Video yang direkomendasikan + Sembunyikan video dengan penayangan rendah + "Sembunyikan video dengan kurang dari 1.000 penayangan dari feed beranda yang telah diunggah dari saluran yang tidak berlangganan. + +Filter ini mungkin tidak lagi berfungsi, gunakan 'Filter jumlah penayangan' sebagai gantinya." + Sembunyikan video yang direkomendasikan + "Menyembunyikan video yang direkomendasikan berikut ini: + +• Video dengan frasa seperti 'Orang-orang juga menonton' di bawahnya." + + Filter jumlah penayangan + Sembunyikan video beranda berdasarkan penayangan + Video di feed beranda difilter. + Video di feed beranda tidak difilter. + Sembunyikan hasil pencarian berdasarkan penayangan + Hasil pencarian difilter. + Hasil pencarian tidak difilter. + Sembunyikan video langganan berdasarkan penayangan + Video di feed langganan disaring. + Video dalam feed langganan tidak disaring. + Lebih besar dari penayangan + Video dengan jumlah penayangan yang lebih besar dari angka ini akan disembunyikan. + Kurang dari penayangan + Video dengan jumlah penayangan yang lebih kurang dari angka ini akan disembunyikan. + Lihat kunci + Tentukan templat bahasa Anda untuk jumlah tampilan yang ditampilkan di bawah setiap video di antarmuka pengguna. Setiap kunci (huruf/kata dalam bahasa Anda) -> nilai (yang berarti kunci) harus berada di baris baru. Kunci diletakkan sebelum tanda \"->\". Jika Anda mengubah bahasa aplikasi atau sistem, Anda perlu mengatur ulang pengaturan ini.\n\nContoh:\nInggris: 10K tayangan = K -> 1000, tayangan -> tayangan\nSpanyol: 10 K tayangan = K -> 1000, tayangan -> tayangan + K -> 1 000\nM -> 1 000 000\nB -> 1 000 000 000\ntayangan -> tayangan + Tentang penyaringan jumlah tayangan + "Beranda / Langganan / Hasil pencarian disaring untuk menyembunyikan video dengan jumlah penayangan kurang atau lebih besar dari jumlah yang ditentukan. + +Keterbatasan: +• Shorts tidak dapat disembunyikan. +• Video dengan 0 penayangan tidak disaring." + Sembunyikan video terkait + Video terkait disembunyikan. + Video terkait ditampilkan. + "Pengaturan ini membatasi jumlah maksimum tata letak yang dapat dimuat pada layar pemutar. + +Jika tata letak layar pemutar berubah karena perubahan di sisi server, tata letak yang tidak diinginkan mungkin disembunyikan di layar pemutar." + Offset + + Umum + Ganti halaman awal + Default + Semua langganan + Jelajahi saluran + Kursus / Pembelajaran + Jelajahi + Busana & Kecantikan + Gaming + Riwayat + Pustaka + Video disukai + Siaran Langsung + Film + Musik + Berita + Pemberitahuan + Daftar Putar + Podcast + Cari + Belanja + Shorts + Olahraga + Langganan + Sedang Populer + Realitas Virtual + Tonton nanti + Klip Anda + Ganti jenis halaman awal + "Halaman awal selalu berubah. + +Keterbatasan: Tombol Kembali pada bilah alat mungkin tidak berfungsi." + Halaman awal berubah hanya sekali. + Nonaktifkan trek audio otomatis yang dipaksakan + Trek audio otomatis yang dipaksakan dinonaktifkan. + Trek audio otomatis yang dipaksakan diaktifkan. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml index 65d79b779..8ad850239 100644 --- a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml +++ b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml @@ -21,57 +21,116 @@ Si prega di scaricare %2$s dal sito web." %s non è installato. Per favore installalo. Lingua di RVX Lingua dell\'app - Arabo - Azero - Bulgaro - Bengalese - Catalano - Ceco - Danese - Tedesco - Greco - Inglese - Spagnolo - Estone - Persiano - Finlandese - Francese - Gujarati - Hindi - Croato - Ungherese - Indonesiano - Italiano - Giapponese - Kazako - Coreano - Lituano - Lettone - Macedone - Mongolo - Marathi - Malese - Birmano - Olandese - Odia - Punjabi - Polacco - Portoghese - Rumeno - Russo - Slovacco - Sloveno - Serbo - Svevo - Swahili - Tamil - Telugu - Tailandese - Turco - Ucraino - Urdu - Vietnamita - Cinese + "Amarico +አማርኛ" + "Arabo +العربية" + "Azero +Azərbaycan" + "Bielorusso +беларуская" + "Bulgaro +Български" + "Bengalese +বাংলা" + "Catalano +Català" + "Ceco +Čeština" + "Danese +Dansk" + "Tedesco +Deutsch" + "Greco +Ελληνικά" + "Inglese +English" + "Spagnolo +Español" + "Estone +Eesti" + "Persiano +فارسی" + "Finlandese +Suomi" + "Francese +Français" + "Gugiarati +ગુજરાતી" + "Ebraico +עברי" + "Hindi +हिन्दी" + "Croato +Hrvatski" + "Ungherese +Magyar" + "Indonesiano +Indonesia" + "Italiano +Italiano" + "Giapponese +日本語" + "Cazaco +Қазақ тілі" + "Coreano +한국어" + "Lituano +Lietuvių" + "Lettone +Latviešu" + "Macedone +Македонски" + "Mongolo +Монгол" + "Maratti +मराठी" + "Malese +Melayu" + "Birmano +ဗမာ" + "Olandese +Nederlands" + "Oriya +ଓଡ଼ିଆ" + "Pangiabi +ਪੰਜਾਬੀ" + "Polacco +Polski" + "Portoghese +Português" + "Rumeno +Română" + "Russo +Русский" + "Slovacco +Slovenčina" + "Albanese +Shqip" + "Sloveno +Slovenščina" + "Serbo +Српски" + "Svedese +Svenska" + "Suahili +Kiswahili" + "Tàmil +தமிழ்" + "Tèlugu +తెలుగు" + "Tailandese +ไทย" + "Turco +Türkçe" + "Ucraino +Українська" + "Urdù +اردو" + "Vietnamese +Tiếng Việt" + "Cinese +中文" Annunci Nascondi il banner del negozio alla fine dei video @@ -419,13 +478,26 @@ Nota: i canali non si aprono se gli Shorts live sono aperti nel riproduttore nor Tablet Tablet (minimo 600 dp) Semovente - "Le modifiche dell'interfaccia: + "Le modifiche includono: Tablet: i post della community sono nascosti. Semovente: • Gli Shorts verranno aperti nel riproduttore normale. • Il feed è organizzato per argomenti e canali. • La descrizione dei video non può essere aperta quando \"Camuffa i dati in streaming\" è disattivato." + Disattiva gli aggiornamenti dell\'interfaccia + L\'interfaccia non verrà aggiornata dal server. + L\'interfaccia verrà aggiornata dal server. + "L'interfaccia dell'app viene ripristinata all'interfaccia usata al momento della prima installazione. + +Nota: alcune interfacce lato server potrebbero non essere ripristinate. + +Le modifiche includono: +• I componenti nel menù a comparsa (o le impostazioni correlate) potrebbero non funzionare. +• Le animazioni dei contatori numerici sono disattivate. +• Viene usata la scheda Raccolta. +• La sezione Musica nella descrizione dei video potrebbe non funzionare. +• Il pulsante Cambia Account potrebbe essere nascosto nella scheda Raccolta. Usa l'impostazione \"Attiva la barra di ricerca estesa nella scheda Tu\"." Attiva il camuffamento della versione dell\'app Il camuffamento della versione dell\'app è attivato. Il camuffamento della versione dell\'app è disattivato. @@ -433,7 +505,7 @@ Semovente: Questo cambierà l'aspetto e le caratteristiche dell'app, ma potrebbero verificarsi effetti collaterali sconosciuti. -Se in seguito verrà disattivato, si consiglia di cancellare i dati dell'app per evitare bug dell'interfaccia." +Se in seguito verrà disattivata, si consiglia di cancellare i dati dell'app per evitare bug dell'interfaccia." Modifica la versione dell\'app da camuffare Digita la versione dell\'app da camuffare. Versione dell\'app da camuffare @@ -443,8 +515,10 @@ Se in seguito verrà disattivato, si consiglia di cancellare i dati dell'app per 18.33.40 - Ripristina la vecchia barra delle azioni degli Shorts 18.38.45 - Ripristina il comportamento della vecchia qualità video predefinita 18.48.39 - Disattiva l\'aggiornamento in tempo reale delle visualizzazioni e dei mi piace + 19.01.34 - Disattiva l\'interazione con la descrizione dei video 19.26.42 - Disattiva l\'icona Cairo nella navigazione e nella barra degli strumenti 19.33.37 - Ripristina il vecchio pannello della velocità di riproduzione + Versione dell\'app da camuffare non valida: %s Menù dell\'account Personalizza i componenti dei menù dell\'account e della scheda Tu. @@ -533,7 +607,6 @@ Se questa impostazione non ha effetto, prova a passare alla navigazione in incog Attiva la barra di navigazione traslucida La barra di navigazione è traslucida. La barra di navigazione è opaca. - In alcune versioni di YouTube, questa impostazione può rendere trasparente la barra di navigazione del sistema, oppure l\'interfaccia potrebbe non funzionare correttamente in modalità PIP. Nascondi la barra di navigazione La barra di navigazione è nascosta. La barra di navigazione è visibile. @@ -1215,9 +1288,9 @@ Questa impostazione funziona meglio con una connessione internet molto veloce."< Descrizione dei video Personalizza i componenti della descrizione dei video. - Disattiva l\'effetto contatore dei numeri - L\'effetto contatore dei numeri è disattivato. - L\'effetto contatore dei numeri è attivato. + Disattiva le animazioni dei contatori numerici + Le animazioni dei contatori numerici sono disattivate. + Le animazioni dei contatori numerici sono attivate. Nascondi la sezione Riepilogo Video Generato dall\'IA La sezione Riepilogo Video Generato dall\'IA è nascosta. La sezione Riepilogo Video Generato dall\'IA è visibile. @@ -1409,9 +1482,7 @@ Nota: solo gli scaffali con l'intestazione Shorts nella scheda Home sono nascost Attiva le azioni personalizzate nei menù a comparsa "Le azioni personalizzate nei menù a comparsa sono attivate. -Note: -• Non funziona se la versione dell'app è camuffata alla versione 18.49.37 o precedente. -• Non funziona con i video live." +Nota: non funziona con i video live." Le azioni personalizzate nei menù a comparsa sono disattivate. Attiva le azioni personalizzate nella barra degli strumenti "Le azioni personalizzate nella barra degli strumenti sono attivate. diff --git a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml index f25311f54..c3e2aa758 100644 --- a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml +++ b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml @@ -21,57 +21,6 @@ %s はインストールされていません。インストールしてください。 YouTube と Revanced Extended 設定の言語 アプリの設定言語に従う - アラビア語 - アゼルバイジャン語 - ブルガリア語 - ベンガル語 - カタロニア語 - チェコ語 - デンマーク語 - ドイツ語 - ギリシャ語 - 英語 - スペイン語 - エストニア語 - ペルシャ語 - フィンランド語 - フランス語 - グジャラート語 - ヒンディー語 - クロアチア語 - ハンガリー語 - インドネシア語 - イタリア語 - 日本語 - カザフ語 - 韓国語 - リトアニア語 - ラトビア語 - マケドニア語 - モンゴル語 - マラーティー語 - マレー語 - ビルマ語 (ミャンマー語) - オランダ語 - オディア語 - パンジャーブ語 - ポーランド語 - ポルトガル語 - ルーマニア語 - ロシア語 - スロバキア語 - スロベニア語 - セルビア語 - スウェーデン語 - スワヒリ語 - タミル語 - テルグ語 - タイ語 - トルコ語 - ウクライナ語 - ウルドゥー語 - ベトナム語 - 中国語 広告 終了画面の商品バナーを非表示 @@ -540,7 +489,6 @@ DeArrow の詳細については、ここをタップしてください。"半透明のナビゲーションバーを有効化 ナビゲーションバー (ホーム、登録チャンネルなどのボタン) を半透明にします。 ナビゲーションバー (ホーム、登録チャンネルなどのボタン) を半透明にします。 - 特定の YouTube バージョンでは、この設定によりシステムナビゲーションバーが透明になるか、ピクチャーインピクチャーモードでレイアウトが崩れることがあります。 ナビゲーションバーを非表示 ナビゲーションバー(ホーム、登録チャンネルなどのボタン)を非表示にします。 ナビゲーションバー(ホーム、登録チャンネルなどのボタン)を非表示にします。 diff --git a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml index 8818e060a..48747bc40 100644 --- a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml +++ b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml @@ -19,59 +19,148 @@ "%1$s 가 설치되어 있지 않습니다. 웹사이트에서 %2$s 를 다운로드하세요." %s가 설치되지 않았습니다. 설치하세요. + 현재 재생목록에 추가하기 + 현재 재생목록에 추가하고 현재 재생목록 열기 + 현재 재생목록에 추가하고 동영상 재생하기 + 외부 다운로더 + 현재 재생목록 열기 + 현재 재생목록 + 현재 재생목록에서 제거하기 + 현재 재생목록에서 제거하고 현재 재생목록 열기 + 현재 재생목록 제거하기 + 현재 재생목록 저장하기 + "외부 다운로더가 아닌 현재 재생목록 관리자 다이얼로그를 실행할 수 있습니다. + +시스템 네비게이션 바에서 '뒤로 가기' 버튼을 길게 눌러서 현재 재생목록 관리자를 실행할 수도 있습니다. + +이 기능은 아직 개발 중이므로 대부분의 기능이 작동하지 않을 수 있습니다." + 로그인이 요구됨 + 현재 재생목록 관리자를 실행할 수 없습니다. (%s) + 재생목록을 식별할 수 없음 + 현재 재생목록이 비어져 있음 + 동영상을 식별할 수 없음 + 동영상을 추가할 수 없습니다. + 현재 재생목록을 만들 수 없습니다. + 현재 재생목록을 제거할 수 없습니다. + 동영상을 제거할 수 없습니다. + 현재 재생목록을 저장할 수 없습니다. + 동영상을 성공적으로 추가하였습니다. + 현재 재생목록을 성공적으로 만들었습니다. + 현재 재생목록을 성공적으로 제거하였습니다. + 동영상을 성공적으로 제거하였습니다. + 현재 재생목록을 \'%s\'에 성공적으로 저장하였습니다. RVX 언어 앱 언어 - 아랍어 - 아제르바이잔어 - 불가리아어 - 뱅골어 - 카탈루냐어 - 체코어 - 덴마크어 - 독일어 - 그리스어 - 영어 - 스페인어 - 에스토니아어 - 페르시아어 - 핀란드어 - 프랑스어 - 구자라트어 - 힌디어 - 크로아티아어 - 헝가리어 - 인도네시아어 - 이탈리아어 - 일본어 - 카자흐어 - 한국어 - 리투아니아어 - 라트비아어 - 마케도니아어 - 몽골어 - 마라티어 - 말레이어 - 버마어 - 네덜란드어 - 오리야어 - 펀자브어 - 폴란드어 - 포르투갈어 - 루마니아어 - 러시아어 - 슬로바키아어 - 슬로베니아어 - 세르비아어 - 스웨덴어 - 스와힐리어 - 타밀어 - 텔루구어 - 태국어 - 터키어 - 우크라이나어 - 우르두어 - 베트남어 - 중국어 + "Amharic +አማርኛ" + "Arabic +العربية" + "Azerbaijani +Azərbaycan" + "Belarusian +беларуская" + "Bulgarian +Български" + "Bengali +বাংলা" + "Catalan +Català" + "Czech +Čeština" + "Danish +Dansk" + "German +Deutsch" + "Greek +Ελληνικά" + "English +English" + "Spanish +Español" + "Estonian +Eesti" + "Persian +فارسی" + "Finnish +Suomi" + "French +Français" + "Gujarati +ગુજરાતી" + "Hebrew +עברי" + "Hindi +हिन्दी" + "Croatian +Hrvatski" + "Hungarian +Magyar" + "Indonesian +Indonesia" + "Italian +Italiano" + "Japanese +日本語" + "Kazakh +Қазақ тілі" + "Korean +한국어" + "Lithuanian +Lietuvių" + "Latvian +Latviešu" + "Macedonian +Македонски" + "Mongolian +Монгол" + "Marathi +मराठी" + "Malay +Melayu" + "Burmese +ဗမာ" + "Dutch +Nederlands" + "Odia +ଓଡ଼ିଆ" + "Punjabi +ਪੰਜਾਬੀ" + "Polish +Polski" + "Portuguese +Português" + "Romanian +Română" + "Russian +Русский" + "Slovak +Slovenčina" + "Albanian +Shqip" + "Slovene +Slovenščina" + "Serbian +Српски" + "Swedish +Svenska" + "Swahili +Kiswahili" + "Tamil +தமிழ்" + "Telugu +తెలుగు" + "Thai +ไทย" + "Turkish +Türkçe" + "Ukrainian +Українська" + "Urdu +اردو" + "Vietnamese +Tiếng Việt" + "Chinese +中文" 광고 최종 화면에서 스토어 배너 숨기기 @@ -114,7 +203,7 @@ 대체 썸네일 홈 탭 - 플레이어: 재생목록, 관련 동영상 ... + 플레이어: 재생목록, 관련 동영상, etc. 검색 결과 구독 탭 내 페이지 탭 @@ -149,7 +238,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 이미지 표시 제한 국가 이미지 표시 제한 국가 우회하기 대체 이미지 도메인을 사용합니다.\n\n대체 이미지 도메인 기본값: yt4.ggpht.com - 기본 이미지 도메인을 사용합니다.\n\n이 설정을 활성화하면 일부 국가에서 차단된 이미지를 수신할 수 있습니다. (채널 프로필 사진, 커뮤니티 게시물 이미지 ...) + 기본 이미지 도메인을 사용합니다.\n\n이 설정을 활성화하면 일부 국가에서 차단된 이미지를 수신할 수 있습니다. (채널 프로필 사진, 커뮤니티 게시물 이미지, etc.) 피드 음악 앨범 카드 숨기기 @@ -168,14 +257,14 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." • 주요 뉴스, 뉴스 속보 • 맞춤 실시간 스트림 • 라이브 쇼핑 -• 보건 정보 출처 ..." - 다음 선반이 표시됩니다:\n• 다시 듣기\n• 다시 시청하기\n• 이어서 시청하기\n• 채널 더보기\n• 이 게임 더보기\n• 주요 뉴스, 뉴스 속보\n• 맞춤 실시간 스트림\n• 라이브 쇼핑\n• 보건 정보 출처 ... +• 보건 정보 출처, etc." + 다음 선반이 표시됩니다:\n• 다시 듣기\n• 다시 시청하기\n• 이어서 시청하기\n• 채널 더보기\n• 이 게임 더보기\n• 주요 뉴스, 뉴스 속보\n• 맞춤 실시간 스트림\n• 라이브 쇼핑\n• 보건 정보 출처, etc. 더 많은 주제 탐색 선반 숨기기 더 많은 주제 탐색 선반이 숨겨집니다. 더 많은 주제 탐색 선반이 표시됩니다. 펼쳐볼 수 있는 정보 숨기기 - 썸네일 하단에서 다음 정보들이 숨겨집니다:\n동영상 설명, 챕터, 주요 순간, 스크립트,\n재생목록의 동영상, 이 동영상에 나온 제품 ... - 썸네일 하단에서 다음 정보들이 표시됩니다:\n동영상 설명, 챕터, 주요 순간, 스크립트,\n재생목록의 동영상, 이 동영상에 나온 제품 ... + 썸네일 하단에서 다음 정보들이 숨겨집니다:\n동영상 설명, 챕터, 주요 순간, 스크립트,\n재생목록의 동영상, 이 동영상에 나온 제품, etc. + 썸네일 하단에서 다음 정보들이 표시됩니다:\n동영상 설명, 챕터, 주요 순간, 스크립트,\n재생목록의 동영상, 이 동영상에 나온 제품, etc. 펼쳐볼 수 있는 선반 숨기기 다음 선반이 숨겨집니다:\n좋아하는 장르 선택 선반 다음 선반이 표시됩니다:\n좋아하는 장르 선택 선반 @@ -410,7 +499,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 동영상들 사이에서 회색 구분선이 숨겨집니다. 동영상들 사이에서 회색 구분선이 표시됩니다. 시청 경고 다이얼로그 제거하기 - "다음 동영상을 시청하기 전에 표시되는 시청 경고 다이얼로그를 제거합니다:\n• 연령 제한 동영상\n• 혐오감을 주는 동영상\n• 자살 또는 자해와 관련된 동영상 ...\n\n이 설정은 다이얼로그를 자동으로 허용하기만 하며 연령 제한(성인인증 절차)을 우회할 수 없습니다." + "다음 동영상을 시청하기 전에 표시되는 시청 경고 다이얼로그를 제거합니다:\n• 연령 제한 동영상\n• 혐오감을 주는 동영상\n• 자살 또는 자해와 관련된 동영상, etc.\n\n이 설정은 다이얼로그를 자동으로 허용하기만 하며 연령 제한(성인인증 절차)을 우회할 수 없습니다." 라이브 링 누르기 동작 변경하기 "라이브 링이 표시된 채널 아이콘을 누르면 채널 프로필으로 연결됩니다. @@ -433,6 +522,19 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." • Shorts가 일반 플레이어에서 재생됩니다. • 피드가 주제와 채널별로 구성됩니다. • '스트리밍 데이터 변경하기'가 비활성화되어있으면 동영상 설명을 열 수 없습니다." + 레이아웃 업데이트 비활성화하기 + 레이아웃이 서버에 의해 업데이트되지 않습니다. + 레이아웃이 서버에 의해 업데이트됩니다. + "앱 레이아웃이 처음 설치할 때 사용되는 레이아웃으로 되돌아갑니다. + +일부 서버 측 레이아웃은 되돌려지지 않을 수 있습니다. + +변경 사항 +• 플레이어 메뉴 구성 요소(또는 관련 설정)가 작동되지 않을 수 있습니다. +• 롤링 넘버 애니메이션이 적용되지 않습니다. +• 보관함 탭이 사용됩니다. +• 동영상 설명에서 음악 섹션이 작동되지 않을 수 있습니다. +• 보관함 탭에서 계정 전환 버튼이 표시되지 않을 수 있습니다. '내 페이지에서 넓은 검색창 활성화하기' 설정을 사용하세요." 앱 버전 변경하기 앱 버전을 변경합니다. 앱 버전을 변경하지 않습니다. @@ -446,8 +548,10 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 18.33.40 - 이전 Shorts 액션바로 복원합니다. 18.38.45 - 이전 기본 동영상 화질 적용 방식으로 복원합니다. 18.48.39 - \'조회수\' & \'좋아요\'의 실시간 업데이트를 비활성화합니다. + 19.01.34 - 동영상 설명 상호작용을 비활성화합니다. 19.26.42 - 하단바와 툴바에서 Cairo 아이콘을 비활성화합니다. 19.33.37 - 이전 동영상 재생 속도 구성요소 패널을 복원합니다. + 변경할 앱 버전이 잘못되었습니다: %s 계정 메뉴 계정 메뉴 및 내 페이지에서 구성요소를 숨기거나 표시할 수 있습니다. @@ -481,8 +585,11 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 기본 재생목록 오프라인 저장 버튼이 항상 표시되어 있으며, 공개 재생목록에서는 그 버튼으로 외부 다운로더를 실행할 수 있습니다. 기본 재생목록 오프라인 저장 버튼이 표시되어 있으면, 그 버튼으로 기본 다운로더를 실행할 수 있습니다. (YouTube Premium 기능) 동영상 오프라인 저장 버튼 재정의하기 - 동영상 오프라인 저장 버튼으로 외부 다운로더를 실행할 수 있습니다. - 동영상 오프라인 저장 버튼으로 기본 다운로더를 실행할 수 있습니다. (YouTube Premium 기능) + 기본 동영상 오프라인 저장 버튼으로 외부 다운로더를 실행할 수 있습니다. + 기본 동영상 오프라인 저장 버튼으로 기본 다운로더를 실행할 수 있습니다. (YouTube Premium 기능) + 현재 재생목록 관리자 + 기본 동영상 오프라인 저장 버튼으로 현재 재생목록 관리자를 실행합니다. + 기본 동영상 오프라인 저장 버튼으로 외부 다운로더를 실행합니다. 재생목록 외부 다운로더 앱 패키지명 YTDLnis와 같은 설치된 외부 다운로더 앱 패키지명을 설정하세요. @@ -536,7 +643,6 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 반투명 하단바 활성화하기 하단바가 반투명합니다. 하단바가 불투명합니다. - 특정 YouTube 앱 버전에서는 이 설정으로 인하여 시스템 네비게이션 바가 투명해지거나 PIP 모드에서 레이아웃이 깨질 수 있습니다. 하단바 숨기기 하단바가 숨겨집니다. 하단바가 표시됩니다. @@ -689,8 +795,8 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 설정 → 자동재생 / 재생 → 다음 동영상 자동재생" 이 설정을 활성화하면 자동재생이 켜져 있는 동안에 음악 동영상을 재생하면 YouTube 믹스 재생목록으로 자동전환되지 않습니다. 플레이어 팝업 패널 비활성화하기 - 자동 플레이어 팝업 패널을 비활성화합니다.\n• 재생목록, 실시간 채팅, 제품 패널 ... - 자동 플레이어 팝업 패널을 활성화합니다.\n• 재생목록, 실시간 채팅, 제품 패널 ... + 자동 플레이어 팝업 패널을 비활성화합니다.\n• 재생목록, 실시간 채팅, 제품 패널, etc. + 자동 플레이어 팝업 패널을 활성화합니다.\n• 재생목록, 실시간 채팅, 제품 패널, etc. 동영상 재생 속도 오버레이 비활성화하기 "화면을 길게 눌러서 '2배속 >>'을 비활성화합니다. @@ -750,8 +856,8 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 줌 오버레이가 숨겨집니다. 줌 오버레이가 표시됩니다. 동영상 제목 하단 정리하기 - "제목 하단에서 다음 문구들이 숨겨집니다:\n#(해시태그), 모금 행사, 쇼핑, n개 제품, 더빙,\n인기 급상승 동영상 #순위, 회원 전용 ..." - "제목 하단에서 다음 문구들이 표시됩니다:\n#(해시태그), 모금 행사, 쇼핑, n개 제품, 더빙,\n인기 급상승 동영상 #순위, 회원 전용 ..." + "제목 하단에서 다음 문구들이 숨겨집니다:\n#(해시태그), 모금 행사, 쇼핑, n개 제품, 더빙,\n인기 급상승 동영상 #순위, 회원 전용, etc." + "제목 하단에서 다음 문구들이 표시됩니다:\n#(해시태그), 모금 행사, 쇼핑, n개 제품, 더빙,\n인기 급상승 동영상 #순위, 회원 전용, etc." 액션 버튼 플레이어 하단에 있는 액션 버튼을 숨기거나 표시할 수 있습니다. @@ -1117,6 +1223,8 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 버튼을 눌러서 재생 중인 동영상을 음소거할 수 있습니다.\n다시 누르면 음소거가 해제됩니다. 외부 다운로더 버튼 표시하기 버튼을 눌러서 외부 다운로더를 실행할 수 있습니다. + 현재 재생목록 관리자 + 외부 다운로더가 아닌 현재 재생목록 관리자를 실행할 수 있습니다. 동영상 재생 속도 다이얼로그 버튼 표시하기 "버튼을 눌러서 동영상 재생 속도 다이얼로그를 열 수 있습니다. 길게 누르면 동영상 재생 속도 값이 1.0배속으로 설정되고, 다시 길게 누르면 기본 동영상 재생 속도 값으로 설정됩니다." @@ -1255,7 +1363,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." • 길게 눌러서 텍스트 선택하기" 동영상 설명 펼치기 동영상 설명이 자동으로 펼쳐집니다. - 동영상 설명이 수동으로 펼쳐집니다. + 동영상 설명이 자동으로 펼쳐지지 않습니다. Shorts Shorts 백그라운드 재생 비활성화하기 @@ -1277,7 +1385,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." • 아티스트 또는 크리에이터의 최신 동영상 • 이전에 시청한 동영상 • 관련 검색어의 검색결과 -• 새로운 맞춤 채널 ..." +• 새로운 맞춤 채널, etc." 채널에서 Shorts 선반 숨기기 "채널에서 Shorts 선반이 숨겨집니다. @@ -1421,7 +1529,6 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." "메뉴 구성요소에서 사용자 정의 동작을 활성화합니다. 알려진 문제점: -• 앱 버전이 18.49.37 이하로 변경된 경우에는 작동되지 않습니다. • 실시간 스트림에서는 작동되지 않습니다." 메뉴 구성요소에서 사용자 정의 동작을 비활성화합니다. 툴바에서 사용자 정의 동작 활성화하기 diff --git a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml index 2a409d692..a41c9b431 100644 --- a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml +++ b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml @@ -21,57 +21,116 @@ Pobierz %2$s ze strony internetowej." %s nie jest zainstalowany. Proszę go zainstalować. Język RVX Język aplikacji - Arabski - Azerbejdżański - Bułgarski - Bengalski - Kataloński - Czeski - Duński - Niemiecki - Grecki - Angielski - Hiszpański - Estoński - Perski - Fiński - Francuski - Gudżaracki - Hindi - Chorwacki - Węgierski - Indonezyjski - Włoski - Japoński - Kazachski - Koreański - Litewski - Łotewski - Macedoński - Mongolski - Maratyjski - Malajski - Birmański - Niderlandzki - Orija - Pendżabski - Polski - Portugalski - Rumuński - Rosyjski - Słowacki - Słoweński - Serbski - Szwedzki - Suahili - Tamilski - Telugu - Tajski - Turecki - Ukraiński - Urdu - Wietnamski - Chiński + "Amharski +አማርኛ" + "Arabski +العربية" + "Azerbejdżański +Azərbaycan" + "Białoruski +беларуская" + "Bułgarski +Български" + "Bengalski +বাংলা" + "Kataloński +Català" + "Czeski +Čeština" + "Duński +Dansk" + "Niemiecki +Deutsch" + "Grecki +Ελληνικά" + "Angielski +English" + "Hiszpański +Español" + "Estoński +Eesti" + "Perski +فارسی" + "Fiński +Suomi" + "Francuski +Français" + "Gudżarati +ગુજરાતી" + "Hebrajski +עברי" + "Hindi +हिन्दी" + "Chorwacki +Hrvatski" + "Węgierski +Magyar" + "Indonezyjski +Indonesia" + "Włoski +Italiano" + "Japoński +日本語" + "Kazachski +Қазақ тілі" + "Koreański +한국어" + "Litewski +Lietuvių" + "Łotewski +Latviešu" + "Macedoński +Македонски" + "Mongolski +Монгол" + "Marathi +मराठी" + "Malajski +Melayu" + "Birmański +ဗမာ" + "Niderlandzki +Nederlands" + "Orija +ଓଡ଼ିଆ" + "Pendżabski +ਪੰਜਾਬੀ" + "Polski +Polski" + "Portugalski +Português" + "Rumuński +Română" + "Rosyjski +Русский" + "Słowacki +Slovenčina" + "Albański +Shqip" + "Słoweński +Slovenščina" + "Serbski +Српски" + "Szwedzki +Svenska" + "Suahili +Kiswahili" + "Tamilski +தமிழ்" + "Telugu +తెలుగు" + "Tajski +ไทย" + "Turecki +Türkçe" + "Ukraiński +Українська" + "Urdu +اردو" + "Wietnamski +Tiếng Việt" + "Chiński +中文" Reklamy Baner sklepowy po zakończeniu filmu @@ -430,6 +489,19 @@ Układ samochodowy: • Shortsy otwierają się w zwykłym odtwarzaczu • Strona główna jest sortowana po tematach i kanałach • Opis filmu nie może być otwarty po wyłączeniu 'Oszukuj strumień danych'" + Aktualizacje układu aplikacji przez serwer + Wyłączone + Włączone + "Układ aplikacji wraca do układu używanego przy pierwszej instalacji. + +Większość powiązanych serwerowo układów aplikacji może się nie przywrócić. + +Zmiany zawierają: +• Komponenty menu ustawień filmu (i powiązanych ustawień) mogą nie działać +• Animacje liczb nie działają +• Zakładka biblioteki jest używana +• Sekcja muzyki w opisie filmu może nie działać +• Przycisk od przełączania konta może się nie pojawiać w zakładce biblioteki. Użyj ustawienia 'Szeroki pasek wyszukiwania w zakładce Ty'" Oszukiwanie wersji aplikacji Włączone Wyłączone @@ -447,8 +519,10 @@ Jeśli później zostanie to wyłączone, rekomendowane jest usunięcie danych a 18.33.40 - Przywraca stary pasek akcji Shortsów 18.38.45 - Przywraca stare zachowanie domyślnej jakości filmu 18.48.39 - Wyłącza aktualizowanie wyświetleń i łapek w górę w czasie rzeczywistym + 19.01.34 - Wyłącza interakcje z opisami filmów 19.26.42 - Wyłącza ikony Cairo w pasku nawigacji oraz narzędzi 19.33.37 - Przywraca stare menu szybkości odtwarzania + Nieprawidłowa oszukiwana wersja aplikacji: %s. Menu konta Ukryj bądź pokaż elementy w menu konta i zakładki Ty @@ -538,7 +612,6 @@ Jeśli opcja nie przynosi skutku, spróbuj przełączyć się na tryb incognito. Wygląd paska nawigacji Półprzezroczysty Nieprzezroczysty - W niektórych wersjach YouTube, to ustawienie może sprawić systemowy pasek nawigacji przezroczystym, lub popsuć układ w trybie PiP. Pasek nawigacji Ukryty Widoczny @@ -637,7 +710,7 @@ Jeśli zajdą zmiany po stronie serwera, kolor tła tych komunikatów może się Szeroki pasek wyszukiwania z nagłówkiem YouTube Włączony Wyłączony - Szeroki pasek wyszukiwania na stronie Ty + Szeroki pasek wyszukiwania w zakładce Ty "Włączony By dostać się do ustawień, użyj następującej ścieżki: @@ -1416,8 +1489,7 @@ Informacja: Własne akcje w menu ustawień Shortsa "Włączone -Ograniczenia: -• Nie działają, jeśli wersja aplikacji jest oszukana do 18.49.37, bądź wcześniejszej +Ograniczenie: • Nie działają na transmisjach na żywo" Wyłączone Własne akcje w pasku narzędzi diff --git a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml index a3668074b..5199a8307 100644 --- a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml +++ b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml @@ -21,57 +21,6 @@ Por favor, baixe %2$s do site." %s não está instalado. Por favor, instale-o. Idioma do RVX Idioma do app - Árabe - Azerbaijano - Búlgaro - Bengalês - Catalão - Tcheco - Dinamarquês - Alemão - Grego - Inglês - Espanhol - Estoniano - Persa - Finlandês - Francês - Guzerate - Hindu - Croata - Húngaro - Indonésio - Italiano - Japonês - Cazaque - Coreano - Lituano - Letão - Macedônio - Mongol - Marata - Malaio - Birmanês - Holandês - Odia - Punjabi - Polonês - Português - Romeno - Russo - Eslovaco - Esloveno - Sérvio - Sueco - Suaíli - Tâmil - Telugu - Tailandês - Turco - Ucraniano - Urdu - Vietnamita - Chinês Anúncios Ocultar banner da loja na tela final @@ -407,6 +356,22 @@ Isso não ignora a restrição de idade, apenas aceita isso automaticamente."Alterar ação de clique do anel ao vivo "O canal é aberto quando o anel ao vivo é clicado." A transmissão ao vivo é aberta quando o anel ao vivo é clicado. + Fator de forma de layout + Padrão + Telefone + Telefone (Máximo 480 dp) + Tablet + Tablet (Min 600 dp) + Automotivo + "As alterações incluem: + +Tablet layout +• Os posts da comunidade estão ocultos. + +Automotivo layout +• Shorts abertos no reprodutor regular. +• O feed é organizado por tópicos e canais. +• A descrição do vídeo não pode ser aberta quando o 'Falsificar dados de reprodução' está desligado." Falsificar versão do aplicativo Versão falsificada Versão não falsificada @@ -512,7 +477,6 @@ Se essa configuração não surtir efeito, tente alternar para o modo anônimo." Ativar barra de navegação transparente A barra de navegação está transparente. A barra de navegação está opaca. - Em certas versões do YouTube, esta configuração pode tornar a barra de navegação do sistema transparente ou o layout pode ser quebrado no modo PIP. Ocultar barra de navegação A barra de navegação está oculta. A barra de navegação será exibida. @@ -1001,6 +965,7 @@ Limitação: Título do vídeo desaparece quando clicado." Mini reprodutor Alterar o estilo do reprodutor minimizado no aplicativo. + Desativar retomada do mini reprodutor Tipo de mini reprodutor Desativado Original @@ -1903,6 +1868,14 @@ Toque no botão continuar e desative as otimizações da bateria." "Ativar isso pode melhorar a duração da bateria e corrigir travamentos na reprodução. O AVC tem uma resolução máxima de 1080p, o codec de áudio Opus não está disponível e a reprodução de vídeo usará mais dados da internet do que VP9 ou AV1." + Pular criptografia de resposta Onesie + "Pular criptografia de resposta Onesie. + +• Corrige um novo tipo de problema de reprodução que alguns usuários estão enfrentando. +• O codec AV1 pode não estar disponível." + "Não pule a criptografia de resposta Onesie. + +• Alguns usuários podem experimentar um novo tipo de problema de reprodução." Exibir em Estatísticas para nerds O cliente usado para buscar dados de streaming é mostrado em Estatísticas para nerds. O cliente usado para buscar dados de streaming está oculto em Estatísticas para nerds. diff --git a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml index c1e134bcd..1dfb72ae5 100644 --- a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml +++ b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml @@ -21,57 +21,116 @@ %s не установлен. Установите его. Язык RVX Язык приложения - عَرَبِيّ - Azərbaycan - Български - বাংলা - Català - Čeština - Dansk - Deutsch - Ελληνικά - English - Español - Eesti keel - فارسی - Suomalainen - Le français - ગુજરાતી - हिन्दी - Hrvatski - Magyar - Indonesia - Italiano - 日本語 - Қазақ - 한국어 - Lietùvių - Latviešu - Македонски - Монгол - Marāṭhī / मराठी - Melayu - မြန်မာ - Nederlands - ଓଡ଼ିଆ - ਪੰਜਾਬੀ / پنجابی - Polski - Português - Romanesc - Русский - Slovenský - Slovenski - Српски - Svenska - Kiswahili - தமிழ் - తెలుగు - แบบไทย - Türkçe - Українська - اردو - Tiếng Việt - 中文 + "Амхарский +አማርኛ" + "Арабский +العربية" + "Азербайджанский +Azərbaycan" + "Белорусский +беларуская" + "Болгарский +Български" + "Бенгальский +বাংলা" + "Каталонский +Català" + "Чешский +Čeština" + "Датский +Dansk" + "Немецкий +Deutsch" + "Греческий +Ελληνικά" + "Английский +English" + "Испанский +Español" + "Эстонский +Eesti" + "Персидский +فارسی" + "Финский +Suomi" + "Французский +Français" + "Гуджаратский +ગુજરાતી" + "Ивритский +עברי" + "Хинди +हिन्दी" + "Хорватский +Hrvatski" + "Венгерский +Magyar" + "Индонезийский +Indonesia" + "Итальянский +Italiano" + "Японский +日本語" + "Казахский +Қазақ тілі" + "Корейский +한국어" + "Литовский +Lietuvių" + "Латышский +Latviešu" + "Македонский +Македонски" + "Монгольский +Монгол" + "Маратхский +मराठी" + "Малайский +Melayu" + "Бирманский +ဗမာ" + "Голландский +Nederlands" + "Ория +ଓଡ଼ିଆ" + "Панджабский +ਪੰਜਾਬੀ" + "Польский +Polski" + "Португальский +Português" + "Румынский +Română" + "Русский +Русский" + "Словацкий +Slovenčina" + "Албанский +Shqip" + "Словенский +Slovenščina" + "Сербский +Српски" + "Шведский +Svenska" + "Суахилийский +Kiswahili" + "Тамильский +தமிழ்" + "Телугуский +తెలుగు" + "Тайский +ไทย" + "Турецкий +Türkçe" + "Украинский +Українська" + "Урдуский +اردو" + "Вьетнамский +Tiếng Việt" + "Китайский +中文" Реклама Скрыть баннер магазина на конечном экране @@ -418,7 +477,7 @@ Shorts Серые разделители отображены. Скрыть диалог возрастного ограничения "Возрастные ограничения будут приниматься автоматически." - Действие нажатия на точку прямого эфира + Действие нажатия на значок прямого эфира "Открывается канал." Открывается прямой эфир. Макет интерфейса @@ -437,6 +496,19 @@ Shorts • Shorts открываются в обычном плеере. • Лента организована по темам и каналам. • Описание видео нельзя открыть, если «Подмена потоковых данных» отключена." + Отключить обновление макета + Макет не будет обновляться сервером. + Макет будет обновляться сервером. + "Макет программы возвращается к макету, который использовался при первой установке. + +Некоторые серверные макеты могут не вернуться. + +Изменения включают: +• Компоненты в раскрывающемся меню плеера (или связанные настройки) могут не работать. +• Анимация прокручивания чисел. +• Используется вкладка Библиотека. +• Секция Музыка в описании видео может не работать. +• Кнопка переключения аккаунта может не появляться во вкладке Библиотека. Используйте настройки 'Включить широкую панель поиска на вкладке Вы'." Подмена версии приложения Версия приложения подменена Версия приложения не подменена @@ -454,8 +526,10 @@ Shorts 18.33.40 - Восстановление старой панели действий Shorts 18.38.45 - Восстановление старого поведения качества видео по умолчанию 18.48.39 - Отключение обновления \"просмотров\" и \"лайков\" в реальном времени + 19.01.34 - Отключить взаимодействие с описанием видео 19.26.42 - Выключится значок Каир в навигации и панели инструментов 19.33.37 - Восстановит старый стиль выпадающей панели скорости проигрывания + Неверная версия подмены: %s. Меню аккаунта Настройка меню аккаунта и вкладки Вы. @@ -489,7 +563,7 @@ Shorts Кнопка \"Скачать\" для плейлиста, использует внешний загрузчик. Кнопка \"Скачать\" для плейлиста, использует внутренний загрузчик. Действие кнопки \"Скачать\" для видео - Кнопка \"Скачать\" использует внешний загрузчик. + Кнопка \"Скачать\" открывает внешний загрузчик. Кнопка \"Скачать\" использует внутренний загрузчик. Внешний загрузчик для плейлиста, название пакета Например: NewPipe или YTDLnis, или др. (Для плейлиста). @@ -545,7 +619,6 @@ Shorts Полупрозрачность панели навигации Полупрозрачность включена. Полупрозрачность отключена. - В некоторых версиях YouTube этот параметр может сделать панель навигации прозрачной или нарушить макет в режиме PIP. Панель навигации Панель навигации скрыта. Панель навигации отображена. @@ -1255,7 +1328,7 @@ Shorts Секция \"Расшифровка видео\" скрыта. Секция \"Расшифровка видео\" отображена. - Взаимодействие с описанием видео + Отключить взаимодействие с описанием видео "Отключает следующее взаимодействие при расширении описания видео: • Нажать - прокрутка. diff --git a/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml b/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml index 23ebdab7c..85187d99c 100644 --- a/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml +++ b/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml @@ -21,57 +21,6 @@ Lütfen web sitesinden %2$s dosyasını indirin." %s kurulmamış. Lütfen önce indiriniz. RVX dili Uygulama dili - Arapça - Azerbaycanca - Bulgarca - Bengalce - Katalanca - Çekçe - Danca - Almanca - Yunanca - İngilizce - İspanyolca - Estonca - Farsça - Fince - Fransızca - Gujarati - Hintçe - Hırvatça - Macarca - Endonezce - İtalyanca - Japonca - Kazakça - Korece - Litvanca - Letonca - Makedonca - Moğolca - Marathi dili - Malayca - Birmanca - Flemenkçe - Odiyaca - Pencapça - Lehçe - Portekizce - Rumence - Rusça - Slovakça - Slovence - Sırpça - İsveççe - Svahili dili - Tamil Dili - Teluguca - Tayca - Türkçe - Ukraynaca - Urdu dili - Vietnamca - Çince Reklamlar Bitiş ekranındaki mağaza afişini gizle @@ -508,7 +457,6 @@ Bu ayar etkili olmazsa Gizli moda geçmeyi deneyin." Yarı saydam gezinme çubuğunu etkinleştir Gezinme çubuğu yarı saydam. Gezinme çubuğu opaktır. - Bazı YouTube sürümlerinde, bu ayar sistem gezinme çubuğunu şeffaf hale getirebilir veya PIP modunda düzen bozulabilir. Gezinme çubuğunu gizle Gezinme çubuğu gizlendi. Gezinme çubuğu gösteriliyor. diff --git a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml index ccf60c3de..8f488794a 100644 --- a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml +++ b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml @@ -19,59 +19,150 @@ "%1$s не встановлено. Будь ласка, завантажте %2$s з сайту." %s не встановлено. Будь ласка, встановіть його. + Додати до черги + Додати до черги й відкрити чергу + Додати до черги й відтворити відео + Зовнішній завантажувач + Відкрити чергу + Черга + Видалити з черги + Вилучити з черги й відкрити чергу + Вилучити чергу + Зберегти чергу + "Замість відкривання зовнішнього завантажувача відкриває діалог керування чергою. + +Також можливо відкрити керування чергою натисканням та утриманням кнопки назад на панелі навігації. + +Ця функція все ще перебуває в процесі розробки, тому більшість функцій не працюють. + +Будь ласка, використовуйте її лише для налагодження." + Необхідна авторизація + Керування чергою недоступне (%s). + Не вдалося ідентифікувати список відтворення + Черга порожня + Не вдалося ідентифікувати відео + Не вдалося додати відео. + Не вдалося створити чергу. + Не вдалося видалити чергу. + Не вдалося вилучити відео. + Не вдалося зберегти чергу. + Відео додано успішно. + Чергу створено успішно. + Чергу видалено успішно. + Відео вилучено успішно. + Чергу збережено успішно до: \'%s\'. Мова RVX Мова додатка - Арабська - Азербайджанська - Болгарська - Бенгальська - Каталонська - Чеська - Данська - Німецька - Грецька - Англійська - Іспанська - Естонська - Перська - Фінська - Французька - Гуджаратська - Хінді - Хорватська - Угорська - Індонезійська - Італійська - Японська - Казахська - Корейська - Литовська - Латвійська - Македонська - Монгольська - Маратхі - Малайська - Бірманська - Голландська - Одія - Пенджабі - Польська - Португальська - Румунська - Російська - Словацька - Словенська - Сербська - Шведська - Суахілі - Тамільська - Телуґу - Тайська - Турецька - Українська - Урду - В’єтнамська - Китайська + "Амхарська +አማርኛ" + "Арабська +العربية" + "Азербайджанська +Azərbaycan" + "Білоруська +Беларуская" + "Болгарська +Български" + "Бенгальська +বাংলা" + "Каталонська +Català" + "Чеська +Čeština" + "Данська +Dansk" + "Німецька +Deutsch" + "Грецька +Ελληνικά" + "Англійська +English" + "Іспанська +Español" + "Естонська +Eesti" + "Перська +فارسی" + "Фінська +Suomi" + "Французька +Français" + "Гуджараті +ગુજરાતી" + "Іврит +עברי" + "Хінді +हिन्दी" + "Хорватська +Hrvatski" + "Угорська +Magyar" + "Індонезійська +Indonesia" + "Італійська +Italiano" + "Японська +日本語" + "Казахська +Қазақ тілі" + "Корейська +한국어" + "Литовська +Lietuvių" + "Латвійська +Latviešu" + "Македонська +Македонски" + "Монгольська +Монгол" + "Маратхі +मराठी" + "Малайська +Melayu" + "Бірманська +ဗမာ" + "Нідерландська +Nederlands" + "Одія +ଓଡ଼ିଆ" + "Пенджабі +ਪੰਜਾਬੀ" + "Польська +Polski" + "Португальська +Português" + "Румунська +Română" + "Російська +Русский" + "Словацька +Slovenčina" + "Албанська +Shqip" + "Словенська +Slovenščina" + "Сербська +Српски" + "Шведська +Svenska" + "Суахілі +Kiswahili" + "Тамільська +தமிழ்" + "Телуґу +తెలుగు" + "Тайська +ไทย" + "Турецька +Türkçe" + "Українська +Українська" + "Урду +اردو" + "В'єтнамська +Tiếng Việt" + "Китайська +中文" Реклама Приховати банер магазину на кінцевому екрані @@ -430,6 +521,19 @@ • Shorts відкриваються у поточному плеєрі. • Стрічка організована за темами та каналами. • Опис відео не відкривається, якщо вимкнена функція 'Підробити дані трансляції'." + Вимкнути оновлення макета + Макет не оновлюватиметься сервером. + Макет оновлюватиметься сервером. + "Макет програми повертається до макета, який використовувався при першому встановленні. + +Деякі серверні макети можуть не повернутися. + +Зміни включають: +• Компоненти у випадаючому меню плеєра (чи пов'язані налаштування) можуть не працювати. +• Лічильники не анімовані. +• Використовується вкладку Бібліотека. +• Секція Музика опису відео може не працювати. +• Кнопка перемикання облікового запису може не з'являтися у вкладці Бібліотека. Використовуйте налаштування 'Увімкнути широку панель пошуку у вкладці Ви'." Підробити версію програми Версію підроблено Версію не підроблено @@ -447,8 +551,10 @@ 18.33.40 - відновлення старої панелі дій Shorts 18.38.45 - Відновлення старої поведінки типової якості відео 18.48.39 - Виключає \'переглянуті\' та \'вподобані\' з оновлення в режимі реального часу + 19.01.34 - Вимикання взаємодії з описом відео 19.26.42 - Вимикання значка Каїр в панелі навігації та інструментів 19.33.37 - Відновлення старої висувної панелі швидкості відтворення + Недійсне підроблення версії програми: %s. Меню облікового запису Приховувати чи показувати елементи меню облікового запису і вкладки Ви. @@ -484,6 +590,9 @@ Перевизначити кнопку завантаження відео Кнопка завантаження відео відкриває зовнішній завантажувач. Кнопка завантаження відео відкриває вбудований завантажувач. + Керування чергою + Кнопка завантаження відео відкриває керування чергою. + Кнопка завантаження відео відкриває зовнішній завантажувач. Ім\'я пакета завантажувача списку відтворення Ім\'я пакета встановленого зовнішнього завантажувача, наприклад YTDLnis. @@ -537,7 +646,6 @@ Увімкнути напівпрозорість панелі навігації Панель навігації напівпрозора. Панель навігації непрозора. - У певних версіях YouTube цей параметр може зробити панель навігації прозорою або порушити макет у режимі PIP. Приховати панель навігації Панель навігації приховано. Панель навігації показується. @@ -1116,6 +1224,8 @@ Натисніть, щоб вимкнути звук поточного відео. Натисніть знову, щоб увімкнути. Показувати кнопку зовнішнього завантажувача Натисніть для запуску зовнішнього завантажувача + Керування чергою + Замість запуску зовнішнього завантажувача відкриває керування чергою. Показувати кнопку Діалог швидкості "Натисніть, щоб відкрити діалог швидкості. Натисніть і утримуйте, щоб скинути швидкість відтворення до 1.0x. Натисніть і утримуйте ще раз, щоб скинути швидкість назад до типової." @@ -1415,7 +1525,6 @@ "Спеціальні дії увімкнено у висувному меню. Застереження: -• Не працює, якщо версію програми підроблено на 18.49.37 чи нижче. • Не працює з прямими трансляціями." Спеціальні дії вимкнено у висловному меню. Увімкнути спеціальні дії в панелі інструментів diff --git a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml index 67bdd30be..8450f5ce8 100644 --- a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml +++ b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml @@ -21,57 +21,6 @@ Hiện %s chưa được cài đặt. Hãy cài đặt và thử lại. Ngôn ngữ trong cài đặt RVX Theo ứng dụng - Tiếng Ả Rập - Tiếng Azerbaijan - Tiếng Bulgaria - Tiếng Bengal - Tiếng Catalan - Tiếng Séc - Tiếng Đan Mạch - Tiếng Đức - Tiếng Hy Lạp - Tiếng Anh - Tiếng Tây Ban Nha - Tiếng Estonia - Tiếng Ba Tư - Tiếng Phần Lan - Tiếng Pháp - Tiếng Gujarati - Tiếng Hindi - Tiếng Croatia - Tiếng Hungary - Tiếng Indonesia - Tiếng Ý - Tiếng Nhật - Tiếng Kazakh - Tiếng Hàn - Người Lithuania - Tiếng Latvia - Tiếng Macedonia - Tiếng Mông Cổ - Tiếng Marathi - Tiếng Mã Lai - Tiếng Miến Điện - Tiếng Hà Lan - Tiếng Odia - Tiếng Punjab - Tiếng Ba Lan - Tiếng Bồ Đào Nha - Tiếng Romania - Tiếng Nga - Tiếng Slovak - Tiếng Slovenia - Tiếng Serbia - Tiếng Thuỵ Điển - Tiếng Swahili - Tiếng Tamil - Tiếng Telugu - Tiếng Thái - Tiếng Thổ Nhĩ Kỳ - Tiếng Ukraina - Tiếng Urdu - Tiếng Việt - Tiếng Trung Quảng cáo Ẩn dải quảng cáo cửa hàng ở cuối video @@ -430,6 +379,19 @@ Bố cục màn hình ô tô • Video ngắn sẽ được mở trong trình phát thông thường. • Bảng tin được sắp xếp theo chủ đề và kênh. • Không thể mở mô tả video khi cài đặt \"Giả mạo luồng dữ liệu trực tuyến\" đang tắt." + Tắt cập nhật bố cục + Bố cục sẽ không được máy chủ cập nhật. + Bố cục sẽ được máy chủ cập nhật. + "Bố cục ứng dụng sẽ trở về như lần đầu bạn mở ứng dụng. + +Một số bố cục do máy chủ kiểm soát có thể không được hoàn nguyên. + +Các thay đổi bao gồm: +• Các mục trong trình đơn tuỳ chọn (hoặc các cài đặt liên quan) có thể không hoạt động. +• Hiệu ứng số cuộn không được hiển thị. +• Thẻ Thư viện được hiển thị thay vì thẻ Bạn. +• Phần Âm nhạc trong mô tả video có thể không hoạt động. +• Nút chuyển đổi tài khoản có thể không xuất hiện trong thẻ Thư viện. Hãy sử dụng tuỳ chọn \"Thanh tìm kiếm rộng trong thẻ Bạn\"." Giả mạo phiên bản ứng dụng Phiên bản được giả mạo Phiên bản không được giả mạo @@ -447,8 +409,10 @@ Nếu muốn tắt tính năng này sau đó, bạn nên xóa dữ liệu ứng 18.33.40 - Khôi phục thanh thao tác trình Shorts kiểu cũ 18.38.45 - Khôi phục phương thức áp dụng chất lượng video mặc định kiểu cũ 18.48.39 - Vô hiệu hoá cập nhật số \"lượt xem\" và \"lượt thích\" theo thời gian thực + 19.01.34 - Tắt tương tác với mô tả video 19.26.42 - Tắt biểu tượng Cairo trong thanh điều hướng và thanh công cụ 19.33.37 - Khôi phục bảng trình đơn tốc độ phát kiểu cũ + Phiên bản ứng dụng đã chọn không hợp lệ: %s. Trình đơn Tài khoản Ẩn hoặc hiển thị các mục của trình đơn Tài khoản và thẻ Bạn. @@ -537,7 +501,6 @@ Nếu cài đặt này không có hiệu lực, hãy thử chuyển sang chế Thanh điều hướng trong suốt Thanh điều hướng trong suốt đang được áp dụng. Thanh điều hướng mặc định đang được áp dụng. - Trong một số phiên bản YouTube, cài đặt này có thể khiến thanh điều hướng hệ thống trở nên trong suốt hoặc gây ra lỗi giao diện trong chế độ Hình trong hình (PIP). Ẩn thanh điều hướng Thanh điều hướng đã ẩn. Thanh điều hướng được hiển thị. @@ -634,7 +597,7 @@ Bạn có thể đổi màu nền cho chúng, nhưng nếu phía máy chủ thay Thanh tìm kiếm rộng với tiêu đề YouTube Thanh tìm kiếm rộng được hiển thị cùng với tiêu đề YouTube. Thanh tìm kiếm rộng đã ẩn và làm ẩn tiêu đề YouTube. - Thanh tìm kiếm rộng trên thẻ Bạn + Thanh tìm kiếm rộng trong thẻ Bạn "Thanh tìm kiếm rộng được bật trong thẻ Bạn. Để vào cài đặt, vui lòng thao tác theo đường dẫn sau: @@ -1408,10 +1371,9 @@ Chi tiết: Tác vụ tuỳ chỉnh Tác vụ tuỳ chỉnh trong trình đơn tuỳ chọn - "Tác vụ tuỳ chỉnh được bật trong trình đơn tuỳ chọn. + "Tác vụ tuỳ chỉnh đã được bật trong trình đơn tuỳ chọn. Hạn chế: -• Không hoạt động nếu phiên bản đang được giả mạo sang 18.49.37 hoặc cũ hơn nữa. • Không hoạt động đối với video phát trực tiếp." Tác vụ tuỳ chỉnh đã tắt trong trình đơn tuỳ chọn. Tác vụ tuỳ chỉnh trong thanh công cụ diff --git a/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml b/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml index 76505ebc0..1ac78882e 100644 --- a/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml @@ -20,57 +20,6 @@ %s 未安装,请先安装它。 RVX 语言 应用程序语言 - 阿拉伯语 - 阿塞拜疆语 - 保加利亚语 - 孟加拉语 - 加泰罗尼亚语 - 捷克语 - 丹麦语 - 德语 - 希腊语 - 英语 - 西班牙语 - 爱沙尼亚语 - 波斯语 - 芬兰语 - 法语 - 古吉拉特语 - 印地语 - 克罗地亚语 - 匈牙利语 - 印度尼西亚语 - 意大利语 - 日语 - 哈萨克语 - 韩语 - 立陶宛语 - 拉脱维亚语 - 马其顿语 - 蒙古语 - 马拉提语 - 马来西亚语 - 缅甸语 - 荷兰语 - 奥迪亚语 - 旁遮普语 - 波兰语 - 葡萄牙语 - 罗马尼亚语 - 俄语 - 斯洛伐克文 - 斯洛文尼亚语 - 塞尔维亚语 - 瑞典语 - 斯瓦希里语 - 泰米尔语 - 泰卢固语 - 泰语 - 土耳其语 - 乌克兰语 - 乌尔都语 - 越南语 - 中文 广告 隐藏片尾商店横幅 diff --git a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml index 4c6d7ebc5..ffcfb0a68 100644 --- a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml @@ -21,57 +21,6 @@ 未安裝 %s。請安裝該應用程式。 RVX 語言 應用程式語言 - 阿拉伯文 - 亞塞拜然文 - 保加利亞文 - 孟加拉文 - 加泰隆尼亞文 - 捷克文 - 丹麥文 - 德文 - 希臘文 - 英文 - 西班牙文 - 愛沙尼亞文 - 波斯文 - 芬蘭文 - 法文 - 古吉拉特文 - 印地文 - 克羅埃西亞文 - 匈牙利文 - 印尼文 - 義大利文 - 日文 - 哈薩克文 - 韓文 - 立陶宛文 - 拉脫維亞文 - 馬其頓文 - 蒙古文 - 馬拉提文 - 馬來文 - 緬甸文 - 荷蘭文 - 歐迪亞語 - 旁遮普語 - 波蘭語 - 葡萄牙語 - 羅馬尼亞語 - 俄語 - 斯洛伐克語 - 斯洛維尼亞語 - 塞爾維亞語 - 瑞典語 - 史瓦希利語 - 坦米爾語 - 泰盧固語 - 泰語 - 土耳其語 - 烏克蘭語 - 烏爾都語 - 越南語 - 中文 廣告 隱藏片尾商店橫幅 @@ -408,6 +357,22 @@ 變更點擊直播狀態頻道圖示的動作 "點擊直播按鈕 頻道將會開啟。" 點擊直播按鈕 直播將會開啟。 + 版面配置形式 + 預設 + 手機 + 手機 (最大 480 dp) + 平板 + 平板電腦 (最少 600 dp) + 車用 + "改變包括: + +平板佈局 +• 社群貼文被隱藏。 + +車用佈局 +• 常規播放器中的短影片開啟。 +• 資訊流依主題和頻道進行組織。 +• 關閉「偽裝串流資料」時無法開啟影片說明。" 偽裝應用程式版本 已偽裝版本 未偽裝版本 @@ -515,7 +480,6 @@ 啟用半透明導覽列 導覽列是半透明的。 導覽列不透明。 - 在某些 YouTube 版本中,此設定可以使系統導覽列透明,或在 PIP 模式下可以破壞佈局。 隱藏導覽列 導覽列已隱藏。 導覽列已顯示。 @@ -1913,6 +1877,14 @@ "啟用此功能可能會延長電池壽命並修復播放卡頓問題。 AVC 的最大解析度為 1080p,Opus 音訊編解碼器不可用,影片播放將使用比 VP9 或 AV1 更多的網路資料。" + 跳過單件式回應加密 + "跳過單件式回應加密。 + +• 修正了某些使用者遇到的新型播放問題。 +• AV1 編解碼器可能無法使用。" + "不要跳過單件式回應加密。 + +• 有些使用者可能會遇到新型播放問題。" 顯示統計資料 用於取得串流資料的用戶端顯示在統計資料中。 用於獲取串流資料的用戶端隱藏在統計資料中。 From 4bed9f346dd4a7401e806f5b579e90554f4642cd Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Mon, 24 Mar 2025 22:06:53 +0900 Subject: [PATCH 22/77] bump 5.6.1-dev.1 --- README.md | 142 +++++----- gradle.properties | 2 +- patches.json | 583 ++++++++++++++++------------------------ patches/api/patches.api | 23 +- 4 files changed, 320 insertions(+), 430 deletions(-) diff --git a/README.md b/README.md index 6273da940..f171d803f 100644 --- a/README.md +++ b/README.md @@ -11,72 +11,73 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `Alternative thumbnails` | Adds options to replace video thumbnails using the DeArrow API or image captures from the video. | 18.29.38 ~ 19.44.39 | -| `Ambient mode control` | Adds options to disable Ambient mode and to bypass Ambient mode restrictions. | 18.29.38 ~ 19.44.39 | -| `Bypass URL redirects` | Adds an option to bypass URL redirects and open the original URL directly. | 18.29.38 ~ 19.44.39 | -| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 18.29.38 ~ 19.44.39 | -| `Change form factor` | Adds an option to change the UI appearance to a phone, tablet, or automotive device. | 18.29.38 ~ 19.44.39 | -| `Change live ring click action` | Adds an option to open the channel instead of the live stream when clicking on the live ring. | 18.29.38 ~ 19.44.39 | -| `Change player flyout menu toggles` | Adds an option to use text toggles instead of switch toggles within the additional settings menu. | 18.29.38 ~ 19.44.39 | -| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 18.29.38 ~ 19.44.39 | -| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 18.29.38 ~ 19.44.39 | -| `Custom Shorts action buttons` | Changes, at compile time, the icon of the action buttons of the Shorts player. | 18.29.38 ~ 19.44.39 | -| `Custom branding icon for YouTube` | Changes the YouTube app icon to the icon specified in patch options. | 18.29.38 ~ 19.44.39 | -| `Custom branding name for YouTube` | Changes the YouTube app name to the name specified in patch options. | 18.29.38 ~ 19.44.39 | -| `Custom double tap length` | Adds Double-tap to seek values that are specified in patch options. | 18.29.38 ~ 19.44.39 | -| `Custom header for YouTube` | Applies a custom header in the top left corner within the app. | 18.29.38 ~ 19.44.39 | -| `Description components` | Adds options to hide and disable description components. | 18.29.38 ~ 19.44.39 | -| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 18.29.38 ~ 19.44.39 | -| `Disable forced auto audio tracks` | Adds an option to disable audio tracks from being automatically enabled. | 18.29.38 ~ 19.44.39 | -| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 18.29.38 ~ 19.44.39 | -| `Disable haptic feedback` | Adds options to disable haptic feedback when swiping in the video player. | 18.29.38 ~ 19.44.39 | -| `Disable resuming Miniplayer on startup` | Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup. | 18.29.38 ~ 19.44.39 | -| `Disable resuming Shorts on startup` | Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched. | 18.29.38 ~ 19.44.39 | -| `Disable splash animation` | Adds an option to disable the splash animation on app startup. | 18.29.38 ~ 19.44.39 | -| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 18.29.38 ~ 19.44.39 | -| `Enable debug logging` | Adds an option to enable debug logging. | 18.29.38 ~ 19.44.39 | -| `Enable gradient loading screen` | Adds an option to enable the gradient loading screen. | 18.29.38 ~ 19.44.39 | -| `Force hide player buttons background` | Removes, at compile time, the dark background surrounding the video player controls. | 18.29.38 ~ 19.44.39 | -| `Fullscreen components` | Adds options to hide or change components related to fullscreen. | 18.29.38 ~ 19.44.39 | -| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 18.29.38 ~ 19.44.39 | -| `Hide Shorts dimming` | Removes, at compile time, the dimming effect at the top and bottom of Shorts videos. | 18.29.38 ~ 19.44.39 | -| `Hide accessibility controls dialog` | Removes, at compile time, accessibility controls dialog 'Turn on accessibility controls for the video player?'. | 18.29.38 ~ 19.44.39 | -| `Hide action buttons` | Adds options to hide action buttons under videos. | 18.29.38 ~ 19.44.39 | -| `Hide ads` | Adds options to hide ads. | 18.29.38 ~ 19.44.39 | -| `Hide comments components` | Adds options to hide components related to comments. | 18.29.38 ~ 19.44.39 | -| `Hide feed components` | Adds options to hide components related to feeds. | 18.29.38 ~ 19.44.39 | -| `Hide feed flyout menu` | Adds the ability to hide feed flyout menu components using a custom filter. | 18.29.38 ~ 19.44.39 | -| `Hide layout components` | Adds options to hide general layout components. | 18.29.38 ~ 19.44.39 | -| `Hide player buttons` | Adds options to hide buttons in the video player. | 18.29.38 ~ 19.44.39 | -| `Hide player flyout menu` | Adds options to hide player flyout menu components. | 18.29.38 ~ 19.44.39 | -| `Hide shortcuts` | Remove, at compile time, the app shortcuts that appears when the app icon is long pressed. | 18.29.38 ~ 19.44.39 | -| `Hook YouTube Music actions` | Adds support for opening music in RVX Music using the in-app YouTube Music button. | 18.29.38 ~ 19.44.39 | -| `Hook download actions` | Adds support to download videos with an external downloader app using the in-app download button. | 18.29.38 ~ 19.44.39 | -| `MaterialYou` | Applies the MaterialYou theme for Android 12+ devices. | 18.29.38 ~ 19.44.39 | -| `Miniplayer` | Adds options to change the in-app minimized player, and if patching target 19.16+ adds options to use modern miniplayers. | 18.29.38 ~ 19.44.39 | -| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 18.29.38 ~ 19.44.39 | -| `Open links externally` | Adds an option to always open links in your browser instead of the in-app browser. | 18.29.38 ~ 19.44.39 | -| `Overlay buttons` | Adds options to display useful overlay buttons in the video player. | 18.29.38 ~ 19.44.39 | -| `Player components` | Adds options to hide or change components related to the video player. | 18.29.38 ~ 19.44.39 | -| `Remove background playback restrictions` | Removes restrictions on background playback, including for music and kids videos. | 18.29.38 ~ 19.44.39 | -| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 18.29.38 ~ 19.44.39 | -| `Return YouTube Dislike` | Adds an option to show the dislike count of videos using the Return YouTube Dislike API. | 18.29.38 ~ 19.44.39 | -| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 18.29.38 ~ 19.44.39 | -| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 18.29.38 ~ 19.44.39 | -| `Seekbar components` | Adds options to hide or change components related to the seekbar. | 18.29.38 ~ 19.44.39 | -| `Settings for YouTube` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 18.29.38 ~ 19.44.39 | -| `Shorts components` | Adds options to hide or change components related to YouTube Shorts. | 18.29.38 ~ 19.44.39 | -| `Snack bar components` | Adds options to hide or change components related to the snack bar. | 18.29.38 ~ 19.44.39 | -| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content. | 18.29.38 ~ 19.44.39 | -| `Spoof app version` | Adds options to spoof the YouTube client version. This can be used to restore old UI elements and features. | 18.29.38 ~ 19.44.39 | -| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 18.29.38 ~ 19.44.39 | -| `Swipe controls` | Adds options for controlling volume and brightness with swiping, and whether to enter fullscreen when swiping down below the player. | 18.29.38 ~ 19.44.39 | -| `Theme` | Changes the app's themes to the values specified in patch options. | 18.29.38 ~ 19.44.39 | -| `Toolbar components` | Adds options to hide or change components located on the toolbar, such as the search bar, header, and toolbar buttons. | 18.29.38 ~ 19.44.39 | -| `Translations for YouTube` | Add translations or remove string resources. | 18.29.38 ~ 19.44.39 | -| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 18.29.38 ~ 19.44.39 | -| `Visual preferences icons for YouTube` | Adds icons to specific preferences in the settings. | 18.29.38 ~ 19.44.39 | -| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 18.29.38 ~ 19.44.39 | +| `Alternative thumbnails` | Adds options to replace video thumbnails using the DeArrow API or image captures from the video. | 19.05.36 ~ 19.47.53 | +| `Ambient mode control` | Adds options to disable Ambient mode and to bypass Ambient mode restrictions. | 19.05.36 ~ 19.47.53 | +| `Bypass URL redirects` | Adds an option to bypass URL redirects and open the original URL directly. | 19.05.36 ~ 19.47.53 | +| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 19.05.36 ~ 19.47.53 | +| `Change form factor` | Adds an option to change the UI appearance to a phone, tablet, or automotive device. | 19.05.36 ~ 19.47.53 | +| `Change live ring click action` | Adds an option to open the channel instead of the live stream when clicking on the live ring. | 19.05.36 ~ 19.47.53 | +| `Change player flyout menu toggles` | Adds an option to use text toggles instead of switch toggles within the additional settings menu. | 19.05.36 ~ 19.47.53 | +| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 19.05.36 ~ 19.47.53 | +| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 19.05.36 ~ 19.47.53 | +| `Custom Shorts action buttons` | Changes, at compile time, the icon of the action buttons of the Shorts player. | 19.05.36 ~ 19.47.53 | +| `Custom branding icon for YouTube` | Changes the YouTube app icon to the icon specified in patch options. | 19.05.36 ~ 19.47.53 | +| `Custom branding name for YouTube` | Changes the YouTube app name to the name specified in patch options. | 19.05.36 ~ 19.47.53 | +| `Custom double tap length` | Adds Double-tap to seek values that are specified in patch options. | 19.05.36 ~ 19.47.53 | +| `Custom header for YouTube` | Applies a custom header in the top left corner within the app. | 19.05.36 ~ 19.47.53 | +| `Description components` | Adds options to hide and disable description components. | 19.05.36 ~ 19.47.53 | +| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 19.05.36 ~ 19.47.53 | +| `Disable forced auto audio tracks` | Adds an option to disable audio tracks from being automatically enabled. | 19.05.36 ~ 19.47.53 | +| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 19.05.36 ~ 19.47.53 | +| `Disable haptic feedback` | Adds options to disable haptic feedback when swiping in the video player. | 19.05.36 ~ 19.47.53 | +| `Disable layout updates` | Adds an option to disable layout updates by server. | 19.05.36 ~ 19.47.53 | +| `Disable resuming Miniplayer on startup` | Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup. | 19.05.36 ~ 19.47.53 | +| `Disable resuming Shorts on startup` | Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched. | 19.05.36 ~ 19.47.53 | +| `Disable splash animation` | Adds an option to disable the splash animation on app startup. | 19.05.36 ~ 19.47.53 | +| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 19.05.36 ~ 19.47.53 | +| `Enable debug logging` | Adds an option to enable debug logging. | 19.05.36 ~ 19.47.53 | +| `Enable gradient loading screen` | Adds an option to enable the gradient loading screen. | 19.05.36 ~ 19.47.53 | +| `Force hide player buttons background` | Removes, at compile time, the dark background surrounding the video player controls. | 19.05.36 ~ 19.47.53 | +| `Fullscreen components` | Adds options to hide or change components related to fullscreen. | 19.05.36 ~ 19.47.53 | +| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 19.05.36 ~ 19.47.53 | +| `Hide Shorts dimming` | Removes, at compile time, the dimming effect at the top and bottom of Shorts videos. | 19.05.36 ~ 19.47.53 | +| `Hide accessibility controls dialog` | Removes, at compile time, accessibility controls dialog 'Turn on accessibility controls for the video player?'. | 19.05.36 ~ 19.47.53 | +| `Hide action buttons` | Adds options to hide action buttons under videos. | 19.05.36 ~ 19.47.53 | +| `Hide ads` | Adds options to hide ads. | 19.05.36 ~ 19.47.53 | +| `Hide comments components` | Adds options to hide components related to comments. | 19.05.36 ~ 19.47.53 | +| `Hide feed components` | Adds options to hide components related to feeds. | 19.05.36 ~ 19.47.53 | +| `Hide feed flyout menu` | Adds the ability to hide feed flyout menu components using a custom filter. | 19.05.36 ~ 19.47.53 | +| `Hide layout components` | Adds options to hide general layout components. | 19.05.36 ~ 19.47.53 | +| `Hide player buttons` | Adds options to hide buttons in the video player. | 19.05.36 ~ 19.47.53 | +| `Hide player flyout menu` | Adds options to hide player flyout menu components. | 19.05.36 ~ 19.47.53 | +| `Hide shortcuts` | Remove, at compile time, the app shortcuts that appears when the app icon is long pressed. | 19.05.36 ~ 19.47.53 | +| `Hook YouTube Music actions` | Adds support for opening music in RVX Music using the in-app YouTube Music button. | 19.05.36 ~ 19.47.53 | +| `Hook download actions` | Adds support to download videos with an external downloader app using the in-app download button. | 19.05.36 ~ 19.47.53 | +| `MaterialYou` | Applies the MaterialYou theme for Android 12+ devices. | 19.05.36 ~ 19.47.53 | +| `Miniplayer` | Adds options to change the in-app minimized player, and if patching target 19.16+ adds options to use modern miniplayers. | 19.05.36 ~ 19.47.53 | +| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 19.05.36 ~ 19.47.53 | +| `Open links externally` | Adds an option to always open links in your browser instead of the in-app browser. | 19.05.36 ~ 19.47.53 | +| `Overlay buttons` | Adds options to display useful overlay buttons in the video player. | 19.05.36 ~ 19.47.53 | +| `Player components` | Adds options to hide or change components related to the video player. | 19.05.36 ~ 19.47.53 | +| `Remove background playback restrictions` | Removes restrictions on background playback, including for music and kids videos. | 19.05.36 ~ 19.47.53 | +| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 19.05.36 ~ 19.47.53 | +| `Return YouTube Dislike` | Adds an option to show the dislike count of videos using the Return YouTube Dislike API. | 19.05.36 ~ 19.47.53 | +| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 19.05.36 ~ 19.47.53 | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 19.05.36 ~ 19.47.53 | +| `Seekbar components` | Adds options to hide or change components related to the seekbar. | 19.05.36 ~ 19.47.53 | +| `Settings for YouTube` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 19.05.36 ~ 19.47.53 | +| `Shorts components` | Adds options to hide or change components related to YouTube Shorts. | 19.05.36 ~ 19.47.53 | +| `Snack bar components` | Adds options to hide or change components related to the snack bar. | 19.05.36 ~ 19.47.53 | +| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content. | 19.05.36 ~ 19.47.53 | +| `Spoof app version` | Adds options to spoof the YouTube client version. This can be used to restore old UI elements and features. | 19.05.36 ~ 19.47.53 | +| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 19.05.36 ~ 19.47.53 | +| `Swipe controls` | Adds options for controlling volume and brightness with swiping, and whether to enter fullscreen when swiping down below the player. | 19.05.36 ~ 19.47.53 | +| `Theme` | Changes the app's themes to the values specified in patch options. | 19.05.36 ~ 19.47.53 | +| `Toolbar components` | Adds options to hide or change components located on the toolbar, such as the search bar, header, and toolbar buttons. | 19.05.36 ~ 19.47.53 | +| `Translations for YouTube` | Add translations or remove string resources. | 19.05.36 ~ 19.47.53 | +| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 19.05.36 ~ 19.47.53 | +| `Visual preferences icons for YouTube` | Adds icons to specific preferences in the settings. | 19.05.36 ~ 19.47.53 | +| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 19.05.36 ~ 19.47.53 | ### [📦 `com.google.android.apps.youtube.music`](https://play.google.com/store/apps/details?id=com.google.android.apps.youtube.music) @@ -121,7 +122,6 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | `Settings for YouTube Music` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 6.20.51 ~ 8.10.51 | | `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as non-music sections. | 6.20.51 ~ 8.10.51 | | `Spoof app version` | Adds options to spoof the YouTube Music client version. This can be used to restore old UI elements and features. | 6.51.53 ~ 7.16.53 | -| `Spoof client` | Adds options to spoof the client to allow playback. | 6.20.51 ~ 8.10.51 | | `Spoof player parameter` | Adds options to spoof player parameter to allow playback. | 6.20.51 ~ 8.10.51 | | `Translations for YouTube Music` | Add translations or remove string resources. | 6.20.51 ~ 8.10.51 | | `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 6.20.51 ~ 8.10.51 | @@ -165,13 +165,11 @@ Example: "use":true, "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] diff --git a/gradle.properties b/gradle.properties index 8b8969587..05834439c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official kotlin.jvm.target.validation.mode = IGNORE -version = 5.5.1 +version = 5.6.1-dev.1 diff --git a/patches.json b/patches.json index 93b46884c..c016eadaa 100644 --- a/patches.json +++ b/patches.json @@ -11,13 +11,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -32,13 +30,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -73,13 +69,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -116,13 +110,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -157,13 +149,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -180,13 +170,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -227,13 +215,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -272,13 +258,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -314,13 +298,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -356,13 +338,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -394,13 +374,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -532,13 +510,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -617,13 +593,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -647,13 +621,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -768,13 +740,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -853,13 +823,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -886,6 +854,14 @@ }, "options": [] }, + { + "name": "Disable edge-to-edge display", + "description": "Disable forced edge-to-edge display on Android 15+ by changing the app\u0027s target SDK version. This patch does not work if the app is installed by mounting.", + "use": false, + "dependencies": [], + "compatiblePackages": null, + "options": [] + }, { "name": "Disable forced auto audio tracks", "description": "Adds an option to disable audio tracks from being automatically enabled.", @@ -895,13 +871,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -938,13 +912,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -958,13 +930,29 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" + ] + }, + "options": [] + }, + { + "name": "Disable layout updates", + "description": "Adds an option to disable layout updates by server.", + "use": true, + "dependencies": [ + "Settings for YouTube" + ], + "compatiblePackages": { + "com.google.android.youtube": [ + "19.05.36", + "19.16.39", + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1001,13 +989,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1022,13 +1008,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1059,13 +1043,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1102,13 +1084,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1143,13 +1123,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1163,13 +1141,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1233,13 +1209,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1260,13 +1234,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1348,13 +1320,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -1428,13 +1398,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1448,13 +1416,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1519,13 +1485,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1587,13 +1551,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1610,13 +1572,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1637,13 +1597,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1658,13 +1616,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1708,13 +1664,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1769,13 +1723,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1793,13 +1745,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1848,13 +1798,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -1905,13 +1853,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1921,19 +1867,18 @@ "description": "Adds support to download videos with an external downloader app using the in-app download button.", "use": true, "dependencies": [ + "BytecodePatch", "BytecodePatch", "ResourcePatch", "Settings for YouTube" ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1948,13 +1893,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -1970,13 +1913,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2019,13 +1960,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2072,13 +2011,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2092,18 +2029,17 @@ "BytecodePatch", "BytecodePatch", "ResourcePatch", + "BytecodePatch", "ResourcePatch", "Settings for YouTube" ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -2198,13 +2134,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2254,13 +2188,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2312,13 +2244,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2379,13 +2309,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2423,13 +2351,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2481,13 +2407,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2507,13 +2431,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2560,13 +2482,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -2673,13 +2593,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2694,13 +2612,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -2808,13 +2724,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -2868,38 +2782,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" - ] - }, - "options": [] - }, - { - "name": "Spoof client", - "description": "Adds options to spoof the client to allow playback.", - "use": false, - "dependencies": [ - "Settings for YouTube Music", - "ResourcePatch", - "BytecodePatch", - "ResourcePatch", - "BytecodePatch" - ], - "compatiblePackages": { - "com.google.android.apps.youtube.music": [ - "6.20.51", - "6.29.59", - "6.42.55", - "6.51.53", - "7.16.53", - "7.25.53", - "8.05.51", - "8.10.51" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2940,13 +2827,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2965,13 +2850,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -2986,13 +2869,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -3048,13 +2929,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -3068,13 +2947,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -3093,7 +2970,7 @@ "description": "A list of translations to be added for the RVX settings, separated by commas.", "required": true, "type": "kotlin.String", - "default": "ar, bg-rBG, de-rDE, el-rGR, es-rES, fr-rFR, hu-rHU, it-rIT, ja-rJP, ko-rKR, pl-rPL, pt-rBR, ru-rRU, tr-rTR, uk-rUA, vi-rVN, zh-rCN, zh-rTW", + "default": "ar, bg-rBG, de-rDE, el-rGR, es-rES, fr-rFR, hu-rHU, id-rID, in, it-rIT, ja-rJP, ko-rKR, pl-rPL, pt-rBR, ru-rRU, tr-rTR, uk-rUA, vi-rVN, zh-rCN, zh-rTW", "values": null }, { @@ -3197,13 +3074,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] @@ -3217,13 +3092,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [ @@ -3323,13 +3196,11 @@ ], "compatiblePackages": { "com.google.android.youtube": [ - "18.29.38", - "18.33.40", - "18.38.44", - "18.48.39", "19.05.36", "19.16.39", - "19.44.39" + "19.43.41", + "19.44.39", + "19.47.53" ] }, "options": [] diff --git a/patches/api/patches.api b/patches/api/patches.api index 30b027aeb..3208bf21c 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -6,6 +6,10 @@ public final class app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWi public static final fun getSpoofWifiPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/all/misc/display/edgetoedge/EdgeToEdgeDisplayPatchKt { + public static final fun getEdgeToEdgeDisplayPatch ()Lapp/revanced/patcher/patch/ResourcePatch; +} + public abstract interface class app/revanced/patches/all/misc/transformation/IMethodCall { public abstract fun getDefinedClassName ()Ljava/lang/String; public abstract fun getMethodName ()Ljava/lang/String; @@ -281,6 +285,7 @@ public final class app/revanced/patches/music/utils/resourceid/SharedResourceIdP public static final fun getPrivacyTosFooter ()J public static final fun getQualityAuto ()J public static final fun getRemixGenericButtonSize ()J + public static final fun getSearchButton ()J public static final fun getSlidingDialogAnimation ()J public static final fun getTapBloomView ()J public static final fun getText1 ()J @@ -715,6 +720,10 @@ public final class app/revanced/patches/youtube/general/toolbar/ToolBarComponent public static final fun getToolBarComponentsPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/general/updates/LayoutUpdatesPatchKt { + public static final fun getLayoutUpdatesPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/youtube/layout/actionbuttons/ShortsActionButtonsPatchKt { public static final fun getShortsActionButtonsPatch ()Lapp/revanced/patcher/patch/ResourcePatch; } @@ -1013,6 +1022,10 @@ public final class app/revanced/patches/youtube/utils/playertype/PlayerTypeHookP public static final fun getPlayerTypeHookPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/youtube/utils/playlist/PlaylistPatchKt { + public static final fun getPlaylistPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/youtube/utils/playservice/VersionCheckPatchKt { public static final fun getVersionCheckPatch ()Lapp/revanced/patcher/patch/ResourcePatch; public static final fun is_18_31_or_greater ()Z @@ -1020,12 +1033,15 @@ public final class app/revanced/patches/youtube/utils/playservice/VersionCheckPa public static final fun is_18_39_or_greater ()Z public static final fun is_18_42_or_greater ()Z public static final fun is_18_49_or_greater ()Z + public static final fun is_19_01_or_greater ()Z public static final fun is_19_02_or_greater ()Z public static final fun is_19_04_or_greater ()Z + public static final fun is_19_05_or_greater ()Z public static final fun is_19_09_or_greater ()Z public static final fun is_19_15_or_greater ()Z public static final fun is_19_16_or_greater ()Z public static final fun is_19_17_or_greater ()Z + public static final fun is_19_18_or_greater ()Z public static final fun is_19_23_or_greater ()Z public static final fun is_19_25_or_greater ()Z public static final fun is_19_26_or_greater ()Z @@ -1043,7 +1059,9 @@ public final class app/revanced/patches/youtube/utils/playservice/VersionCheckPa public static final fun is_20_02_or_greater ()Z public static final fun is_20_03_or_greater ()Z public static final fun is_20_05_or_greater ()Z + public static final fun is_20_09_or_greater ()Z public static final fun is_20_10_or_greater ()Z + public static final fun is_20_12_or_greater ()Z } public final class app/revanced/patches/youtube/utils/recyclerview/RecyclerViewTreeObserverPatchKt { @@ -1145,7 +1163,6 @@ public final class app/revanced/patches/youtube/utils/resourceid/SharedResourceI public static final fun getRelatedChipCloudMargin ()J public static final fun getRightComment ()J public static final fun getScrimOverlay ()J - public static final fun getScrubbing ()J public static final fun getSeekEasyHorizontalTouchOffsetToStartScrubbing ()J public static final fun getSeekUndoEduOverlayStub ()J public static final fun getSettingsFragment ()J @@ -1160,13 +1177,17 @@ public final class app/revanced/patches/youtube/utils/resourceid/SharedResourceI public static final fun getTotalTime ()J public static final fun getTouchArea ()J public static final fun getVarispeedUnavailableTitle ()J + public static final fun getVerticalTouchOffsetToEnterFineScrubbing ()J + public static final fun getVerticalTouchOffsetToStartFineScrubbing ()J public static final fun getVideoQualityBottomSheet ()J public static final fun getVideoQualityUnavailableAnnouncement ()J public static final fun getVideoZoomSnapIndicator ()J public static final fun getVoiceSearch ()J public static final fun getYouTubeControlsOverlaySubtitleButton ()J public static final fun getYouTubeLogo ()J + public static final fun getYtCallToAction ()J public static final fun getYtFillBell ()J + public static final fun getYtOutlineLibrary ()J public static final fun getYtOutlineMoonZ ()J public static final fun getYtOutlinePictureInPictureWhite ()J public static final fun getYtOutlineVideoCamera ()J From 123082b6767c60518828cd98b3c5a635bbc53576 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 26 Mar 2025 12:31:03 +0900 Subject: [PATCH 23/77] refactor(InnterTube): Move classes to the appropriate path --- .../patches/misc/requests/PlaylistRequest.kt | 13 +- .../client/YouTubeAppClient.kt | 42 +--- .../client/YouTubeMusicAppClient.java} | 6 +- .../client/YouTubeWebClient.kt | 10 +- .../requests/InnerTubeRequestBody.kt} | 199 +++++++----------- .../innertube/requests/InnerTubeRoutes.kt | 108 ++++++++++ .../patches/spoof/SpoofClientPatch.java | 6 +- .../spoof/SpoofStreamingDataPatch.java | 10 +- .../spoof/requests/StreamingDataRequest.kt | 136 ++++-------- .../shared/settings/BaseSettings.java | 11 +- .../general/requests/VideoDetailsRequest.kt | 13 +- .../player/requests/ActionButtonRequest.kt | 66 +++--- .../utils/requests/CreatePlaylistRequest.kt | 107 ++++------ .../utils/requests/DeletePlaylistRequest.kt | 53 ++--- .../utils/requests/EditPlaylistRequest.kt | 67 ++---- .../utils/requests/GetPlaylistsRequest.kt | 55 ++--- .../utils/requests/SavePlaylistRequest.kt | 56 ++--- .../patches/video/requests/MusicRequest.kt | 23 +- 18 files changed, 405 insertions(+), 576 deletions(-) rename extensions/shared/src/main/java/app/revanced/extension/shared/{patches => innertube}/client/YouTubeAppClient.kt (90%) rename extensions/shared/src/main/java/app/revanced/extension/shared/{patches/client/MusicAppClient.java => innertube/client/YouTubeMusicAppClient.java} (98%) rename extensions/shared/src/main/java/app/revanced/extension/shared/{patches => innertube}/client/YouTubeWebClient.kt (72%) rename extensions/shared/src/main/java/app/revanced/extension/shared/{patches/spoof/requests/PlayerRoutes.kt => innertube/requests/InnerTubeRequestBody.kt} (68%) create mode 100644 extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRoutes.kt diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/requests/PlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/requests/PlaylistRequest.kt index 90fb6f963..62b98a5e3 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/requests/PlaylistRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/requests/PlaylistRequest.kt @@ -2,8 +2,10 @@ package app.revanced.extension.music.patches.misc.requests import android.annotation.SuppressLint import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.createApplicationRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.GET_PLAYLIST_PAGE import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.settings.AppLanguage import app.revanced.extension.shared.utils.Logger @@ -136,10 +138,11 @@ class PlaylistRequest private constructor( Logger.printDebug { "Fetching playlist request for: $videoId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.GET_PLAYLIST_PAGE, + val connection = getInnerTubeResponseConnectionFromRoute( + GET_PLAYLIST_PAGE, clientType ) + /** * For some reason, the tracks in Top Songs have the playlistId of the album: * [ReVanced_Extended#2835](https://github.com/inotia00/ReVanced_Extended/issues/2835) @@ -152,7 +155,7 @@ class PlaylistRequest private constructor( * So we can work around this by setting the language to English when sending the request. */ val requestBody = - PlayerRoutes.createApplicationRequestBody( + createApplicationRequestBody( clientType = clientType, videoId = videoId, playlistId = playlistId, diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeAppClient.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeAppClient.kt similarity index 90% rename from extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeAppClient.kt rename to extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeAppClient.kt index f32c1b425..4c0ddbbda 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeAppClient.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeAppClient.kt @@ -1,4 +1,4 @@ -package app.revanced.extension.shared.patches.client +package app.revanced.extension.shared.innertube.client import android.os.Build import app.revanced.extension.shared.settings.BaseSettings @@ -11,24 +11,6 @@ import java.util.Locale */ object YouTubeAppClient { // IOS - /** - * Video not playable: Paid / Movie / Private / Age-restricted - * Note: Audio track available - */ - private const val PACKAGE_NAME_IOS = "com.google.ios.youtube" - - /** - * The hardcoded client version of the iOS app used for InnerTube requests with this client. - * - * It can be extracted by getting the latest release version of the app on - * [the App Store page of the YouTube app](https://apps.apple.com/us/app/youtube-watch-listen-stream/id544007664/), - * in the `What’s New` section. - */ - private val CLIENT_VERSION_IOS = if (forceAVC()) - "17.40.5" - else - "20.10.4" - private const val DEVICE_MAKE_IOS = "Apple" private const val OS_NAME_IOS = "iOS" @@ -49,7 +31,6 @@ object YouTubeAppClient { "13_7" else "18_3_2" - private val USER_AGENT_IOS = iOSUserAgent(PACKAGE_NAME_IOS, CLIENT_VERSION_IOS) // IOS UNPLUGGED @@ -202,6 +183,7 @@ object YouTubeAppClient { * Example: 'com.google.ios.youtube/16.38.2 (iPhone9,4; U; CPU iOS 14_7_1 like Mac OS X; en_AU)' * Source: https://github.com/mitmproxy/mitmproxy/issues/4836. */ + @Suppress("SameParameterValue") private fun iOSUserAgent( packageName: String, clientVersion: String @@ -278,10 +260,6 @@ object YouTubeAppClient { * If true, 'Authorization' must be included. */ val requireAuth: Boolean = false, - /** - * Whether a poToken is required to get playback for more than 1 minute. - */ - val requirePoToken: Boolean = false, /** * Client name for innertube body. */ @@ -362,22 +340,6 @@ object YouTubeAppClient { "iOS TV Force AVC" else "iOS TV" - ), - IOS( - id = 5, - deviceMake = DEVICE_MAKE_IOS, - deviceModel = DEVICE_MODEL_IOS, - osName = OS_NAME_IOS, - osVersion = OS_VERSION_IOS, - userAgent = USER_AGENT_IOS, - clientVersion = CLIENT_VERSION_IOS, - supportsCookies = false, - requirePoToken = true, - clientName = "IOS", - friendlyName = if (forceAVC()) - "iOS Force AVC" - else - "iOS" ); companion object { diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/MusicAppClient.java b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeMusicAppClient.java similarity index 98% rename from extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/MusicAppClient.java rename to extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeMusicAppClient.java index 21b580c8d..24081156a 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/MusicAppClient.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeMusicAppClient.java @@ -1,10 +1,10 @@ -package app.revanced.extension.shared.patches.client; +package app.revanced.extension.shared.innertube.client; import android.os.Build; import java.util.Locale; -public class MusicAppClient { +public class YouTubeMusicAppClient { // Response to the '/next' request is 'Please update to continue using the app': // https://github.com/inotia00/ReVanced_Extended/issues/2743 @@ -46,7 +46,7 @@ public class MusicAppClient { private static final String DEVICE_MAKE_IOS_MUSIC = "Apple"; private static final String OS_NAME_IOS_MUSIC = "iOS"; - private MusicAppClient() { + private YouTubeMusicAppClient() { } private static String androidUserAgent(String clientVersion) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeWebClient.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeWebClient.kt similarity index 72% rename from extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeWebClient.kt rename to extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeWebClient.kt index 331d1d9a4..3f9c5e8c0 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/client/YouTubeWebClient.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeWebClient.kt @@ -1,14 +1,10 @@ -package app.revanced.extension.shared.patches.client +package app.revanced.extension.shared.innertube.client /** * Used to fetch video information. */ @Suppress("unused") object YouTubeWebClient { - /** - * This user agent does not require a PoToken in [ClientType.MWEB] - * https://github.com/yt-dlp/yt-dlp/blob/0b6b7742c2e7f2a1fcb0b54ef3dd484bab404b3f/yt_dlp/extractor/youtube.py#L259 - */ private const val USER_AGENT_SAFARI = "Mozilla/5.0 (iPad; CPU OS 16_7_10 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1,gzip(gfe)" @@ -26,11 +22,11 @@ object YouTubeWebClient { * Client version. */ @JvmField - val clientVersion: String + val clientVersion: String, ) { MWEB( id = 2, - clientVersion = "2.20241202.07.00" + clientVersion = "2.20241202.07.00", ), WEB_REMIX( id = 29, diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRequestBody.kt similarity index 68% rename from extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt rename to extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRequestBody.kt index 5ef4a4212..9e6154bbd 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/PlayerRoutes.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRequestBody.kt @@ -1,9 +1,8 @@ -package app.revanced.extension.shared.patches.spoof.requests +package app.revanced.extension.shared.innertube.requests -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.client.YouTubeWebClient +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.client.YouTubeWebClient import app.revanced.extension.shared.requests.Requester -import app.revanced.extension.shared.requests.Route import app.revanced.extension.shared.requests.Route.CompiledRoute import app.revanced.extension.shared.settings.BaseSettings import app.revanced.extension.shared.utils.Logger @@ -21,96 +20,17 @@ import java.util.Locale import java.util.TimeZone @Suppress("deprecation") -object PlayerRoutes { - @JvmField - val CREATE_PLAYLIST: CompiledRoute = Route( - Route.Method.POST, - "playlist/create" + - "?prettyPrint=false" + - "&fields=playlistId" - ).compile() - - @JvmField - val DELETE_PLAYLIST: CompiledRoute = Route( - Route.Method.POST, - "playlist/delete" + - "?prettyPrint=false" - ).compile() - - @JvmField - val EDIT_PLAYLIST: CompiledRoute = Route( - Route.Method.POST, - "browse/edit_playlist" + - "?prettyPrint=false" + - "&fields=status," + - "playlistEditResults" - ).compile() - - @JvmField - val GET_PLAYLISTS: CompiledRoute = Route( - Route.Method.POST, - "playlist/get_add_to_playlist" + - "?prettyPrint=false" + - "&fields=contents.addToPlaylistRenderer.playlists.playlistAddToOptionRenderer" - ).compile() - - @JvmField - val GET_CATEGORY: CompiledRoute = Route( - Route.Method.POST, - "player" + - "?prettyPrint=false" + - "&fields=microformat.playerMicroformatRenderer.category" - ).compile() - - @JvmField - val GET_SET_VIDEO_ID: CompiledRoute = Route( - Route.Method.POST, - "next" + - "?prettyPrint=false" + - "&fields=contents.singleColumnWatchNextResults." + - "playlist.playlist.contents.playlistPanelVideoRenderer." + - "playlistSetVideoId" - ).compile() - - @JvmField - val GET_PLAYLIST_PAGE: CompiledRoute = Route( - Route.Method.POST, - "next" + - "?prettyPrint=false" + - "&fields=contents.singleColumnWatchNextResults.playlist.playlist" - ).compile() - - @JvmField - val GET_STREAMING_DATA: CompiledRoute = Route( - Route.Method.POST, - "player" + - "?fields=streamingData" + - "&alt=proto" - ).compile() - - @JvmField - val GET_VIDEO_ACTION_BUTTON: CompiledRoute = Route( - Route.Method.POST, - "next" + - "?prettyPrint=false" + - "&fields=contents.singleColumnWatchNextResults." + - "results.results.contents.slimVideoMetadataSectionRenderer." + - "contents.elementRenderer.newElement.type.componentType." + - "model.videoActionBarModel.buttons.buttonViewModel" - ).compile() - - @JvmField - val GET_VIDEO_DETAILS: CompiledRoute = Route( - Route.Method.POST, - "player" + - "?prettyPrint=false" + - "&fields=videoDetails.channelId," + - "videoDetails.isLiveContent," + - "videoDetails.isUpcoming" - ).compile() +object InnerTubeRequestBody { private const val YT_API_URL = "https://youtubei.googleapis.com/youtubei/v1/" + private const val AUTHORIZATION_HEADER = "Authorization" + private val REQUEST_HEADER_KEYS = setOf( + AUTHORIZATION_HEADER, // Available only to logged-in users. + "X-GOOG-API-FORMAT-VERSION", + "X-Goog-Visitor-Id" + ) + /** * TCP connection and HTTP read timeout */ @@ -230,16 +150,10 @@ object PlayerRoutes { client.put("osName", clientType.osName) client.put("osVersion", clientType.osVersion) client.put("androidSdkVersion", clientType.androidSdkVersion) - if (clientType.gmscoreVersionCode != null) { - client.put("gmscoreVersionCode", clientType.gmscoreVersionCode) - } - client.put( - "hl", - LOCALE_LANGUAGE - ) + client.put("hl", LOCALE_LANGUAGE) client.put("gl", LOCALE_COUNTRY) client.put("timeZone", TIME_ZONE_ID) - client.put("utcOffsetMinutes", "$UTC_OFFSET_MINUTES") + client.put("utcOffsetMinutes", UTC_OFFSET_MINUTES.toString()) val context = JSONObject() context.put("client", client) @@ -269,7 +183,7 @@ object PlayerRoutes { videoIds.put(0, videoId) innerTubeBody.put("videoIds", videoIds) } catch (e: JSONException) { - Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + Logger.printException({ "Failed to create create/playlist innerTubeBody" }, e) } return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) @@ -284,7 +198,7 @@ object PlayerRoutes { try { innerTubeBody.put("playlistId", playlistId) } catch (e: JSONException) { - Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + Logger.printException({ "Failed to create delete/playlist innerTubeBody" }, e) } return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) @@ -314,7 +228,7 @@ object PlayerRoutes { actionsArray.put(0, actionsObject) innerTubeBody.put("actions", actionsArray) } catch (e: JSONException) { - Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + Logger.printException({ "Failed to create edit/playlist innerTubeBody" }, e) } return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) @@ -330,7 +244,7 @@ object PlayerRoutes { innerTubeBody.put("playlistId", playlistId) innerTubeBody.put("excludeWatchLater", false) } catch (e: JSONException) { - Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + Logger.printException({ "Failed to create get/playlists innerTubeBody" }, e) } return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) @@ -354,44 +268,57 @@ object PlayerRoutes { actionsArray.put(0, actionsObject) innerTubeBody.put("actions", actionsArray) } catch (e: JSONException) { - Logger.printException({ "Failed to create playlist innerTubeBody" }, e) + Logger.printException({ "Failed to create save/playlist innerTubeBody" }, e) } return innerTubeBody.toString().toByteArray(StandardCharsets.UTF_8) } @JvmStatic - fun getPlayerResponseConnectionFromRoute( + fun getInnerTubeResponseConnectionFromRoute( route: CompiledRoute, - clientType: YouTubeAppClient.ClientType - ): HttpURLConnection { - return getPlayerResponseConnectionFromRoute( - route, - clientType.userAgent, - clientType.id.toString(), - clientType.clientVersion - ) - } + clientType: YouTubeAppClient.ClientType, + requestHeader: Map? = null, + connectTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, + readTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, + ) = getInnerTubeResponseConnectionFromRoute( + route = route, + userAgent = clientType.userAgent, + clientId = clientType.id.toString(), + clientVersion = clientType.clientVersion, + supportsCookies = clientType.supportsCookies, + requestHeader = requestHeader, + connectTimeout = connectTimeout, + readTimeout = readTimeout, + ) @JvmStatic - fun getPlayerResponseConnectionFromRoute( + fun getInnerTubeResponseConnectionFromRoute( route: CompiledRoute, - clientType: YouTubeWebClient.ClientType - ): HttpURLConnection { - return getPlayerResponseConnectionFromRoute( - route, - clientType.userAgent, - clientType.id.toString(), - clientType.clientVersion, - ) - } + clientType: YouTubeWebClient.ClientType, + requestHeader: Map? = null, + connectTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, + readTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, + ) = getInnerTubeResponseConnectionFromRoute( + route = route, + userAgent = clientType.userAgent, + clientId = clientType.id.toString(), + clientVersion = clientType.clientVersion, + requestHeader = requestHeader, + connectTimeout = connectTimeout, + readTimeout = readTimeout, + ) @Throws(IOException::class) - fun getPlayerResponseConnectionFromRoute( + fun getInnerTubeResponseConnectionFromRoute( route: CompiledRoute, userAgent: String, clientId: String, - clientVersion: String + clientVersion: String, + supportsCookies: Boolean = true, + requestHeader: Map? = null, + connectTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, + readTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, ): HttpURLConnection { val connection = Requester.getConnectionFromCompiledRoute(YT_API_URL, route) @@ -403,8 +330,24 @@ object PlayerRoutes { connection.useCaches = false connection.doOutput = true - connection.connectTimeout = CONNECTION_TIMEOUT_MILLISECONDS - connection.readTimeout = CONNECTION_TIMEOUT_MILLISECONDS + connection.connectTimeout = connectTimeout + connection.readTimeout = readTimeout + + if (requestHeader != null) { + for (key in REQUEST_HEADER_KEYS) { + var value = requestHeader[key] + if (value != null) { + if (key == AUTHORIZATION_HEADER) { + if (!supportsCookies) { + continue + } + } + + connection.setRequestProperty(key, value) + } + } + } + return connection } diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRoutes.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRoutes.kt new file mode 100644 index 000000000..48ee66f8f --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRoutes.kt @@ -0,0 +1,108 @@ +package app.revanced.extension.shared.innertube.requests + +import app.revanced.extension.shared.requests.Route +import app.revanced.extension.shared.requests.Route.CompiledRoute + +object InnerTubeRoutes { + + @JvmField + val CREATE_PLAYLIST = compileRoute( + endpoint = "playlist/create", + fields = "playlistId", + ) + + @JvmField + val DELETE_PLAYLIST = compileRoute( + endpoint = "playlist/delete", + ) + + @JvmField + val EDIT_PLAYLIST = compileRoute( + endpoint = "browse/edit_playlist", + fields = "status," + "playlistEditResults", + ) + + @JvmField + val GET_CATEGORY = compileRoute( + endpoint = "player", + fields = "microformat.playerMicroformatRenderer.category", + ) + + @JvmField + val GET_PLAYLISTS = compileRoute( + endpoint = "playlist/get_add_to_playlist", + fields = "contents.addToPlaylistRenderer.playlists.playlistAddToOptionRenderer", + ) + + @JvmField + val GET_SET_VIDEO_ID = compileRoute( + endpoint = "next", + fields = "contents.singleColumnWatchNextResults." + + "playlist.playlist.contents.playlistPanelVideoRenderer." + + "playlistSetVideoId", + ) + + @JvmField + val GET_PLAYLIST_PAGE = compileRoute( + endpoint = "next", + fields = "contents.singleColumnWatchNextResults.playlist.playlist", + ) + + @JvmField + val GET_STREAMING_DATA = compileRoute( + endpoint = "player", + fields = "streamingData", + alt = "proto", + prettier = true, + ) + + @JvmField + val GET_VIDEO_ACTION_BUTTON = compileRoute( + endpoint = "next", + fields = "contents.singleColumnWatchNextResults." + + "results.results.contents.slimVideoMetadataSectionRenderer." + + "contents.elementRenderer.newElement.type.componentType." + + "model.videoActionBarModel.buttons.buttonViewModel" + ) + + @JvmField + val GET_VIDEO_DETAILS = compileRoute( + endpoint = "player", + fields = "videoDetails.channelId," + + "videoDetails.isLiveContent," + + "videoDetails.isUpcoming" + ) + + private fun compileRoute( + endpoint: String, + fields: String? = null, + alt: String? = null, + prettier: Boolean = false, + ): CompiledRoute { + var query = Array(4) { "&" } + var i = 0 + query[i] = "?" + + val sb = StringBuilder(endpoint) + if (prettier == false) { + sb.append(query[i++]) + sb.append("prettyPrint=false") + } + if (fields != null) { + sb.append(query[i++]) + sb.append("fields=") + sb.append(fields) + } + if (alt != null) { + sb.append(query[i++]) + sb.append("alt=") + sb.append(alt) + } + + return Route( + Route.Method.POST, + sb.toString() + ).compile() + } + +} \ No newline at end of file diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofClientPatch.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofClientPatch.java index f26063a4f..a0faa7e06 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofClientPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofClientPatch.java @@ -1,11 +1,11 @@ package app.revanced.extension.shared.patches.spoof; -import app.revanced.extension.shared.patches.client.MusicAppClient.ClientType; -import app.revanced.extension.music.settings.Settings; +import app.revanced.extension.shared.innertube.client.YouTubeMusicAppClient.ClientType; +import app.revanced.extension.shared.settings.BaseSettings; @SuppressWarnings("unused") public class SpoofClientPatch extends BlockRequestPatch { - private static final ClientType CLIENT_TYPE = Settings.SPOOF_CLIENT_TYPE.get(); + private static final ClientType CLIENT_TYPE = BaseSettings.SPOOF_CLIENT_TYPE.get(); /** * Injection point. diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java index ef9d62ae7..9b087b276 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java @@ -10,7 +10,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import app.revanced.extension.shared.patches.client.YouTubeAppClient.ClientType; +import app.revanced.extension.shared.innertube.client.YouTubeAppClient.ClientType; import app.revanced.extension.shared.patches.spoof.requests.StreamingDataRequest; import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.settings.Setting; @@ -19,10 +19,6 @@ import app.revanced.extension.shared.utils.Utils; @SuppressWarnings("unused") public class SpoofStreamingDataPatch extends BlockRequestPatch { - private static final String PO_TOKEN = - BaseSettings.SPOOF_STREAMING_DATA_PO_TOKEN.get(); - private static final String VISITOR_DATA = - BaseSettings.SPOOF_STREAMING_DATA_VISITOR_DATA.get(); private static final boolean SPOOF_STREAMING_DATA_SKIP_RESPONSE_ENCRYPTION = SPOOF_STREAMING_DATA && BaseSettings.SPOOF_STREAMING_DATA_SKIP_RESPONSE_ENCRYPTION.get(); @@ -79,7 +75,7 @@ public class SpoofStreamingDataPatch extends BlockRequestPatch { /** * Injection point. */ - public static void fetchStreams(String url, Map requestHeaders) { + public static void fetchStreams(String url, Map requestHeader) { if (SPOOF_STREAMING_DATA) { String id = Utils.getVideoIdFromRequest(url); if (id == null) { @@ -89,7 +85,7 @@ public class SpoofStreamingDataPatch extends BlockRequestPatch { return; } - StreamingDataRequest.fetchRequest(id, requestHeaders, VISITOR_DATA, PO_TOKEN); + StreamingDataRequest.fetchRequest(id, requestHeader); } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt index 425ccfcb3..018bb48d5 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt @@ -1,14 +1,13 @@ package app.revanced.extension.shared.patches.spoof.requests import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes.GET_STREAMING_DATA -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes.createApplicationRequestBody -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes.getPlayerResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.createApplicationRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.GET_STREAMING_DATA import app.revanced.extension.shared.settings.BaseSettings import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils -import org.apache.commons.lang3.StringUtils import java.io.BufferedInputStream import java.io.ByteArrayOutputStream import java.io.IOException @@ -32,21 +31,19 @@ import java.util.concurrent.TimeoutException * did use its own client streams. */ class StreamingDataRequest private constructor( - videoId: String, playerHeaders: Map, - visitorId: String, botGuardPoToken: String + videoId: String, + requestHeader: Map, ) { private val videoId: String private val future: Future init { - Objects.requireNonNull(playerHeaders) + Objects.requireNonNull(requestHeader) this.videoId = videoId this.future = Utils.submitOnBackgroundThread { fetch( videoId, - playerHeaders, - visitorId, - botGuardPoToken + requestHeader, ) } } @@ -86,33 +83,16 @@ class StreamingDataRequest private constructor( companion object { private const val AUTHORIZATION_HEADER = "Authorization" - private const val VISITOR_ID_HEADER = "X-Goog-Visitor-Id" - private val REQUEST_HEADER_KEYS = arrayOf( - AUTHORIZATION_HEADER, // Available only to logged-in users. - "X-GOOG-API-FORMAT-VERSION", - VISITOR_ID_HEADER - ) + private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 + private val SPOOF_STREAMING_DATA_TYPE: YouTubeAppClient.ClientType = BaseSettings.SPOOF_STREAMING_DATA_TYPE.get() - private val CLIENT_ORDER_TO_USE: Array = YouTubeAppClient.availableClientTypes(SPOOF_STREAMING_DATA_TYPE) - private val DEFAULT_CLIENT_IS_ANDROID_VR_NO_AUTH: Boolean = SPOOF_STREAMING_DATA_TYPE == YouTubeAppClient.ClientType.ANDROID_VR_NO_AUTH - private var lastSpoofedClientType: YouTubeAppClient.ClientType? = null - - - /** - * TCP connection and HTTP read timeout. - */ - private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 - - /** - * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] - */ - private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 + private var lastSpoofedClientFriendlyName: String? = null @GuardedBy("itself") val cache: MutableMap = Collections.synchronizedMap( @@ -126,22 +106,24 @@ class StreamingDataRequest private constructor( @JvmStatic val lastSpoofedClientName: String - get() = lastSpoofedClientType - ?.friendlyName - ?: "Unknown" + get() { + return if (lastSpoofedClientFriendlyName != null) { + lastSpoofedClientFriendlyName!! + } else { + "Unknown" + } + } @JvmStatic fun fetchRequest( - videoId: String, fetchHeaders: Map, - visitorId: String, botGuardPoToken: String + videoId: String, + fetchHeaders: Map, ) { // Always fetch, even if there is an existing request for the same video. cache[videoId] = StreamingDataRequest( videoId, - fetchHeaders, - visitorId, - botGuardPoToken + fetchHeaders ) } @@ -157,64 +139,28 @@ class StreamingDataRequest private constructor( private fun send( clientType: YouTubeAppClient.ClientType, videoId: String, - playerHeaders: Map, - visitorId: String, - botGuardPoToken: String + requestHeader: Map, ): HttpURLConnection? { Objects.requireNonNull(clientType) Objects.requireNonNull(videoId) - Objects.requireNonNull(playerHeaders) + Objects.requireNonNull(requestHeader) val startTime = System.currentTimeMillis() Logger.printDebug { "Fetching video streams for: $videoId using client: $clientType" } try { val connection = - getPlayerResponseConnectionFromRoute(GET_STREAMING_DATA, clientType) - connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS - connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS - - val usePoToken = - clientType.requirePoToken && !StringUtils.isAnyEmpty(botGuardPoToken, visitorId) - - for (key in REQUEST_HEADER_KEYS) { - var value = playerHeaders[key] - if (value != null) { - if (key == AUTHORIZATION_HEADER) { - if (!clientType.supportsCookies) { - Logger.printDebug { "Not including request header: $key" } - continue - } - } - if (key == VISITOR_ID_HEADER && usePoToken) { - val originalVisitorId: String = value - Logger.printDebug { "Original visitor id:\n$originalVisitorId" } - Logger.printDebug { "Replaced visitor id:\n$visitorId" } - value = visitorId - } - - connection.setRequestProperty(key, value) - } - } - - val requestBody: ByteArray - if (usePoToken) { - requestBody = createApplicationRequestBody( - clientType = clientType, - videoId = videoId, - botGuardPoToken = botGuardPoToken, - visitorId = visitorId, - setLocale = DEFAULT_CLIENT_IS_ANDROID_VR_NO_AUTH, + getInnerTubeResponseConnectionFromRoute( + GET_STREAMING_DATA, + clientType, + requestHeader ) - Logger.printDebug { "Set poToken (botGuardPoToken):\n$botGuardPoToken" } - } else { - requestBody = - createApplicationRequestBody( - clientType = clientType, - videoId = videoId, - setLocale = DEFAULT_CLIENT_IS_ANDROID_VR_NO_AUTH, - ) - } + + val requestBody = createApplicationRequestBody( + clientType = clientType, + videoId = videoId, + setLocale = DEFAULT_CLIENT_IS_ANDROID_VR_NO_AUTH, + ) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -243,15 +189,15 @@ class StreamingDataRequest private constructor( } private fun fetch( - videoId: String, playerHeaders: Map, - visitorId: String, botGuardPoToken: String + videoId: String, + requestHeader: Map, ): ByteBuffer? { - lastSpoofedClientType = null + lastSpoofedClientFriendlyName = null // Retry with different client if empty response body is received. for (clientType in CLIENT_ORDER_TO_USE) { if (clientType.requireAuth && - playerHeaders[AUTHORIZATION_HEADER] == null + requestHeader[AUTHORIZATION_HEADER] == null ) { Logger.printDebug { "Skipped login-required client (incognito mode or not logged in)\nClient: $clientType\nVideo: $videoId" } continue @@ -259,9 +205,7 @@ class StreamingDataRequest private constructor( send( clientType, videoId, - playerHeaders, - visitorId, - botGuardPoToken + requestHeader, )?.let { connection -> try { // gzip encoding doesn't response with content length (-1), @@ -271,14 +215,14 @@ class StreamingDataRequest private constructor( } else { BufferedInputStream(connection.inputStream).use { inputStream -> ByteArrayOutputStream().use { stream -> - val buffer = ByteArray(2048) + val buffer = ByteArray(4096) var bytesRead: Int while ((inputStream.read(buffer) .also { bytesRead = it }) >= 0 ) { stream.write(buffer, 0, bytesRead) } - lastSpoofedClientType = clientType + lastSpoofedClientFriendlyName = clientType.friendlyName return ByteBuffer.wrap(stream.toByteArray()) } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java b/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java index 004766e99..71fe7fbba 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java @@ -3,10 +3,10 @@ package app.revanced.extension.shared.settings; import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; +import app.revanced.extension.shared.innertube.client.YouTubeAppClient; +import app.revanced.extension.shared.innertube.client.YouTubeMusicAppClient; import app.revanced.extension.shared.patches.ReturnYouTubeUsernamePatch.DisplayFormat; import app.revanced.extension.shared.patches.WatchHistoryPatch.WatchHistoryType; -import app.revanced.extension.shared.patches.client.MusicAppClient; -import app.revanced.extension.shared.patches.client.YouTubeAppClient; import app.revanced.extension.shared.patches.spoof.SpoofStreamingDataPatch.AudioStreamLanguageOverrideAvailability; /** @@ -31,7 +31,7 @@ public class BaseSettings { * Some patches are in a shared path, so they are declared here. */ public static final BooleanSetting SPOOF_CLIENT = new BooleanSetting("revanced_spoof_client", FALSE, true); - public static final EnumSetting SPOOF_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_client_type", MusicAppClient.ClientType.IOS_MUSIC_6_21, true); + public static final EnumSetting SPOOF_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_client_type", YouTubeMusicAppClient.ClientType.IOS_MUSIC_6_21, true); /** * These settings are used by YouTube. @@ -44,10 +44,7 @@ public class BaseSettings { public static final BooleanSetting SPOOF_STREAMING_DATA_SKIP_RESPONSE_ENCRYPTION = new BooleanSetting("revanced_spoof_streaming_data_skip_response_encryption", TRUE, true); public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE); // Client type must be last spoof setting due to cyclic references. - public static final EnumSetting SPOOF_STREAMING_DATA_TYPE = new EnumSetting<>("revanced_spoof_streaming_data_type", YouTubeAppClient.ClientType.ANDROID_UNPLUGGED, true); - - public static final StringSetting SPOOF_STREAMING_DATA_PO_TOKEN = new StringSetting("revanced_spoof_streaming_data_po_token", "", true); - public static final StringSetting SPOOF_STREAMING_DATA_VISITOR_DATA = new StringSetting("revanced_spoof_streaming_data_visitor_data", "", true); + public static final EnumSetting SPOOF_STREAMING_DATA_TYPE = new EnumSetting<>("revanced_spoof_streaming_data_type", YouTubeAppClient.ClientType.ANDROID_VR, true); /** * These settings are used by YouTube and YouTube Music. diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/requests/VideoDetailsRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/requests/VideoDetailsRequest.kt index 1db71775a..64c3897aa 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/requests/VideoDetailsRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/requests/VideoDetailsRequest.kt @@ -2,8 +2,10 @@ package app.revanced.extension.youtube.patches.general.requests import android.annotation.SuppressLint import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeWebClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.innertube.client.YouTubeWebClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.createWebInnertubeBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.GET_VIDEO_DETAILS import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils @@ -86,12 +88,11 @@ class VideoDetailsRequest private constructor( Logger.printDebug { "Fetching video details request for: $videoId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.GET_VIDEO_DETAILS, + val connection = getInnerTubeResponseConnectionFromRoute( + GET_VIDEO_DETAILS, clientType ) - val requestBody = - PlayerRoutes.createWebInnertubeBody(clientType, videoId) + val requestBody = createWebInnertubeBody(clientType, videoId) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/requests/ActionButtonRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/requests/ActionButtonRequest.kt index af38ab459..b485dec6f 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/requests/ActionButtonRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/requests/ActionButtonRequest.kt @@ -1,8 +1,10 @@ package app.revanced.extension.youtube.patches.player.requests import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.createApplicationRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.GET_VIDEO_ACTION_BUTTON import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils @@ -20,10 +22,10 @@ import java.util.concurrent.TimeoutException class ActionButtonRequest private constructor( private val videoId: String, - private val playerHeaders: Map, + private val requestHeader: Map, ) { private val future: Future> = Utils.submitOnBackgroundThread { - fetch(videoId, playerHeaders) + fetch(videoId, requestHeader) } val array: Array @@ -52,14 +54,6 @@ class ActionButtonRequest private constructor( } companion object { - /** - * TCP connection and HTTP read timeout. - */ - private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 - - /** - * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] - */ private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 @GuardedBy("itself") @@ -73,11 +67,11 @@ class ActionButtonRequest private constructor( }) @JvmStatic - fun fetchRequestIfNeeded(videoId: String, playerHeaders: Map) { + fun fetchRequestIfNeeded(videoId: String, requestHeader: Map) { Objects.requireNonNull(videoId) synchronized(cache) { if (!cache.containsKey(videoId)) { - cache[videoId] = ActionButtonRequest(videoId, playerHeaders) + cache[videoId] = ActionButtonRequest(videoId, requestHeader) } } } @@ -93,43 +87,28 @@ class ActionButtonRequest private constructor( Logger.printInfo({ toastMessage }, ex) } - private val REQUEST_HEADER_KEYS = arrayOf( - "Authorization", // Available only to logged-in users. - "X-GOOG-API-FORMAT-VERSION", - "X-Goog-Visitor-Id" - ) - - private fun sendRequest(videoId: String, playerHeaders: Map): JSONObject? { + private fun sendRequest(videoId: String, requestHeader: Map): JSONObject? { Objects.requireNonNull(videoId) val startTime = System.currentTimeMillis() - // '/next' request does not require PoToken. + // '/next' endpoint does not require PoToken. val clientType = YouTubeAppClient.ClientType.ANDROID val clientTypeName = clientType.name Logger.printDebug { "Fetching playlist request for: $videoId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.GET_VIDEO_ACTION_BUTTON, - clientType - ) - connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS - connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS - // Since [THANKS] button and [CLIP] button are shown only with the logged in, // Set the [Authorization] field to property to get the correct action buttons. - for (key in REQUEST_HEADER_KEYS) { - var value = playerHeaders[key] - if (value != null) { - connection.setRequestProperty(key, value) - } - } + val connection = getInnerTubeResponseConnectionFromRoute( + GET_VIDEO_ACTION_BUTTON, + clientType, + requestHeader, + ) - val requestBody = - PlayerRoutes.createApplicationRequestBody( - clientType = clientType, - videoId = videoId - ) + val requestBody = createApplicationRequestBody( + clientType = clientType, + videoId = videoId + ) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -214,8 +193,11 @@ class ActionButtonRequest private constructor( return emptyArray() } - private fun fetch(videoId: String, playerHeaders: Map): Array { - val json = sendRequest(videoId, playerHeaders) + private fun fetch( + videoId: String, + requestHeader: Map + ): Array { + val json = sendRequest(videoId, requestHeader) if (json != null) { return parseResponse(json) } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt index bf72d8966..69ad16e98 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt @@ -1,12 +1,15 @@ package app.revanced.extension.youtube.patches.utils.requests import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.createApplicationRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.createPlaylistRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.CREATE_PLAYLIST +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.GET_SET_VIDEO_ID import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils -import app.revanced.extension.youtube.patches.utils.requests.CreatePlaylistRequest.Companion.HTTP_TIMEOUT_MILLISECONDS import org.json.JSONException import org.json.JSONObject import java.io.IOException @@ -20,10 +23,10 @@ import java.util.concurrent.TimeoutException class CreatePlaylistRequest private constructor( private val videoId: String, - private val playerHeaders: Map, + private val requestHeader: Map, ) { private val future: Future> = Utils.submitOnBackgroundThread { - fetch(videoId, playerHeaders) + fetch(videoId, requestHeader) } val playlistId: Pair? @@ -52,14 +55,6 @@ class CreatePlaylistRequest private constructor( } companion object { - /** - * TCP connection and HTTP read timeout. - */ - private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 - - /** - * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] - */ private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 @GuardedBy("itself") @@ -80,11 +75,11 @@ class CreatePlaylistRequest private constructor( } @JvmStatic - fun fetchRequestIfNeeded(videoId: String, playerHeaders: Map) { + fun fetchRequestIfNeeded(videoId: String, requestHeader: Map) { Objects.requireNonNull(videoId) synchronized(cache) { if (!cache.containsKey(videoId)) { - cache[videoId] = CreatePlaylistRequest(videoId, playerHeaders) + cache[videoId] = CreatePlaylistRequest(videoId, requestHeader) } } } @@ -100,40 +95,26 @@ class CreatePlaylistRequest private constructor( Logger.printInfo({ toastMessage }, ex) } - private val REQUEST_HEADER_KEYS = arrayOf( - "Authorization", // Available only to logged-in users. - "X-GOOG-API-FORMAT-VERSION", - "X-Goog-Visitor-Id" - ) - - private fun sendCreatePlaylistRequest(videoId: String, playerHeaders: Map): JSONObject? { + private fun sendCreatePlaylistRequest( + videoId: String, + requestHeader: Map + ): JSONObject? { Objects.requireNonNull(videoId) val startTime = System.currentTimeMillis() - // 'playlist/create' request does not require PoToken. + // 'playlist/create' endpoint does not require PoToken. val clientType = YouTubeAppClient.ClientType.ANDROID val clientTypeName = clientType.name Logger.printDebug { "Fetching create playlist request for: $videoId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.CREATE_PLAYLIST, - clientType + val connection = getInnerTubeResponseConnectionFromRoute( + CREATE_PLAYLIST, + clientType, + requestHeader, ) - connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS - connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS - for (key in REQUEST_HEADER_KEYS) { - var value = playerHeaders[key] - if (value != null) { - connection.setRequestProperty(key, value) - } - } - - val requestBody = - PlayerRoutes.createPlaylistRequestBody( - videoId = videoId - ) + val requestBody = createPlaylistRequestBody(videoId = videoId) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -159,36 +140,31 @@ class CreatePlaylistRequest private constructor( return null } - private fun sendSetVideoIdRequest(videoId: String, playlistId: String, playerHeaders: Map): JSONObject? { + private fun sendSetVideoIdRequest( + videoId: String, + playlistId: String, + requestHeader: Map + ): JSONObject? { Objects.requireNonNull(playlistId) val startTime = System.currentTimeMillis() - // 'playlist/create' request does not require PoToken. + // 'playlist/create' endpoint does not require PoToken. val clientType = YouTubeAppClient.ClientType.ANDROID val clientTypeName = clientType.name Logger.printDebug { "Fetching set video id request for: $playlistId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.GET_SET_VIDEO_ID, - clientType + val connection = getInnerTubeResponseConnectionFromRoute( + GET_SET_VIDEO_ID, + clientType, + requestHeader ) - connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS - connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS - for (key in REQUEST_HEADER_KEYS) { - var value = playerHeaders[key] - if (value != null) { - connection.setRequestProperty(key, value) - } - } - - val requestBody = - PlayerRoutes.createApplicationRequestBody( - clientType = clientType, - videoId = videoId, - playlistId = playlistId - ) + val requestBody = createApplicationRequestBody( + clientType = clientType, + videoId = videoId, + playlistId = playlistId + ) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -240,8 +216,8 @@ class CreatePlaylistRequest private constructor( if (secondaryContentsJsonObject is JSONObject) { return secondaryContentsJsonObject - .getJSONObject("playlistPanelVideoRenderer") - .getString("playlistSetVideoId") + .getJSONObject("playlistPanelVideoRenderer") + .getString("playlistSetVideoId") } } catch (e: JSONException) { val jsonForMessage = json.toString() @@ -254,12 +230,15 @@ class CreatePlaylistRequest private constructor( return null } - private fun fetch(videoId: String, playerHeaders: Map): Pair? { - val createPlaylistJson = sendCreatePlaylistRequest(videoId, playerHeaders) + private fun fetch( + videoId: String, + requestHeader: Map + ): Pair? { + val createPlaylistJson = sendCreatePlaylistRequest(videoId, requestHeader) if (createPlaylistJson != null) { val playlistId = parseCreatePlaylistResponse(createPlaylistJson) if (playlistId != null) { - val setVideoIdJson = sendSetVideoIdRequest(videoId, playlistId, playerHeaders) + val setVideoIdJson = sendSetVideoIdRequest(videoId, playlistId, requestHeader) if (setVideoIdJson != null) { val setVideoId = parseSetVideoIdResponse(setVideoIdJson) if (setVideoId != null) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt index 7a0c8fc95..60675fe30 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt @@ -1,12 +1,13 @@ package app.revanced.extension.youtube.patches.utils.requests import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.deletePlaylistRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.DELETE_PLAYLIST import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils -import app.revanced.extension.youtube.patches.utils.requests.DeletePlaylistRequest.Companion.HTTP_TIMEOUT_MILLISECONDS import org.json.JSONException import org.json.JSONObject import java.io.IOException @@ -20,12 +21,12 @@ import java.util.concurrent.TimeoutException class DeletePlaylistRequest private constructor( private val playlistId: String, - private val playerHeaders: Map, + private val requestHeader: Map, ) { private val future: Future = Utils.submitOnBackgroundThread { fetch( playlistId, - playerHeaders, + requestHeader, ) } @@ -55,14 +56,6 @@ class DeletePlaylistRequest private constructor( } companion object { - /** - * TCP connection and HTTP read timeout. - */ - private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 - - /** - * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] - */ private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 @GuardedBy("itself") @@ -85,14 +78,14 @@ class DeletePlaylistRequest private constructor( @JvmStatic fun fetchRequestIfNeeded( playlistId: String, - playerHeaders: Map + requestHeader: Map ) { Objects.requireNonNull(playlistId) synchronized(cache) { if (!cache.containsKey(playlistId)) { cache[playlistId] = DeletePlaylistRequest( playlistId, - playerHeaders + requestHeader ) } } @@ -109,40 +102,26 @@ class DeletePlaylistRequest private constructor( Logger.printInfo({ toastMessage }, ex) } - private val REQUEST_HEADER_KEYS = arrayOf( - "Authorization", // Available only to logged-in users. - "X-GOOG-API-FORMAT-VERSION", - "X-Goog-Visitor-Id" - ) - private fun sendRequest( playlistId: String, - playerHeaders: Map + requestHeader: Map ): JSONObject? { Objects.requireNonNull(playlistId) val startTime = System.currentTimeMillis() - // 'playlist/delete' request does not require PoToken. + // 'playlist/delete' endpoint does not require PoToken. val clientType = YouTubeAppClient.ClientType.ANDROID val clientTypeName = clientType.name Logger.printDebug { "Fetching delete playlist request, playlistId: $playlistId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.DELETE_PLAYLIST, + val connection = getInnerTubeResponseConnectionFromRoute( + DELETE_PLAYLIST, clientType, + requestHeader ) - connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS - connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS - for (key in REQUEST_HEADER_KEYS) { - var value = playerHeaders[key] - if (value != null) { - connection.setRequestProperty(key, value) - } - } - - val requestBody = PlayerRoutes.deletePlaylistRequestBody(playlistId) + val requestBody = deletePlaylistRequestBody(playlistId) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -184,9 +163,9 @@ class DeletePlaylistRequest private constructor( private fun fetch( playlistId: String, - playerHeaders: Map + requestHeader: Map ): Boolean? { - val json = sendRequest(playlistId, playerHeaders) + val json = sendRequest(playlistId, requestHeader) if (json != null) { return parseResponse(json) } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt index 7372cb89a..826b36b8a 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt @@ -1,12 +1,13 @@ package app.revanced.extension.youtube.patches.utils.requests import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.editPlaylistRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.EDIT_PLAYLIST import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils -import app.revanced.extension.youtube.patches.utils.requests.EditPlaylistRequest.Companion.HTTP_TIMEOUT_MILLISECONDS import org.apache.commons.lang3.StringUtils import org.json.JSONException import org.json.JSONObject @@ -23,14 +24,14 @@ class EditPlaylistRequest private constructor( private val videoId: String, private val playlistId: String, private val setVideoId: String?, - private val playerHeaders: Map, + private val requestHeader: Map, ) { private val future: Future = Utils.submitOnBackgroundThread { fetch( videoId, playlistId, setVideoId, - playerHeaders, + requestHeader, ) } @@ -60,14 +61,6 @@ class EditPlaylistRequest private constructor( } companion object { - /** - * TCP connection and HTTP read timeout. - */ - private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 - - /** - * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] - */ private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 @GuardedBy("itself") @@ -99,7 +92,7 @@ class EditPlaylistRequest private constructor( videoId: String, playlistId: String, setVideoId: String?, - playerHeaders: Map + requestHeader: Map ) { Objects.requireNonNull(videoId) synchronized(cache) { @@ -108,7 +101,7 @@ class EditPlaylistRequest private constructor( videoId, playlistId, setVideoId, - playerHeaders + requestHeader ) } } @@ -125,47 +118,32 @@ class EditPlaylistRequest private constructor( Logger.printInfo({ toastMessage }, ex) } - private val REQUEST_HEADER_KEYS = arrayOf( - "Authorization", // Available only to logged-in users. - "X-GOOG-API-FORMAT-VERSION", - "X-Goog-Visitor-Id" - ) - private fun sendRequest( videoId: String, playlistId: String, setVideoId: String?, - playerHeaders: Map + requestHeader: Map ): JSONObject? { Objects.requireNonNull(videoId) val startTime = System.currentTimeMillis() - // 'browse/edit_playlist' request does not require PoToken. + // 'browse/edit_playlist' endpoint does not require PoToken. val clientType = YouTubeAppClient.ClientType.ANDROID val clientTypeName = clientType.name Logger.printDebug { "Fetching edit playlist request, videoId: $videoId, playlistId: $playlistId, setVideoId: $setVideoId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.EDIT_PLAYLIST, - clientType + val connection = getInnerTubeResponseConnectionFromRoute( + EDIT_PLAYLIST, + clientType, + requestHeader ) - connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS - connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS - for (key in REQUEST_HEADER_KEYS) { - var value = playerHeaders[key] - if (value != null) { - connection.setRequestProperty(key, value) - } - } - - val requestBody = - PlayerRoutes.editPlaylistRequestBody( - videoId = videoId, - playlistId = playlistId, - setVideoId = setVideoId, - ) + val requestBody = editPlaylistRequestBody( + videoId = videoId, + playlistId = playlistId, + setVideoId = setVideoId + ) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -197,7 +175,8 @@ class EditPlaylistRequest private constructor( if (remove) { return "" } - val playlistEditResultsJSONObject = json.getJSONArray("playlistEditResults").get(0) + val playlistEditResultsJSONObject = + json.getJSONArray("playlistEditResults").get(0) if (playlistEditResultsJSONObject is JSONObject) { return playlistEditResultsJSONObject @@ -220,9 +199,9 @@ class EditPlaylistRequest private constructor( videoId: String, playlistId: String, setVideoId: String?, - playerHeaders: Map + requestHeader: Map ): String? { - val json = sendRequest(videoId, playlistId, setVideoId, playerHeaders) + val json = sendRequest(videoId, playlistId, setVideoId, requestHeader) if (json != null) { return parseResponse(json, StringUtils.isNotEmpty(setVideoId)) } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt index 54f54f33c..5a57f00e2 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt @@ -1,12 +1,13 @@ package app.revanced.extension.youtube.patches.utils.requests import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getPlaylistsRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.GET_PLAYLISTS import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils -import app.revanced.extension.youtube.patches.utils.requests.GetPlaylistsRequest.Companion.HTTP_TIMEOUT_MILLISECONDS import org.json.JSONException import org.json.JSONObject import java.io.IOException @@ -20,12 +21,12 @@ import java.util.concurrent.TimeoutException class GetPlaylistsRequest private constructor( private val playlistId: String, - private val playerHeaders: Map, + private val requestHeader: Map, ) { private val future: Future>> = Utils.submitOnBackgroundThread { fetch( playlistId, - playerHeaders, + requestHeader, ) } @@ -55,14 +56,6 @@ class GetPlaylistsRequest private constructor( } companion object { - /** - * TCP connection and HTTP read timeout. - */ - private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 - - /** - * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] - */ private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 @GuardedBy("itself") @@ -85,14 +78,14 @@ class GetPlaylistsRequest private constructor( @JvmStatic fun fetchRequestIfNeeded( playlistId: String, - playerHeaders: Map + requestHeader: Map ) { Objects.requireNonNull(playlistId) synchronized(cache) { if (!cache.containsKey(playlistId)) { cache[playlistId] = GetPlaylistsRequest( playlistId, - playerHeaders + requestHeader ) } } @@ -109,40 +102,26 @@ class GetPlaylistsRequest private constructor( Logger.printInfo({ toastMessage }, ex) } - private val REQUEST_HEADER_KEYS = arrayOf( - "Authorization", // Available only to logged-in users. - "X-GOOG-API-FORMAT-VERSION", - "X-Goog-Visitor-Id" - ) - private fun sendRequest( playlistId: String, - playerHeaders: Map + requestHeader: Map ): JSONObject? { Objects.requireNonNull(playlistId) val startTime = System.currentTimeMillis() - // 'playlist/get_add_to_playlist' request does not require PoToken. + // 'playlist/get_add_to_playlist' endpoint does not require PoToken. val clientType = YouTubeAppClient.ClientType.ANDROID val clientTypeName = clientType.name Logger.printDebug { "Fetching get playlists request, playlistId: $playlistId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.GET_PLAYLISTS, - clientType + val connection = getInnerTubeResponseConnectionFromRoute( + GET_PLAYLISTS, + clientType, + requestHeader ) - connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS - connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS - for (key in REQUEST_HEADER_KEYS) { - var value = playerHeaders[key] - if (value != null) { - connection.setRequestProperty(key, value) - } - } - - val requestBody = PlayerRoutes.getPlaylistsRequestBody(playlistId) + val requestBody = getPlaylistsRequestBody(playlistId) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -223,9 +202,9 @@ class GetPlaylistsRequest private constructor( private fun fetch( playlistId: String, - playerHeaders: Map + requestHeader: Map ): Array>? { - val json = sendRequest(playlistId, playerHeaders) + val json = sendRequest(playlistId, requestHeader) if (json != null) { return parseResponse(json) } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt index c5d3a611a..58b737869 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt @@ -1,12 +1,13 @@ package app.revanced.extension.youtube.patches.utils.requests import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.savePlaylistRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.EDIT_PLAYLIST import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils -import app.revanced.extension.youtube.patches.utils.requests.SavePlaylistRequest.Companion.HTTP_TIMEOUT_MILLISECONDS import org.json.JSONException import org.json.JSONObject import java.io.IOException @@ -21,13 +22,13 @@ import java.util.concurrent.TimeoutException class SavePlaylistRequest private constructor( private val playlistId: String, private val libraryId: String, - private val playerHeaders: Map, + private val requestHeader: Map, ) { private val future: Future = Utils.submitOnBackgroundThread { fetch( playlistId, libraryId, - playerHeaders, + requestHeader, ) } @@ -57,14 +58,6 @@ class SavePlaylistRequest private constructor( } companion object { - /** - * TCP connection and HTTP read timeout. - */ - private const val HTTP_TIMEOUT_MILLISECONDS = 10 * 1000 - - /** - * Any arbitrarily large value, but must be at least twice [HTTP_TIMEOUT_MILLISECONDS] - */ private const val MAX_MILLISECONDS_TO_WAIT_FOR_FETCH = 20 * 1000 @GuardedBy("itself") @@ -88,14 +81,14 @@ class SavePlaylistRequest private constructor( fun fetchRequestIfNeeded( playlistId: String, libraryId: String, - playerHeaders: Map + requestHeader: Map ) { Objects.requireNonNull(playlistId) synchronized(cache) { cache[libraryId] = SavePlaylistRequest( playlistId, libraryId, - playerHeaders + requestHeader ) } } @@ -111,43 +104,28 @@ class SavePlaylistRequest private constructor( Logger.printInfo({ toastMessage }, ex) } - private val REQUEST_HEADER_KEYS = arrayOf( - "Authorization", // Available only to logged-in users. - "X-GOOG-API-FORMAT-VERSION", - "X-Goog-Visitor-Id" - ) - private fun sendRequest( playlistId: String, libraryId: String, - playerHeaders: Map + requestHeader: Map ): JSONObject? { Objects.requireNonNull(playlistId) Objects.requireNonNull(libraryId) val startTime = System.currentTimeMillis() - // 'browse/edit_playlist' request does not require PoToken. + // 'browse/edit_playlist' endpoint does not require PoToken. val clientType = YouTubeAppClient.ClientType.ANDROID val clientTypeName = clientType.name Logger.printDebug { "Fetching edit playlist request, playlistId: $playlistId, libraryId: $libraryId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.EDIT_PLAYLIST, - clientType + val connection = getInnerTubeResponseConnectionFromRoute( + EDIT_PLAYLIST, + clientType, + requestHeader ) - connection.connectTimeout = HTTP_TIMEOUT_MILLISECONDS - connection.readTimeout = HTTP_TIMEOUT_MILLISECONDS - for (key in REQUEST_HEADER_KEYS) { - var value = playerHeaders[key] - if (value != null) { - connection.setRequestProperty(key, value) - } - } - - val requestBody = - PlayerRoutes.savePlaylistRequestBody(libraryId, playlistId) + val requestBody = savePlaylistRequestBody(libraryId, playlistId) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) @@ -190,9 +168,9 @@ class SavePlaylistRequest private constructor( private fun fetch( playlistId: String, libraryId: String, - playerHeaders: Map + requestHeader: Map ): Boolean? { - val json = sendRequest(playlistId, libraryId,playerHeaders) + val json = sendRequest(playlistId, libraryId, requestHeader) if (json != null) { return parseResponse(json) } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/requests/MusicRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/requests/MusicRequest.kt index d48ca8b51..a5283ad3d 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/requests/MusicRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/requests/MusicRequest.kt @@ -2,9 +2,13 @@ package app.revanced.extension.youtube.patches.video.requests import android.annotation.SuppressLint import androidx.annotation.GuardedBy -import app.revanced.extension.shared.patches.client.YouTubeAppClient -import app.revanced.extension.shared.patches.client.YouTubeWebClient -import app.revanced.extension.shared.patches.spoof.requests.PlayerRoutes +import app.revanced.extension.shared.innertube.client.YouTubeAppClient +import app.revanced.extension.shared.innertube.client.YouTubeWebClient +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.createApplicationRequestBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.createWebInnertubeBody +import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.getInnerTubeResponseConnectionFromRoute +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.GET_CATEGORY +import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.GET_PLAYLIST_PAGE import app.revanced.extension.shared.requests.Requester import app.revanced.extension.shared.utils.Logger import app.revanced.extension.shared.utils.Utils @@ -124,12 +128,12 @@ class MusicRequest private constructor( Logger.printDebug { "Fetching playlist request for: $videoId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.GET_PLAYLIST_PAGE, + val connection = getInnerTubeResponseConnectionFromRoute( + GET_PLAYLIST_PAGE, clientType ) val requestBody = - PlayerRoutes.createApplicationRequestBody( + createApplicationRequestBody( clientType = clientType, videoId = videoId, playlistId = "RD$videoId" @@ -168,12 +172,11 @@ class MusicRequest private constructor( Logger.printDebug { "Fetching microformat request for: $videoId, using client: $clientTypeName" } try { - val connection = PlayerRoutes.getPlayerResponseConnectionFromRoute( - PlayerRoutes.GET_CATEGORY, + val connection = getInnerTubeResponseConnectionFromRoute( + GET_CATEGORY, clientType ) - val requestBody = - PlayerRoutes.createWebInnertubeBody(clientType, videoId) + val requestBody = createWebInnertubeBody(clientType, videoId) connection.setFixedLengthStreamingMode(requestBody.size) connection.outputStream.write(requestBody) From 6ac6fcf95348f7c5e62e585d4afba638b13e2076 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 26 Mar 2025 14:55:48 +0900 Subject: [PATCH 24/77] feat(YouTube - Hide layout components): Change default value of `Disable translucent status bar` setting and move it to experimental flag --- .../app/revanced/extension/youtube/settings/Settings.java | 2 +- .../youtube/general/components/LayoutComponentsPatch.kt | 1 + .../resources/youtube/settings/host/values/strings.xml | 8 ++++---- .../resources/youtube/settings/xml/revanced_prefs.xml | 6 +++--- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index f450f1974..8be012903 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -150,7 +150,6 @@ public class Settings extends BaseSettings { new ChangeStartPagePatch.ChangeStartPageTypeAvailability()); public static final BooleanSetting DISABLE_AUTO_AUDIO_TRACKS = new BooleanSetting("revanced_disable_auto_audio_tracks", FALSE); public static final BooleanSetting DISABLE_SPLASH_ANIMATION = new BooleanSetting("revanced_disable_splash_animation", PatchStatus.SplashAnimation(), true); - public static final BooleanSetting DISABLE_TRANSLUCENT_STATUS_BAR = new BooleanSetting("revanced_disable_translucent_status_bar", TRUE, true); public static final BooleanSetting ENABLE_GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_enable_gradient_loading_screen", FALSE, true); public static final BooleanSetting HIDE_FLOATING_MICROPHONE = new BooleanSetting("revanced_hide_floating_microphone", TRUE, true); public static final BooleanSetting HIDE_GRAY_SEPARATOR = new BooleanSetting("revanced_hide_gray_separator", TRUE); @@ -159,6 +158,7 @@ public class Settings extends BaseSettings { public static final EnumSetting CHANGE_FORM_FACTOR = new EnumSetting<>("revanced_change_form_factor", FormFactor.DEFAULT, true, "revanced_change_form_factor_user_dialog_message"); public static final BooleanSetting CHANGE_LIVE_RING_CLICK_ACTION = new BooleanSetting("revanced_change_live_ring_click_action", FALSE, true); public static final BooleanSetting DISABLE_LAYOUT_UPDATES = new BooleanSetting("revanced_disable_layout_updates", false, true, "revanced_disable_layout_updates_user_dialog_message"); + public static final BooleanSetting DISABLE_TRANSLUCENT_STATUS_BAR = new BooleanSetting("revanced_disable_translucent_status_bar", FALSE, true, "revanced_disable_translucent_status_bar_user_dialog_message"); public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", false, true, "revanced_spoof_app_version_user_dialog_message"); public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", PatchStatus.SpoofAppVersionDefaultString(), true, parent(SPOOF_APP_VERSION)); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt index 003903a3f..a48e5eab6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/components/LayoutComponentsPatch.kt @@ -103,6 +103,7 @@ val layoutComponentsPatch = bytecodePatch( "$GENERAL_CLASS_DESCRIPTOR->disableTranslucentStatusBar(Z)Z" ) + settingArray += "PREFERENCE_CATEGORY: GENERAL_EXPERIMENTAL_FLAGS" settingArray += "SETTINGS: DISABLE_TRANSLUCENT_STATUS_BAR" } diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index c1eddda0c..4d511c850 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -514,9 +514,6 @@ Limitation: Back button on the toolbar may not work." Disable splash animation Splash animation is disabled. Splash animation is enabled. - Disable translucent status bar - Status bar is opaque. - Status bar is opaque or translucent. Enable gradient loading screen Gradient loading screen is enabled. Gradient loading screen is disabled. @@ -565,7 +562,10 @@ Changes include: • The Library tab is used. • The Music section of video description may not work. • Account switch button may not appear on the Library tab. Use the 'Enable wide search bar in You tab' setting." - + Disable translucent status bar + Status bar is opaque. + Status bar is opaque or translucent. + For some manufacturer ROMs running Android 12+, enabling this feature may make the system navigation bar transparent. Spoof app version Version spoofed Version not spoofed diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index b869b7988..05eccc79f 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -254,9 +254,6 @@ - - @@ -279,6 +276,9 @@ + + + %1$s to %2$s Choose the segment category Category is disabled in settings. Enable category to submit. From 99fa9698576a643d3a89b653a2024b20a22dd016 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 26 Mar 2025 15:24:58 +0900 Subject: [PATCH 32/77] fix(YouTube - SponsorBlock): Dependencies for some settings are not set --- .../SegmentCategoryListPreference.java | 2 -- .../SponsorBlockSettingsPreference.java | 2 +- .../youtube/settings/xml/revanced_prefs.xml | 18 +++++++++--------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/SegmentCategoryListPreference.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/SegmentCategoryListPreference.java index c62353d60..68b8727a5 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/SegmentCategoryListPreference.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/SegmentCategoryListPreference.java @@ -21,7 +21,6 @@ import java.util.Objects; import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; -import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour; import app.revanced.extension.youtube.sponsorblock.objects.SegmentCategory; @@ -277,7 +276,6 @@ public class SegmentCategoryListPreference extends ListPreference { applyOpacityToCategoryColor(); setTitle(category.getTitleWithColorDot(categoryColor)); - setEnabled(Settings.SB_ENABLED.get()); } private void updateCategoryColorDot() { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/SponsorBlockSettingsPreference.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/SponsorBlockSettingsPreference.java index d3107381f..e98b55d65 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/SponsorBlockSettingsPreference.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/SponsorBlockSettingsPreference.java @@ -233,6 +233,7 @@ public class SponsorBlockSettingsPreference extends ReVancedPreferenceFragment { statsCategory = new PreferenceCategory(mActivity); statsCategory.setLayoutResource(preferencesCategoryLayout); statsCategory.setTitle(str("revanced_sb_stats")); + statsCategory.setEnabled(Settings.SB_ENABLED.get()); mPreferenceScreen.addPreference(statsCategory); fetchAndDisplayStats(); @@ -261,7 +262,6 @@ public class SponsorBlockSettingsPreference extends ReVancedPreferenceFragment { final String key = category.keyValue; if (mPreferenceManager.findPreference(key) instanceof SegmentCategoryListPreference segmentCategoryListPreference) { segmentCategoryListPreference.setTitle(category.getTitleWithColorDot()); - segmentCategoryListPreference.setEnabled(Settings.SB_ENABLED.get()); } } } catch (Exception ex) { diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 05eccc79f..355ae717e 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -793,15 +793,15 @@ - - - - - - - - - + + + + + + + + + From 451a14a74d93549131158b27777140b368ccc041 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 26 Mar 2025 18:58:02 +0900 Subject: [PATCH 33/77] feat(YouTube - Swipe controls): Add `Swipe overlay alternative UI` setting (Closes https://github.com/inotia00/ReVanced_Extended/issues/2828) --- .../patches/swipe/SwipeControlsPatch.java | 17 + .../extension/youtube/settings/Settings.java | 11 +- .../SwipeControlsConfigurationProvider.kt | 55 ++- .../SwipeControlsHostActivity.kt | 2 +- .../views/SwipeControlsOverlayLayout.kt | 391 ++++++++++++++++-- .../swipe/controls/SwipeControlsPatch.kt | 18 +- .../youtube/settings/host/values/strings.xml | 23 +- .../youtube/settings/xml/revanced_prefs.xml | 5 +- .../drawable/ic_sc_brightness_auto.xml | 5 - .../drawable/ic_sc_brightness_manual.xml | 5 - .../drawable/ic_sc_volume_mute.xml | 5 - .../drawable/ic_sc_volume_normal.xml | 5 - .../revanced_ic_sc_brightness_auto.xml | 28 ++ .../revanced_ic_sc_brightness_full.xml | 29 ++ .../revanced_ic_sc_brightness_high.xml | 29 ++ .../revanced_ic_sc_brightness_low.xml | 29 ++ .../revanced_ic_sc_brightness_manual.xml | 30 ++ .../revanced_ic_sc_brightness_medium.xml | 28 ++ .../drawable/revanced_ic_sc_volume_high.xml | 29 ++ .../drawable/revanced_ic_sc_volume_low.xml | 29 ++ .../drawable/revanced_ic_sc_volume_mute.xml | 28 ++ .../drawable/revanced_ic_sc_volume_normal.xml | 29 ++ 22 files changed, 768 insertions(+), 62 deletions(-) delete mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_auto.xml delete mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_manual.xml delete mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_mute.xml delete mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_normal.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_manual.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_high.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_low.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml create mode 100644 patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/swipe/SwipeControlsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/swipe/SwipeControlsPatch.java index f4b0d16ad..794b9f0e1 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/swipe/SwipeControlsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/swipe/SwipeControlsPatch.java @@ -4,6 +4,7 @@ import android.view.View; import java.lang.ref.WeakReference; +import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.youtube.settings.Settings; @SuppressWarnings({"unused", "deprecation"}) @@ -59,4 +60,20 @@ public class SwipeControlsPatch { return engagementOverlayView != null && engagementOverlayView.getVisibility() == View.VISIBLE; } + public static final class SwipeOverlayTextSizeAvailability implements Setting.Availability { + @Override + public boolean isAvailable() { + return (Settings.ENABLE_SWIPE_BRIGHTNESS.get() || Settings.ENABLE_SWIPE_VOLUME.get()) && + !Settings.SWIPE_OVERLAY_ALTERNATIVE_UI.get(); + } + } + + public static final class SwipeOverlayModernUIAvailability implements Setting.Availability { + @Override + public boolean isAvailable() { + return (Settings.ENABLE_SWIPE_BRIGHTNESS.get() || Settings.ENABLE_SWIPE_VOLUME.get()) && + Settings.SWIPE_OVERLAY_ALTERNATIVE_UI.get(); + } + } + } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index b5bc6994e..ae6f3fea3 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -42,6 +42,7 @@ import app.revanced.extension.youtube.patches.player.ExitFullscreenPatch.Fullscr import app.revanced.extension.youtube.patches.player.MiniplayerPatch; import app.revanced.extension.youtube.patches.shorts.AnimationFeedbackPatch.AnimationType; import app.revanced.extension.youtube.patches.shorts.ShortsRepeatStatePatch.ShortsLoopBehavior; +import app.revanced.extension.youtube.patches.swipe.SwipeControlsPatch; import app.revanced.extension.youtube.patches.utils.PatchStatus; import app.revanced.extension.youtube.shared.PlaylistIdPrefix; import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings; @@ -522,9 +523,15 @@ public class Settings extends BaseSettings { public static final BooleanSetting ENABLE_SWIPE_PRESS_TO_ENGAGE = new BooleanSetting("revanced_enable_swipe_press_to_engage", FALSE, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); public static final BooleanSetting ENABLE_SWIPE_HAPTIC_FEEDBACK = new BooleanSetting("revanced_enable_swipe_haptic_feedback", TRUE, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); public static final BooleanSetting SWIPE_LOCK_MODE = new BooleanSetting("revanced_swipe_gestures_lock_mode", FALSE, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); + public static final BooleanSetting SWIPE_OVERLAY_ALTERNATIVE_UI = new BooleanSetting("revanced_swipe_overlay_alternative_ui", TRUE, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); + public static final BooleanSetting SWIPE_SHOW_CIRCULAR_OVERLAY = new BooleanSetting("revanced_swipe_show_circular_overlay", FALSE, true, + new SwipeControlsPatch.SwipeOverlayModernUIAvailability()); + public static final BooleanSetting SWIPE_OVERLAY_MINIMAL_STYLE = new BooleanSetting("revanced_swipe_overlay_minimal_style", FALSE, true, + new SwipeControlsPatch.SwipeOverlayModernUIAvailability()); + public static final IntegerSetting SWIPE_OVERLAY_BACKGROUND_OPACITY = new IntegerSetting("revanced_swipe_overlay_background_opacity", 60, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); + public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_overlay_text_size", 20, true, + new SwipeControlsPatch.SwipeOverlayTextSizeAvailability()); public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_magnitude_threshold", 0, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); - public static final IntegerSetting SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); - public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_overlay_text_size", 20, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); public static final IntegerSetting SWIPE_OVERLAY_RECT_SIZE = new IntegerSetting("revanced_swipe_overlay_rect_size", 20, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); public static final LongSetting SWIPE_OVERLAY_TIMEOUT = new LongSetting("revanced_swipe_overlay_timeout", 500L, true, parentsAny(ENABLE_SWIPE_BRIGHTNESS, ENABLE_SWIPE_VOLUME)); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt index 3d3c5d83d..dbe9cf385 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt @@ -125,7 +125,7 @@ class SwipeControlsConfigurationProvider( * get the background color for text on the overlay, as a color int */ val overlayTextBackgroundColor: Int - get() = Color.argb(Settings.SWIPE_OVERLAY_BACKGROUND_ALPHA.get(), 0, 0, 0) + get() = overlayBackgroundOpacity /** * get the foreground color for text on the overlay, as a color int @@ -133,6 +133,59 @@ class SwipeControlsConfigurationProvider( val overlayForegroundColor: Int get() = Color.WHITE + /** + * Gets the opacity value (0-100%) is converted to an alpha value (0-255) for transparency. + * If the opacity value is out of range, it resets to the default and displays a warning message. + */ + val overlayBackgroundOpacity: Int + get() { + var opacity = validateValue( + Settings.SWIPE_OVERLAY_BACKGROUND_OPACITY, + 0, + 100, + "revanced_swipe_overlay_background_opacity_invalid_toast" + ) + + opacity = opacity * 255 / 100 + return Color.argb(opacity, 0, 0, 0) + } + + /** + * The color of the progress overlay. + */ + val overlayProgressColor: Int + get() = 0xBFFFFFFF.toInt() + + /** + * The color used for the background of the progress overlay fill. + */ + val overlayFillBackgroundPaint: Int + get() = 0x80D3D3D3.toInt() + + /** + * The color used for the text and icons in the overlay. + */ + val overlayTextColor: Int + get() = Color.WHITE + + /** + * A flag that determines whether to use the alternate UI. + */ + val isAlternativeUI: Boolean + get() = Settings.SWIPE_OVERLAY_ALTERNATIVE_UI.get() + + /** + * A flag that determines if the overlay should only show the icon. + */ + val overlayShowOverlayMinimalStyle: Boolean + get() = isAlternativeUI && Settings.SWIPE_OVERLAY_MINIMAL_STYLE.get() + + /** + * A flag that determines if the progress bar should be circular. + */ + val isCircularProgressBar: Boolean + get() = isAlternativeUI && Settings.SWIPE_SHOW_CIRCULAR_OVERLAY.get() + // endregion // region behaviour diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity.kt index 3ebebc252..f2b5e4aa4 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity.kt @@ -24,7 +24,7 @@ import java.lang.ref.WeakReference * The main controller for volume and brightness swipe controls. * note that the superclass is overwritten to the superclass of the MainActivity at patch time * - * @smali Lapp/revanced/integrations/youtube/swipecontrols/SwipeControlsHostActivity; + * @smali Lapp/revanced/extension/youtube/swipecontrols/SwipeControlsHostActivity; */ class SwipeControlsHostActivity : Activity() { /** diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt index 6d2cef606..edc936b75 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt @@ -1,14 +1,18 @@ package app.revanced.extension.youtube.swipecontrols.views +import android.annotation.SuppressLint import android.content.Context +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.RectF import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable import android.os.Handler import android.os.Looper +import android.util.AttributeSet import android.util.TypedValue import android.view.HapticFeedbackConstants import android.view.View -import android.view.ViewGroup import android.widget.RelativeLayout import android.widget.TextView import app.revanced.extension.shared.utils.ResourceUtils.ResourceType @@ -17,6 +21,7 @@ import app.revanced.extension.shared.utils.StringRef.str import app.revanced.extension.youtube.swipecontrols.SwipeControlsConfigurationProvider import app.revanced.extension.youtube.swipecontrols.misc.SwipeControlsOverlay import app.revanced.extension.youtube.swipecontrols.misc.applyDimension +import kotlin.math.min import kotlin.math.round /** @@ -33,36 +38,82 @@ class SwipeControlsOverlayLayout( */ constructor(context: Context) : this(context, SwipeControlsConfigurationProvider(context)) - private val feedbackTextView: TextView private val autoBrightnessIcon: Drawable + private val lowBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_low") + private val mediumBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_medium") + private val highBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_high") + private val fullBrightnessIcon: Drawable = getDrawable("revanced_ic_sc_brightness_full") private val manualBrightnessIcon: Drawable private val mutedVolumeIcon: Drawable + private val lowVolumeIcon: Drawable = getDrawable("revanced_ic_sc_volume_low") private val normalVolumeIcon: Drawable + private val feedbackTextView: TextView + private val fullVolumeIcon: Drawable = getDrawable("revanced_ic_sc_volume_high") - private fun getDrawable(name: String, width: Int, height: Int): Drawable { - return resources.getDrawable( + private val circularProgressView: CircularProgressView = CircularProgressView( + context, + config.overlayBackgroundOpacity, + config.overlayShowOverlayMinimalStyle, + config.overlayProgressColor, + config.overlayFillBackgroundPaint, + config.overlayTextColor + ).apply { + layoutParams = LayoutParams(300, 300).apply { + addRule(CENTER_IN_PARENT, TRUE) + } + visibility = GONE // Initially hidden + } + private val horizontalProgressView: HorizontalProgressView + + private val isAlternativeUI: Boolean = config.isAlternativeUI + + private fun getDrawable(name: String, width: Int? = null, height: Int? = null): Drawable { + val drawable = resources.getDrawable( getIdentifier(name, ResourceType.DRAWABLE, context), - context.theme - ).apply { - setTint(config.overlayForegroundColor) - setBounds( + context.theme, + ) + + if (width != null && height != null) { + drawable.setTint(config.overlayForegroundColor) + drawable.setBounds( 0, 0, width, height, ) + } else { + drawable.setTint(config.overlayTextColor) } + return drawable } init { + // Initialize horizontal progress bar + val screenWidth = resources.displayMetrics.widthPixels + val layoutWidth = (screenWidth * 2 / 3).toInt() // 2/3 of screen width + horizontalProgressView = HorizontalProgressView( + context, + config.overlayBackgroundOpacity, + config.overlayShowOverlayMinimalStyle, + config.overlayProgressColor, + config.overlayFillBackgroundPaint, + config.overlayTextColor + ).apply { + layoutParams = LayoutParams(layoutWidth, 100).apply { + addRule(CENTER_HORIZONTAL) + topMargin = 40 // Top margin + } + visibility = GONE // Initially hidden + } + // init views val feedbackYTextViewPadding = 5.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) val feedbackXTextViewPadding = 12.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) val compoundIconPadding = 4.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) feedbackTextView = TextView(context).apply { layoutParams = LayoutParams( - ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, + LayoutParams.WRAP_CONTENT, ).apply { addRule(CENTER_IN_PARENT, TRUE) setPadding( @@ -81,19 +132,34 @@ class SwipeControlsOverlayLayout( compoundDrawablePadding = compoundIconPadding visibility = GONE } - addView(feedbackTextView) - // get icons scaled, assuming square icons - val iconHeight = round(feedbackTextView.lineHeight * .8).toInt() - autoBrightnessIcon = getDrawable("ic_sc_brightness_auto", iconHeight, iconHeight) - manualBrightnessIcon = getDrawable("ic_sc_brightness_manual", iconHeight, iconHeight) - mutedVolumeIcon = getDrawable("ic_sc_volume_mute", iconHeight, iconHeight) - normalVolumeIcon = getDrawable("ic_sc_volume_normal", iconHeight, iconHeight) + if (isAlternativeUI) { + addView(circularProgressView) + addView(horizontalProgressView) + + autoBrightnessIcon = getDrawable("revanced_ic_sc_brightness_auto") + manualBrightnessIcon = getDrawable("revanced_ic_sc_brightness_manual") + mutedVolumeIcon = getDrawable("revanced_ic_sc_volume_mute") + normalVolumeIcon = getDrawable("revanced_ic_sc_volume_normal") + } else { + addView(feedbackTextView) + // get icons scaled, assuming square icons + val iconHeight = round(feedbackTextView.lineHeight * .8).toInt() + autoBrightnessIcon = getDrawable("revanced_ic_sc_brightness_auto", iconHeight, iconHeight) + manualBrightnessIcon = getDrawable("revanced_ic_sc_brightness_manual", iconHeight, iconHeight) + mutedVolumeIcon = getDrawable("revanced_ic_sc_volume_mute", iconHeight, iconHeight) + normalVolumeIcon = getDrawable("revanced_ic_sc_volume_normal", iconHeight, iconHeight) + } } private val feedbackHideHandler = Handler(Looper.getMainLooper()) private val feedbackHideCallback = Runnable { - feedbackTextView.visibility = View.GONE + if (isAlternativeUI) { + circularProgressView.visibility = GONE + horizontalProgressView.visibility = GONE + } else { + feedbackTextView.visibility = GONE + } } /** @@ -117,21 +183,68 @@ class SwipeControlsOverlayLayout( } } + /** + * Displays the progress bar with the appropriate value, icon, and type (brightness or volume). + */ + private fun showFeedbackView(value: String, progress: Int, max: Int, icon: Drawable, isBrightness: Boolean) { + feedbackHideHandler.removeCallbacks(feedbackHideCallback) + feedbackHideHandler.postDelayed(feedbackHideCallback, config.overlayShowTimeoutMillis) + + val viewToShow = if (config.isCircularProgressBar) circularProgressView else horizontalProgressView + viewToShow.apply { + setProgress(progress, max, value, isBrightness) + this.icon = icon + visibility = VISIBLE + } + } + override fun onVolumeChanged(newVolume: Int, maximumVolume: Int) { - showFeedbackView( - "$newVolume", - if (newVolume > 0) normalVolumeIcon else mutedVolumeIcon, - ) + if (isAlternativeUI) { + val volumePercentage = (newVolume.toFloat() / maximumVolume) * 100 + val icon = when { + newVolume == 0 -> mutedVolumeIcon + volumePercentage < 33 -> lowVolumeIcon + volumePercentage < 66 -> normalVolumeIcon + else -> fullVolumeIcon + } + showFeedbackView("$newVolume", newVolume, maximumVolume, icon, isBrightness = false) + } else { + showFeedbackView( + "$newVolume", + if (newVolume > 0) normalVolumeIcon else mutedVolumeIcon, + ) + } } override fun onBrightnessChanged(brightness: Double) { if (config.shouldLowestValueEnableAutoBrightness && brightness <= 0) { - showFeedbackView( - str("revanced_swipe_lowest_value_auto_brightness_overlay_text"), - autoBrightnessIcon, - ) + if (isAlternativeUI) { + showFeedbackView( + str("revanced_swipe_lowest_value_auto_brightness_overlay_text"), + 0, + 100, + autoBrightnessIcon, + isBrightness = true, + ) + } else { + showFeedbackView( + str("revanced_swipe_lowest_value_auto_brightness_overlay_text"), + autoBrightnessIcon, + ) + } } else if (brightness >= 0) { - showFeedbackView("${round(brightness).toInt()}%", manualBrightnessIcon) + if (isAlternativeUI) { + val brightnessValue = round(brightness).toInt() + val icon = when { + brightnessValue < 25 -> lowBrightnessIcon + brightnessValue < 50 -> mediumBrightnessIcon + brightnessValue < 75 -> highBrightnessIcon + else -> fullBrightnessIcon + } + showFeedbackView("$brightnessValue%", brightnessValue, 100, icon, isBrightness = true) + } else { + showFeedbackView("${round(brightness).toInt()}%", manualBrightnessIcon) + } } } @@ -145,3 +258,227 @@ class SwipeControlsOverlayLayout( } } } + +/** + * Abstract base class for progress views. + */ +abstract class AbstractProgressView( + context: Context, + overlayBackgroundOpacity: Int, + protected val overlayShowOverlayMinimalStyle: Boolean, + overlayProgressColor: Int, + overlayFillBackgroundPaint: Int, + protected val overlayTextColor: Int, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : View(context, attrs, defStyleAttr) { + + // Combined paint creation function for both fill and stroke styles + private fun createPaint(color: Int, style: Paint.Style = Paint.Style.FILL, strokeCap: Paint.Cap = Paint.Cap.BUTT, strokeWidth: Float = 0f) = Paint(Paint.ANTI_ALIAS_FLAG).apply { + this.style = style + this.color = color + this.strokeCap = strokeCap + this.strokeWidth = strokeWidth + } + + // Initialize paints + val backgroundPaint = createPaint(overlayBackgroundOpacity, style = Paint.Style.FILL) + val progressPaint = createPaint(overlayProgressColor, style = Paint.Style.STROKE, strokeCap = Paint.Cap.ROUND, strokeWidth = 20f) + val fillBackgroundPaint = createPaint(overlayFillBackgroundPaint, style = Paint.Style.FILL) + val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { + color = overlayTextColor + textAlign = Paint.Align.CENTER + textSize = 40f // Can adjust based on need + } + + protected var progress = 0 + protected var maxProgress = 100 + protected var displayText: String = "0" + protected var isBrightness = true + var icon: Drawable? = null + + fun setProgress(value: Int, max: Int, text: String, isBrightnessMode: Boolean) { + progress = value + maxProgress = max + displayText = text + isBrightness = isBrightnessMode + invalidate() + } + + override fun onDraw(canvas: Canvas) { + // Base class implementation can be empty + } +} + +/** + * Custom view for rendering a circular progress indicator with icons and text. + */ +@SuppressLint("ViewConstructor") +class CircularProgressView( + context: Context, + overlayBackgroundOpacity: Int, + overlayShowOverlayMinimalStyle: Boolean, + overlayProgressColor: Int, + overlayFillBackgroundPaint: Int, + overlayTextColor: Int, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : AbstractProgressView( + context, + overlayBackgroundOpacity, + overlayShowOverlayMinimalStyle, + overlayProgressColor, + overlayFillBackgroundPaint, + overlayTextColor, + attrs, + defStyleAttr +) { + private val rectF = RectF() + + init { + textPaint.textSize = 40f // Override default text size for circular view + progressPaint.strokeWidth = 20f + fillBackgroundPaint.strokeWidth = 20f + progressPaint.strokeCap = Paint.Cap.ROUND + fillBackgroundPaint.strokeCap = Paint.Cap.BUTT + progressPaint.style = Paint.Style.STROKE + fillBackgroundPaint.style = Paint.Style.STROKE + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + + val size = min(width, height).toFloat() + rectF.set(20f, 20f, size - 20f, size - 20f) + + canvas.drawOval(rectF, fillBackgroundPaint) // Draw the outer ring. + canvas.drawCircle(width / 2f, height / 2f, size / 3, backgroundPaint) // Draw the inner circle. + + // Select the paint for drawing based on whether it's brightness or volume. + val sweepAngle = (progress.toFloat() / maxProgress) * 360 + canvas.drawArc(rectF, -90f, sweepAngle, false, progressPaint) // Draw the progress arc. + + // Draw the icon in the center. + icon?.let { + val iconSize = if (overlayShowOverlayMinimalStyle) 100 else 80 + val iconX = (width - iconSize) / 2 + val iconY = (height / 2) - if (overlayShowOverlayMinimalStyle) 50 else 80 + it.setBounds(iconX, iconY, iconX + iconSize, iconY + iconSize) + it.draw(canvas) + } + + // If not a minimal style mode, draw the text inside the ring. + if (!overlayShowOverlayMinimalStyle) { + canvas.drawText(displayText, width / 2f, height / 2f + 60f, textPaint) + } + } +} + +/** + * Custom view for rendering a rectangular progress bar with icons and text. + */ +@SuppressLint("ViewConstructor") +class HorizontalProgressView( + context: Context, + overlayBackgroundOpacity: Int, + overlayShowOverlayMinimalStyle: Boolean, + overlayProgressColor: Int, + overlayFillBackgroundPaint: Int, + overlayTextColor: Int, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : AbstractProgressView( + context, + overlayBackgroundOpacity, + overlayShowOverlayMinimalStyle, + overlayProgressColor, + overlayFillBackgroundPaint, + overlayTextColor, + attrs, + defStyleAttr +) { + + private val iconSize = 60f + private val padding = 40f + + init { + textPaint.textSize = 36f // Override default text size for horizontal view + progressPaint.strokeWidth = 0f + progressPaint.strokeCap = Paint.Cap.BUTT + progressPaint.style = Paint.Style.FILL + fillBackgroundPaint.style = Paint.Style.FILL + } + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + + val width = width.toFloat() + val height = height.toFloat() + + // Radius for rounded corners + val cornerRadius = min(width, height) / 2 + + // Calculate the total width for the elements + val minimalElementWidth = 5 * padding + iconSize + + // Calculate the starting point (X) to center the elements + val minimalStartX = (width - minimalElementWidth) / 2 + + // Draw the background + if (!overlayShowOverlayMinimalStyle) { + canvas.drawRoundRect(0f, 0f, width, height, cornerRadius, cornerRadius, backgroundPaint) + } else { + canvas.drawRoundRect(minimalStartX, 0f, minimalStartX + minimalElementWidth, height, cornerRadius, cornerRadius, backgroundPaint) + } + + if (!overlayShowOverlayMinimalStyle) { + // Draw the fill background + val startX = 2 * padding + iconSize + val endX = width - 4 * padding + val fillWidth = endX - startX + + canvas.drawRoundRect( + startX, + height / 2 - 5f, + endX, + height / 2 + 5f, + 10f, 10f, + fillBackgroundPaint + ) + + // Draw the progress + val progressWidth = (progress.toFloat() / maxProgress) * fillWidth + canvas.drawRoundRect( + startX, + height / 2 - 5f, + startX + progressWidth, + height / 2 + 5f, + 10f, 10f, + progressPaint + ) + } + + // Draw the icon + icon?.let { + val iconX = if (!overlayShowOverlayMinimalStyle) { + padding + } else { + padding + minimalStartX + } + val iconY = height / 2 - iconSize / 2 + it.setBounds(iconX.toInt(), iconY.toInt(), (iconX + iconSize).toInt(), (iconY + iconSize).toInt()) + it.draw(canvas) + } + + // Draw the text on the right + val textX = if (!overlayShowOverlayMinimalStyle) { + width - 2 * padding + } else { + minimalStartX + minimalElementWidth - 2 * padding + } + val textY = height / 2 + textPaint.textSize / 3 + + // Draw the text + canvas.drawText(displayText, textX, textY, textPaint) + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt index af0c104b5..3b82fb404 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/swipe/controls/SwipeControlsPatch.kt @@ -160,13 +160,13 @@ val swipeControlsPatch = bytecodePatch( val reference = getReference() opcode == Opcode.INVOKE_VIRTUAL && reference?.returnType == "V" && - reference.parameterTypes.size == 0 + reference.parameterTypes.isEmpty() } val targetIndex = indexOfFirstInstructionOrThrow(middleIndex + 1) { val reference = getReference() opcode == Opcode.INVOKE_VIRTUAL && reference?.returnType == "V" && - reference.parameterTypes.size == 0 + reference.parameterTypes.isEmpty() } if (getInstruction(targetIndex - 1).opcode != Opcode.IGET_OBJECT) { throw PatchException( @@ -242,10 +242,16 @@ val swipeControlsPatch = bytecodePatch( "youtube/swipecontrols", ResourceGroup( "drawable", - "ic_sc_brightness_auto.xml", - "ic_sc_brightness_manual.xml", - "ic_sc_volume_mute.xml", - "ic_sc_volume_normal.xml" + "revanced_ic_sc_brightness_auto.xml", + "revanced_ic_sc_brightness_full.xml", + "revanced_ic_sc_brightness_high.xml", + "revanced_ic_sc_brightness_low.xml", + "revanced_ic_sc_brightness_manual.xml", + "revanced_ic_sc_brightness_medium.xml", + "revanced_ic_sc_volume_high.xml", + "revanced_ic_sc_volume_low.xml", + "revanced_ic_sc_volume_mute.xml", + "revanced_ic_sc_volume_normal.xml", ) ) diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index c2bdc0677..13936985f 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -1693,10 +1693,14 @@ No margins on top and bottom of player." Lowest value of the brightness gesture activates auto-brightness. Lowest value of the brightness gesture does not activate auto-brightness. Enable brightness gesture - Brightness swipe is enabled. + "Fullscreen brightness swipe is enabled. + + Adjust brightness by swiping vertically on the left side of the screen." Brightness swipe is disabled. Enable volume gesture - Volume swipe is enabled. + "Fullscreen volume swipe is enabled. + + Adjust volume by swiping vertically on the right side of the screen." Volume swipe is disabled. Enable save and restore brightness Save and restore brightness when exiting or entering fullscreen. @@ -1710,10 +1714,20 @@ No margins on top and bottom of player." Swipe gestures in Lock screen mode Swipe gestures are enabled in Lock screen mode. Swipe gestures are disabled in Lock screen mode. - Swipe background visibility - The visibility of the swipe overlay background. Swipe magnitude threshold The threshold for a swipe to occur. + Swipe overlay alternative UI + Alternative UI is used. + Legacy UI is used. + Enable minimal style + Minimal overlay style is enabled. + Minimal overlay style is disabled. + Show circular overlay + Circular overlay is shown. + Horizontal overlay is shown. + Swipe overlay background opacity + Opacity value between 0-100. + Swipe opacity must be between 0-100. Swipe overlay text size The text size in the swipe overlay. Swipe overlay screen size @@ -1721,6 +1735,7 @@ No margins on top and bottom of player." Swipeable area size cannot be more than 50. Swipe overlay timeout The amount of milliseconds the overlay is visible. + Brightness swipe sensitivity Configure the minimum distance for brightness swiping between 1 and 1000 (%).\nThe shorter the minimum distance, the faster the brightness level changes. Brightness swipe sensitivity must be between 1-1000 (%). diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 355ae717e..f75bc168d 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -700,8 +700,11 @@ - + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_auto.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_auto.xml deleted file mode 100644 index 827919d70..000000000 --- a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_auto.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_manual.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_manual.xml deleted file mode 100644 index 567940298..000000000 --- a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_brightness_manual.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_mute.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_mute.xml deleted file mode 100644 index d3b17332a..000000000 --- a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_mute.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_normal.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_normal.xml deleted file mode 100644 index 144ec4c4c..000000000 --- a/patches/src/main/resources/youtube/swipecontrols/drawable/ic_sc_volume_normal.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml new file mode 100644 index 000000000..252a97982 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_auto.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml new file mode 100644 index 000000000..c0d45293c --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_full.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml new file mode 100644 index 000000000..fe45b31be --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_high.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml new file mode 100644 index 000000000..66010e253 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_low.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_manual.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_manual.xml new file mode 100644 index 000000000..a5dc31c48 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_manual.xml @@ -0,0 +1,30 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml new file mode 100644 index 000000000..fc191d25e --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_brightness_medium.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_high.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_high.xml new file mode 100644 index 000000000..5dfb76a0e --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_high.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_low.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_low.xml new file mode 100644 index 000000000..e52b1fe4a --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_low.xml @@ -0,0 +1,29 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml new file mode 100644 index 000000000..59b9e72e4 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_mute.xml @@ -0,0 +1,28 @@ + + + + + diff --git a/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml new file mode 100644 index 000000000..602cd2a64 --- /dev/null +++ b/patches/src/main/resources/youtube/swipecontrols/drawable/revanced_ic_sc_volume_normal.xml @@ -0,0 +1,29 @@ + + + + + From d4ad05d4ba690c985a79a9758a11b5e076059d5a Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 26 Mar 2025 20:34:30 +0900 Subject: [PATCH 34/77] fix(YouTube - Theme): Change method to fix dark theme in YouTube 19.32+ --- .../youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt index 845e676be..c4fa63890 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt @@ -38,7 +38,6 @@ val darkModeSplashScreenPatch = resourcePatch( mainActivityElement.setAttribute("android:launchMode", "singleTask") } - return@finalize } if (restoreOldSplashAnimationIncluded) { From dcb72cc803afe0b6b3a764f27974df91c0dc12bd Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 26 Mar 2025 20:45:45 +0900 Subject: [PATCH 35/77] feat(YouTube Music - Custom branding icon): Update afn icons https://github.com/inotia00/ReVanced_Extended/issues/2866 --- .../header/drawable-hdpi/action_bar_logo.png | Bin 3721 -> 3012 bytes .../header/drawable-hdpi/logo_music.png | Bin 6903 -> 9970 bytes .../header/drawable-hdpi/ytm_logo.png | Bin 6903 -> 9970 bytes .../header/drawable-mdpi/action_bar_logo.png | Bin 2347 -> 1937 bytes .../header/drawable-mdpi/logo_music.png | Bin 4363 -> 6113 bytes .../header/drawable-mdpi/ytm_logo.png | Bin 4363 -> 6113 bytes .../header/drawable-xhdpi/action_bar_logo.png | Bin 4576 -> 4011 bytes .../header/drawable-xhdpi/logo_music.png | Bin 9479 -> 13663 bytes .../header/drawable-xhdpi/ytm_logo.png | Bin 9479 -> 13663 bytes .../drawable-xxhdpi/action_bar_logo.png | Bin 6308 -> 6308 bytes .../header/drawable-xxhdpi/logo_music.png | Bin 16358 -> 21494 bytes .../header/drawable-xxhdpi/ytm_logo.png | Bin 16358 -> 21494 bytes .../drawable-xxxhdpi/action_bar_logo.png | Bin 5613 -> 7598 bytes .../header/drawable-xxxhdpi/logo_music.png | Bin 19985 -> 16345 bytes .../header/drawable-xxxhdpi/ytm_logo.png | Bin 19985 -> 16345 bytes ...uct_youtube_music_foreground_color_108.png | Bin 2689 -> 3189 bytes .../mipmap-hdpi/ic_launcher_release.png | Bin 6037 -> 4201 bytes ...uct_youtube_music_foreground_color_108.png | Bin 2286 -> 1951 bytes .../mipmap-mdpi/ic_launcher_release.png | Bin 3652 -> 2791 bytes ...uct_youtube_music_foreground_color_108.png | Bin 3786 -> 4489 bytes .../mipmap-xhdpi/ic_launcher_release.png | Bin 8305 -> 5707 bytes ...uct_youtube_music_foreground_color_108.png | Bin 5933 -> 7065 bytes .../mipmap-xxhdpi/ic_launcher_release.png | Bin 14245 -> 9660 bytes ...uct_youtube_music_foreground_color_108.png | Bin 8910 -> 10091 bytes .../mipmap-xxxhdpi/ic_launcher_release.png | Bin 6521 -> 9310 bytes .../drawable-hdpi/action_bar_logo_release.png | Bin 3626 -> 2330 bytes .../afn_blue/splash/drawable-hdpi/record.png | Bin 8592 -> 5907 bytes .../splash/drawable-large-hdpi/record.png | Bin 12171 -> 9589 bytes .../splash/drawable-large-mdpi/record.png | Bin 8250 -> 5969 bytes .../splash/drawable-large-xhdpi/record.png | Bin 13004 -> 13957 bytes .../afn_blue/splash/drawable-mdpi/record.png | Bin 5460 -> 3592 bytes .../afn_blue/splash/drawable-xhdpi/record.png | Bin 9996 -> 8439 bytes .../splash/drawable-xlarge-hdpi/record.png | Bin 12796 -> 13749 bytes .../splash/drawable-xlarge-mdpi/record.png | Bin 9996 -> 8439 bytes .../splash/drawable-xxhdpi/record.png | Bin 12796 -> 13749 bytes .../header/drawable-hdpi/action_bar_logo.png | Bin 2035 -> 2847 bytes .../header/drawable-hdpi/logo_music.png | Bin 6052 -> 10257 bytes .../afn_red/header/drawable-hdpi/ytm_logo.png | Bin 6052 -> 10257 bytes .../header/drawable-mdpi/action_bar_logo.png | Bin 1797 -> 1903 bytes .../header/drawable-mdpi/logo_music.png | Bin 3827 -> 6369 bytes .../afn_red/header/drawable-mdpi/ytm_logo.png | Bin 3827 -> 6369 bytes .../header/drawable-xhdpi/action_bar_logo.png | Bin 2879 -> 4138 bytes .../header/drawable-xhdpi/logo_music.png | Bin 8123 -> 14346 bytes .../header/drawable-xhdpi/ytm_logo.png | Bin 8123 -> 14346 bytes .../drawable-xxhdpi/action_bar_logo.png | Bin 4061 -> 6920 bytes .../header/drawable-xxhdpi/logo_music.png | Bin 14712 -> 23012 bytes .../header/drawable-xxhdpi/ytm_logo.png | Bin 14712 -> 23012 bytes .../drawable-xxxhdpi/action_bar_logo.png | Bin 6208 -> 7367 bytes .../header/drawable-xxxhdpi/logo_music.png | Bin 19307 -> 19777 bytes .../header/drawable-xxxhdpi/ytm_logo.png | Bin 19307 -> 19777 bytes ...uct_youtube_music_foreground_color_108.png | Bin 4083 -> 3184 bytes .../mipmap-hdpi/ic_launcher_release.png | Bin 3208 -> 4195 bytes ...uct_youtube_music_foreground_color_108.png | Bin 2410 -> 1958 bytes .../mipmap-mdpi/ic_launcher_release.png | Bin 1663 -> 2736 bytes ...uct_youtube_music_foreground_color_108.png | Bin 5383 -> 4460 bytes .../mipmap-xhdpi/ic_launcher_release.png | Bin 3492 -> 5654 bytes ...uct_youtube_music_foreground_color_108.png | Bin 8687 -> 6842 bytes .../mipmap-xxhdpi/ic_launcher_release.png | Bin 7223 -> 9398 bytes ...uct_youtube_music_foreground_color_108.png | Bin 11374 -> 9748 bytes .../mipmap-xxxhdpi/ic_launcher_release.png | Bin 8160 -> 8511 bytes .../drawable-hdpi/action_bar_logo_release.png | Bin 2016 -> 3503 bytes .../afn_red/splash/drawable-hdpi/record.png | Bin 6797 -> 8301 bytes .../splash/drawable-large-hdpi/record.png | Bin 17706 -> 14341 bytes .../splash/drawable-large-mdpi/record.png | Bin 9039 -> 8684 bytes .../splash/drawable-large-xhdpi/record.png | Bin 26504 -> 18972 bytes .../afn_red/splash/drawable-mdpi/record.png | Bin 4681 -> 5445 bytes .../afn_red/splash/drawable-xhdpi/record.png | Bin 11634 -> 10663 bytes .../splash/drawable-xlarge-hdpi/record.png | Bin 23779 -> 16568 bytes .../splash/drawable-xlarge-mdpi/record.png | Bin 11634 -> 10663 bytes .../afn_red/splash/drawable-xxhdpi/record.png | Bin 23779 -> 16411 bytes 70 files changed, 0 insertions(+), 0 deletions(-) diff --git a/patches/src/main/resources/music/branding/afn_blue/header/drawable-hdpi/action_bar_logo.png b/patches/src/main/resources/music/branding/afn_blue/header/drawable-hdpi/action_bar_logo.png index 5c4fb04e290836e7acd1bd65388ca80c6253dbd4..0b45aa0871ef58359a3fc254e825e1ce32b192a4 100644 GIT binary patch delta 3007 zcmV;w3qbUV9mE%qBYz8vNklEtcJj7Xe;hcG#XQ;yCh#L*H1a-+ zkj;@3!Y#otWPeA#MtTMZp+E2humhN$#kfa-FMui~RRafrTSCT8clvGC#(x1kn8h60 z62AhTMmEDez*|5`E(o`T$v;Dm-pgD0+vg%X`bD692K~=*o?Vqx?9>ep89TyxmT2R_ z+u>g~zN?js$$kR`B8bU}4{igd0jAe$De!nMeptcHz<-B8w~&7IY1%Fg8Jn)XF=XtS zfC+R7s1K@Z5pgxY6xf4&^tpy3^9+%Ee+F*P#g7J{H=>kvY~lDaL|zBsd_)oaUq&;q zJD@(OE^DYvejH(9d*EVVUO}9#yZ3Y3w$Hf__(3jyFb%o^ueWe)F`_2~;oCs0g>=s( z7HH+SfPa7Fg0RZuJN3p`gnqS$SiEx|8-QoCqGO+LmdgMN<;4jU=nhCb_dRLCi@_w z$!3Dth}|8ADv}vCCPlwXl>BGp$Si3i>_@DYN`I0~#a2PJlN<0KYj1Zf_E(QXnz+R=Umy=v<28zK5ZMIS+ACs3uOK9ZI_Iu7OqS;Incqi?`1&q2N4 zv;3!!m%2Ely$Eq@sz=@^t@dA5Uu?&eh7QJgvpQ<9d=gbP=!z z@0~tGVgV{j-HgX%m$^~N6Mtck^OTg2=zLx(a`Q&a8Rw=L5MhOF5w$HiuLM?9LqoDr zP>n=@QlTK^rQLRQ`II3VC(ctnu3gh9FNAJupuf)`t-N0=XXB(P)ylPaIz%&~h^i=b zGYQ4Zh#)L?ceJ7SbWLR6L{XQ8ZK(atiQiwFCKDt23nA4lkhMB3)<|6h+R{t|KJNWK%IU9CAh! z_0u2H`U`ViW*ba1pusSp<`_&H1~DsX68%XZeL5BL5-!$j zRqo$~oG3RU^3!L>W`BSJ{0gJ4G(U}qz@3Ozo)8TllcTsh&}H03I4jLGq0xl8W+;q+ zWrA(G-G2nd?O|^tY&i;h8mKyH zP|;+8E%Lm{ws@?`rmVh^B_DqY`%l3AqhR@DXy=zc(?TY_HKg4|E#m!h(cO9WR_Z?I z%!L#mN9 z+rYbxHlG}CWPfgcgdKSn#4WhtLb!7%jL;>c;1`64|FXFYwjQ}#1|D-&Ca=wcRxU6D zI85-ZlR1bL5OAxmZQvc(F%t6C5M~dy$Hd%4FV+<7K!!>;+0qi_XpD#}E!J$)3 z-*ynXx0h600DV*6x0nb#lEK`n6QzxbFOz&hDuOYg@YP^%i#g7p=>h~b{(deXfHvVOZyLhkD_Y)kiVnQYx zQ7pr?aeqCVciLf_f+4*UgiPRG!~~dyhbs^hdva^um}M!&-ExqSWfmkuNKb^ zE(9jyX`_{he9Q!`{bPf9h$reZWGAT`VG92D>Q81kj$D#Zp*wXft(@>ds7$U>8EiyE zYtG9f8jmssk&&6+m5L)SzT&Ws8g`TU>ek^pA`D~^x-u-AW52~3tONHlqI<0B4vghm zIe!}$tA6RCgk-%#zX+M=uQK@oq6xn>M5whb=9(sBVbf5*|E_Y>uF#U0+b$ zfH#4Kh(lzm*1jf-xxI=aXB|9)$l=K(Yv1*V*AJ2=Y6CWvh(Y!F;j{8Vo^X&vC>&+KS&UABda^ zt}lBNexLPl9QU6i zcd1_uc)x+jfyJ)4=}${tJ<4md+=zo!I~Y002ovPDHLkV1n`P Blnej> literal 3721 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/header/drawable-hdpi/logo_music.png b/patches/src/main/resources/music/branding/afn_blue/header/drawable-hdpi/logo_music.png index c7985512bc6ea7006a2aaf4e5c49b49942515a4f..962f20dd67db20196c0248313b48e7ade21194e4 100644 GIT binary patch literal 9970 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/header/drawable-hdpi/ytm_logo.png b/patches/src/main/resources/music/branding/afn_blue/header/drawable-hdpi/ytm_logo.png index c7985512bc6ea7006a2aaf4e5c49b49942515a4f..962f20dd67db20196c0248313b48e7ade21194e4 100644 GIT binary patch literal 9970 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/header/drawable-mdpi/action_bar_logo.png b/patches/src/main/resources/music/branding/afn_blue/header/drawable-mdpi/action_bar_logo.png index f0667b5e03d6f2b5c9eca1e85a607d24792fb4c9..4c92895d004dc9d4ec7beb2d5526fb83c8d3a31f 100644 GIT binary patch delta 1923 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%0AO=8 zRZJ;zoe~6Kjsf^WIB8ZJDf0!EwwC3;J~ojKokXU{n17UA2(^&!|CV~x=fA3>7pe@| zda=FgF#~Q>813)O0FPN8*3vJrE}sE-PyoE?0yt6t1gu-A?k3hYNL+>4GAmpb`=VTT zX|dc-ZO+$L7O;o@NgjKftxtvhUg%8QXfFp&b~AlRZWoZGSpfR_+MG1hPq3{yIW72- zS3wOXl7IC#hiH2yG*+fQ6+iJj2l|k;x~gvN>uI82)6}8O88_EunOr3Gkd(WQe!g#; z3r-5loorXs?`v;?^mF`tf@8~|4zrDCN!=mxFN73(X<%+s+AbSjZOiAIJd%mGnkI8zEjK#3iLSjaJ{lLFumAZkkvP_oS^BVk00000NkvXX Hu0mjf000-LNkl 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 literal 4363 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 FV1mDbP;CGJ diff --git a/patches/src/main/resources/music/branding/afn_blue/header/drawable-mdpi/ytm_logo.png b/patches/src/main/resources/music/branding/afn_blue/header/drawable-mdpi/ytm_logo.png index 92f52a841d2af105e33c18a315943effde6ba840..a45e2fc3ce888e3c45a63c57f9401462ef42ae24 100644 GIT binary patch literal 6113 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 literal 4363 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 FV1mDbP;CGJ diff --git a/patches/src/main/resources/music/branding/afn_blue/header/drawable-xhdpi/action_bar_logo.png b/patches/src/main/resources/music/branding/afn_blue/header/drawable-xhdpi/action_bar_logo.png index 77c0656965490fff04ba77787de19860e492080a..21ce0f9f9b8996a00ebcfaa359207b7d92cd8b46 100644 GIT binary patch literal 4011 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 literal 4576 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�XPn9B~c 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 N+u86Nkl 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 N+u8 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 P^Z_uqXR6bvKrX+DP) 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 Q+5i9m07*qoM6N<$f*OQQ9smFU literal 5613 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 O1t-m{OiN6NG5-SxH&<2w diff --git a/patches/src/main/resources/music/branding/afn_blue/header/drawable-xxxhdpi/logo_music.png b/patches/src/main/resources/music/branding/afn_blue/header/drawable-xxxhdpi/logo_music.png index 73d72b9d8ffe554f01672ffcabc030e90c41273c..0f86b5b571b889a3c5cc0046d6f9cbdaeebdb5f1 100644 GIT binary patch literal 16345 zcmb8WWmKD8&^8(pf|dd$xI=L-MT!K6;_hyR;-pq!ALq|miaZteIqy7y?qzxt-c}Q_D#%4SWU#;;_d(knMz38=d zXyHSObN8wOG=5MAS(ovJaXBll5=4z95gU_RpJnKE zo(V^SAHv<>XePEMj1PYK%zONTYa7xg!pB?{1Rj(gAP-y*5^IoA)CT^4KPAq1jpw3U z#pc9(?77TovNiNhvmnm$tu#^VH(aSwIHffDEQ<~mC^eo^ zS0H-;uCXc>N(GOh3702&7FGC6jrM`HWS`2R!lgDaFj&s$uV7Fgi&0yvDy zj{Fjc((KAW;N`ysvxON`o4rS@k5OF`&@&AlgPxJu? z34$#MIP)(D(vsh)z4U&ufZ~nm(O1dwESn1W`^^Ph6OJ42)}y613O9$-!D$@~ai29w zEE{MY@)6D=it6;5#`iRn^GKPr0?5Dk->k)JX=p{q`0*QF&5qU5qHmHfC&Q!4$p8Bx zDz4}XKax&h|3BKNqNjL^u~>vA`SG2ud_La`)rU;--)RF zCIR(84ysiKhnJl#BkpE4DgRl`RT6-|Wnh9uza$foEdRB0UD=D!+GRiD*`WTvAv(Uj zK))^xBf^DKGAFX*JX;yW)B^`ZrC}|N5WIMn)qEj-v}!xwZ~xB+x7BRN?h0ijnL?hg zu7ySqX0Z`dpzipMHcFrb(4tw*UwHSzgOvYoCFQgB18|Wn8ZfRgITvba12}9rYkSI^ z4?+>rV-$*fFzjpYbnk#VBy?ESYK>USDvXruhgY?Ak{Q@?Vy_emHCKHK7T zhz-7IA4nNA-{>Y;(fNMad0GB{R2D17gOL%zbpn0SomioaDfXw$@) zVum?Loc3zax`P;++&cM6OU*x8U%%jNSid^l@l?m6e01tR(nl`6Sb;;oIXtoNoPRB9 z^vuq_!_*9z_Tr5}2@ZZ+iQbUl;?;EDx|vS`9&Lpa8VFMJXM^M337{*09N>y$i`XCS z7nK!LZ@+#0vL$8v!06PFJ?~!aane!LW@IypUYS|j2G9vieY(?6P&2MI$*1X`5=@{# zez20f*AP_qZ#EFbg^49$cd9wk5{vlSF&SkTyQr&URZu!CVS^_t{`pqvh=*bcf4M}0 zc{hh298Hp>A~4?XU0w=K=ExSa z&6U0v$IQ6>_!e-+^?lc9KlU#aE9K|At5;6K$L&e$u9c&n+}cRS(SvO<@7qvHkVp&# z)q3wS>Cvi%lK7p0?5ml`naJChmt$}%GtO3)!bwSm>kt(fT;1eig2+fD%GlJ5p8=H+vu zeJwJ7WR-`vb)d(WDTF6&68_aNIylfIB=i!n-SRWrf6#vR74wfle|5wdc{(>DHSfv( zeFJA2yvO|)5Tc>r#)9z=Sl~+{!6nuc$F}6h_(5)!Ziw%!LLRWw@)HDWU;O}%iXnqI zVX6rZMNt3D82V(&F!K^kJTfwR?2?^pu8b%k67YwiZKJz3Y4$5!AezBp%TJOF^4Wnh zees|-L>_2FD|6qg%nuj14Vq(u?tKI0Hr2W2C@8WI!aEWHMd`hg%dsAYND2z0>Hc@< z1kt0xxT*omiS}H6eByrJ+ztS+>01knx7r0NF6t9FW(3zwxw$3ddhxWrGB97ck0O!Z zIy7uKNGK;gxkdU)-r@yjkO2+W=EB~XJI=hcxX!XgMHrQYL>lLcQSs--1+z>z2Evp% zobP<){@{dnqq;5)oy32zkSj14meC@$CsP&E_@6xDY(ijU?7X zt>wBl%H90RI$sjw?h<7E%^{Y|S41xswh;O=saXpQ#UoqN$C2wPBC@~gwr)0Kq=#K{ zgb_aKf(-UuGkr;vroHtKel?*w`iM z^F|3r&-f%S<;PS}rSkRmLu2zl#BEd*}4Q`!Wr~-|9ok4h^GeEGdRi`1YWKLQ$`=rR;YEJwbk)Rs_5k@Q0$e+_f zxYrc)Pk$zom?UuDKkVE!7izgp9UQQ0!Q_CFnasbD#s5)!-Px$AbL%##Uqwu5Ah%)L z(Z8?Ltt`E_>bBgOlYY&yo;)#S6tg9g3HJ>XPXu+6ro4>lsulqd8*~KOZhz50dQDAl zWCP^Hh{N0}hLgj;RJI1JXTU@n-8!k~tFM;W&723ESAwXzC2Va;JZ7?b6yeGi;3SdY z1~)h=B_L6%Dn?gD|B2@iAnm%;?L8E#)`-?3Zf(Nk#8$z{6LA6aRCFW6DDNw&*c&Ws z<=*rW!7r%x%3tSvdHqTnqD3lEP%Ieg0phv)PVD@t71lu@*zTbcK-2N%=ZvzZ$ zC@Qekals`O^44vJ3~uFTUh=Oe#V#ET3-+n_hG~PTwI+{OuqP(C6Rc^)Nd0Tnc58+v ze=UFgL?~*@31lSl3{<`xxyY}sdpxg-#NI`Dq@DWBTPV%0@W<=|&=J=hoi4*g+)&@w zjb+dJH+8WZlk-n4-Z%b+9CvQ{Bhl9>GcSocSk)!91fNz ztHSYWf1Gc1!Wc`>+WRghQlh^ZpbT9s3TWdXUpJm%ry$>x%ywKo?2m)IIi`Lq^QQMR zcvM}IYsdFCl1T&F`;alTC3=_KIsG@Bxv?7hvs#U^eEM~Z<4Haa{xq{LEk|y{9UBrb zX#l%NmL490rV3P9SpVW78*l&kQTg`met>RG6mSp`T|jB|_ThX`zn@ zhqplnI%juEDF0y;y}W>%K{K;Evdj)~O`SP2TyBncU@Aj7L{d`Z`B3G4ivxYQ%(Y^p z&+rD)vs_UO3o&7t`%iFY8_Q-A#@YBaqwz{VOSIXY^cK6QtNiYL!Zy?;j`K=>)9;Xc z*?Fc-dPk@KVN*5@ z(BjBFjZ=C=MB>zFgo25R5?v<*_s4^6xOcXq(zeKA$5M?L8Lsdtu>N)E*-6W$403A! z+%30x6!tjWwNTnkj%S=$?m9jMu)CHIFVk>is}uH*w`BmDtzD_cMvfwa8{{$RVmK>V z4CG}1)peEuc+|0<5cf#t8iFTyZJnL*$ogX{y{98dhfu$fWEy0w#PjI~hjZMXz9$A1 zXIJeVsQuHy`$&VGIe*x!PA7CMAZj&df>$f0HA*%a5sa$De}ag%!beb2uvokq$IC>G zbBBKX>M$%Mo;0mu@O!mAb#BE|p-b5Hf|6?h3{fYuE)V!nD43ig;zq~>W zYuJ3lc!fmix?3EIw#&eL8rhvQoXg-!VGO$LoE$stnt(4A>Xy{fdk;8buqL8%($eo4 z2%7ywIP~S@vN9|<3vTI)thXCXmtnJhc*n6=h$y+><$xlf6|{gq$f)eUhSZrqTBDwh zBan_?h?yjMf^cM$tn@kTX4#r6>W@G)g%<;laG5gl%HPv)?dR|-F@le2AdzkMcSM@- z9UzO)$Vf(}PsHw;7ERn$#mEx|X{QtXkU5K{Qt2i&$5Or*H0)_0Z}{6#)Uat6v9Fs{U~x}FY9koyH6=kQY*=kVgj;XN+9OM~ z;^<4+<7YJs>|Eprb$X*I2Y-K`S5rS@LivDiEU!Fr*K#^AU!r%B78{UBC&8gx#kbab z;4jOiF8^qeTMWDMPso|zDB9dCP`?H?kq0!x#nc$2Bo>A8brWU;3VfD*N*uoXKLy01q^z3%@GDRrWD~$v-o`?Cc6eHZ_&P zl(Jfn(nsf-n!}l>vvOaIUNPmiWz@D2@b?AiQ~k^sBtTrFs*{r`0J3m&nSvgRf`1sa zd8k~+A2Ye0s!6#bbfKNEhrKDRX;U917O)p=MEQ84s8S#KGLVR(nMzuD^nLk)+S>Mp z>X6O^^`d0A#^h}G%Cmh@Hg?JDfdx%C_*Tfh746x1buk8}Ooca~QH;OR6`5?XhF!b5_0jWX}S^rmA8M@6-k`8m1ZE1S9 z1%7m=ckbl=CtOjzy+MD~ANRA7YP$;+KDE>N=2o?a?0n3*6rmjsA~n-}rqX}0fzoDt zf!RlycO*{5YP-z@_FL_R)A_(YUEVwF+)1n-_5_k$R5eh%IEcIB5TWG!8HCi|59p^M z_h3Z?+EB&l+Ot<(h`nl3Tv>A!{BZ5%8Hq zVI%GbpJGPTej9n zfy9;(v_JEES-mP8XBAQnFjD-9SHduZJgtvV4f1Lqd7VV$6MZG3DBFd4?}h=7Jym~B zL}igC}o`T*)dgNR6;0K+F#3cMdqQTPc@8Sb_$oRJc~bKO!6IO2*yv&xV` zca-D7YtjGGth3btq)8&}UBQClo*Bu%Y-*+>i1-dYhZ3Xsd!h*?V1A|x4O_L-_0O3C zU7O$E>{@8@+?*9xHq<#H-C*d*YPEYqZ;yrBI0vZSgnhh#>h_eLnB~D0JKO*6lFmB| zGi~3V1ETGf@(-&Ai;+U?I|iFK#?4P5sQl??WGs3wC+EV3u7D^I>nzdl?l8Pi3c|}Y z8;2$94${mQqk5Dw0uKVx*LEATsim;;7`fIA?NVkbfzT=$#9kfM69L?Fd|)1@>w-DP zD2d=p=k#*GFfh~G(w}}^>1D17(OAQdPj>O7j@K`df>!lREYkKYx<_ak%e2GEB`_&D zjAQ!*;e3XIrvBB2g3A%p)5&Z)#O58rgbex>Cq-b=0Q0vm2D+6NL6eP_3?Tx$yJ@3( z#>;cKiQAgRFR4>~iSY(hl$0|bWOKE)UH86Wj59%z)|Ic%Pi9(XFvz!31`|6PGeXg6 zJy0C1vXgeZzNv+C!z>xuLBZOE0H6+l)%8G9Qcj(Lg=T>DD(Y9vr}y;6(e`#0u(p2z zSRK?qsph~*JMo_$EJ$ClmT2MTSdBnoO--mw|2~P*78Eve{C=P6gS38O!p<5vo#o*H zuQlrv3&IAMZBYI_p%u4L9pac~@9TR!5sTr276gECk{q98l@_Yl^5ncLBJv;B z>+gd~-`Q9VZ@*yrqOp(N(htRJH*%xt#OQw4;(2!BL#cOY^oyeJxKj|K@0CLS;)@z} zGHBnwXqgUQ#rxOEFsRfqj&HQp8Je{^PX=*?1}Ps-i$ED8Df>6+_Pg^N)`ezXUgt~% zL_Hx~%!fDr5vpJH`FdOAWI}%qg{P?--r>SJ;A~!hek~$WRE+1FmV|`jb#To~u1Zkh zOYdi1_uo10t>Q6RkAIN2h{ubA^H91}e+Q zkHexY2UHV_uNYFH-?#mG772uK$-e(AOHw|C{*hMGzuT)Qj(#O2(Iu3XJLc4}qPHg> z!4pmo>%^eEC9n5P8=2s{1Z;Wxv|c?)DUm4$CKzJ$>@fa7O3d``MWsu}reZJ;ni*|2#`^bxYnR;cbNI7t~Ux}I}T#=nNj2pEp3oBqsLo(qC3h_^spZTknowLE@M7CTpe$myK#&Dk5|KVws)z#dCsIGC64=|LHV! zL#?knEFa$nXFteO*yRC(`e?0B^?V(l;u->lG!W$4uN-tn>YPwqggN-hd*eKup=xFT z^st1s=fcoZR_FZ93S{H7%*U}M-+&Y0Aw9UnQLfWPIhJ;IX3XHY0ac0DODQ2Fn0i5njcSN6U$$5QGh1jF zG!QgRjud@pLx|?ovh{Iki|7HXP&-Tb+dh6v9}=c)a*@ik{lS-OtwMiR{p34#ua>lN z$`O++Qt-(GqO&m<7DKi>hmRFXiTTjEl7jp6AGm~W$%WC=JPE@u1|JXFgZxrzUMS87IzCXwn4Flt)S2(ty;bx3 z3Zouth*CrMz8?{z{_Uv+wQcWsMs8ESov*Z+5+i7N7qIQu&LNK;xt^K)D;V%Z5_f|I z|Fm45q=xl`evd-?ID<3t)lIOpHp-*!)9R~L&$bdUyM`Q=x}1G^JV|yuN&jk3Gti!E z0ed;en=mU1uz@FNbbyk!*Moe!8GY7&h^JEGQTM0*YK&vBy@RohOxHzf-c3E6G=4R+ z|E%(albO(WdCotkp)6!A`sR!hl!XzTIXU(By27!-WQ`h=H&E?!Kb;_`E+WDKSeD=X z#W;5oDp$Ccpti-F>zft-D>L3kMJ@`(SN8nL-vHv2WtlwuyX0Jm24!N=#Z^&N&M@wa z*wjpWVY~oFgK+SjLo$b;OARhnxoyz5yLA0b$lkzPxaZllatd)X6GTw5j(oh2tdbwx zvliz!gw62eZk8DP;fyz?n+XdX@1yp1YGL7PROBcwD3hBOaHo5`#`Qc!b$!90ZLm}I zU$m6`_}eBD9vi95V7bBwE_IqZ?NqJdPuIc0A7_;nM={?PbD5_x%@);Oh@0eYe8J8t zJ3Lz=3}2!1z7I_W(lDOk82|8Lj~8W}{FisU(@t)C;S06LKel2FA5^JPYFp?mBDs2f zq5oikxV_e$F?nBpn{3WB{h~npo$>sQ)wie&hs^U7yT41y@oMcS^EynfAg6ju%9jNh zIicKU6*tT~=e0c~g@x+>kjA+do<18fbVUJzgoe?beCaBZPA2G~D--oR-K)wJq)4w= z@>GPNH~C?nI9qGRqz==L>ZfRtHvFgywCA zJ`=tWp|b7XOeHDy+koKU1J=3EvSjI&GsT;mwQYKN6EnE29-rCM)V(^SVO7!npW7Oa zcjmR?zb>OQz75Xef1_pmrd)GH|JuUQmGP1H#%jrik9tA+4Q39#xvZnPc{7-0p4(O{ zzKSS4^NB&0$S7*o*hwZ;O25=p0I{xS|9rMvE`Hj5yr}1hd|%nmKCAY^rag*V{el;o zUq!r;&;v!p0e?py_v11lz2R@)@+^(1U=A8(^lk_FEYfBi5d2rvrDk8$_zGI`E4;@QkgSns@^bea57YfRy^D z;83v$;8)PQ2y5s`j9FY@t2^m1a3{YpkgCdg9h`%!r$s9ZGq8O5?-zg0e#`4+eiN#cmu;+S0skpo_=%- z@W>i0k-2KBGgab>a4&atWB+UtQl*3q(q0lWgL-~{&&*Hb?x^Dpa-qrVI2#`|5fq8b ztUM`<5w_n7B&AZJRrJS4b7H@Yc?@l1J{F_c_r2mpNF#WMl(ltk(ssqRy!YpfB9ES< zLLFWe*n)6EIFjYjn#`L+o>AD#AID6;IvS5_qa`9OuK)d}eM>VZ$t4he9LE1Z(EG3LKqIzi z@Yyb(kVh-~%DSbcx1HC%p^vf1?W<5$0a^dfMjrgu-RH2>c zhYxXuoa1{gj;f1gfa-T2gY5-4?;bG933>L8!W7*-+EmQ``n0dN?YLIpgH23sUHsttf)`nqbRiC;N*ZX+Ij5mCZXz|CL8hYnndM9s z0W8fe!yBYgv*RDs*KuF+(X!G$%rT0=s-Lb5D@nx{UMrUT#lbDa@yS97FWV@oHlrjV zG^5)+x8iIn+0LUl~`&`Lun~IjcJ%4LK(RaPS6Ib-!dKZEQWo$es(Eu6z%XRB*<<9KSI^WPs7=w%qNh_qS|H0JgH<}m56w| zgWF-jDvW}q_I0(F%zO4Dy}Ei37FJ@&zO8;F-K)hVD9IfiCzW0r-TaBJ<9Zre9R_PS zY}?UMC!>uwFqoWroe3t?qjPwd=;%0a%yCx{yPg@&$HekVvt0p^L#1qc@}hi~BZp)> zbVxq6Lh&oxm(z~_Cbz1>b@lc*BZQkOuiBFrc53YF$)zfjmdEj$`PnFtQ(LbD5*>{j z6cwrT5n-)6<*1gb>Z;Fy#J|Vcg%JDdp1%C|1hQ-^-{1bgvtKe+Rj=kat{Aygl{YyD z%G1o@EPN()inUCZfbCs0xw1?hulPPubSOmFnaMwrrq&(_8io91o)0ZlFW`D-1MNRQ zU>W+NZ+&D~J!2#Y)Ngd7{eTkbafc`Rw@+1a?8ie4)d2`S$^$(53;r1RH^e^9wd6Lv zIm80D@6%9&>?E2>@D>{3@034~Wj^S#Xmk?i%sS} z5gFgU`NhbQ%P2>q5BY8+)c^gMAJuZ)8KRkB-;(zMbyaqQi|VkKSXh`tb;6H2>4_*q zT%EO}-u}J@6MqZuPkBJODw9?>$+E%kD{=d(VNc|;_9(dpzBoj|5GUaDM&?Qxb1W#i zT$OxrQbXeWdn->-8}u@PT6`#H0)f7VeWvUxENnC$N!ek!DgO2LW3AdQ5|8(Fm(BHY z$kg@8;4?5;BzI2~JoZ#v!#3S(!cE4*1InAcp8{5Mu+~X&{VqBVlR&flI}jSaWlks{ zW+XGsGlKtR^Ln7}Gc9WKk6#6i!Ui!lS408=hjdL&XNg!|(LR5PjYWhu4K)SHI{HF!AUIM<*ULEnJDr4X;qg_P=~q$>ev4w#zH~0cRXn z*JiaA(H(!>L!^qZ>FMcE-oQ6v2rEqPoa4h68XUpO0@?nfdUz8&m&NWnt}l3`A^U=n0?V~syp7N%&h?M`2Zx511G2K$Kgnco zHnNYqV6XMjSCk3tu9@C9YIlEW$Y2u)`qVDJ?*@5@u;BFw z;^l>0;g_(qvbJTp3I!^gNtyx{noGig$RQW0rtW&-Fqd1+(u*xQ?|+{dzOjy4Dj#c_ z;9kBHH=ik3?FlBrJh?r@W_7^``#}?sCkp%QkRGj?GRFIrKK9QELV5iYW#plvla4Dv zGVTI`?#MQ@OKV}F4?&+^r#{liobhbxX0&qNj+qLft{5d5qc9)Z2;xtdCm88%_ITm*G?*0Syqr!= zn9*(e-)1tCKx9k2U$@>v31fy@$bVUE6@>jV^xO;3-rK!2A2hZn@&f(f!+8~mIOod( z3l{1k2;Jzmhv5Yc&=4T4t6T4X9as=)Vq{_zVnyivAP){4Dpu5b0w4|h^wlGw*8edv znvab2`w||J^HR1iVX96;@(%?1-rbD=BP#`G%(oC|3D(Y;_=jv|yn1P}(urC#Z6(;$ zzKm83WXu?yCFwcr>6V93TNqwfc>W7m#ZR}##P|h68qV-|l@z`TfeaRs+4xf>^bCd} zq1V0Y8PDaw;lc4*?Ka0Wi260dRLHWAoL+#4n_XPqntW<&Fd<#mE4`r6rPC6=)<;Qq zq*Ovg$ssy;3>0QV&kQo#LA>A1a49X*@BWMdClVP2EdQGiwy zu<^q^6gu!G7hWq&JLmh_%#RxBIi=>d8n#%l)TBf!^f&oG1L%fu`(TEUg+cWL+{M%Y8Bml7wo8k@;pZpj173J4P~A0c*7fQ^F@ zW()q<&^2%-YZK5Uh>$~F;CW^QfPS6-xbamsH*IQfntWpvH4{0IKvW8t@(>={Wgiwt zwCas<2QKCg=-$&aTER21BuwH@KVkfUjiaB?Lnj)mZFc{+7DNy#FrcQrtQRjJk*w2n z{uk{bC@?eLD$Qu|RX1t2s5Hm8d1%JtVFKYBjSwhz0w;gKVl=n9i#Yyw-3xb! z186w}ag!+HBF4s9D)ML|6KWsk3Ew?-t=u-IH%&}!n%{R`Y>yH#%utrTTTOiIpd z5!p0Hzp+}7RucCXdKOsRu@nKzpr$D1-cOzOj|>b!QdKM&b1CwRZQtaf<*@_#Z-|jq^wnrZ{suSPT2{uX`DV?t@Ml;Kn(xRgro3d3)NF3MGSP`#Ncmz4IwX2 zkCVkZA(V(rZf|shV;~A>FT7uMbegC!m1}y3NLHZtD{(SON=6Z%y)ZO11{f%PWnTWG zx95b<7gUv-0l=Vp8-Pju5BOU>a^EWev#sFg$DO)&TtJ4|U6R3O|G`a#$MATHiM`vVx;u0p# zEbsh6rvpLC+1U;Mm8(|(iN7T|HaE#;!G<~ZyXb7-c;oA|ovqX_sziRK@&5hy4iT5I zuVteQciHAn!_EDip&sW~O=$)W3^(OD;}|YbNad3Q#TFF5W66tvRfiz6T}6y>TT|{& zZ_bcYt%8whUYC-)i(d!L${7H^nL+_}FJJP!TQag3_flk1Mg|$#*{QstNWPM8DF~O- z&k)#B#*kRdh5s{d*wIkXBw>2`3yt3PmEe@3A`iR{cfU1_=?4>9vZ~x7d^|S(`nm`l!`EKdemV{>S&H9@k14*~Q zYUUnIR`HaQ&{6jshmXX`7iVdbc%rWWZ0k}#nJRz66&B)0X4746-=JRMvzjUc!1n+A zBrS=;A^HWIEQORlS{K%usGty^EBu0WZL5z~Fb6T?B|aq^N=rMdlGF z2}xCc$7R%d|9EZ~JC~Z$wzYUo2?D3-N_m$~@AWQ`(|d;dN%ORzo8z-or3i4nIvt^W z?Ns#tz4$5m?717ZGpie$4(!?vm>fR+Gd?vaXHBEh6SaF+88(0~stRmI1>IRZcvsXs$B<8Jd;(1Gm<^)CQxnu_` z8?D40xo(iv|5>i7BQ8N|iy}Trns+1kM>HCeVqU(N(9;EB|MBx}T8>&f7Y}b8-Xl^L zY#%<#D3;|Yz0IOQUDVhp!*l^&PK>{NIy-xXld7;9jWjT;x{eR^nb%@e!eVu~zt$~K zoUX;mWdT?xcLdfEx1cQmCO2Cmv};m(_)uH&Z+y#GQB1?_ln^{SOW*Z5|5^UM62Ec6 z0?Kc#rf2bk-*ETeBWX~R$r%Duq<3u2u@JcVQR23dX3+F4u=Jub_&;zu_)nWm39Tsg=?$5`nfR<~UI6rqVON(-IGGhfTizx- zPHImqo;Ot^StDrA@sZVKO0w5f zY}N!1ER5|^RQC%lIPk;s`x=mLz@SiLXS?ZA-$X*1|ow@%hhB2+RY@0a{^Gf5&y z$UR``w<~e2saBfD9<~0ANW*`fq5AmVPbhCn?FE!;6!Ym#+Fv`rmcG}JgMa2FNjjJd zdxc|pZYhY!9Df-8y5&I5HpR2R@gHrdSon}#u+Nc|3c?4Z|W@???A%eBu9PA2N_ELKA0wg zwuGeo>d~~49F>eSHV8A@oAeL?b+w{BfK9m(I}kPZ5laW>tdzdnP6X=Zwe*_8pXgFv zMK+Wd{Ntl}ql*-qlbcD$+7$1eK_Fmj3~{C?tA%E#cuzs$S%I`pU6N}Hed4dn)$ zMF9w#-7;RgxUkZDOK+Rn%~p_eas{9czM0wqcVG;>R%{_^VD6odl(YM={p*+OYjcbt z<{&@an?UjDC2iQ}f6kR|`j`JCE74~8m%TFEg6;=r*we`~>`_EOZT{&dC(De>v2{BN zAf;cQd~%Ro*c*|r9Rrk6>7!-}V#i-R>r8J?GwJ3$<3(0k*-L)T0L%m}3$5Scwm$qS zG7dZOY?1w+eOVtsd&a7A4>Y5H5}J@pk=V`P489hSopZ>qWXc*lKHsM1f4OyTpv!bu z)qiU`T~Y|5B7mj2bN{M4KDvRf9j!>h12H-I#qHJHv)SyiA%LRQDr!1!ty&rlZUT7H{VKtUO7^6mvx?n?x@d%+uOR^xzAp) z#=xx6Wh;%58CHTxNyI3ATL0iXrkY_#dD3v`>JV{EJjwgDnDgIpbid8UFR`S|$(gyl zGqrgac86pNc``MwUb8&l48V{2KK^~ICtg9Io=8WM$P?GT2-$r_XNPdmxO0UqDlfP9 zH7)EQpm|=ePFt=Cv1nga1?3T~+0!umV4y zET>9{p`3{ZuOQ-7V1rxV^75{I$f+jtq(wa6 zjq$Z-r17ru8F=ULeBW2=qTFNm4`_1}ogFY?xzs9deXZLO3fG?q$qM9zCe^1H5Bf`znh4gO6;hF(np-gQ3Mm>I#q zBEm9cbUR$I5B;GCP2_202rmalm{XSg;fD~$$eQ7sTFzJxY4nc0D~%m^uMmDj%bBeM zNapmnqcpeCDjnIW#`^Hy8JS+7{nb)P!zjERL4W4*>q35;7_R8zqEWrfs-zr!peZ2x zAu0D(UmmU9rZU!p;H=T=s*%(E@bz;kKyt)~_3qT+FzmXx|P_N29)$^JMaowRfbs?Aot){v>DJ^;&rA3tj;s9`;9Yn9;67)9~SzC z2ic;HCrk(ABPfGBHj@ST9<1b1xSlxp`Eyz(1ZFs&w2`AFe&)G{ib1rIh`g`7%hcOdIovT7=0Y;?Wnx=42neR2 z1h@i}vlziF@qZ=Ionl!a8^`!Zr-*MXFaXQ>j$f+ z@Rda+Zbp46Mw)oG=rY6CGh9aYe&KYyt+T%Y<+3=Z)#&`w2r1I?{fF^NPq`LX;pq+1 zz~0@wJkjjArozJDAWX+BAq@O^Bi)9m>D%#&)Qcj`5EDMYt!hM_90H~(H?L^I$HM9m z$51PLs@RvP|0Pf>cxAzbR5Mhxd}8yp&xMe}r=E;2d$#zfrTYer;D+M34#Dq@R11r( z{kb5KAZ{RE9P(Ysug}qZas15>ms=x~=%jmeX+R=chvLSgv30tTV<=AA~V=3GqZndZ|55G15D;MSS|^Ga3%l{MGzTlxfc>xx)3Qq*T`rIt)?F*WOTU@s@DWrux*Qz9d&EWpumMd-& zjdi`*aeUprxRIu>AX&FX{7mm{q`W4#ELH@Hb;bEEcQtRE8O{+l=0=Xku(ZXqn`s*3 z@Ud`8?Wov15+>IF5(wQ^VXy9x7gv;aFkq6Nf%@zc)%!^(6j!p)FrW@EkpmVY!0u5xP zVLRDXKmUsu? zwhXV}=CdRJV*fC(>X>}-ba{s(Z%-%Rzyg?CTnv`wC1IfD{2AB|^u~H`+O0~qifWRe zRz!2E!*o`E@_F?koidQAO8A#Y&j|haPRmC{1f^c4O$;@h*Z2e)V|;y$=`;*Ilsd76 z+#!hor}2{rk^^+n>Ct>|aFX`t!X!uM=A>J&huEhU$h22Q6Yu}jf;z*P@U6z98a-}j;b2=sdBi=`9f7HoAZQ2} z2rdQu3Q@rOj+Hb??|DK8qxdO>8ZH%ttSGj!CIY{)gyd%=VF>9eTw6Q|ZFm_0lrla& z76y8Z!nF%asxWg+K1SA2hK-KQhZ zo#c4$<`piIsnIc&`^f#3xee^H9&y%RbHX>?1v^`0WS8QiXkZIH?*A}wv4DM_e>C%2 zgBC$l_*;vIo+C`({3|U@F8L)AZ*?>O6;5ezi%=GP zCPLUE4#5|6h}F(6C$!c&+r%f|c%ebM`5n`fl3$O>m(OdlH`@tw5SaKg5ZibS$+;m-Mp{|uRz zQtqzb1;_(TqujbHH&%qeJ`UXb;(_;LX9JYwkup?`CQz8^DXGK`Wj_ZMc3XWAR4_@drOPia1$137^Q z$cY72U55;uSgvs1P;eE<^Ksl}ajA`?a56QC%mz1vv7{0`sXYGHVf0(34D3~JVpu*r zS*2|uGL&-uUS#mnYbr}B;V0-fD0i|oiNlPt$GbQIUMSU#ofH^arX64}&BJ#UqofRf zjUOqf?t=67nCkN;nQG~3KK8Su+(}hY?hV|9r#DV!L?@srS{NXYwz#V($k=rJA13e4 zu3oUNqQ##qDg7`}CRe_wC>ita5PM#Ld!xu9iTfGk3UMc%#=V0Bp3=tYz) z(K~gfsbwoo)!G=`85z)wS=DahFLxN_*qoQeW`q=@92Z1i$skZQQY70u_z3xn^|Bz` zui5Q2Br2-B(rG1P_QvcKTHbb>1{T!UsaVDz-|+){(W@f5{aOr&2Bz0q?6DbnbliqC zBf?enXku=Ems^@;eRw|2uY2TbjhjBki<~3NzX<#=%Co&L+QV;;8b_`W^=(as!=i!@?*p{f~Zg(%fT+-@54GD$zr7~@}_oVctZZikkvv1H_Q)oN#Ew5 zpv;+deN|Jp^uh9?V7iHv!j3e znNjJ5bm;{G8WpUaX4uZlE4rpZctL&J#iClH;@Tz1dRHbI0#~85vNO&~{w3YuTPiEX z$1`R9472t57 zuK#=xit`iOKO1IcAovQLYoSs#H+FE4{gcxaQFjzHFS5MS954!zl{kJ=S~|$`&OMg$ zeCX!|s{#K@yvQ#&6_^!RoDgmxS0G#VeXE`9?d;buLr**pphs+3S>IF=SJ>k|qt!EW z(V@{2n}B@*mk4Eldu-oF!Klc6XLr}EBfv5!JSq5+PUc9X8UUOn;m+ahsH7D4NCVNU zA_XZ*0no)g-oD7nwbTdHEqRe%&N~kNo>fdLqjD_k>_$cJU)6?#%Tk{k zk7Gm7GT2fAbp?c5bR;_72`9k>nQWL5Eu4Yk$SQtyJrEzE&RSY=qcjwf(0tbC&R`Wf z4Rs1C5pMt)x;JU_jZ)yY9k4AVY-ZPOH|)8;)WZUqQA7~v2Y%^#5DI^_jG2@``rNaN zLrjb`FfyMs7JSCV#UQ?;i#^oI`WgR(79mVWLK=3j`V~C}ir!CUi1GHAaM^{~#IyNX zoNp)qqt_Rn&Pn@9T!^&?Qf~Oa-M35?Caj>BC`!nWJF|&$YiyCn#L=OY&uy_EBmqHd z4v6+;7Pwqr+v`+!&UZd;C=Tv>;m<>|g#yBRDY=S!+E7|{XA^Ty1USjn(eF_D+7NR= z(+utg{LQ6M*IGk+tuu#-B^1OYcp9p&{oJ8zBaN&g6p6G6GzLoxT;`Hp6E%RY3Fup4 zh+(PtrI1w+bwW1cNYrN6+#I`34Vx$Q<1ha+s6kZl@RYZq`;qjH*o9KRzz|41K!D_tzS#disC&bz4+2 z!~mgD#7uMe1z>4Fm%pi97~AP9d7t)uMK}XoK%ul0nt4Vey_mZe*|1f@knkldwHNhK6eLXePdSeEWk5JZJtM8X0I6{Sl`X#{Dc zrIub`f#3T1zWTrTzhSv9*k_(IXU@z$_uMDZ_@)jGB?lz{fJRSO(-Z&_B=Pr7IE?rc zEZM#V;KrDqrkZ)s_(mQ@7_-(vhlZEUmcPHvl$H(acHb*BeW#!dMbe*&ix(4wMJX?q zXsfC5bHy2`Q3vX_u=HklQFUI@t?VR$XkK8TyM2=m8GCEkI;gtz{vA6`l8VZ|2@{Uu3JU@e+EQ)$?U?st?pvZvn7~y z{vV@V>e3;GbWM>4pt~IAHHB_qM}FhBA)f+ylugfHohLquMZu;Zr-I+u&s5pN<-c7y z=3TMI^L#0A1J}>txSp+2vW)-iOS2KO>?pj}%i&`C^tOWo=~#?*pmt*#4;m}OtU{^6 zqe7;_q(X5@d#1`XMK#4e#V|!X#gW>ypnm;$<3iXeDKMw|YACCs{hv$pl*S_8(OYxD zg}9+(d~Hppe(WI#R0LP}1sYL_0;9slR!`N|(Q7O0D}fAgwpw4BF(tEy5wG5<|L@xl zv-fifhWf(Qs%HM)$&mBN&<9#ylv%Q_~191eBI)VEgs9E8O5Lca||=pN`f~nFWRnL6IsIqnWKS1RX_N5Pc|{R zcc+{tUC|2EqJNv14M~V9()$+*Nw6SCr(4Mqc-=4d%QHN7RP9-h`JfjhmzqaT`ZKp* zlrWq6Kx|RfKbb_av%91?D>|#-qk(sY7LeD;_Cw2KIFQ; z2zn?@BAgsqiP!|2(1|nZed}3|>~2mdp!?6B>E2w4>cMwqw_Q)@C8_PhmAREWZ?66GsEF!)K^YmTklFe7w8qnr&{TCJIIBT*C^wCeP7+p{V~>dtAIUgqKatrm8Wh zNL4MO4;AVD8XGkIM8Rzk*xdoSw`x!133V~tixeassf+Sz z)2n9*stlx_f53w##jZ4ya4%1ErF6HJ)?jU_l4hvcyWJJ)wyCL+W%pDo86j}dGj!`NE2L0S54x?F7L;_Kt zT)zYhn;&-*_YznDezf+5W?lsRjkvez@826ZUQNzZjm{J*FH%D2eUU3`J6Rvt^EDj0 zKkho<8ZhzfVXw%CZ;D2jKKZB>3PGNXgW*svEJ_SrJ3wPS@8-66ZSi4PxO&vL^slp@ z?hob!YnfssRS|*VS)df5rgpcC@ddTl_;72Z6pXLz0nub-rQ1itcnY-c1)kH@4;r-+ zaT0f~l#GucgJVsXQ~1jyw;ruVMaYu7#LN!WNFaC25^^Vv#BM$mBBboNYRI=W)*kUw zYzCV|H56Js98f&4?7Cc|se|vLuT5s6Z!5|xX98~q`JzX3xKSoVE7>u;G0g4`MT*rE znJeSwt)j!6ebvzH_<7_daJfuqE6ri6gK2bu1vzghmH@U*YOU3KISK zUmQ(Fp=4-x9*{K%;rk@efH)IhRe-I+)g@_SxeY8@&773RM(($yry@R?#v2{X)q`Hg z%&C75zAHgv&MWk9w_(^Y?upHZZ|APwsv&uT2_i%3g>dl~dBAZ)oAx-pZ8Wdy=_1c* zg?FGa5GI2NFKQ`&Pwrlu+F)1CXue0d`?)%Z=5@@kpx(RbtVa%iSGpi|r2H!ZB-oF# zgM9ubtoD*5d{0z2UU&vKTez)?kS^^@S0C3=QE`5H8-rQ6I@hs8j+zueOny##3IsL! z4ZuM!NW}&EV=}QfA_6K;bmh+KSG}CkFXo@FkPSCyYT)eAJ7RFO`Y+MwVJ#uz!<`_d zuNS1xtcE`AbBLGc6nyfPS3bO|uFGh*u_(2Z$puG+L6s+B%#lyy+bvqEH^-ft%J zSW2*4n@xOgn4)Pl#tLHHerG)7ZDLVt=kN~6bSQ6E~+fhdC2}Yq1m3-VhX_#Z8WKGQtRGR$d1m_&`#{ar*tlQ=KX~xWaKd@| zL1tQ-U8`w52b~>kCRZrz)nh&%wg8B39|Is8Zm_(pDXR-)A@q7%0r_tnCZ_bRaYbc+ zh~)50MOTD%h0d3}qDI(+wWfz2zhgMFIZdP9QN1US)PsG#rR{fM1bQjPDo!=?loT{` zE<#TuLFf69046SJZnz0X!e`0_j5!0*uV|m&BtG>*82s8vJvrGMBMRWkdcDtx1s`ln zj#tC!g|qiWHF^>lqxpBozHgAvJ*VdwIvvY?Fi_2=AZx%5MM79Ie=-;7q~F1fg%S^` zH$Z;s@9=Z2%`1)5FrG6lJ^I!87G%A;MDU{p2%GT#c1^mbJl@Z5Bxk)B$MLj^EWnHN zO|%gC_I*DO628XnG!yRY)aK;GFs|28%31Ay6rnX*%t1?rR;34fvg+iDi|p-c&C9Xy z?5`)uN85n+5$Bom2l8mhP*K6-Da|6zkG`RtL8kJ=1AeAL)#R@L$=E`=j8!h~unnt` zUrqa$Y`+AqTg_E}-w1$x0Lf4^exHCh4e3?kJg7jtal6|a zffKUY^SrQLcWIAek8Xu@MRMSrp`5%uZAD15H(O7&66W3XZ@zLPNPt-}Bw z|AC?PiD)3;vvsRn&#tpV=>v^nWm=>%tTc}fm{K98#p=Vv{SV_Xf`pSLPbp!`zGJsQ zGnJ>5KEH051^${T$ibeF*6=i^aVi%SQW|ZtL7QO;}n=05sh3%c$Kow@E4F{tP8Da zSkd`vAVmB3&-#|W_-D&PFP%1RgHfWh%PfR5C)mLz_4JRYs@6Eqem^`n=XVS)KTXH^ z#lTI6<+t~B`Y~ANSvp%%FU5YiyjM}TVh#2E745KcKf@X$I5xT6xjaJF$G84 z^XhixOh-#eBbmTsdx+Y*_GleJIx#NnbF&+9RLC9z$dJctk|1mdg4daGW)NgK9QxLFwAoXJ73BzuH%MAI zbOV+>PYPDJdv;mHSuqz+gi%QNX8|zn!Vmu73Q;=#bqqS&gsN-Tx2%WDqj~FY6g4C@_8CWEYSSHhsAYG&=|U8bqvE*N zx%ToNJQ4$osW{CfacX2xeV&In6e*!4p22Y=b@1!xh#=%8qmUZ0o;{9ooA!ZX-66=n z&~^f}XPfDs&LMLIE^{vbpk+n?T-)r$1|wjZqfJBK|E~Yu3Vxy-Hua&>VX+Hd5s-UH z+Ba#nMIIN1s=5r-D}t+8v==`juHxAKS|Z0r;^0>|1~8TUpZ8Qr+De+P1Ac-aqFjow zhoeD+E$GOhrr?m$sjHuZyDrppCF~0@QXQ}w47Y9=AN?)Uc|Z23ZSW`}aq;9fX@QUg z2{MeOOOYn(jhp7&WXHpdnr&j$AvU>+-~$qH(2xbtA|+#T=Sz|!@Ol&gabWRu0JA_1 z)3aeu5sfRb&Z9GY`HXFFCYFKs^(58?FDsGS-YeC1osFk|_1i?Z2l-l|Tu3%qNlP*5 z%kl>yKoLc_OmqA8*H;YipE;9mAIXs6|Cv(-^|NG1h9)D|Kt#`Ey*BDPC~Alc6eC0! z)zOr_qVe)HS9(4Y@lMlxY6%^ zm^%kKwB6+WxQ9zjf3ZZl_j7wV4!kyC;3~F)N8zidt1dwJR3%;qd|8dn$S}Uqv3qlH zwl29nlmWEASy+gy`zbb|Kg@~|G8%mxaoEl}I`C-Kq(QE(7vh?@*2JVBw?8j7pw$$kPMNI)|KOKGp>% zNnsX*<|;$zDX->vjOv^d59=4+`a26RtuGcQ)OP0i$SO_-)yV1VQ^m7|_cC}V)V9m+ zQ^4zHe(QPX9bn}XJ=CNZ$rV&K)ouY@!|CE{?{3%|5cB_3BHEDG9=jr5PjpPZz!ic4&;mUXy?9quNn__EK1FuU!GVBd$%Ad0b z7JDl#2QzKmsGhl47IHKbJqorYo)}`w!Yi^BsBl8}rz-%&!r0 zx87;|*3sU`kHyeIPB2gj%FW1^s~q)}0fR;j}Xj+=*Jwehub8gn>&k@3tA?$an6uP_`Lq4#~>`FCFaiazqIDlCy5aZQYELgA%uk#8i7zf-ZVl9t8g+Q&xHAwlmFl>6NOK)2*pbxXI70UU@}Gp{Bn| zP%HC9u*$4U7zfqr$I6? zugnE_8L88Ex9|4dzxSeZwqSMeci^wqq^|P^BEQJ_mYptRD3y{Ijj8}}a>3;n%BEea z(Tu(xrD5x@3ml~Z$tB1%#nl`+x5onA)Wj%pew$cE)9CFS4@17AM}HRp{s$yjuiK%) zEk@;U&FtQgpzte3(x~vQJJi!wKa%{m4CClVFC|XxNLsljD+df`(>w*Ty$<7U>bF4U zvT(qHD1BRA4C1`wI?RT(O2**eBdRv7veA+=>TXzVisTJywNs*xtfA`VzwlveZZ?-m z_Mmq2}G>yGl!&==|cim-#A8(T1`0j`m>uUI;K%e4Z&fvy08X14loJ zv>1A!0?FtCy5WpJERAAEK1qYblnKPMz2o4+P&|Li@%|Lbydlsfpv@T|J^HSi8Xht)hWsC_v!n zb~l*P#9b66+=GDh=y1-L?&vg?xK zd>DM5<$k%GKuM0`vft~VK^}A^ahrj`nu^4!)W)hC_xtZB`h~PmNZbJ>9gFOzF}B%Jct5u2&kmNGV}1O8f`{&zNrXJyfCS96Dy)yf3Yk|bPM#lA z0z_IEoiBL)YE0^u_qgnPNx#-E>Om?t<=Pl-Hd~VD!*j>HyhR4|BaMtPx0aOtx-DK$ z2>8pgCN!N?DIED!=T^2;;~^{&io6WrbIP2~yhr0-$pI*kHZGBFt-Rxety>lg5Tu+D zpd>?u97kfNpAzA~v?frO56)COyqjI*CL|qFeFZJ+r@}dLFXqWY|0acML6ec~$U{lh zoq2lTsDrN%z+W#GyD8SRwLKDdQ;R-indxA^u`&8r)j6q!HA$49bG9C2MS}_$n;Bzl z0$CarT)oQt)lMltnjT(YgCdJbu?P3KpIXzRv&bkzoI;l5Z#8VMD;i6qJO_>}Z3v|O z98fG51UVHgs6b7QYOBsU{izSWMer%*)KY%S{V(8}s25Xlhy{m$g<$$)_M5{)WIYama-_30YDnmZ5vbJ7X&Y z13N!Pu8G5tt^QFAv`Va(o-l`!>^S77iDJJ&ItQkx(CU#G+el)b#eTuN-2AgdzP41}MP^!!Dz+&46OZnj&yJf_ z0}6vnnz7%W*!)hRVA!AP)eHotJDXwe6gOd>EU>T5pDzJvejuWh!27F)nsE9JT5H=R z-#dIZj;n8ZeuoU*_Ddn;^<`n21Ds&-YR@&*O_RnBi6tPb2aG=o#?Q6%z2E^cGl=ag zC$7VlormX?)f-Xye-8_M7wYHP#=ZwfrXLPl2;yX>NKurcb0sZs!N0&pSv7yrHFoIg`P_9<;F z>Ea)}PAcGzgYsQ+erDhchq!RqyU$85$Iqv>$E80vZq|Z_3Tn4Qk4P|G{OCSEUYv{p+gyi~j(4W| zdxNkWEtoH7=)9gO+S3~p$X?%7A99bf>)07^rJ4+{Ft7lI??fNo{<3HBwQIv9Tw}jN zo*j}Q0)#c@=f5OjuY|bWjT_W`a*=}>t-WeoY!$|ObQKu(?7<1J>7GFHEed45H=>}a zkF#N}gGQD1QC(dC6#HG7)Q`cv>ke(si#JvIAI<*a@s1Q652!$QB0v?#ApV*`5Rbs~ zjSM@%w*Y$NwC=H+3M$+NCVqZlo{q)DR9U>>LO*xKO^d15=N>5-N!$h= z+q=_HXFL>As29H}yGRfgY4D!m|-1^dHi3L4=b%PhRPOPna z7NR7^K6VsK9{1~i4C}FO#;#3UQ}E7QBPnno(&!lDS!Y)`PDTt6ey}Xj%Njwj)fX4n zj`4x%SA1;7Li+csyFe+1VjlhRdyx_mr0JvRK5f$xU{*Tq!3V$I4H3@=83-?)tH?AT z)-gz3D@a>~z_A}_7p=I}6rMl48+WRT=#d7C!GJz0-9`XkL4}_aKpq|hswK~i*)Z5W zyBB&Rm9r$+{rkuLvWbbl?6l4yyG&*6@D`iDJe!?;T<16e&N-nEY<%2#NjF z;?n{)PCUT=u)yd!HTt&0j9uRkAedID6;&lC+FNBAJulA(q$R*<>43M9Modqiinhk5 zyBB7Dkbu`6)9%0T=V-7e4w?#uPtzr1VwRB&HVfVfi~D+rD<62{3$K=HZUP!y%uoQ_-o|HEAt z`4$YK26}Jl(ZSn9ZS+|R(tFGim?teha)E$Bd+39Vq+N3*lG%mO7Yrcx0=hb>UZKEM z^dMQXEVD%0-kc6bhNV%=5?VL>&5>#z+T9*0e;w>Ig9T@|WUpCbF-<*@4tgXW%`-o? z@!)xJ*9oE&4+IdUu+Sj8*bk)O|Cf3A1tAgZk6 zz{`6S3^LM;43`6PsnOj*7j=k5#CIx+QbWn;6Qn9S?+Qii!0^ZX6-3{YP!*RJi^m-HwMM9C4b#kq#+gW}0%t+}~b)uh)Sl>C~2&SMx zKX^!uWR12QP=sQ`p#NTq?Wm$wCn8KxzD~F=ofr351qqB1uyVuu%QIITzvPmk;=-UK zwstUw=Qr)|(K&UCy)4>9Wq%D#!@mwzH!`_Is41zxj`vccM-5(pOePDPxD`Vk0(E=j zxEw9mc+ft+6_Hi$nUMa`l@3EXWH;g4aZwq=dejG#3@19`^o6e=TXan@6O_IZmr$D^ zDBU&HbTR=hA2)${3dmZeLQfmhA*2Bf)FlB7zeArY+Vj_rh=bv9enC|``25x!Fo&p$ z9e>kdH!ArNGJ9Vk6)$7OQB z2xH{L7TAvSB5>+;I?t<#nsU4VTop#1j)f%wY}e*P$qUEQhhDSJkDQ`fMFkM;XF8}W zQJ71XqxkW4(k1JFT^xm#Q}fTJrIFWTPb z7XAC09b&9y^Bx!QO~_Apsl&`Loy#(G0_qcL* zn?B$JuB)8rVm#op+g8n=WrCvCqeUUY6cHE&R=M;S7;o@4JWOKXDz@4=A((D-{nH6VnYPFd3UX`)WXc z9x(Sx9~x(Wizh`S6Po%=+rywMku21|P;()_1;JirWmoA#umTOivH)E!&!^oEFR7i` zrG>?sh6Ch&QlN<^u-;#|Rn6}dj_?(_74ZI1pp*mu(uMA$N_^&YNO z2PFzzKy*XwdabwEnB7kj5#7Pcd+uklwHo($1kJ&e29k*@V&UX zIL7_RmTx-0KOWh2^XF+aj$!shM`TGrfU}LXl{%Q?_M4vOS2qHg-#;?Sdhx}||e`;Qga_s_5KXue`&rc>?wc`8gq=>!p6_?um zm^(exq{xPGt!)?-`_MQe4wv~yWoKTpBVC>l6iLUsKNmoK8*{Ym>}S$ZZ(FDXzv6y+>uvBqO41;B_kU-OFe=<&mo-`C>eF$0B6 z6*p+*tuD5C_J1I{R}YJ_E6$KpWS*ccz2VU)7^5f%q!oda)0{J}Toh`YTkl|QOc}}n zLvx@5LaT#a4IDY*47ZUVw5X87~mT0k=j+}UIrZ+-Sh77)ya?ISk;w~>yV5ih;G&;(mfW;6^~vSN+uAiED=0@54>(Se{-@F z{^Rfw4vsvX1bYuw6i{zL1|9w}#3jLgVuD(6Noqx*^=@e7jo-cF@?Flo<~-*zHr|#> z-*hNYHEUPw`xgs$b}u>aPrR3T|6M68XrI2gsoM~SR06M=-+_$l#p9Q{LJM9myru8E z@v}NU=8*w#WCw5G3?)RD1jSE_WgX~&*Q-fl9zZwIfCM2wpZNz>X{T(t!7T7Y4EcLj zE&wg&q?3p9b1)VXv^6;hkM5f(RrK| zlX@3Ov0P6(jzrq#l?C}On{M}3UV&t20o`2K9msLAv3i+KQ>t_rJ$)m|ixUWC3m~*I!$Vx4P4CX5 z$G=^BJ$d(MyyA>)-=<3=QgQIAg(*k~)qbY*jWxu>qkw^6o^mGMar+}1WLIFhp_121 zqAI0~-*8Oxfs+iR-+H}u?G80s(Z%b%B0raohxN&6!2%bt&msrGNbl-49SSZYF##b8 zEoz{UQUFRUvRrY3?9Uvqslbp~AV!kM!cr9Lgcs2S}x|Q0h z-0dkt?)^QZqWgjT;I{(dhxxkvio#1SgzKC$8B%}{Jl}q$^Jw@}<$8u+CK2k7IpSJX zE;QY0)h8nAcL91kSo9Vq!I<0|V_pl*auiE^|xcvP zxnb!YnX$v_9BO21JDffuoSZNCBh~jXIH&W|ro{(;OMSmoEc4{8MZFfG9wY-rWRV!z zh<~Wi_H2g`0}z4pGuLeY#H<@xO_$6xkHkg2xF^1S*);zd(MeB=XfZbaI# z;ZBbT%1sxZcDNV;M_pk57U=4w8&eOAT4+CG6d-CxlIYRL-r#RM5G-!sI&FQnvlGV) zQK_6UA(lY@1ZaKoSiXGHoIY`*b;xrIXF3MoC<#?i5_7?a8X^iRH^CTNgdFwk&XXa- zx_c_rt+xHo;}<`AVZ=h`Rz7hk$C4hsbBo8#py|*e zyXpMZUpW8eF9JZC6(stMsBa}hpm{82_Bo88eGP6bGW_GE2+&O-T!+OlYzY+ChBc?J z2UhH&EZAv6P?TZyF1`x_$o_J>;gY_~k9==!)&F`r;|R+vX&xjaygo`gN_5N(<->0$ z9X|YVcw#N8Hu0&fa3bxi;(0)G7*3$L@!NBEx~rR8ki98;LE=#C0tX7dbGCo0;oRu{ zF#msSW7Y@K(uqtl)9t5;u@(9+iPS9sf48X6E${$ZC?bs^$!z=Ng2P;Yez@_FJNH42 z^y-@nT8v}G7A@)S5X9!xB)7G=?_nG-6vGU~#wA~Jsj`lOyvR$=ju22_G!$pLj9i#b zZs>Uh%*lr(Omav(Od#EZx2}yF0!MGq-TjSuxWv)8aD)DP0}=k+hF~N3!B2G}UeIGO zvrCH{|0fk$=R)`YoQ{`CmQy3I@*f*g&2&{(o%tG1j_?Kgthmf2?%hHds?Hw8#VhS|Fb!({6(JtC3qNn!Ly_7L?3pcKCZ1>-Y6MrbT@sE2x{l4GOnCh190Sp>f#ixv~m~$iLS+087Z1%4ETUz`S-zE4J(i1&pXU|%bCSuAZwEXv3n8C z>k0mx1oIPQE#HfKY*m*LMz=BFcD}nS*~vFwB=I_BK+r20!V!~Z?gd`I|V$*IV3vKo+#sDmr}_s;Z>}m=QoQ=hkm>*T5A1ge}Qicb5B92s2)golH8J#pJnyeB75KhO2?aFJj2 zwpn?nm{J_2vfkXms*l*^bCCx{wR0URf93`H=rCtK3CLwf)u~UqQ9`%%P5btjm&M0J z8}y=L$!5P@*vfP>q(n@%zA`hCg7P`p75ABQZ9OZ0Mq%7I=fp~a#gp;T!MhnclAhva zABmChiIMhCba$q&!*7S&LZ^2SO9A3H9`*Z=8^LNO*8SbI0By*_H4*$&?VTdBGzG)_ zV|_d97!gL&p#~QOLZiCMGEvCYoyeONiCmQ@sx4kS1_L5q z6(H?*X{W)RS7W}T6bam~b3e7(1+#6geA8F-z>xPls*?1ppR?x&zc+fT{3m+9RyS(Y zpeI6HVfL@jEcC=doeRE|epqu#7Vd*y2)qQ{NY2KV?Y^WLw zaJNQP)So>RRK8JuP@H~fUIj(b&4_1$1kkyr9Mpso&*|cwbNbISMIj{p{qVWv)8sjw z12(d#b$e!)exHNpip+cCtC&~ib4l_BMX?9L)Lc|=qv&|IA12IZ%GyQU?#XkWnOVA9 zxtieTss55;D>Zjz=rTE<`=ZV}oz?F=cYvtKSN%n)cWnoWc@2j;V&FLtRt37Mtd~NM z{Hn#Y>CL-YY3cvv5jnM=hES|u48~k)|B@0jo_&=ZRjDFAOC<3tk}`3g7_oaNqw7(% zuXgTtb@n@v8LfJ+HaOqbb>{eSYc_s)Pw)F^+%EfA(#xv>wQI>Nc1jq%1dX}yZH7Je z%vQQXnSpmzV0-*v+GeMV82#=@ za$A1<5{640@-kEBqC|eX)z_XvcU^y54`q5Hu)TIZW9$pavHbAM8g;Wm^!Pef5`0Qo4DZSHb}qCj?j-a(DYX^F zyzCK3;ba|ZizLHT32i=aN4Yg-H_u8eIv`F>Dt{cXFr*OfCfa&J@N?evzfBq*b3)MH zO0Qqu+H(u4%lUQ*ci$0x8Bji~ZhHa*F_r3EN}YmOq|f zcjL#;4cSSyV{f$cpu4-vApQm^wLyM0?{3u@dH$pJSeCoz`}7N;NM-Wd+A$k3K-lXm z*B_awCy2X|Pu@nCsFg}M!WG<2OYfk ztnYn}!$fR~k*Od||d;y)W7Xj^u?4M)D> zGP}hU_>sWVeYwvI+#pxo?dyu8Y{hQFxwnY;Oaj798(vZYK?(c%;bd8kbP61+h<;n!6xMiB{ ztqbn)4bQKIaIez78_#~4hzbf0L`?d)NF&BLE^RLeIFcnrlV8hWt zob|MOmvnCxEId3?Z8@CvHzvy7fbPDtK4kl`eU`S-_Uzj6Wf&GlBA!Btw04R11kcln z?0aUnPK37bFDUA}MJ%yV_hBZ&yPkIIj`JZW{;c)u&{3V!R;ds_dt99N<{@zAZSFpi zjq1%Rk9&Ln1|HHd93Htpt8>sJ_13Hq^lOMJra1YO6t*!c2!y4pN95l5i_g~x zFL|GbUDr-~zu9P_D<_q*WGeOiBg;u-=m#>y;82h)<_iaJsA-#=xaTrNEYiDbq7`Q2C98foE{q6^Z$mo^DAEr-87 zq$p)b=i_C$=pVP-1Db!0t*6j330=PJk+mKmo1Jos9mt}bp(Sza@c;C+Iesc-Im#mI zDbadOZM&EGPd4z{kW-Tb9&XrXyO*?-NmPzQj1xwS@_Z1#w1is80!dTBNdKFk&jI=Z zQjLS0j~1~-k-k&)A+}K&F(2MR2#QLlRv`&nCtTy@p)2ABLe5C5mS_r|K8Bb)CCyt;r>_YX(ILEl%3=-O5z_m>;Xr=r$WA}S}aV_ zLro5+-=RQz*S<-5jAc?(GrnO)k|FK-PDgHIM08@khRDvri8=TZ5LT*IM$8dg3n;IW zqDSQ)7+yY8zV)RB0$r^3<0^5cOwaiz^WtH$!Sc<67&aT%sHR&#@i^Zy_H2LE@rNGx zxmD`dJW?pdYmDFxMGTL)QLNVG{Agh!lR5~@VfttS1@9S4Sh@Isc!TD!mSi3%EfRqU zi>;XwB3}3j_gr}D5um*XI+;)eqPCQrs0eN)_8(kC$-;mf;fN{L>%q)p+#6e)lKDES zrdtV^uQRVESI=UuXv<$+DWy|QtoY3*DPO%;ntp<+C7)0u_Qgq+)x!$5EtrE+apE{7 z5~2$gbo*qZwIG&~McZf`f4oA>3ye-y1sYbWX5Oh+2Jjp<%G~l1VnhrA#XjZ%dkyxD zg{o>qR+I#h*409c$`(1o*%ZxH3jWgPXL+e@IiC*S)S0xu-&INb&T*fPFU5wpsyA?< z^Dkg6W15YYh&*NEot;OGIkwW!WA1SQ)2NFPNf7YC)GGcqjE|`8G%eQQ{{$3IY zJN!6$?Xa?rK6eX0_T#!p#Xp#Vwf^#XQd91R^4orjHmm7D%H%xdyvG`QXLtyPl2>!H zCK{}~Dk-m*0$6tvJ_Ax?vsREn9K^Lg^P$oTCgz4Y#jHh_w$YN;Fs$`*cH#94;jTwom#b6|*{u zUnw7dHe*L$5CHY*K(I+C;3F4;DGF_53nvPxFeG#AV0Gm?zRH|{8ho&Njb%tVJ?VpR zX{OK#=joi3#VB#XBI!>!HIpuar>@5Fw|OCzL^IXfa2-}Z@yuXI>HBq#ej!f36L`6S zSn9;Xs(uJ@^wg5Sv%_;l!GLn?GoOSd3a0`06q~GD&9_Z-&?|umy!vt>L ziHdZTB_2CPW-ZVy04PJ4JT-v177g{U2R=V2k*}0P7DzaF?puYpP2OC)>z5HbQLxlh zbX7otlkXOht7+-lCh`r%Cvli+E4Tyx6meO`@`&Zm-pHZXEnN2#(%9f%orS|+iC4eS z(C98K@m^387;Yzy-rh2~JH91GJSkB`oSKfXjFu~O(oyPM09oZ4!M8QXY%Sa@;|f)` z;(N|XztG<8_Tk#95(Nuza@0=L`vXc+6c-$k_M7OuW4!!N)^B_f?}jfmCG?Hp+1p<5 zoMb8b`>^TJofBtjHOQ6Y3nbWEiX$c!YPXfNh*h@ZsmCbxr{Ty)W$qia$UHyczAs^V zp_YrrKHy<)g1>zBTxBxt-nP7#2S#h~&ga8tVz&&#Z&`ZcMgHryYlfBp@%Cl-1Cfcw z)rq(AI?4qG+f}2K^^DbyQWtL~^C~)=iq8`K#A}2(g1bcaQ(-$tf&0Se>=yVYc)r-r(B>{k~$yD&I#q zJx zja>D#Ev7;Qr|hG``Y;~%CLa-Roc`+Sg`={eHx6XrYf0nq0-k~l^#C8qTbN64~#4K zPF4Dd=bhQ{oR=S(jK-nmPMdRA{0}pih4=_T5c+st&f|kO)SF^HYTv*4-l01+3Slr> z&>iXH$>n+y(Mn!D3?=Q!AmRed`(zT}WJ!(YQvCJQfCqADBKMV4MC7ZXA%7Tb{LwCP zu(rxz8DY({N+~6ok&rn4-kUv%c-0`}Mrb*$pAjRj6(Mge*^Xe`^Cf)u8P)mhej9>( zxVc)cYY}pTreV0A^52A0V?{47y7YP`xmqoDh;p=xz|E?CBTF^VAGnZ{hF?u3|6D&o+B()?2`v2pUTr>-HmzH(0waa&miw9 z$#rZb%{d(w?#jA!htRg`Dz`l$geDvL3&A4S<_@C_ejDd z(BXY(;~cMRR*N)QrAOron(9}NS0qTp;UoR*x*^iv&$EO{{E@*L`%*olAzxuuBDc73 z@mB__q?*`3eLA@{O$kkn8=f~SAEE;22R(B`r+Wj^k<6g zhc`^h%cB>{JW+kp&GouGgOnq=mg}GRum-g@>I}lL@Ot&kRAXq+m!jarkmJ}uR(!a$ z1)7SEZTfQm<#JlHcjPj?p+qg8_rcbgfW^T)`jz=!7 z31mS=ty6x`dbqJ&9q036^lo3(MVOHo0cDeGbpFYjF7RsNfmmbH2(9A)X+>FMo^Yjp zB%F#ud!ZZVYmNn9SPA11TOraq4{>&qbATBL#t`T*EKsMsn>-9Pgd1qK6FePC=>>#| z`o*CiNK0cyOyZ2rUCC(s@MBH4)pdZH-gz@ZYBCp&CAPomLVEfJR^1h4xLE^7I&Ix$#@7QUzH9$uni#L7yzQLeMJwPuB}F(^g8&zL{^m&q($&x zN=861A`%+kb7U2#CI8Yn&|&tEnb+2as61L zY^EDKB|ywXa=IGP?( zc<^A@tTDk;2`>jQGEm+yzZS=o*zi-J15^=@RxOqOIVYR?zB zSG8J>;C>BOxk0wm^&AIx%JpX-RH%S&*J#df>Vpsp{h7#d*FrbPJJW9x=H`{6dNCR62x?|Gq1froD{JGdr^A{Q9s|UMpi$kUeR)s_t8R=Wn3%uJ>S}W`9pmr%>J<0DMgv$ON;QZp@|^bBCPk@q=hK!Vf1(uq8(pnx41FA(+=UtX}R|i zH5xBBJcH8X;MUj)()jhu6nTdsn=PFa$VXDh>bscq!S%jKHoqDleWn*-Sd^KOA%a@- z5%4%8C)HM3S>Wr{y7uC$cE{3~Q(4l@=}KiKhwRpZomQq`?jjobk(M6NVkfD+ac$}b zs%`E2o2%lj&Af;RTw>t4H88FD6>g}=IWILBegYgiX7}om&wPX+pSrUdS}dWryto<4 zs1jo`FQ~Z$3OK4p3I^rTRCOg-LIbm%J0IYf5rw^C2ODxt+Jy0RsaNVy&3^OPm0X_> z(O&a>y6L8T^Ci0f=&0r7DF@wT?~W$ufT@G$q3J%=7L>;Pp}tj z?@&i6c=QOS#04q(79@#@Cg7zK++vR|RBc*aG5T-4BrF?IY|ph1x+&)~a*u>*S%E{3 zd7~OKu`MY%iF@KvNH!n{!(Z)d-T&jy>$Kkj;oRHcSg7$P5zZg}!)jZW%~mS>6OeLL zf8tdDNlNxC39|JfnQj-D#O6ks3dK@uXm8(W?>!*OK53|HQ2|QzqurBSr2o&?k@gq( zd7n2x95NOK|ER_By?>%~V4uoEn&Gv|7ZILOL-t!0Zpq<#$1h-~vp=#CM953pVyz`@ zVVQ&WJT96H6!2Av7F0@LPZNZur)QX=opnEw-+C>L9n@dW=2U~-Jb23f0u$07%bu@3 zkwEF8k~Z3)Q767xdI(TTC`wyDifCn}Yk$upl;Y#t<}=Grq(gu9H{{JZLh}@r>X&(I zCDD*Ecnl*vu!w!S^Z%I8nuVyn6L$~^<97|kKNO%phtMtpXOuT5rGCAzVS|F4JPHeE zQd@7|o}o7J@5pS6;$hpog|XL;+|B8up=mcaZFz~3x9ne~?Bjn5aWNKteqO=mcM1c! z57sbPFpwkpAF3&ft8<)8oA%WRko#q_&QcocM9H8zd--xB`FrAJTwKWORU)EYtQs{} zO_V8NN;dW{$i+@L&F*>$-ZkAH3GY1a!1Ys+`5X9JwyB4h_Yw*x0dF?TtW=O6f!%qS zf4Nni0M$eHe#w{Ql>gA}o_`AAEtF_r!#2>v{!`{>&(`3$tigAY>-tQ0$_<%>bjC7;hdN9CD62S0ZQg&N*l8W#Dmr$0L< z&HlhXvfSH^mHLf%fqF#rZ=fE%4Pizga{`KSS86#M#TpTfu2_4O@IqqFVLTWg#Eb%F zwHRn}3waB^w*czCvN%e>YwbIj39=1L%t&{LXrt$0&BXD2)SIQLok_(hkJ$eK1ZSI3 diff --git a/patches/src/main/resources/music/branding/afn_blue/header/drawable-xxxhdpi/ytm_logo.png b/patches/src/main/resources/music/branding/afn_blue/header/drawable-xxxhdpi/ytm_logo.png index 73d72b9d8ffe554f01672ffcabc030e90c41273c..0f86b5b571b889a3c5cc0046d6f9cbdaeebdb5f1 100644 GIT binary patch literal 16345 zcmb8WWmKD8&^8(pf|dd$xI=L-MT!K6;_hyR;-pq!ALq|miaZteIqy7y?qzxt-c}Q_D#%4SWU#;;_d(knMz38=d zXyHSObN8wOG=5MAS(ovJaXBll5=4z95gU_RpJnKE zo(V^SAHv<>XePEMj1PYK%zONTYa7xg!pB?{1Rj(gAP-y*5^IoA)CT^4KPAq1jpw3U z#pc9(?77TovNiNhvmnm$tu#^VH(aSwIHffDEQ<~mC^eo^ zS0H-;uCXc>N(GOh3702&7FGC6jrM`HWS`2R!lgDaFj&s$uV7Fgi&0yvDy zj{Fjc((KAW;N`ysvxON`o4rS@k5OF`&@&AlgPxJu? z34$#MIP)(D(vsh)z4U&ufZ~nm(O1dwESn1W`^^Ph6OJ42)}y613O9$-!D$@~ai29w zEE{MY@)6D=it6;5#`iRn^GKPr0?5Dk->k)JX=p{q`0*QF&5qU5qHmHfC&Q!4$p8Bx zDz4}XKax&h|3BKNqNjL^u~>vA`SG2ud_La`)rU;--)RF zCIR(84ysiKhnJl#BkpE4DgRl`RT6-|Wnh9uza$foEdRB0UD=D!+GRiD*`WTvAv(Uj zK))^xBf^DKGAFX*JX;yW)B^`ZrC}|N5WIMn)qEj-v}!xwZ~xB+x7BRN?h0ijnL?hg zu7ySqX0Z`dpzipMHcFrb(4tw*UwHSzgOvYoCFQgB18|Wn8ZfRgITvba12}9rYkSI^ z4?+>rV-$*fFzjpYbnk#VBy?ESYK>USDvXruhgY?Ak{Q@?Vy_emHCKHK7T zhz-7IA4nNA-{>Y;(fNMad0GB{R2D17gOL%zbpn0SomioaDfXw$@) zVum?Loc3zax`P;++&cM6OU*x8U%%jNSid^l@l?m6e01tR(nl`6Sb;;oIXtoNoPRB9 z^vuq_!_*9z_Tr5}2@ZZ+iQbUl;?;EDx|vS`9&Lpa8VFMJXM^M337{*09N>y$i`XCS z7nK!LZ@+#0vL$8v!06PFJ?~!aane!LW@IypUYS|j2G9vieY(?6P&2MI$*1X`5=@{# zez20f*AP_qZ#EFbg^49$cd9wk5{vlSF&SkTyQr&URZu!CVS^_t{`pqvh=*bcf4M}0 zc{hh298Hp>A~4?XU0w=K=ExSa z&6U0v$IQ6>_!e-+^?lc9KlU#aE9K|At5;6K$L&e$u9c&n+}cRS(SvO<@7qvHkVp&# z)q3wS>Cvi%lK7p0?5ml`naJChmt$}%GtO3)!bwSm>kt(fT;1eig2+fD%GlJ5p8=H+vu zeJwJ7WR-`vb)d(WDTF6&68_aNIylfIB=i!n-SRWrf6#vR74wfle|5wdc{(>DHSfv( zeFJA2yvO|)5Tc>r#)9z=Sl~+{!6nuc$F}6h_(5)!Ziw%!LLRWw@)HDWU;O}%iXnqI zVX6rZMNt3D82V(&F!K^kJTfwR?2?^pu8b%k67YwiZKJz3Y4$5!AezBp%TJOF^4Wnh zees|-L>_2FD|6qg%nuj14Vq(u?tKI0Hr2W2C@8WI!aEWHMd`hg%dsAYND2z0>Hc@< z1kt0xxT*omiS}H6eByrJ+ztS+>01knx7r0NF6t9FW(3zwxw$3ddhxWrGB97ck0O!Z zIy7uKNGK;gxkdU)-r@yjkO2+W=EB~XJI=hcxX!XgMHrQYL>lLcQSs--1+z>z2Evp% zobP<){@{dnqq;5)oy32zkSj14meC@$CsP&E_@6xDY(ijU?7X zt>wBl%H90RI$sjw?h<7E%^{Y|S41xswh;O=saXpQ#UoqN$C2wPBC@~gwr)0Kq=#K{ zgb_aKf(-UuGkr;vroHtKel?*w`iM z^F|3r&-f%S<;PS}rSkRmLu2zl#BEd*}4Q`!Wr~-|9ok4h^GeEGdRi`1YWKLQ$`=rR;YEJwbk)Rs_5k@Q0$e+_f zxYrc)Pk$zom?UuDKkVE!7izgp9UQQ0!Q_CFnasbD#s5)!-Px$AbL%##Uqwu5Ah%)L z(Z8?Ltt`E_>bBgOlYY&yo;)#S6tg9g3HJ>XPXu+6ro4>lsulqd8*~KOZhz50dQDAl zWCP^Hh{N0}hLgj;RJI1JXTU@n-8!k~tFM;W&723ESAwXzC2Va;JZ7?b6yeGi;3SdY z1~)h=B_L6%Dn?gD|B2@iAnm%;?L8E#)`-?3Zf(Nk#8$z{6LA6aRCFW6DDNw&*c&Ws z<=*rW!7r%x%3tSvdHqTnqD3lEP%Ieg0phv)PVD@t71lu@*zTbcK-2N%=ZvzZ$ zC@Qekals`O^44vJ3~uFTUh=Oe#V#ET3-+n_hG~PTwI+{OuqP(C6Rc^)Nd0Tnc58+v ze=UFgL?~*@31lSl3{<`xxyY}sdpxg-#NI`Dq@DWBTPV%0@W<=|&=J=hoi4*g+)&@w zjb+dJH+8WZlk-n4-Z%b+9CvQ{Bhl9>GcSocSk)!91fNz ztHSYWf1Gc1!Wc`>+WRghQlh^ZpbT9s3TWdXUpJm%ry$>x%ywKo?2m)IIi`Lq^QQMR zcvM}IYsdFCl1T&F`;alTC3=_KIsG@Bxv?7hvs#U^eEM~Z<4Haa{xq{LEk|y{9UBrb zX#l%NmL490rV3P9SpVW78*l&kQTg`met>RG6mSp`T|jB|_ThX`zn@ zhqplnI%juEDF0y;y}W>%K{K;Evdj)~O`SP2TyBncU@Aj7L{d`Z`B3G4ivxYQ%(Y^p z&+rD)vs_UO3o&7t`%iFY8_Q-A#@YBaqwz{VOSIXY^cK6QtNiYL!Zy?;j`K=>)9;Xc z*?Fc-dPk@KVN*5@ z(BjBFjZ=C=MB>zFgo25R5?v<*_s4^6xOcXq(zeKA$5M?L8Lsdtu>N)E*-6W$403A! z+%30x6!tjWwNTnkj%S=$?m9jMu)CHIFVk>is}uH*w`BmDtzD_cMvfwa8{{$RVmK>V z4CG}1)peEuc+|0<5cf#t8iFTyZJnL*$ogX{y{98dhfu$fWEy0w#PjI~hjZMXz9$A1 zXIJeVsQuHy`$&VGIe*x!PA7CMAZj&df>$f0HA*%a5sa$De}ag%!beb2uvokq$IC>G zbBBKX>M$%Mo;0mu@O!mAb#BE|p-b5Hf|6?h3{fYuE)V!nD43ig;zq~>W zYuJ3lc!fmix?3EIw#&eL8rhvQoXg-!VGO$LoE$stnt(4A>Xy{fdk;8buqL8%($eo4 z2%7ywIP~S@vN9|<3vTI)thXCXmtnJhc*n6=h$y+><$xlf6|{gq$f)eUhSZrqTBDwh zBan_?h?yjMf^cM$tn@kTX4#r6>W@G)g%<;laG5gl%HPv)?dR|-F@le2AdzkMcSM@- z9UzO)$Vf(}PsHw;7ERn$#mEx|X{QtXkU5K{Qt2i&$5Or*H0)_0Z}{6#)Uat6v9Fs{U~x}FY9koyH6=kQY*=kVgj;XN+9OM~ z;^<4+<7YJs>|Eprb$X*I2Y-K`S5rS@LivDiEU!Fr*K#^AU!r%B78{UBC&8gx#kbab z;4jOiF8^qeTMWDMPso|zDB9dCP`?H?kq0!x#nc$2Bo>A8brWU;3VfD*N*uoXKLy01q^z3%@GDRrWD~$v-o`?Cc6eHZ_&P zl(Jfn(nsf-n!}l>vvOaIUNPmiWz@D2@b?AiQ~k^sBtTrFs*{r`0J3m&nSvgRf`1sa zd8k~+A2Ye0s!6#bbfKNEhrKDRX;U917O)p=MEQ84s8S#KGLVR(nMzuD^nLk)+S>Mp z>X6O^^`d0A#^h}G%Cmh@Hg?JDfdx%C_*Tfh746x1buk8}Ooca~QH;OR6`5?XhF!b5_0jWX}S^rmA8M@6-k`8m1ZE1S9 z1%7m=ckbl=CtOjzy+MD~ANRA7YP$;+KDE>N=2o?a?0n3*6rmjsA~n-}rqX}0fzoDt zf!RlycO*{5YP-z@_FL_R)A_(YUEVwF+)1n-_5_k$R5eh%IEcIB5TWG!8HCi|59p^M z_h3Z?+EB&l+Ot<(h`nl3Tv>A!{BZ5%8Hq zVI%GbpJGPTej9n zfy9;(v_JEES-mP8XBAQnFjD-9SHduZJgtvV4f1Lqd7VV$6MZG3DBFd4?}h=7Jym~B zL}igC}o`T*)dgNR6;0K+F#3cMdqQTPc@8Sb_$oRJc~bKO!6IO2*yv&xV` zca-D7YtjGGth3btq)8&}UBQClo*Bu%Y-*+>i1-dYhZ3Xsd!h*?V1A|x4O_L-_0O3C zU7O$E>{@8@+?*9xHq<#H-C*d*YPEYqZ;yrBI0vZSgnhh#>h_eLnB~D0JKO*6lFmB| zGi~3V1ETGf@(-&Ai;+U?I|iFK#?4P5sQl??WGs3wC+EV3u7D^I>nzdl?l8Pi3c|}Y z8;2$94${mQqk5Dw0uKVx*LEATsim;;7`fIA?NVkbfzT=$#9kfM69L?Fd|)1@>w-DP zD2d=p=k#*GFfh~G(w}}^>1D17(OAQdPj>O7j@K`df>!lREYkKYx<_ak%e2GEB`_&D zjAQ!*;e3XIrvBB2g3A%p)5&Z)#O58rgbex>Cq-b=0Q0vm2D+6NL6eP_3?Tx$yJ@3( z#>;cKiQAgRFR4>~iSY(hl$0|bWOKE)UH86Wj59%z)|Ic%Pi9(XFvz!31`|6PGeXg6 zJy0C1vXgeZzNv+C!z>xuLBZOE0H6+l)%8G9Qcj(Lg=T>DD(Y9vr}y;6(e`#0u(p2z zSRK?qsph~*JMo_$EJ$ClmT2MTSdBnoO--mw|2~P*78Eve{C=P6gS38O!p<5vo#o*H zuQlrv3&IAMZBYI_p%u4L9pac~@9TR!5sTr276gECk{q98l@_Yl^5ncLBJv;B z>+gd~-`Q9VZ@*yrqOp(N(htRJH*%xt#OQw4;(2!BL#cOY^oyeJxKj|K@0CLS;)@z} zGHBnwXqgUQ#rxOEFsRfqj&HQp8Je{^PX=*?1}Ps-i$ED8Df>6+_Pg^N)`ezXUgt~% zL_Hx~%!fDr5vpJH`FdOAWI}%qg{P?--r>SJ;A~!hek~$WRE+1FmV|`jb#To~u1Zkh zOYdi1_uo10t>Q6RkAIN2h{ubA^H91}e+Q zkHexY2UHV_uNYFH-?#mG772uK$-e(AOHw|C{*hMGzuT)Qj(#O2(Iu3XJLc4}qPHg> z!4pmo>%^eEC9n5P8=2s{1Z;Wxv|c?)DUm4$CKzJ$>@fa7O3d``MWsu}reZJ;ni*|2#`^bxYnR;cbNI7t~Ux}I}T#=nNj2pEp3oBqsLo(qC3h_^spZTknowLE@M7CTpe$myK#&Dk5|KVws)z#dCsIGC64=|LHV! zL#?knEFa$nXFteO*yRC(`e?0B^?V(l;u->lG!W$4uN-tn>YPwqggN-hd*eKup=xFT z^st1s=fcoZR_FZ93S{H7%*U}M-+&Y0Aw9UnQLfWPIhJ;IX3XHY0ac0DODQ2Fn0i5njcSN6U$$5QGh1jF zG!QgRjud@pLx|?ovh{Iki|7HXP&-Tb+dh6v9}=c)a*@ik{lS-OtwMiR{p34#ua>lN z$`O++Qt-(GqO&m<7DKi>hmRFXiTTjEl7jp6AGm~W$%WC=JPE@u1|JXFgZxrzUMS87IzCXwn4Flt)S2(ty;bx3 z3Zouth*CrMz8?{z{_Uv+wQcWsMs8ESov*Z+5+i7N7qIQu&LNK;xt^K)D;V%Z5_f|I z|Fm45q=xl`evd-?ID<3t)lIOpHp-*!)9R~L&$bdUyM`Q=x}1G^JV|yuN&jk3Gti!E z0ed;en=mU1uz@FNbbyk!*Moe!8GY7&h^JEGQTM0*YK&vBy@RohOxHzf-c3E6G=4R+ z|E%(albO(WdCotkp)6!A`sR!hl!XzTIXU(By27!-WQ`h=H&E?!Kb;_`E+WDKSeD=X z#W;5oDp$Ccpti-F>zft-D>L3kMJ@`(SN8nL-vHv2WtlwuyX0Jm24!N=#Z^&N&M@wa z*wjpWVY~oFgK+SjLo$b;OARhnxoyz5yLA0b$lkzPxaZllatd)X6GTw5j(oh2tdbwx zvliz!gw62eZk8DP;fyz?n+XdX@1yp1YGL7PROBcwD3hBOaHo5`#`Qc!b$!90ZLm}I zU$m6`_}eBD9vi95V7bBwE_IqZ?NqJdPuIc0A7_;nM={?PbD5_x%@);Oh@0eYe8J8t zJ3Lz=3}2!1z7I_W(lDOk82|8Lj~8W}{FisU(@t)C;S06LKel2FA5^JPYFp?mBDs2f zq5oikxV_e$F?nBpn{3WB{h~npo$>sQ)wie&hs^U7yT41y@oMcS^EynfAg6ju%9jNh zIicKU6*tT~=e0c~g@x+>kjA+do<18fbVUJzgoe?beCaBZPA2G~D--oR-K)wJq)4w= z@>GPNH~C?nI9qGRqz==L>ZfRtHvFgywCA zJ`=tWp|b7XOeHDy+koKU1J=3EvSjI&GsT;mwQYKN6EnE29-rCM)V(^SVO7!npW7Oa zcjmR?zb>OQz75Xef1_pmrd)GH|JuUQmGP1H#%jrik9tA+4Q39#xvZnPc{7-0p4(O{ zzKSS4^NB&0$S7*o*hwZ;O25=p0I{xS|9rMvE`Hj5yr}1hd|%nmKCAY^rag*V{el;o zUq!r;&;v!p0e?py_v11lz2R@)@+^(1U=A8(^lk_FEYfBi5d2rvrDk8$_zGI`E4;@QkgSns@^bea57YfRy^D z;83v$;8)PQ2y5s`j9FY@t2^m1a3{YpkgCdg9h`%!r$s9ZGq8O5?-zg0e#`4+eiN#cmu;+S0skpo_=%- z@W>i0k-2KBGgab>a4&atWB+UtQl*3q(q0lWgL-~{&&*Hb?x^Dpa-qrVI2#`|5fq8b ztUM`<5w_n7B&AZJRrJS4b7H@Yc?@l1J{F_c_r2mpNF#WMl(ltk(ssqRy!YpfB9ES< zLLFWe*n)6EIFjYjn#`L+o>AD#AID6;IvS5_qa`9OuK)d}eM>VZ$t4he9LE1Z(EG3LKqIzi z@Yyb(kVh-~%DSbcx1HC%p^vf1?W<5$0a^dfMjrgu-RH2>c zhYxXuoa1{gj;f1gfa-T2gY5-4?;bG933>L8!W7*-+EmQ``n0dN?YLIpgH23sUHsttf)`nqbRiC;N*ZX+Ij5mCZXz|CL8hYnndM9s z0W8fe!yBYgv*RDs*KuF+(X!G$%rT0=s-Lb5D@nx{UMrUT#lbDa@yS97FWV@oHlrjV zG^5)+x8iIn+0LUl~`&`Lun~IjcJ%4LK(RaPS6Ib-!dKZEQWo$es(Eu6z%XRB*<<9KSI^WPs7=w%qNh_qS|H0JgH<}m56w| zgWF-jDvW}q_I0(F%zO4Dy}Ei37FJ@&zO8;F-K)hVD9IfiCzW0r-TaBJ<9Zre9R_PS zY}?UMC!>uwFqoWroe3t?qjPwd=;%0a%yCx{yPg@&$HekVvt0p^L#1qc@}hi~BZp)> zbVxq6Lh&oxm(z~_Cbz1>b@lc*BZQkOuiBFrc53YF$)zfjmdEj$`PnFtQ(LbD5*>{j z6cwrT5n-)6<*1gb>Z;Fy#J|Vcg%JDdp1%C|1hQ-^-{1bgvtKe+Rj=kat{Aygl{YyD z%G1o@EPN()inUCZfbCs0xw1?hulPPubSOmFnaMwrrq&(_8io91o)0ZlFW`D-1MNRQ zU>W+NZ+&D~J!2#Y)Ngd7{eTkbafc`Rw@+1a?8ie4)d2`S$^$(53;r1RH^e^9wd6Lv zIm80D@6%9&>?E2>@D>{3@034~Wj^S#Xmk?i%sS} z5gFgU`NhbQ%P2>q5BY8+)c^gMAJuZ)8KRkB-;(zMbyaqQi|VkKSXh`tb;6H2>4_*q zT%EO}-u}J@6MqZuPkBJODw9?>$+E%kD{=d(VNc|;_9(dpzBoj|5GUaDM&?Qxb1W#i zT$OxrQbXeWdn->-8}u@PT6`#H0)f7VeWvUxENnC$N!ek!DgO2LW3AdQ5|8(Fm(BHY z$kg@8;4?5;BzI2~JoZ#v!#3S(!cE4*1InAcp8{5Mu+~X&{VqBVlR&flI}jSaWlks{ zW+XGsGlKtR^Ln7}Gc9WKk6#6i!Ui!lS408=hjdL&XNg!|(LR5PjYWhu4K)SHI{HF!AUIM<*ULEnJDr4X;qg_P=~q$>ev4w#zH~0cRXn z*JiaA(H(!>L!^qZ>FMcE-oQ6v2rEqPoa4h68XUpO0@?nfdUz8&m&NWnt}l3`A^U=n0?V~syp7N%&h?M`2Zx511G2K$Kgnco zHnNYqV6XMjSCk3tu9@C9YIlEW$Y2u)`qVDJ?*@5@u;BFw z;^l>0;g_(qvbJTp3I!^gNtyx{noGig$RQW0rtW&-Fqd1+(u*xQ?|+{dzOjy4Dj#c_ z;9kBHH=ik3?FlBrJh?r@W_7^``#}?sCkp%QkRGj?GRFIrKK9QELV5iYW#plvla4Dv zGVTI`?#MQ@OKV}F4?&+^r#{liobhbxX0&qNj+qLft{5d5qc9)Z2;xtdCm88%_ITm*G?*0Syqr!= zn9*(e-)1tCKx9k2U$@>v31fy@$bVUE6@>jV^xO;3-rK!2A2hZn@&f(f!+8~mIOod( z3l{1k2;Jzmhv5Yc&=4T4t6T4X9as=)Vq{_zVnyivAP){4Dpu5b0w4|h^wlGw*8edv znvab2`w||J^HR1iVX96;@(%?1-rbD=BP#`G%(oC|3D(Y;_=jv|yn1P}(urC#Z6(;$ zzKm83WXu?yCFwcr>6V93TNqwfc>W7m#ZR}##P|h68qV-|l@z`TfeaRs+4xf>^bCd} zq1V0Y8PDaw;lc4*?Ka0Wi260dRLHWAoL+#4n_XPqntW<&Fd<#mE4`r6rPC6=)<;Qq zq*Ovg$ssy;3>0QV&kQo#LA>A1a49X*@BWMdClVP2EdQGiwy zu<^q^6gu!G7hWq&JLmh_%#RxBIi=>d8n#%l)TBf!^f&oG1L%fu`(TEUg+cWL+{M%Y8Bml7wo8k@;pZpj173J4P~A0c*7fQ^F@ zW()q<&^2%-YZK5Uh>$~F;CW^QfPS6-xbamsH*IQfntWpvH4{0IKvW8t@(>={Wgiwt zwCas<2QKCg=-$&aTER21BuwH@KVkfUjiaB?Lnj)mZFc{+7DNy#FrcQrtQRjJk*w2n z{uk{bC@?eLD$Qu|RX1t2s5Hm8d1%JtVFKYBjSwhz0w;gKVl=n9i#Yyw-3xb! z186w}ag!+HBF4s9D)ML|6KWsk3Ew?-t=u-IH%&}!n%{R`Y>yH#%utrTTTOiIpd z5!p0Hzp+}7RucCXdKOsRu@nKzpr$D1-cOzOj|>b!QdKM&b1CwRZQtaf<*@_#Z-|jq^wnrZ{suSPT2{uX`DV?t@Ml;Kn(xRgro3d3)NF3MGSP`#Ncmz4IwX2 zkCVkZA(V(rZf|shV;~A>FT7uMbegC!m1}y3NLHZtD{(SON=6Z%y)ZO11{f%PWnTWG zx95b<7gUv-0l=Vp8-Pju5BOU>a^EWev#sFg$DO)&TtJ4|U6R3O|G`a#$MATHiM`vVx;u0p# zEbsh6rvpLC+1U;Mm8(|(iN7T|HaE#;!G<~ZyXb7-c;oA|ovqX_sziRK@&5hy4iT5I zuVteQciHAn!_EDip&sW~O=$)W3^(OD;}|YbNad3Q#TFF5W66tvRfiz6T}6y>TT|{& zZ_bcYt%8whUYC-)i(d!L${7H^nL+_}FJJP!TQag3_flk1Mg|$#*{QstNWPM8DF~O- z&k)#B#*kRdh5s{d*wIkXBw>2`3yt3PmEe@3A`iR{cfU1_=?4>9vZ~x7d^|S(`nm`l!`EKdemV{>S&H9@k14*~Q zYUUnIR`HaQ&{6jshmXX`7iVdbc%rWWZ0k}#nJRz66&B)0X4746-=JRMvzjUc!1n+A zBrS=;A^HWIEQORlS{K%usGty^EBu0WZL5z~Fb6T?B|aq^N=rMdlGF z2}xCc$7R%d|9EZ~JC~Z$wzYUo2?D3-N_m$~@AWQ`(|d;dN%ORzo8z-or3i4nIvt^W z?Ns#tz4$5m?717ZGpie$4(!?vm>fR+Gd?vaXHBEh6SaF+88(0~stRmI1>IRZcvsXs$B<8Jd;(1Gm<^)CQxnu_` z8?D40xo(iv|5>i7BQ8N|iy}Trns+1kM>HCeVqU(N(9;EB|MBx}T8>&f7Y}b8-Xl^L zY#%<#D3;|Yz0IOQUDVhp!*l^&PK>{NIy-xXld7;9jWjT;x{eR^nb%@e!eVu~zt$~K zoUX;mWdT?xcLdfEx1cQmCO2Cmv};m(_)uH&Z+y#GQB1?_ln^{SOW*Z5|5^UM62Ec6 z0?Kc#rf2bk-*ETeBWX~R$r%Duq<3u2u@JcVQR23dX3+F4u=Jub_&;zu_)nWm39Tsg=?$5`nfR<~UI6rqVON(-IGGhfTizx- zPHImqo;Ot^StDrA@sZVKO0w5f zY}N!1ER5|^RQC%lIPk;s`x=mLz@SiLXS?ZA-$X*1|ow@%hhB2+RY@0a{^Gf5&y z$UR``w<~e2saBfD9<~0ANW*`fq5AmVPbhCn?FE!;6!Ym#+Fv`rmcG}JgMa2FNjjJd zdxc|pZYhY!9Df-8y5&I5HpR2R@gHrdSon}#u+Nc|3c?4Z|W@???A%eBu9PA2N_ELKA0wg zwuGeo>d~~49F>eSHV8A@oAeL?b+w{BfK9m(I}kPZ5laW>tdzdnP6X=Zwe*_8pXgFv zMK+Wd{Ntl}ql*-qlbcD$+7$1eK_Fmj3~{C?tA%E#cuzs$S%I`pU6N}Hed4dn)$ zMF9w#-7;RgxUkZDOK+Rn%~p_eas{9czM0wqcVG;>R%{_^VD6odl(YM={p*+OYjcbt z<{&@an?UjDC2iQ}f6kR|`j`JCE74~8m%TFEg6;=r*we`~>`_EOZT{&dC(De>v2{BN zAf;cQd~%Ro*c*|r9Rrk6>7!-}V#i-R>r8J?GwJ3$<3(0k*-L)T0L%m}3$5Scwm$qS zG7dZOY?1w+eOVtsd&a7A4>Y5H5}J@pk=V`P489hSopZ>qWXc*lKHsM1f4OyTpv!bu z)qiU`T~Y|5B7mj2bN{M4KDvRf9j!>h12H-I#qHJHv)SyiA%LRQDr!1!ty&rlZUT7H{VKtUO7^6mvx?n?x@d%+uOR^xzAp) z#=xx6Wh;%58CHTxNyI3ATL0iXrkY_#dD3v`>JV{EJjwgDnDgIpbid8UFR`S|$(gyl zGqrgac86pNc``MwUb8&l48V{2KK^~ICtg9Io=8WM$P?GT2-$r_XNPdmxO0UqDlfP9 zH7)EQpm|=ePFt=Cv1nga1?3T~+0!umV4y zET>9{p`3{ZuOQ-7V1rxV^75{I$f+jtq(wa6 zjq$Z-r17ru8F=ULeBW2=qTFNm4`_1}ogFY?xzs9deXZLO3fG?q$qM9zCe^1H5Bf`znh4gO6;hF(np-gQ3Mm>I#q zBEm9cbUR$I5B;GCP2_202rmalm{XSg;fD~$$eQ7sTFzJxY4nc0D~%m^uMmDj%bBeM zNapmnqcpeCDjnIW#`^Hy8JS+7{nb)P!zjERL4W4*>q35;7_R8zqEWrfs-zr!peZ2x zAu0D(UmmU9rZU!p;H=T=s*%(E@bz;kKyt)~_3qT+FzmXx|P_N29)$^JMaowRfbs?Aot){v>DJ^;&rA3tj;s9`;9Yn9;67)9~SzC z2ic;HCrk(ABPfGBHj@ST9<1b1xSlxp`Eyz(1ZFs&w2`AFe&)G{ib1rIh`g`7%hcOdIovT7=0Y;?Wnx=42neR2 z1h@i}vlziF@qZ=Ionl!a8^`!Zr-*MXFaXQ>j$f+ z@Rda+Zbp46Mw)oG=rY6CGh9aYe&KYyt+T%Y<+3=Z)#&`w2r1I?{fF^NPq`LX;pq+1 zz~0@wJkjjArozJDAWX+BAq@O^Bi)9m>D%#&)Qcj`5EDMYt!hM_90H~(H?L^I$HM9m z$51PLs@RvP|0Pf>cxAzbR5Mhxd}8yp&xMe}r=E;2d$#zfrTYer;D+M34#Dq@R11r( z{kb5KAZ{RE9P(Ysug}qZas15>ms=x~=%jmeX+R=chvLSgv30tTV<=AA~V=3GqZndZ|55G15D;MSS|^Ga3%l{MGzTlxfc>xx)3Qq*T`rIt)?F*WOTU@s@DWrux*Qz9d&EWpumMd-& zjdi`*aeUprxRIu>AX&FX{7mm{q`W4#ELH@Hb;bEEcQtRE8O{+l=0=Xku(ZXqn`s*3 z@Ud`8?Wov15+>IF5(wQ^VXy9x7gv;aFkq6Nf%@zc)%!^(6j!p)FrW@EkpmVY!0u5xP zVLRDXKmUsu? zwhXV}=CdRJV*fC(>X>}-ba{s(Z%-%Rzyg?CTnv`wC1IfD{2AB|^u~H`+O0~qifWRe zRz!2E!*o`E@_F?koidQAO8A#Y&j|haPRmC{1f^c4O$;@h*Z2e)V|;y$=`;*Ilsd76 z+#!hor}2{rk^^+n>Ct>|aFX`t!X!uM=A>J&huEhU$h22Q6Yu}jf;z*P@U6z98a-}j;b2=sdBi=`9f7HoAZQ2} z2rdQu3Q@rOj+Hb??|DK8qxdO>8ZH%ttSGj!CIY{)gyd%=VF>9eTw6Q|ZFm_0lrla& z76y8Z!nF%asxWg+K1SA2hK-KQhZ zo#c4$<`piIsnIc&`^f#3xee^H9&y%RbHX>?1v^`0WS8QiXkZIH?*A}wv4DM_e>C%2 zgBC$l_*;vIo+C`({3|U@F8L)AZ*?>O6;5ezi%=GP zCPLUE4#5|6h}F(6C$!c&+r%f|c%ebM`5n`fl3$O>m(OdlH`@tw5SaKg5ZibS$+;m-Mp{|uRz zQtqzb1;_(TqujbHH&%qeJ`UXb;(_;LX9JYwkup?`CQz8^DXGK`Wj_ZMc3XWAR4_@drOPia1$137^Q z$cY72U55;uSgvs1P;eE<^Ksl}ajA`?a56QC%mz1vv7{0`sXYGHVf0(34D3~JVpu*r zS*2|uGL&-uUS#mnYbr}B;V0-fD0i|oiNlPt$GbQIUMSU#ofH^arX64}&BJ#UqofRf zjUOqf?t=67nCkN;nQG~3KK8Su+(}hY?hV|9r#DV!L?@srS{NXYwz#V($k=rJA13e4 zu3oUNqQ##qDg7`}CRe_wC>ita5PM#Ld!xu9iTfGk3UMc%#=V0Bp3=tYz) z(K~gfsbwoo)!G=`85z)wS=DahFLxN_*qoQeW`q=@92Z1i$skZQQY70u_z3xn^|Bz` zui5Q2Br2-B(rG1P_QvcKTHbb>1{T!UsaVDz-|+){(W@f5{aOr&2Bz0q?6DbnbliqC zBf?enXku=Ems^@;eRw|2uY2TbjhjBki<~3NzX<#=%Co&L+QV;;8b_`W^=(as!=i!@?*p{f~Zg(%fT+-@54GD$zr7~@}_oVctZZikkvv1H_Q)oN#Ew5 zpv;+deN|Jp^uh9?V7iHv!j3e znNjJ5bm;{G8WpUaX4uZlE4rpZctL&J#iClH;@Tz1dRHbI0#~85vNO&~{w3YuTPiEX z$1`R9472t57 zuK#=xit`iOKO1IcAovQLYoSs#H+FE4{gcxaQFjzHFS5MS954!zl{kJ=S~|$`&OMg$ zeCX!|s{#K@yvQ#&6_^!RoDgmxS0G#VeXE`9?d;buLr**pphs+3S>IF=SJ>k|qt!EW z(V@{2n}B@*mk4Eldu-oF!Klc6XLr}EBfv5!JSq5+PUc9X8UUOn;m+ahsH7D4NCVNU zA_XZ*0no)g-oD7nwbTdHEqRe%&N~kNo>fdLqjD_k>_$cJU)6?#%Tk{k zk7Gm7GT2fAbp?c5bR;_72`9k>nQWL5Eu4Yk$SQtyJrEzE&RSY=qcjwf(0tbC&R`Wf z4Rs1C5pMt)x;JU_jZ)yY9k4AVY-ZPOH|)8;)WZUqQA7~v2Y%^#5DI^_jG2@``rNaN zLrjb`FfyMs7JSCV#UQ?;i#^oI`WgR(79mVWLK=3j`V~C}ir!CUi1GHAaM^{~#IyNX zoNp)qqt_Rn&Pn@9T!^&?Qf~Oa-M35?Caj>BC`!nWJF|&$YiyCn#L=OY&uy_EBmqHd z4v6+;7Pwqr+v`+!&UZd;C=Tv>;m<>|g#yBRDY=S!+E7|{XA^Ty1USjn(eF_D+7NR= z(+utg{LQ6M*IGk+tuu#-B^1OYcp9p&{oJ8zBaN&g6p6G6GzLoxT;`Hp6E%RY3Fup4 zh+(PtrI1w+bwW1cNYrN6+#I`34Vx$Q<1ha+s6kZl@RYZq`;qjH*o9KRzz|41K!D_tzS#disC&bz4+2 z!~mgD#7uMe1z>4Fm%pi97~AP9d7t)uMK}XoK%ul0nt4Vey_mZe*|1f@knkldwHNhK6eLXePdSeEWk5JZJtM8X0I6{Sl`X#{Dc zrIub`f#3T1zWTrTzhSv9*k_(IXU@z$_uMDZ_@)jGB?lz{fJRSO(-Z&_B=Pr7IE?rc zEZM#V;KrDqrkZ)s_(mQ@7_-(vhlZEUmcPHvl$H(acHb*BeW#!dMbe*&ix(4wMJX?q zXsfC5bHy2`Q3vX_u=HklQFUI@t?VR$XkK8TyM2=m8GCEkI;gtz{vA6`l8VZ|2@{Uu3JU@e+EQ)$?U?st?pvZvn7~y z{vV@V>e3;GbWM>4pt~IAHHB_qM}FhBA)f+ylugfHohLquMZu;Zr-I+u&s5pN<-c7y z=3TMI^L#0A1J}>txSp+2vW)-iOS2KO>?pj}%i&`C^tOWo=~#?*pmt*#4;m}OtU{^6 zqe7;_q(X5@d#1`XMK#4e#V|!X#gW>ypnm;$<3iXeDKMw|YACCs{hv$pl*S_8(OYxD zg}9+(d~Hppe(WI#R0LP}1sYL_0;9slR!`N|(Q7O0D}fAgwpw4BF(tEy5wG5<|L@xl zv-fifhWf(Qs%HM)$&mBN&<9#ylv%Q_~191eBI)VEgs9E8O5Lca||=pN`f~nFWRnL6IsIqnWKS1RX_N5Pc|{R zcc+{tUC|2EqJNv14M~V9()$+*Nw6SCr(4Mqc-=4d%QHN7RP9-h`JfjhmzqaT`ZKp* zlrWq6Kx|RfKbb_av%91?D>|#-qk(sY7LeD;_Cw2KIFQ; z2zn?@BAgsqiP!|2(1|nZed}3|>~2mdp!?6B>E2w4>cMwqw_Q)@C8_PhmAREWZ?66GsEF!)K^YmTklFe7w8qnr&{TCJIIBT*C^wCeP7+p{V~>dtAIUgqKatrm8Wh zNL4MO4;AVD8XGkIM8Rzk*xdoSw`x!133V~tixeassf+Sz z)2n9*stlx_f53w##jZ4ya4%1ErF6HJ)?jU_l4hvcyWJJ)wyCL+W%pDo86j}dGj!`NE2L0S54x?F7L;_Kt zT)zYhn;&-*_YznDezf+5W?lsRjkvez@826ZUQNzZjm{J*FH%D2eUU3`J6Rvt^EDj0 zKkho<8ZhzfVXw%CZ;D2jKKZB>3PGNXgW*svEJ_SrJ3wPS@8-66ZSi4PxO&vL^slp@ z?hob!YnfssRS|*VS)df5rgpcC@ddTl_;72Z6pXLz0nub-rQ1itcnY-c1)kH@4;r-+ zaT0f~l#GucgJVsXQ~1jyw;ruVMaYu7#LN!WNFaC25^^Vv#BM$mBBboNYRI=W)*kUw zYzCV|H56Js98f&4?7Cc|se|vLuT5s6Z!5|xX98~q`JzX3xKSoVE7>u;G0g4`MT*rE znJeSwt)j!6ebvzH_<7_daJfuqE6ri6gK2bu1vzghmH@U*YOU3KISK zUmQ(Fp=4-x9*{K%;rk@efH)IhRe-I+)g@_SxeY8@&773RM(($yry@R?#v2{X)q`Hg z%&C75zAHgv&MWk9w_(^Y?upHZZ|APwsv&uT2_i%3g>dl~dBAZ)oAx-pZ8Wdy=_1c* zg?FGa5GI2NFKQ`&Pwrlu+F)1CXue0d`?)%Z=5@@kpx(RbtVa%iSGpi|r2H!ZB-oF# zgM9ubtoD*5d{0z2UU&vKTez)?kS^^@S0C3=QE`5H8-rQ6I@hs8j+zueOny##3IsL! z4ZuM!NW}&EV=}QfA_6K;bmh+KSG}CkFXo@FkPSCyYT)eAJ7RFO`Y+MwVJ#uz!<`_d zuNS1xtcE`AbBLGc6nyfPS3bO|uFGh*u_(2Z$puG+L6s+B%#lyy+bvqEH^-ft%J zSW2*4n@xOgn4)Pl#tLHHerG)7ZDLVt=kN~6bSQ6E~+fhdC2}Yq1m3-VhX_#Z8WKGQtRGR$d1m_&`#{ar*tlQ=KX~xWaKd@| zL1tQ-U8`w52b~>kCRZrz)nh&%wg8B39|Is8Zm_(pDXR-)A@q7%0r_tnCZ_bRaYbc+ zh~)50MOTD%h0d3}qDI(+wWfz2zhgMFIZdP9QN1US)PsG#rR{fM1bQjPDo!=?loT{` zE<#TuLFf69046SJZnz0X!e`0_j5!0*uV|m&BtG>*82s8vJvrGMBMRWkdcDtx1s`ln zj#tC!g|qiWHF^>lqxpBozHgAvJ*VdwIvvY?Fi_2=AZx%5MM79Ie=-;7q~F1fg%S^` zH$Z;s@9=Z2%`1)5FrG6lJ^I!87G%A;MDU{p2%GT#c1^mbJl@Z5Bxk)B$MLj^EWnHN zO|%gC_I*DO628XnG!yRY)aK;GFs|28%31Ay6rnX*%t1?rR;34fvg+iDi|p-c&C9Xy z?5`)uN85n+5$Bom2l8mhP*K6-Da|6zkG`RtL8kJ=1AeAL)#R@L$=E`=j8!h~unnt` zUrqa$Y`+AqTg_E}-w1$x0Lf4^exHCh4e3?kJg7jtal6|a zffKUY^SrQLcWIAek8Xu@MRMSrp`5%uZAD15H(O7&66W3XZ@zLPNPt-}Bw z|AC?PiD)3;vvsRn&#tpV=>v^nWm=>%tTc}fm{K98#p=Vv{SV_Xf`pSLPbp!`zGJsQ zGnJ>5KEH051^${T$ibeF*6=i^aVi%SQW|ZtL7QO;}n=05sh3%c$Kow@E4F{tP8Da zSkd`vAVmB3&-#|W_-D&PFP%1RgHfWh%PfR5C)mLz_4JRYs@6Eqem^`n=XVS)KTXH^ z#lTI6<+t~B`Y~ANSvp%%FU5YiyjM}TVh#2E745KcKf@X$I5xT6xjaJF$G84 z^XhixOh-#eBbmTsdx+Y*_GleJIx#NnbF&+9RLC9z$dJctk|1mdg4daGW)NgK9QxLFwAoXJ73BzuH%MAI zbOV+>PYPDJdv;mHSuqz+gi%QNX8|zn!Vmu73Q;=#bqqS&gsN-Tx2%WDqj~FY6g4C@_8CWEYSSHhsAYG&=|U8bqvE*N zx%ToNJQ4$osW{CfacX2xeV&In6e*!4p22Y=b@1!xh#=%8qmUZ0o;{9ooA!ZX-66=n z&~^f}XPfDs&LMLIE^{vbpk+n?T-)r$1|wjZqfJBK|E~Yu3Vxy-Hua&>VX+Hd5s-UH z+Ba#nMIIN1s=5r-D}t+8v==`juHxAKS|Z0r;^0>|1~8TUpZ8Qr+De+P1Ac-aqFjow zhoeD+E$GOhrr?m$sjHuZyDrppCF~0@QXQ}w47Y9=AN?)Uc|Z23ZSW`}aq;9fX@QUg z2{MeOOOYn(jhp7&WXHpdnr&j$AvU>+-~$qH(2xbtA|+#T=Sz|!@Ol&gabWRu0JA_1 z)3aeu5sfRb&Z9GY`HXFFCYFKs^(58?FDsGS-YeC1osFk|_1i?Z2l-l|Tu3%qNlP*5 z%kl>yKoLc_OmqA8*H;YipE;9mAIXs6|Cv(-^|NG1h9)D|Kt#`Ey*BDPC~Alc6eC0! z)zOr_qVe)HS9(4Y@lMlxY6%^ zm^%kKwB6+WxQ9zjf3ZZl_j7wV4!kyC;3~F)N8zidt1dwJR3%;qd|8dn$S}Uqv3qlH zwl29nlmWEASy+gy`zbb|Kg@~|G8%mxaoEl}I`C-Kq(QE(7vh?@*2JVBw?8j7pw$$kPMNI)|KOKGp>% zNnsX*<|;$zDX->vjOv^d59=4+`a26RtuGcQ)OP0i$SO_-)yV1VQ^m7|_cC}V)V9m+ zQ^4zHe(QPX9bn}XJ=CNZ$rV&K)ouY@!|CE{?{3%|5cB_3BHEDG9=jr5PjpPZz!ic4&;mUXy?9quNn__EK1FuU!GVBd$%Ad0b z7JDl#2QzKmsGhl47IHKbJqorYo)}`w!Yi^BsBl8}rz-%&!r0 zx87;|*3sU`kHyeIPB2gj%FW1^s~q)}0fR;j}Xj+=*Jwehub8gn>&k@3tA?$an6uP_`Lq4#~>`FCFaiazqIDlCy5aZQYELgA%uk#8i7zf-ZVl9t8g+Q&xHAwlmFl>6NOK)2*pbxXI70UU@}Gp{Bn| zP%HC9u*$4U7zfqr$I6? zugnE_8L88Ex9|4dzxSeZwqSMeci^wqq^|P^BEQJ_mYptRD3y{Ijj8}}a>3;n%BEea z(Tu(xrD5x@3ml~Z$tB1%#nl`+x5onA)Wj%pew$cE)9CFS4@17AM}HRp{s$yjuiK%) zEk@;U&FtQgpzte3(x~vQJJi!wKa%{m4CClVFC|XxNLsljD+df`(>w*Ty$<7U>bF4U zvT(qHD1BRA4C1`wI?RT(O2**eBdRv7veA+=>TXzVisTJywNs*xtfA`VzwlveZZ?-m z_Mmq2}G>yGl!&==|cim-#A8(T1`0j`m>uUI;K%e4Z&fvy08X14loJ zv>1A!0?FtCy5WpJERAAEK1qYblnKPMz2o4+P&|Li@%|Lbydlsfpv@T|J^HSi8Xht)hWsC_v!n zb~l*P#9b66+=GDh=y1-L?&vg?xK zd>DM5<$k%GKuM0`vft~VK^}A^ahrj`nu^4!)W)hC_xtZB`h~PmNZbJ>9gFOzF}B%Jct5u2&kmNGV}1O8f`{&zNrXJyfCS96Dy)yf3Yk|bPM#lA z0z_IEoiBL)YE0^u_qgnPNx#-E>Om?t<=Pl-Hd~VD!*j>HyhR4|BaMtPx0aOtx-DK$ z2>8pgCN!N?DIED!=T^2;;~^{&io6WrbIP2~yhr0-$pI*kHZGBFt-Rxety>lg5Tu+D zpd>?u97kfNpAzA~v?frO56)COyqjI*CL|qFeFZJ+r@}dLFXqWY|0acML6ec~$U{lh zoq2lTsDrN%z+W#GyD8SRwLKDdQ;R-indxA^u`&8r)j6q!HA$49bG9C2MS}_$n;Bzl z0$CarT)oQt)lMltnjT(YgCdJbu?P3KpIXzRv&bkzoI;l5Z#8VMD;i6qJO_>}Z3v|O z98fG51UVHgs6b7QYOBsU{izSWMer%*)KY%S{V(8}s25Xlhy{m$g<$$)_M5{)WIYama-_30YDnmZ5vbJ7X&Y z13N!Pu8G5tt^QFAv`Va(o-l`!>^S77iDJJ&ItQkx(CU#G+el)b#eTuN-2AgdzP41}MP^!!Dz+&46OZnj&yJf_ z0}6vnnz7%W*!)hRVA!AP)eHotJDXwe6gOd>EU>T5pDzJvejuWh!27F)nsE9JT5H=R z-#dIZj;n8ZeuoU*_Ddn;^<`n21Ds&-YR@&*O_RnBi6tPb2aG=o#?Q6%z2E^cGl=ag zC$7VlormX?)f-Xye-8_M7wYHP#=ZwfrXLPl2;yX>NKurcb0sZs!N0&pSv7yrHFoIg`P_9<;F z>Ea)}PAcGzgYsQ+erDhchq!RqyU$85$Iqv>$E80vZq|Z_3Tn4Qk4P|G{OCSEUYv{p+gyi~j(4W| zdxNkWEtoH7=)9gO+S3~p$X?%7A99bf>)07^rJ4+{Ft7lI??fNo{<3HBwQIv9Tw}jN zo*j}Q0)#c@=f5OjuY|bWjT_W`a*=}>t-WeoY!$|ObQKu(?7<1J>7GFHEed45H=>}a zkF#N}gGQD1QC(dC6#HG7)Q`cv>ke(si#JvIAI<*a@s1Q652!$QB0v?#ApV*`5Rbs~ zjSM@%w*Y$NwC=H+3M$+NCVqZlo{q)DR9U>>LO*xKO^d15=N>5-N!$h= z+q=_HXFL>As29H}yGRfgY4D!m|-1^dHi3L4=b%PhRPOPna z7NR7^K6VsK9{1~i4C}FO#;#3UQ}E7QBPnno(&!lDS!Y)`PDTt6ey}Xj%Njwj)fX4n zj`4x%SA1;7Li+csyFe+1VjlhRdyx_mr0JvRK5f$xU{*Tq!3V$I4H3@=83-?)tH?AT z)-gz3D@a>~z_A}_7p=I}6rMl48+WRT=#d7C!GJz0-9`XkL4}_aKpq|hswK~i*)Z5W zyBB&Rm9r$+{rkuLvWbbl?6l4yyG&*6@D`iDJe!?;T<16e&N-nEY<%2#NjF z;?n{)PCUT=u)yd!HTt&0j9uRkAedID6;&lC+FNBAJulA(q$R*<>43M9Modqiinhk5 zyBB7Dkbu`6)9%0T=V-7e4w?#uPtzr1VwRB&HVfVfi~D+rD<62{3$K=HZUP!y%uoQ_-o|HEAt z`4$YK26}Jl(ZSn9ZS+|R(tFGim?teha)E$Bd+39Vq+N3*lG%mO7Yrcx0=hb>UZKEM z^dMQXEVD%0-kc6bhNV%=5?VL>&5>#z+T9*0e;w>Ig9T@|WUpCbF-<*@4tgXW%`-o? z@!)xJ*9oE&4+IdUu+Sj8*bk)O|Cf3A1tAgZk6 zz{`6S3^LM;43`6PsnOj*7j=k5#CIx+QbWn;6Qn9S?+Qii!0^ZX6-3{YP!*RJi^m-HwMM9C4b#kq#+gW}0%t+}~b)uh)Sl>C~2&SMx zKX^!uWR12QP=sQ`p#NTq?Wm$wCn8KxzD~F=ofr351qqB1uyVuu%QIITzvPmk;=-UK zwstUw=Qr)|(K&UCy)4>9Wq%D#!@mwzH!`_Is41zxj`vccM-5(pOePDPxD`Vk0(E=j zxEw9mc+ft+6_Hi$nUMa`l@3EXWH;g4aZwq=dejG#3@19`^o6e=TXan@6O_IZmr$D^ zDBU&HbTR=hA2)${3dmZeLQfmhA*2Bf)FlB7zeArY+Vj_rh=bv9enC|``25x!Fo&p$ z9e>kdH!ArNGJ9Vk6)$7OQB z2xH{L7TAvSB5>+;I?t<#nsU4VTop#1j)f%wY}e*P$qUEQhhDSJkDQ`fMFkM;XF8}W zQJ71XqxkW4(k1JFT^xm#Q}fTJrIFWTPb z7XAC09b&9y^Bx!QO~_Apsl&`Loy#(G0_qcL* zn?B$JuB)8rVm#op+g8n=WrCvCqeUUY6cHE&R=M;S7;o@4JWOKXDz@4=A((D-{nH6VnYPFd3UX`)WXc z9x(Sx9~x(Wizh`S6Po%=+rywMku21|P;()_1;JirWmoA#umTOivH)E!&!^oEFR7i` zrG>?sh6Ch&QlN<^u-;#|Rn6}dj_?(_74ZI1pp*mu(uMA$N_^&YNO z2PFzzKy*XwdabwEnB7kj5#7Pcd+uklwHo($1kJ&e29k*@V&UX zIL7_RmTx-0KOWh2^XF+aj$!shM`TGrfU}LXl{%Q?_M4vOS2qHg-#;?Sdhx}||e`;Qga_s_5KXue`&rc>?wc`8gq=>!p6_?um zm^(exq{xPGt!)?-`_MQe4wv~yWoKTpBVC>l6iLUsKNmoK8*{Ym>}S$ZZ(FDXzv6y+>uvBqO41;B_kU-OFe=<&mo-`C>eF$0B6 z6*p+*tuD5C_J1I{R}YJ_E6$KpWS*ccz2VU)7^5f%q!oda)0{J}Toh`YTkl|QOc}}n zLvx@5LaT#a4IDY*47ZUVw5X87~mT0k=j+}UIrZ+-Sh77)ya?ISk;w~>yV5ih;G&;(mfW;6^~vSN+uAiED=0@54>(Se{-@F z{^Rfw4vsvX1bYuw6i{zL1|9w}#3jLgVuD(6Noqx*^=@e7jo-cF@?Flo<~-*zHr|#> z-*hNYHEUPw`xgs$b}u>aPrR3T|6M68XrI2gsoM~SR06M=-+_$l#p9Q{LJM9myru8E z@v}NU=8*w#WCw5G3?)RD1jSE_WgX~&*Q-fl9zZwIfCM2wpZNz>X{T(t!7T7Y4EcLj zE&wg&q?3p9b1)VXv^6;hkM5f(RrK| zlX@3Ov0P6(jzrq#l?C}On{M}3UV&t20o`2K9msLAv3i+KQ>t_rJ$)m|ixUWC3m~*I!$Vx4P4CX5 z$G=^BJ$d(MyyA>)-=<3=QgQIAg(*k~)qbY*jWxu>qkw^6o^mGMar+}1WLIFhp_121 zqAI0~-*8Oxfs+iR-+H}u?G80s(Z%b%B0raohxN&6!2%bt&msrGNbl-49SSZYF##b8 zEoz{UQUFRUvRrY3?9Uvqslbp~AV!kM!cr9Lgcs2S}x|Q0h z-0dkt?)^QZqWgjT;I{(dhxxkvio#1SgzKC$8B%}{Jl}q$^Jw@}<$8u+CK2k7IpSJX zE;QY0)h8nAcL91kSo9Vq!I<0|V_pl*auiE^|xcvP zxnb!YnX$v_9BO21JDffuoSZNCBh~jXIH&W|ro{(;OMSmoEc4{8MZFfG9wY-rWRV!z zh<~Wi_H2g`0}z4pGuLeY#H<@xO_$6xkHkg2xF^1S*);zd(MeB=XfZbaI# z;ZBbT%1sxZcDNV;M_pk57U=4w8&eOAT4+CG6d-CxlIYRL-r#RM5G-!sI&FQnvlGV) zQK_6UA(lY@1ZaKoSiXGHoIY`*b;xrIXF3MoC<#?i5_7?a8X^iRH^CTNgdFwk&XXa- zx_c_rt+xHo;}<`AVZ=h`Rz7hk$C4hsbBo8#py|*e zyXpMZUpW8eF9JZC6(stMsBa}hpm{82_Bo88eGP6bGW_GE2+&O-T!+OlYzY+ChBc?J z2UhH&EZAv6P?TZyF1`x_$o_J>;gY_~k9==!)&F`r;|R+vX&xjaygo`gN_5N(<->0$ z9X|YVcw#N8Hu0&fa3bxi;(0)G7*3$L@!NBEx~rR8ki98;LE=#C0tX7dbGCo0;oRu{ zF#msSW7Y@K(uqtl)9t5;u@(9+iPS9sf48X6E${$ZC?bs^$!z=Ng2P;Yez@_FJNH42 z^y-@nT8v}G7A@)S5X9!xB)7G=?_nG-6vGU~#wA~Jsj`lOyvR$=ju22_G!$pLj9i#b zZs>Uh%*lr(Omav(Od#EZx2}yF0!MGq-TjSuxWv)8aD)DP0}=k+hF~N3!B2G}UeIGO zvrCH{|0fk$=R)`YoQ{`CmQy3I@*f*g&2&{(o%tG1j_?Kgthmf2?%hHds?Hw8#VhS|Fb!({6(JtC3qNn!Ly_7L?3pcKCZ1>-Y6MrbT@sE2x{l4GOnCh190Sp>f#ixv~m~$iLS+087Z1%4ETUz`S-zE4J(i1&pXU|%bCSuAZwEXv3n8C z>k0mx1oIPQE#HfKY*m*LMz=BFcD}nS*~vFwB=I_BK+r20!V!~Z?gd`I|V$*IV3vKo+#sDmr}_s;Z>}m=QoQ=hkm>*T5A1ge}Qicb5B92s2)golH8J#pJnyeB75KhO2?aFJj2 zwpn?nm{J_2vfkXms*l*^bCCx{wR0URf93`H=rCtK3CLwf)u~UqQ9`%%P5btjm&M0J z8}y=L$!5P@*vfP>q(n@%zA`hCg7P`p75ABQZ9OZ0Mq%7I=fp~a#gp;T!MhnclAhva zABmChiIMhCba$q&!*7S&LZ^2SO9A3H9`*Z=8^LNO*8SbI0By*_H4*$&?VTdBGzG)_ zV|_d97!gL&p#~QOLZiCMGEvCYoyeONiCmQ@sx4kS1_L5q z6(H?*X{W)RS7W}T6bam~b3e7(1+#6geA8F-z>xPls*?1ppR?x&zc+fT{3m+9RyS(Y zpeI6HVfL@jEcC=doeRE|epqu#7Vd*y2)qQ{NY2KV?Y^WLw zaJNQP)So>RRK8JuP@H~fUIj(b&4_1$1kkyr9Mpso&*|cwbNbISMIj{p{qVWv)8sjw z12(d#b$e!)exHNpip+cCtC&~ib4l_BMX?9L)Lc|=qv&|IA12IZ%GyQU?#XkWnOVA9 zxtieTss55;D>Zjz=rTE<`=ZV}oz?F=cYvtKSN%n)cWnoWc@2j;V&FLtRt37Mtd~NM z{Hn#Y>CL-YY3cvv5jnM=hES|u48~k)|B@0jo_&=ZRjDFAOC<3tk}`3g7_oaNqw7(% zuXgTtb@n@v8LfJ+HaOqbb>{eSYc_s)Pw)F^+%EfA(#xv>wQI>Nc1jq%1dX}yZH7Je z%vQQXnSpmzV0-*v+GeMV82#=@ za$A1<5{640@-kEBqC|eX)z_XvcU^y54`q5Hu)TIZW9$pavHbAM8g;Wm^!Pef5`0Qo4DZSHb}qCj?j-a(DYX^F zyzCK3;ba|ZizLHT32i=aN4Yg-H_u8eIv`F>Dt{cXFr*OfCfa&J@N?evzfBq*b3)MH zO0Qqu+H(u4%lUQ*ci$0x8Bji~ZhHa*F_r3EN}YmOq|f zcjL#;4cSSyV{f$cpu4-vApQm^wLyM0?{3u@dH$pJSeCoz`}7N;NM-Wd+A$k3K-lXm z*B_awCy2X|Pu@nCsFg}M!WG<2OYfk ztnYn}!$fR~k*Od||d;y)W7Xj^u?4M)D> zGP}hU_>sWVeYwvI+#pxo?dyu8Y{hQFxwnY;Oaj798(vZYK?(c%;bd8kbP61+h<;n!6xMiB{ ztqbn)4bQKIaIez78_#~4hzbf0L`?d)NF&BLE^RLeIFcnrlV8hWt zob|MOmvnCxEId3?Z8@CvHzvy7fbPDtK4kl`eU`S-_Uzj6Wf&GlBA!Btw04R11kcln z?0aUnPK37bFDUA}MJ%yV_hBZ&yPkIIj`JZW{;c)u&{3V!R;ds_dt99N<{@zAZSFpi zjq1%Rk9&Ln1|HHd93Htpt8>sJ_13Hq^lOMJra1YO6t*!c2!y4pN95l5i_g~x zFL|GbUDr-~zu9P_D<_q*WGeOiBg;u-=m#>y;82h)<_iaJsA-#=xaTrNEYiDbq7`Q2C98foE{q6^Z$mo^DAEr-87 zq$p)b=i_C$=pVP-1Db!0t*6j330=PJk+mKmo1Jos9mt}bp(Sza@c;C+Iesc-Im#mI zDbadOZM&EGPd4z{kW-Tb9&XrXyO*?-NmPzQj1xwS@_Z1#w1is80!dTBNdKFk&jI=Z zQjLS0j~1~-k-k&)A+}K&F(2MR2#QLlRv`&nCtTy@p)2ABLe5C5mS_r|K8Bb)CCyt;r>_YX(ILEl%3=-O5z_m>;Xr=r$WA}S}aV_ zLro5+-=RQz*S<-5jAc?(GrnO)k|FK-PDgHIM08@khRDvri8=TZ5LT*IM$8dg3n;IW zqDSQ)7+yY8zV)RB0$r^3<0^5cOwaiz^WtH$!Sc<67&aT%sHR&#@i^Zy_H2LE@rNGx zxmD`dJW?pdYmDFxMGTL)QLNVG{Agh!lR5~@VfttS1@9S4Sh@Isc!TD!mSi3%EfRqU zi>;XwB3}3j_gr}D5um*XI+;)eqPCQrs0eN)_8(kC$-;mf;fN{L>%q)p+#6e)lKDES zrdtV^uQRVESI=UuXv<$+DWy|QtoY3*DPO%;ntp<+C7)0u_Qgq+)x!$5EtrE+apE{7 z5~2$gbo*qZwIG&~McZf`f4oA>3ye-y1sYbWX5Oh+2Jjp<%G~l1VnhrA#XjZ%dkyxD zg{o>qR+I#h*409c$`(1o*%ZxH3jWgPXL+e@IiC*S)S0xu-&INb&T*fPFU5wpsyA?< z^Dkg6W15YYh&*NEot;OGIkwW!WA1SQ)2NFPNf7YC)GGcqjE|`8G%eQQ{{$3IY zJN!6$?Xa?rK6eX0_T#!p#Xp#Vwf^#XQd91R^4orjHmm7D%H%xdyvG`QXLtyPl2>!H zCK{}~Dk-m*0$6tvJ_Ax?vsREn9K^Lg^P$oTCgz4Y#jHh_w$YN;Fs$`*cH#94;jTwom#b6|*{u zUnw7dHe*L$5CHY*K(I+C;3F4;DGF_53nvPxFeG#AV0Gm?zRH|{8ho&Njb%tVJ?VpR zX{OK#=joi3#VB#XBI!>!HIpuar>@5Fw|OCzL^IXfa2-}Z@yuXI>HBq#ej!f36L`6S zSn9;Xs(uJ@^wg5Sv%_;l!GLn?GoOSd3a0`06q~GD&9_Z-&?|umy!vt>L ziHdZTB_2CPW-ZVy04PJ4JT-v177g{U2R=V2k*}0P7DzaF?puYpP2OC)>z5HbQLxlh zbX7otlkXOht7+-lCh`r%Cvli+E4Tyx6meO`@`&Zm-pHZXEnN2#(%9f%orS|+iC4eS z(C98K@m^387;Yzy-rh2~JH91GJSkB`oSKfXjFu~O(oyPM09oZ4!M8QXY%Sa@;|f)` z;(N|XztG<8_Tk#95(Nuza@0=L`vXc+6c-$k_M7OuW4!!N)^B_f?}jfmCG?Hp+1p<5 zoMb8b`>^TJofBtjHOQ6Y3nbWEiX$c!YPXfNh*h@ZsmCbxr{Ty)W$qia$UHyczAs^V zp_YrrKHy<)g1>zBTxBxt-nP7#2S#h~&ga8tVz&&#Z&`ZcMgHryYlfBp@%Cl-1Cfcw z)rq(AI?4qG+f}2K^^DbyQWtL~^C~)=iq8`K#A}2(g1bcaQ(-$tf&0Se>=yVYc)r-r(B>{k~$yD&I#q zJx zja>D#Ev7;Qr|hG``Y;~%CLa-Roc`+Sg`={eHx6XrYf0nq0-k~l^#C8qTbN64~#4K zPF4Dd=bhQ{oR=S(jK-nmPMdRA{0}pih4=_T5c+st&f|kO)SF^HYTv*4-l01+3Slr> z&>iXH$>n+y(Mn!D3?=Q!AmRed`(zT}WJ!(YQvCJQfCqADBKMV4MC7ZXA%7Tb{LwCP zu(rxz8DY({N+~6ok&rn4-kUv%c-0`}Mrb*$pAjRj6(Mge*^Xe`^Cf)u8P)mhej9>( zxVc)cYY}pTreV0A^52A0V?{47y7YP`xmqoDh;p=xz|E?CBTF^VAGnZ{hF?u3|6D&o+B()?2`v2pUTr>-HmzH(0waa&miw9 z$#rZb%{d(w?#jA!htRg`Dz`l$geDvL3&A4S<_@C_ejDd z(BXY(;~cMRR*N)QrAOron(9}NS0qTp;UoR*x*^iv&$EO{{E@*L`%*olAzxuuBDc73 z@mB__q?*`3eLA@{O$kkn8=f~SAEE;22R(B`r+Wj^k<6g zhc`^h%cB>{JW+kp&GouGgOnq=mg}GRum-g@>I}lL@Ot&kRAXq+m!jarkmJ}uR(!a$ z1)7SEZTfQm<#JlHcjPj?p+qg8_rcbgfW^T)`jz=!7 z31mS=ty6x`dbqJ&9q036^lo3(MVOHo0cDeGbpFYjF7RsNfmmbH2(9A)X+>FMo^Yjp zB%F#ud!ZZVYmNn9SPA11TOraq4{>&qbATBL#t`T*EKsMsn>-9Pgd1qK6FePC=>>#| z`o*CiNK0cyOyZ2rUCC(s@MBH4)pdZH-gz@ZYBCp&CAPomLVEfJR^1h4xLE^7I&Ix$#@7QUzH9$uni#L7yzQLeMJwPuB}F(^g8&zL{^m&q($&x zN=861A`%+kb7U2#CI8Yn&|&tEnb+2as61L zY^EDKB|ywXa=IGP?( zc<^A@tTDk;2`>jQGEm+yzZS=o*zi-J15^=@RxOqOIVYR?zB zSG8J>;C>BOxk0wm^&AIx%JpX-RH%S&*J#df>Vpsp{h7#d*FrbPJJW9x=H`{6dNCR62x?|Gq1froD{JGdr^A{Q9s|UMpi$kUeR)s_t8R=Wn3%uJ>S}W`9pmr%>J<0DMgv$ON;QZp@|^bBCPk@q=hK!Vf1(uq8(pnx41FA(+=UtX}R|i zH5xBBJcH8X;MUj)()jhu6nTdsn=PFa$VXDh>bscq!S%jKHoqDleWn*-Sd^KOA%a@- z5%4%8C)HM3S>Wr{y7uC$cE{3~Q(4l@=}KiKhwRpZomQq`?jjobk(M6NVkfD+ac$}b zs%`E2o2%lj&Af;RTw>t4H88FD6>g}=IWILBegYgiX7}om&wPX+pSrUdS}dWryto<4 zs1jo`FQ~Z$3OK4p3I^rTRCOg-LIbm%J0IYf5rw^C2ODxt+Jy0RsaNVy&3^OPm0X_> z(O&a>y6L8T^Ci0f=&0r7DF@wT?~W$ufT@G$q3J%=7L>;Pp}tj z?@&i6c=QOS#04q(79@#@Cg7zK++vR|RBc*aG5T-4BrF?IY|ph1x+&)~a*u>*S%E{3 zd7~OKu`MY%iF@KvNH!n{!(Z)d-T&jy>$Kkj;oRHcSg7$P5zZg}!)jZW%~mS>6OeLL zf8tdDNlNxC39|JfnQj-D#O6ks3dK@uXm8(W?>!*OK53|HQ2|QzqurBSr2o&?k@gq( zd7n2x95NOK|ER_By?>%~V4uoEn&Gv|7ZILOL-t!0Zpq<#$1h-~vp=#CM953pVyz`@ zVVQ&WJT96H6!2Av7F0@LPZNZur)QX=opnEw-+C>L9n@dW=2U~-Jb23f0u$07%bu@3 zkwEF8k~Z3)Q767xdI(TTC`wyDifCn}Yk$upl;Y#t<}=Grq(gu9H{{JZLh}@r>X&(I zCDD*Ecnl*vu!w!S^Z%I8nuVyn6L$~^<97|kKNO%phtMtpXOuT5rGCAzVS|F4JPHeE zQd@7|o}o7J@5pS6;$hpog|XL;+|B8up=mcaZFz~3x9ne~?Bjn5aWNKteqO=mcM1c! z57sbPFpwkpAF3&ft8<)8oA%WRko#q_&QcocM9H8zd--xB`FrAJTwKWORU)EYtQs{} zO_V8NN;dW{$i+@L&F*>$-ZkAH3GY1a!1Ys+`5X9JwyB4h_Yw*x0dF?TtW=O6f!%qS zf4Nni0M$eHe#w{Ql>gA}o_`AAEtF_r!#2>v{!`{>&(`3$tigAY>-tQ0$_<%>bjC7;hdN9CD62S0ZQg&N*l8W#Dmr$0L< z&HlhXvfSH^mHLf%fqF#rZ=fE%4Pizga{`KSS86#M#TpTfu2_4O@IqqFVLTWg#Eb%F zwHRn}3waB^w*czCvN%e>YwbIj39=1L%t&{LXrt$0&BXD2)SIQLok_(hkJ$eK1ZSI3 diff --git a/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-hdpi/adaptiveproduct_youtube_music_foreground_color_108.png b/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-hdpi/adaptiveproduct_youtube_music_foreground_color_108.png index 9a83fdf599353fcc0c2ef41846255196ce035fcf..96d698a1b9fb0e2f4d7bd1699e0328fa2ac2fb4e 100644 GIT binary patch literal 3189 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 Kn$%zul=5F)*ob-n literal 2689 zcmb_e`#Td37bm?m_ibHRh_x-Lxs-%lX6CZ7j7Y}UtX)cAVVeWHnM01l> z|HeLXA#zp^9u^Uiw8mo094Q~a-w(LDU!dHvrj|)O4)Xt~@r_;QS7sgP$hx@N*HZ#R z209TQRL0ez+GwkiJe2fIU=dBhR@GBGefjUtYSR=i4={m0NxWvJ@_#05ga%8 zV9(F_KZ|Zz>)`_T&?{GV^-br=XcJ0ZRE%Nh&7XartyI*g^5}j4FUTN?j03vX7-3!B zU6EZX*d|gk?7}Gr{)N@TGO4jMlR44Gux|L=O0XM)WYcV;GII_`JX%~n)3WEryHZZyu?b37 zV4ZPANSI+d)s@#U^3ML-CTP)o`vI-=J#FM-3i5Q`MEJWCZA0ao8x_#(?AHl3A-G2Q z@5z6HxudG!=gU4gQ`Kcx)tQ^ul~fhgPwxog3cpvLa{zA_NGlGp$i*-FGq0K3zV+XS ztz;6g`Fsy3sN$u@DcRi18X0;L>xbzf`gCe5W*dTOD5s>(OXq1J}5nu&8sf zi4k>BzxGPpx%i2^DSIN?kJEO^^Zo6@N6mHudix(XDW}Y% zaN}gFR>WVcd3zHnvA&zgNi#ogdo$p2wE9!a7Cd=Z^eZxu@12*h5Lmn{=G0oqni^>yI-+t}?eVc<$C)Lg(j&*0 z>HZ%l*og@iTzw`F1gKtV>%*PY%dn{KG5NgtSM9Wfd#g&i&%$~0o&7p#2tZ(`I^`dN8nj;^$8*TX`_xq+CBEj z{8CqK!2zDjl;qc{tg9JU_eL&dY>{Pzj7&kyfm(b}DX~#*ib5>`)YDTF)A)l#G)~hc$yb;(4bVSnDFip!?e#NO~GDr@ZYjad@kcvYG zKnRejmKloTYw(7vKl;k^6JFYOX`|DZL~Ltxv+QpTFMAekBAJu%i33a?A5X^T*q+^f zaQ%s_9rY{={DFEt8{r5t++uuZpgqlGf)w9Tx(VE3UN$C~f`&Z3CoI0Mduz*O*nIu` z5g|>dn%z4ge)C=Z`aX!Xh3;;{%vs$I380w$EHxER?iF!xW_|hEfJgdvoIaLv6>S9z z3r|XkiWL(K2vFP{8Z?c4Jn7(52Z)X(n5f9Ohx#aF;~(voCPbLk92pOP0|AeTUwVuUdxD28`Vh(!(y&I4CBrMzw0vo2{|7{&N@kALw z=qBw7Vt^J(@b>IE-3~b*+e()OA~1P<*@@Jj1#Ly4)@Kd+Kbn>HUxc5QlI#XIGK>h#&8vZczr=28qTUmrMa|y7##M|wR=ft$uYHC{lFT4!v#-P zt{at#7Z>0vE!;@zlTO6Rti%aCSvZct%ViaM_=aC_(U~*;B-_BFPCZ^8+ev@Yl`N<@ z5@H;n?rnfvc?>+t3W^&hardRe_>yN(a#BTG2n$g3@=T{d5Cyi3Who8e6Za0udj=SBqHY*7XaGRM? zviFNe zKkDVozC(tan%)?&Wz;*(x?F#GcH?uS5v}1 zNZ7r&I(F{uhYr1JYmm7lp;ohlW#Cm4#5vOpC^Z`2Kh*te&gpJL&WS1CMJ_nkX`Hy( zCxvGQ-x@?Xo*@5P5X~*_fY*<|pV|)JiAe6V9r#bmyhkie0>6141ODc-+ixSKS;^_; z2TrFMQ$5Y+;pZ|s%aqPbtoswPk zyvD&iDJmV@BJE^Kcx*)6{bj})5jqUyv}gT<4+!q289_U0mYp(|-9zYJy0u?hZl~TJ zWd61jei{BAz*uT_hx~mc92R1u$nyX)aSw0zYMAp=mo#*8R-+=LGUg-eZ$x0iA12&` s-Sc0s`|bE8OZYYaKi?&f2KD_BagJaxwwK!dh1OC8YjGY^gZ8}hU#ySjz5oCK diff --git a/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-hdpi/ic_launcher_release.png b/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-hdpi/ic_launcher_release.png index 8f7ff25a15e982c43bf28b29d9ec5a68222eb680..facd33f08caab5f9fdd4da8d2979bd4df7066b1c 100644 GIT binary patch literal 4201 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 P00000NkvXXu0mjf^`m>C diff --git a/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-mdpi/adaptiveproduct_youtube_music_foreground_color_108.png b/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-mdpi/adaptiveproduct_youtube_music_foreground_color_108.png index 16ae17465c0d1f710c722e3ec4849cd363eea6da..d2ec417b87a0ab3452a186fca3a5eb39c0a1ffa4 100644 GIT binary patch literal 1951 zcmcJQ`#%#31IBeC;hI94t@z2|Ru-yfdm`FwwSetMn^Z%=1=*%Pu75)$$*mmRKt z&xrr(=#lT98wMYhkdO{@ak%6gPvI{_W(D{ie<@t*g7_QZ(?Z*o%+(oADp+rOKf|rV zS0r10%_2Q@BG;wXdC!RkNcz5cq9fWM(|ldBc_qUD=UBmV%)Y1ZCz%>@uJ5S@F7jAa z+m#2~^g{l-;zj;g@z_{##Y*V{;iI5yhf*xIS%K|PAo5%;*KEyuaxul-qP3av`+(AE zIkzkj$n^gK709^52`_ainQxK-RL&o}?`uYtgpdER%7ktm!2ZK|H^_ z25b_m^`$j&Ew4l+Y4N7`?vPirvw3XJt^C9>Fu`wHI>aHrcSn{xg*i z2|bGaCdsYrEq~3GF|6kO(Wi29ovIkRw>A%T&qze57o=hz&=@Hv8LM?^#@y3KKsvR0 z4H!#~CM$(IXv%d;k`g~Lc!90Y<~@?q9*Z@!?7_xh;EkV37c<`epsu$(n zC7pVsxn1Do?#)!cISkrXAR*afi9=ai9WM7nlymB70Od)Yh*=HWenB8+F#=nT{W?+GQ$O;@}}?C_c;wYj1M9c)i(4C#exi%*ZnIseJ^R7daw?zle1u` zev)FLKyIF5!9KV@*^6U(&LOF|+jQB0dy2tc1s)fEuvMcidUm;tLUhvFdOk;ffczp%J6^xfUrM8xBDOEbv5gKht>=Fwubp`6jrZ75mz_rIVzZ z1nh6{K9~gaR*!GX;Io|@aB~gK*T^*kl{GHmE5vH4a*$DsBd+_Dd3Nss*WWK<_z`Ck z@vP@LXFt(ZO!NR+06eh#U$qMXlcVbM|kyo~0ndF|z4;x=62+3T)IZk`#x zHW?NdGFWY)Anqti{wCI#cGVw2V+>$!$jda!^#X*be!%o?$(w2tt=+CZhXH|tXiWpR z6FtSJBXoC*PI%bAaGKsS{bcjXRC;_AB=EYM>yMj0cP?+=?Vn~?mOIw#Z44wN=|fCC z<>S&XT8E!i9S|dBo3zjyT&2tKASLp|Df6)|CXd;7t_ zU`0V^Rq!L#(5=MAnU9|zQG`b$_U?d}N409M#a~#@H#CP@)1SwX2v36>$fz~BH zWqX?F$v2R1HmLrjULn$~?~DEN5Yo)Xr@Xcq5#7WV9DBalM_nH+eQjdsxq5TpPRt=H zb$BU(#;8Rvx$4MXbg1(TBoq%O?sVbffA{NNs!as-Roy^tT3d{iD+GD?Fq?;KE`E)hh8DBe7-ySfV>p*Ujsx4gOl}aXhM#1_=EI zjv(}2w4-0fv8tA3h|+dJ_69vxDvdtzty6VwgH3yrgBDPX1pj2(-o6QEm3nEPSRzNKnTA d9EOq){mUDM#C^$J`F^|-E{>iKjdp=|{{}DC!wUca literal 2286 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 l8rnCBNj9*v26?kd=Rq7N01VQmCZ}Fq$ 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 V@C;lJXT$=qynOvq;{~sz{{fE@V~GF& literal 3786 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-xhdpi/ic_launcher_release.png b/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-xhdpi/ic_launcher_release.png index b9372f249bd8b77aebff9eb25a7e9e6e997e03e2..c2423831c4fc6bc8c46f97175bf0042b7001a8b2 100644 GIT binary patch literal 5707 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 literal 8305 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-xxhdpi/adaptiveproduct_youtube_music_foreground_color_108.png b/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-xxhdpi/adaptiveproduct_youtube_music_foreground_color_108.png index c4c79c94fece317851fdbd06b1997259b786e120..cc73999074f1781418b7d673ab4eb953faf8a5ca 100644 GIT binary patch literal 7065 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 ahs-a-D*EpG6ns9)!C2o+uSCb`$^QX_H>bS- diff --git a/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-xxhdpi/ic_launcher_release.png b/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-xxhdpi/ic_launcher_release.png index 1f0852d78a523af4cdf923fb317372529934ce0a..9c6fb1bb1c51ce1d4afb59f78f013efec112fe9d 100644 GIT binary patch literal 9660 zcmV;tB}3YYP)hXb?&+Mo^vi$RSkmQU?!NR11S}l2|{QnC83mrWjSCbIF5vAx^Ns5rs=?OOh~CA zr3+>P5vTqpVcRBzBtQsAj=^zFSe70Cu25hhz!0z~28S&$2o}ZQ!bB_kSfe9 zdVr{F)Ge!$aQYjD+m%^#0iizt2LOY40Dv9<2t?ZeYy)5cFu>SKq^n)m*sWl04IA}) zz`UDCf2Ea-M%^-mLNOR{U~>orhDmnf{~Dwj*QHUTCinUeSpsKAz8m;lfZO#J{pMo5OMEhw0~ zHN*ykoV5&E3}7LFw-eYYsL6JOj!hs22wDBt73qu}YbJ>HEogI>#`vs}{0PH|JwMe4W3N%OJV)kGbw>lho z%i-|N3RdrL5@Ff`fuUgab~tjg!;!a`#jOB(w8v}Eeh3tIfGrJqsmq~dHkaL?*cb>< z2kxf4BmSESij9Fbm)+oUXqkq*6kw~=x}~Fi5QrH<@^qK1mu+44poTF7Kw!h}j)TU* zfrc@})@2VWvR)>EY2fy8T}n(K2Ebhv%)7L-p3#t#@GnoAY=~bM4P%lb>jeelE`Yn1 z`dXEYK*S7yrm|r!cM-aZnM&>$Gc&S2*=>BrMY0G44Q2rs;j7p%mjg7FN@$HrLLee8 zXDRP>I6R*rhLp0a;>5qWUIb8<(M}tmQI^k`ImJ8n?Kg5_!c+`#I6R-FyqAc}eG;A* zicBB|fk(M)y`iOf1w)q1>LhO}CH@5kB1-X&61Uwq*Cw{J@+bOu*fgCnWr)q<#Pr%fR0Cq{K_X7)QWR0rdii6tjTVG7zg9s0AYE z3I%hn%b|-(a{B^^zzY%t@}+Ad04|3vQZVNdbVcD3vm;0X4c9Oix(H1z_S{ag%W8L4 zCkGHU?Q*>#e!X3UrfQfA0Sxy^y%zADK+FUw+>s<`k;CC5O5yLc%PuPqB=s-UHzF_` z4j(~+7D?fb3}R)!U;;5ylb4k4aA{$-3#(U2I*@iA{!nZ%02fv-X<@dM?(pXKt5A^F ztc+x~g_J7wp1?y%(yK0o29#p0rlWRStsyxOC>TUAIJSiqPhrr8WQK-PGL^mI1qE9m z!*F4m4ot)8N(Rk#5gJgcne}fPd4NWrs8BEiERVTa}k=NV9xa8LH9h7$Sfd;0V!^GIed9ZSJEkW-zV-< zB(pa1djiu(cfR>1xq`{J_6UGt^ALa|tmqZZ-hCiX1R`P>LIV;PDjB+?*t5&2WWYR$ z5Vtt~Xq)s+isg6t-5!CU$(SIZHb~MRCN5~+a`NuN5<_)_BhiC|L4QW#h6ahex|~*I z1aY(d57o$yTnva3p$AvL->k@I)XmS+)-U(`BnN=&mc>zwt_dpvXfA zE>xqnHvN;uaM`M~b@-oPvWh|=L%Lux{^+nZCg@=Iq{S&nMxG9KAxO2ujVtYewBysz z9*9RcI&6*6B>!m0{D<{<6UemO<00wtpdPlQiT1;4_(4EVNLy)7?|yx4BH5k!A(sJ? z;&Rh+kI(n3c@c<6SJ@nXNVETugsFHPG!1d+=t%E={kBN{In)fz5;lh)BIqvpd^aZo zB^_teQnxawzu!)CF}s;kf(X8MZ~jF%G8m%26?T7R8cxm*HC0v)&P6t)si(n^&uJFY zFYA+Tb+Vq5Vc4F_XZb*D4W$&y%E~c%)Cde6It0Up?vDe94Z(i<^+iQ_IVvkVqf@5} z7>0ppG>W}@Yq4v0HMVTohEFzZ#D)!@V#CHwSoOhb)YmuU)NZny_RGmHR1Sk6go?pY zrz%Ijl8Y$n*|TrkCxHzY;dd0|s8Xli_z7ml;bRWN$tQgWQ;wg6Lq-gTl(Hb1N-2D_ zdM#dE_y%5D@G9P2@xDLG=7>TkI2i;9waP&Ba0a#MRa2iny;?s33=R4Hs4joFl=(+~ zV(_2=IBUjfIPcsU7(8e|plxmXbTgiq^$ebz{VYD)yfx6ak|@}s5g{b%E*4Oav=xL* zy?gg=OI%k+hgK?>13S9)8Fknpxc2HRG3}%iAVhI9nzYuK|MF}27kwBG|opIy!*Ww44Tu^k2(-xFcc<`Y| zaqDmY7d16|18c{tPn57iUs@u12!p=PcAl)L$Q-nv2-EnvV(XNSILMxU`ZUa%`BzMw zaCE!K18WW;1jddz3>Ta`1KYNLfps6R52PLMi?9ShR0vWH0(w!lh1Tp&G;7K;Q%w7=vLHMFGcN_a}e9NHm9~GPaKcOAN?yrR=X-4STJI-7|y-mhj{(XWxmSw zLLde~lKYl{=(y(N5$e{hf8&YqtkU6HSSu8avU~}Y%i0zI2w8@{hdzKv)zMic)$Mu> zUvK&!*mWDS${9Q6Fg*A4KM{$1Gb~SYG&D5ev>6v+#mZH_%FTCZA0N`Y^+MZYl{VI; z$4|>ps4JKS00L_P7RHYu#Z+&aWv|qgj$XrWM|t-XS~-JYl?_H^-}7NuJrJ#31=i6f zXY41#wsmugPO1Nab>2heC-_eFb2)IrRk;;)6aQNK3zN_86sNVWlRBwF{tfPoTB3Ll* zNsKr+u$lqw3LmXrixW>dr_~{T&^{+az@+Fh$<74DQYWpDG>q<0%7E({&@4xhq?;Ke z^Hrs-9}u&nuuKzO23(GC=h1n|CJ{nemvQLaYdT`JAL5SNuflQ1PRLWkj*Ff>d!SG6 zUYPgND_PHp2dw3rbrK($<$5j=db^G>*Ky1p@nO6H5emf+3dIl!H^4C6sftb0Z}I>@ zv|$enGmLQOF?mXF1j#ax`#D_4f!6<8#m6r=?@UZTeOjyM?~{w^w4{dC1T!))Z}~}lwc*#OuloZ3e$5Rye(H3*x%6$%vN|IE z=eAqWt!wKMr}@Q5=XNy(s_H zF@~!{M=->o)Un>ZQxS=m#B})Yd5g_)Oz6hGfEgK#p_9C9AZ@r7fuP?#d%U9sz^&7EsXVayiPMs<+bjV8-iIjeY^M%o~CB zef1K)SpCyB&+FBzCvLj_8k~RLnV!Nos`u={1Alo0Gaq{j+dki(*LTay%P{@)Q}FLs z{tyQY8*x88$Z|tsQgM|f8pbe43nBsm2LLq4_ttzsef67pkq5}nKU%+j zBaZ*hbo}zyzblwLK)j22?1`sw)Pxi9!iz5#EH4{=^5e@|{XEzhC>lh-0Yn7hx&p2? zj$lxw7g2e6{T_Z(&Gr`ScRAzvc?&Rp;z{_gTW-r3^*8_Jg*g7iGq7gu$DZ5BhCO>~ z@V!fZj9>lc_kk3sI{CyYzJz{wQH?>Bt~QQvT>)vx9?)c-2T2q2p8w(8nXcV^kX9FT z9e8EV@|Ck2J3qb=g(Na6t?|yg@8O>_XQ8~j93u}M0U-pQp7T5|`_Wa1#ca>AbHQ70 zzl-hLci^NGr}%0WhzQlyd$4p_p)2Gfqh^3??Y_Z62rrbPDSOApFx<#TZp~$ zkN4r(=U((x=Kg~RV(gg1e3h9ih3Ph0T$H8b;stmbMeE zSqawu`X^lmeh=X;hX4|Q1kAGT=riUv3_5lW%DU$^&A0k0bJB!y8IK1# z1_ML0(Kp6rgN0*Di`!w^OT%7&vp0oNhHeM^6cBNPLjv*IBmxL`IT!;c&%}P??txX| zeXTARJoD@ezQ#L`8GTsh8SsGbsfGZ9SeS;>ueh5q<%Vp_7G6;~;5-=NswTvN07%AP zkU*yaQ!!-POXxNF21qLy|A?7!*WC~JCeN}=95FV(@R()_d2d@p`wGK!d$hCO3jh$S z^LK8hYS1}x(#S^AkVFe2k!hmah|4f+`m5-A;DsPjShbE!nES$f?A=@Io4gStya(15 zwkHtv6U@}pyM$nv$J&7#+u@tMP~~uhs)oi1l5T;T6DjSzEbD?k$NUmQrq4yV+rhr+ z0>lI6Us~YL^aOwc*WSGKKJi*vR4D-JQ9$dtBUi2w;M&^(_Ag+pyyy5haS~ls%GxwP zmf?N4`vDj-<7spsd8u#u0Kn^SEcH#6*BR+TYDh8wBJ?)^c%M!4(@~?wzgq3_PcDE+ zk1=slP@p6KKpDlTvz!btEx*? zi(^H)skQ*?wrkw^jSQB6(w=&T<7;z9MenBmPP48oW7pPvv?c%{C3=kgkuN&Au0qXT zf6BUaswi)9tT*DDhK$N^MNa+>n(0EKr6sBun0eyP z3+n6ZeUTFmhg%%uTsBWBU=S1!Z?%p$G>jfWSDbIsaB|gv(q4)8NuNZRK5sOf9ARbh zcQU-FxqfNKjc_O5)Cw|YCl?EpPf|}NXc*mu0sCFg6N&jSIC*NCrAhA|(w}mY{^q%} z-q)solhPxbeu?9;n$LXGt5cTZUil&#jkbMKMtG+WgJ6)oL`dPj=~;@GCnytfn)xAy z$34ul!HMo@)4xgiU~L?)Ui)m8R`Nq65b!M@g&IIf?lQrkmK|t-$mCZv zw?an5->E6P=F^<~n~WAQjXbgHjrjWAzx$%o@B@eXA_oAfcQ+fg7O5OFgE|QSW>H#8 zqK)ng0x-*afP{Z))$d%{YJ2GpeKu#>*|!~^KJ_DLH|C2@M;~>#FLD52`;IT0yf5OA z$PmofTC}CqY)^ml^(iS}bsFSbv-`F!&B?z(Gx8*L+`H*DeDcr?#H#&EU_5TJf4Tje zn-wrGMp4oDQU7Pb5HSO zjOsPdF4u^5&<^CAhwS;!+@#V6+TlhCged@NqkM$3qjm>ke35+}d@E?QDm!+)HxmtCe$<3G zcI|d-o^uV>KXf+gK7ZfW_L^hZupzkms>^+qnO=l5mq2=dwh{#-)DBbFTZBms9}7}z zisnYQwH}rBzH;bEzBbLQu=&~lfO2Y~brd_^yc_H8or>z!a}o65Hxh~9!3XX_C=~Kl z?kle@PJ7q(J@jXhl^}$>&J@v445baFAvOXiO3k4N^+{_5M43uj#ny)6GpPxE3=vf;DYX5GedS$|?)23qS8!zFWTQ0#9f4v>OdU=oL%@u|rard3Kk z_%8d2S@uX9)UOjR5|K5g$3+8036*Qp# zet32M)41%?3w_^D?5HEhV$mzl;X5ZB>#N)(=D+-!r!6!K?dBK+0bLW84Rb?g6oOcR zpxy^~W1HV@UA5fKYHRT_!}?UOaaSUr^kd63@sl54hPU6Gj|(q2yH#?8!(sgH_Fv+~ zxliDzBgf|4MmF@{uOI$&*KaZJxyJ+DdFSpw|E1-@HhKX+hVKbU8wu)tVgZ)?Z5r>b)i*ujA(q-@9 z;eR|Hui}woF-;)^CX7D{=bv{bW=ucT*IDLFSp3G)jMd3no7nZM5P7_Wr>Kr`ycVTl zkdyr6DO-o81U{TkE?#C^hstui?{PoJ-VLupJDG24zGdyQVf?rwFn-(-h(@D$`<<0o z{?1B#^2tVQ-S#=^>l@%W4$8{P(5H7#3>h*QV@8d{F~=N*?%lc;)NZa|X8h{czsvGz z_Iu}Fj5Na(v8R&n43Wy}p?Lso0D)|KlT=^ZdmtlKtt=-XBcZISzUV#aDr|rCw@u_0 zT39n1!r?F`PaKcQ6aB5}Qz#yv^-RVJt=w9zCVwk#+5&1`((5%Gq~ghT5}}USJAslz z`b@ey3a|ta+q)TMzXD0RG?gH)B`x=tJb<9Q#8b20^fMhfr=T#Tz?j!j74U z#VmGgbBWgp#dIV${z!)z?gZu7s9y6-#(=ICqp&nWX}2Clw^>c3#HM+TPsHpV1c)!?DdJv6#h4-lVpBirYD^RAensY#!-*t{4%t z>p(~Y15W(|x*l?RMu!=MRQJZLuxrKR*zv}n;nX%(_KHLzc=^SraPUC~`m19*#p*Td zFm>A5CEH>FNM>O;%LUt0!BmsHchWSw#dqLk3GK=l!#I>A`BJW{>Cllt2`6{o=4GfD za5${WzAfi{65UqKhK2Za)=#i|)zi>+)B4S>>tfO3C75x>cfT?Fq-Mj{yLRKub1ueL zU+?ntecy)fM9?l~Ye&pcY&7oLoWA8Hm_P!jXlcySEb`v+G83}>01^^iN1csshs{8w z_dx(_#P)1K?WfDId(|^&*wOZ$so!pS**g3hd@%@ubUi8O9B6tWy-TECy_#2c&~Q2O zwn6~iSO7S7@&r8g&j-Gdo9>=>(T}kB^(CIZ@8=GN@$C(qg>ne=Dhf;5X{)8ww(izaS8_V%NUcaR|-%LY0;KXZRAAiIA-G zE66I>-JA=-;bTYP(SJNpv>D-`@YUD5aN+ka$Ga=u_w@Z>t~Ei&R5?H`Qeb6eWdw%d zHhGzbs~{jW8s`C?)2pw;9e3UXw}8Dng0S!m36o+EO0pkiG|R_Iyktez z5+eeF^g7M*VulD8G2GS{towL99)0X7bno5`hm06rlyu*GptZ)Mk3EI&UwS20zV|_? z)oFpG5iv#VQb1&_IoJw;0D`UtixC=fWc#}OxuL$H0rOsb84F)~1O58;!Qeb&go482 zHweq|B<_~!?(bXoSTD%%r6qOK2sRtt7hpFX`>6+!?UHg0rO=+{I7r7r5~ z2L=xsfOF28j&shQj=_Tl1lrc8pKZYtv!20|v!BJMpKS@WEq_2@)-Yx4CX?LXw7Jfo zT1?G$0s-1}%3?b7v9!we1N&2&wmpD|aQN6!IBDt>9Dm$I95P}!q%150L@9-jR~sRh7H{x{rdGmd081cb*@0?PMsixfaAER*}E6JcUNQU*3Yqi z<0fp_un8MBe2NwCtwNp0l5?d7gCK>fhpWEp+Q!0M!a%61YEavPnP3<;V3@BcHm3w# z)z!~+96z9xhU+?D2BZ`aLPAK9($H^xr66eLVpXb3Au(zAGP%xF+X*3;*sz=kl!m^- z5^pdl)A~oz;cuv~hxXxr3PSStl%m%o@Fs2Ri2!mgPm)&@I)S%KvaieYYo5T|cBp1D zeAd5wr`!>5)8BR(D2e5XLqL*!9f9+zZIc%h7zEdrbD`BE@!+uF9)F@lXlz>~DnVD5 z?6UlBJ3hBt?BA0J^waJmt}W;08xx;z7Y5b@%d!nEuu&mAAn2c)tA9}}zbUA8O6B*( zYyCvG2#q1OZMh`!Gk^K_Me$&F*Ns+R%~~PoM8u>OYI8W5NGS@cJ4?y+T+OW&*<2b+ z3J_Q;xY6pXNx=1@f(++b6`lytS^x;IBNDqwij#{$qFhp^lieQRcSK&JtU#Q0Duwk) zWG^Uv6>;cc&EC?n^Cl1wAJzjVBX}T@~gn;0N-;tu&+4El56h|su?kYt&&G}?P;p1@#JXq=eQIMmte8FiGgC$*}i8ou%jyjGs-ZITf zxUQ9$&G&w-3bH`VfKnz5qjP*h!Bs2RQB%RCAra6xV#{R`GH9fN+^JEwl7Ij(>e*3K z;i?s2z%V*PDYM}2-%nn$W&UEq%9L)|Ay>r79IM;;q3bkEAYtUcl}{cBJ}!gATGy@}2UUN6dm&La zP^!L6#t)k~#O)IaOQ`DackSA7AklV-lL8SufdCN6I>G7+D0K~>JLbe+J4gJQYCx%L z1gk5EWL;a|@dHI65Ri=CGwyU_wP&%aTUY4z1>d3(BqUhXt#f0wXAz7$i}`#OjX(eZ z0vMQWP;@M5HLEd2_FH&EA_PsVSq4SNGBCT?m$SG8N`k4L70!i@T?lP&PiEWJ_;l!ib+!dZ16Wmg?dtY0G1fJi3re~Zi@Ku8d25bKxNRYwEv zqowrhOGh982@||kK%FevKE;jJZ)Mi_mPDBl&lq*1^;;#|rwFK%0oq#XYgJ+bB|rd} z=IPkp@dh>A1YjSK3I+R@M%p#lXHdgUI<|K_nC7*YOVd6GlmH2_jljP#gfmQ%`zS$w z#s9L7HYFBC^jDJHM-AZ&Bk*rXh;60TEFJBNKtSS&W8Oi~7aHVDl%#GaQfW`(HDH;et(T5>o*D^x51#21-})F4oaW| zh(IK^fq5G%doiQzCQG>GvHI$t!Rj_f3SqIb$AJtacX1&h0al49O8;(Je5Kxi)(U`* zuWsrXgfN#Wt!>!5R))&D{640rj+I>lW>9jks}78gO`vqdmqTg*t^xG5%mhQYh&Ajw z8=)Qt3pOAS9Ttn$pDxWvg)|~aPFgaMR-l^`$8?j#LxM>Aj1!gx0OCY&ofwo`9Sw)d zp3)rJprL@+t~H_Z?oYZ(qOqn@Vj1Eaf^QCinjr0|Ch=rE%oZTTVAtJyy9}s<6BPA{0*ES zKE?~;YK|9Iyj+Z&GiQ&i&!qOlIMI+ah&)X&59d+{wQ!l1XvH*VPN^N@^9KB z0nJA;oAIcd#h;VS;lFu70uOF~AP(fYI6n9q&j+94x!}rxKe~vn=I7SOT9Ukf1hwx@ z>_w|K&?ZLw((yj8?;f8RS;sKqCO0K);S@k3c=HhgUfm3bVDM>JBz0#1N`J3zhHM>F zG(KNu^WiLL_?7$}H|^g-GyY9}Uu2!YiuZ)Y*ztmt5cl1oJ!l=)dBOg1xt{T{QiBw% zT_6bl7ks`5P_zhc#)p7}5f~YzhOB_1K!E?I$@kh+bs*J}uF1VRt zfQ3F((n|e*O;vK?oz=8&Q%r7H6J(@0Lx#`V2T~>1=+P4o2#0C{ez9hz;FZ?8DO62t zacJ^kk#(R*IqItTjW=#dlSsP9nZZ{SCe6M=NmYev4nYF1C$!c}`DaGNSYT9B;(&bw zlw%Orv^03V@+BTm+>0l{zBc+mT9Vbvx9t#O(A(bc%B#L-~ zd=OB*y)N>hOKQC}4f{xNxDFmaN%VW=YgjJ)0nLWCDRvFI%&cIPHk95z;UyDbq>@0$ zK2EZbQc{t}8-G6y7L^B+qyZGosy89~Sc(g7<5>R(Awjxka@QgIJh(#ZiYso~k9LQc zSfqX?LkHHPm!i7cf}8=zC~4C6i<$jl9~?@5gUwV^k!}7sYw2VSlM0f$RSBDhsTw^v z)-9}!hZ<(`gMG|>|L>!HflB>~h8hOc*0df)QGv&Kj~buRt12^a@>P>mvdSq04rLRd zLQoakW-2ZX60N~RR2%OJ16A#PyuPM&20zHZ&pslncjBBuKCg7Un+kl+pfusUQ3E(s zL2#TwLluxXR6%fLOI1b{luEMU|BJ$utJ-+kAd%7@97X#+3-OWL7X0L)LEl+$hK(3~ zppT3827+}TR#5@qgjg0Fq0-CH^I7 zb`pycobkQX(lB!5w-%gmRct_AY}hoEIvW%t*&9{$x?sHNyGr6vCUKj>63H4adtg>b zt?@>+mIjGtBf!x94e`2R)Ak?e{&q#PyV}Qk1va!;@Wz1VG!dL5E$CeYkDZ%OJKoO0 zDq9-yS$jxPYaXJ~A|ME1U^#JdM|;xyt$-&IsC9d|&>ajH-mZLNa#U8i;5fH+WQP)` zP_WQWK(esQPnTlg>!cB*fy8RkNO?Xcu$|`vcLaSA_g)Q;z{{R^wE1b838I&keuIUi zPHD#oWq+#s+mhDksJx+jPszIjxr+skqXmWqu?(tI}jO>yi!k34Hjq5#y)T z?eXBe^~#s~O`LF49nJXPCSp|$4n_;O#^v7#X8`3Kz}kpL+k`d0Z-O(EJQath6o5+i%=!l+=c>&TM1wk0H>>4< z(@Y4^6Mik(KDvF+G?;~uhi3iH;EV6$yt@LP3cAK+8o9f}&@KrgRAP)U2MEHF*dS^TzxnpQ!$L! zcq$oGbSicFLo$`CKFuLwGZ4w(6=aa5#%a4p`ZNw5>E`?!XeI5Gz!P4oLN!`s=>oUQx6vOg4+`j8caC~FUq^D`PDiiGQy$<0IiKeJI3!%sV| ze-ibh;raorH+*{)8z|y+?LK%c4PhNPl!c@y)TM*T*=%M@nUim|{Y!RRN;aDy6*sEo z55SGlh-O2iGF0uRK_srArAd%JK%CkKh~#yX#CEckpL?<`WHQgiTS&f=Kq}Q} zw_y({Hc=EPD)d=h{m2;)e6YH5hpvOGyi7GCKCYA(XW)@{x$3fAuVp3yJhI_}FG4k^!RfXSl6hh2~gmP?o6!RFdSL<*@Np5WsiUzDj_ z8BXKSnVe73vfXsjXBT)}#j7Rc;^1VYLbkq&6flP678udi11Fub0Per~nbP$v?pP=l>MOjGGMc+M!B_Bin3B*V-i)B-_$Rs-TOXQ!=D^ zWt_63P}kTtvm)@!o_?%I^ZvDJ3%A{&x@4173Nt&$OkGKaGGR9-fiGAOQxBUBS6_V{ z-tcGOUmtFQzP>&iz*qrf{GPzH<%=!w!V53Lk|oPv%G8}(JPBxQx-g}^&=V>A@YH>;autBKJ$xWX=hov*jj=)u|2$jIv79xP z`@si@e)$rb4{viKeQdpHKDTVw#C|Cj<~Ic=Yv+*HJpSNmaQp4Qf`5Osx!}$1UyzLJ ztFOON?5)XDW-7&%$|qka2cmM$&T^zsPN;%rLfZoV_$56(Q=Gf?a-=5U@rGYl>$sw} zye=p8OvQQ-ni-gu@Mz$W_>>Bg1egBw3fQ>uU#Ld<3aXjn5~NhsX1$2bwF#mA+2X6z zAfC=XqBFf4OM$3ViEnNT5s%C(NUz7G`ha7ALcZ8cMvyX}=whCi-HJ*o^VK@Q#T1fA zX7C6qJVb2`8QKL8Kk{f%Nl-d0m4)iRpZWu|cZ@XzDxE`Ay7^#$k2eNSmDmtM6b{!p z^T;OD%^l$NNoy73(}wgZYVh(|L(Q}mouGCtB~6qlPr8YBr097S?a^|PJTaiq!#V=( zi@(0~N{)dHy8#~i5cQ$g_K$!36HfU4sY?7Pt%_-0DnSxSWf;}kWAzeU^T@ou=-S?S zbL}Udc|FlNN?SFdxb(57w$c|QJvtz)#YaNG3B*_nt0M;xAjT8K#}bf2$~FT@eUniQ zo~ZIB&phi#@bSl=C~oxb2gf-`pMU;2Tz2UdY9NnKHz{`xQTazgdRs_^sG9Z@!+(w~ zc-rW(17fkpHMG(ZHC9mi*s8C}bW2quy~1#BwFZ<~)@IA%y zAfo#nqO2{HFNGoyjW(}oi6x3lAwL)Htfs|Hm61N#fS%IEmPj2g2!hWG2OoMX95#Ok zjGdE$uGuL_&fW>#$MiwZydBUx_ibpKa6JU%HhgSA1t~p`LQ$(Rb)(w4_>x8N>8GFW zCGZr7==0D21LvK8Dalzjc&b!hoT##e1_mQs=hdbUjjO4^CcjwUS-8TY>)8Dx;hKwC zPk1NmiJ7?W4!tgYS9WcN1Sjw?`RM%9z~;t*}w@+F*g)_KZ-u5na?!;pdS^ITcX6Vw)q1u^G+57YeDHB~>Wo~L=aml-5ruwe>$x1pAHM@S5S%u$ z5u&!E2}HONppIh^qPYM`gsA%jfJ4pzm~#3*p?=6r5CiqV3uq^C0XXc4xoGozx)*|D z4Iq}H!YK%^+G1LGYA9=hcI>h>r)$f%Wcs{gQiQ?+* zA6|k|x?<#}Ab0~!(0$|!kRY(k&cdT?gr^OqPdmcXf$$`Vg!(=}*L;A{ry@u{{2F>@ zKLqiH$er{oXB(K{?@uT-hxr1C#t9Wf_5DpN+G*#jSIzv(rS$3rOiH1 z*g7&D_Qw}6s3w?nW}YQLcJh&P(hu-?!*z$iq*MA7c-l?iX+!DLhVZl_JRQfY03{Ki zZGt=Q`lEILx_bkHl>^D*+0di>%X6#2C&mq`%!w4Di$Fvd2rT9r z(`0N_BwWA1y1tzYzMzgvia9c#=>n(d88@5_LMS!?#-Up3&{UQJPFnIHJnb4h?Fddg z`8|XuK>#`tzn+*<0GfQ(J5U$zgbUEneCy4(VaJXgW!%_Zag0lY7okwWJ7 zkll!Ler}Z|Y#Apgsz@MOX`v^-U@m<;A<-wM2eZX&OCR&j73rv^5g;)%9y*DNI!3j3 z+Kv|70LzxmM2*KAsuU8?p{b2G=BIgtJks%MeY=`0Pg!>FDqcpT z2Z+%CBI3^*9H+vg2WPIiEKovH20jjWL9ss{s2Oec~rP|?D@Wo*4m`U*4hac+~ z*+En#ajoBZ=RJ7$y$|5?|7?LBw$x{-AeobJoEZ}LMpM{3( zj+0W*b!s0>J%1C_51j%YPY`$|{W9IkO;&@H2tTG;&WkIPi0#Ua|Z zeFw}x=?pcRFBk*0<(=BgMKT_2j@m2@~hN2r8%9PO<=SUb&vdQnX4o$+%H{1r_ ze6zLS?fmk~FJbwzn_=kiF1#=`+N2=$5Sj7lYyQor4W`pDJg7=rTN7~2l}q72|M{W< z5Sbsmo_)>**|?f6L%|4<)%-KrUKv!b8uMh;7?DENbZ}FB-LPZ^AZ9Q>mtq22Sku%E zxhTDk07^?8Jv=Aoz;kMPr(pa!DHwa)1Hf|uWwv`>V!9{W=9bBspiDCXnACeHsPq^Y!GvR!dnuWQ&?~i|a z0g|1)2v10XNesjn5q4YwpD>W+{43LiWrgh@2lKV80Me^0Jv<0b2SSrL4dFSB zd`-dVvr;hTu<8 zA;qp@azAyZskKrOcy(h3*a$SYbifPGudb*nBOcjpxBptn^=3@fn3H)Qc3K(hQ#`a> zbA*WF!Ykua(?C}wD6yO;_!J|^nNISB0J5sf%Cq9l01A)If@1~G>FQ3LiR$az6m(3# z0dI0dJ;^s!t%U}Xs9T+WDB+t9!idAph1n}Ug|TNp3gO04%Fih@&gpdSk*83Vgq&Yy zWYwctOU626!gM7BP)RAYX3amLr8SwCBc5waR~jHX-3=eF8P7+aibq>m7hCP|GqnFT zqu!SaB(@ie4HX86xab`kIPIvi+BJAOh}0qQoPitR={lRw8RQGJ2+NCWy?0{jONBwodfN zx1~jYCVs;gZ;ox=SFi{`C#kkhhXzkOfd|3qP{2`lVnGT3_2}8*9!2&tfN?8!Lhm)}q3eVd;1gr`{zY&r8Ij>UNn-_( zY3md|4UyW!=_fzA+`=9z&6r+t%`)Yh8YB=en*@NZyeo$Q>FgjPiM(RXHd$`0bM3$1 zpe9Z$FCm0c1zWJ$8AhuID3TA*DOr_8cDn{og21yt+doA62feR@&sht+5Jz}Ix>%2c z9)rAQXtF^Ve(1$8e%UtYx*m=5W$Nx;4loM$=oJ9Hw*VY+)jFsjHAkr=RnlpBRjpCF zL@SCngGesY)KZ3q<^=rxwY6r2(Ir9j?6c1S!-XxnibzFNlU+C7+zz6Zgg*SY=x=Zd zLU=OCOI9i&3<>mwTfNZ^0V4K*7#W*|=d`Tk=}@E&f^!yu2lqmB-7iQ%&)mC73V}|2 zIRl8+qSRub5xOt@AL!P=Ns^7=bRsxixVvvah;9NHdn>@iJNlsWyx&1=^fADA$>aT6 zj&{T_YTObakFk|pdhjSldBqXCWSI z>2(blaL_!Gw3L1!l;urwI73teh%o>(2HMl$=-}x{gG2V&cvDgO9CA?#!tq0t6j-H| zN>TM?@_NZ!QC0-GZ5oVSfzoHW1`vKtAUH_`CwU|O4B_d%8Ku!mfF6Ws%pIscZ$U%* z@;`ysAIEDVD(NV+9wJjIBpY+VGyMovRhmfl!iJ3>=2p`?14#Qeh2B_udykfDF6Tt0 ziY*ZlTNX5trKoNOm@W)(W6AG;nnABnUhUaU(pP2+yb=0UWz@ zC%TIbst3kP4y8|eM5@oaDLc?nHP-oeyx__1p2HH>d`*O@OEz z`-jw-1;s`*l($1CLer@SM<;obx2o_Y5uW5Kb$9*>K|%@CeK#8P_w+&UO>6Nzc$KbY zM11R|kafUScap93UW~_w!Pf2DE0S>bt5tVp@0-5oW6^ZgV$HjX0VFGC1;>fYT^u9a zz~-L)@OEc`I+Q>X0+fd5Y!#jkgeO7ZL2#1i;XWVTYc!x|Uhxs|TwIMnmjIB`L<#|l zHuu7)8+Jk`v31PgxlIQTN}eQwlSIkWiSTsYjR5@yfxZ_F`iE1{cFvtjS_h*5Bo_cE zH=ib3$3_}By}y1#MF9G*$DTkHFB#l;nlCJYY#&8gx$^q5XV$me#c=+|*dk3P?afrT z2~Zjw4W15!Cy{{%ZydtY{gV_-T<{D66fO~Px^L_=mpr%SNFEKIB*K$K za5`~!--`g71!8BilX>Ph3p?QfV3Nrf5#^yKxue> zq{7pI@FWnPqyi6ablAqEP#&WS zqY8M;<}SPq>7F*!wJ5)f<$|v=9;XJh6E{8wAU!x5JP8CRN#OYj?u*ghxU>&?PJ9S& zlwXTNNAg_bf&gi6j--H$Jn91Iz6AloO^oGEgr~C@Jol;abR#(358y_4#yo-$-Mm)m z+{LC}kL^Ko(afe;37+}mUn&C7i>qH$2kYt*?9%|zwrm|IJ-)N|HQm6AWrHuec*c7} zI^}_~72S2}#^(T}lRAkDRCp2yPVyomeemlg==C5#Q-Agmx{1V-3S=5o7B*UQB#@Gd z8h~i~p)l(9od!3((+Zw@P2j;j>S2KKsCC9&`6QWwoUPBY0kr`h@;w6h=3DPpbc8*CGlt9i8QO#|jbjBuWlp!p4 z`GxRuCa2M2W!-okKv4up2ad8YCQ^rhgZrm=124myhI8Jak$R{0I z51ls0qVTMQ6Zs|AsQ`Io13*^C6I7W1(RzUJ?|KB3K>T2SA#2ua*~Snw$2JfFC=Jg= zDm)2e7f}$#{qkk#zAFV?x)@KV22WQG zJc`tL5Wzus#ypaO!=Bs<-KQ=AFCSK=k6^!3tzP;NfJis|JMO%vVgQ|T(wUm1jpls# zC0jLov<>ge93VBaKJXxVp=;0pVV)i!ink|$N(Lwmjs{Nx;YlJm$whcW5uUD};f?%x z3JzY9f}osKQYsjwH;_$$cpX5bOq=t8oR|sY?%AG^JPJ4@#$#~RQFT6m>I(Nb1ZU!- zTj8)(Z$k6vqrpRqO2E!EC%dThkv02Af||PFT6SWpZ1qLz=0}g3fY(*h6+&1`Aj)=K zd?A3M27nIyUe!F8FvvTZv6$gtr=-X7MOXmTp#vv@QYWFolSFtr5uVN~@P__^WDBOC z{n(`lf?sjv^`*Ra0HXPHnRXC@(N^eL{!b;UOrpy~>W~0ow+0W{qYj_>&M^^G%6B|OIO00q-+#!L9CNLcrE6ia5{XUl>DU1PAc2-#TO8f8#PsJtfZlA z0A%kJKKHstjX_awaI)+Fx?D~ASb`mZXgj$inS3A}Krsa9QX@PGgeQUEBvEZ85uVPU z;|)fDMk7GIm%R==Q5gtOx+22*05eBQY5*xx2q9`aWhwOBzf-k&?#qJHeP17pd9V+9 zAMJygk8Oe4-V;HL369N1BxKWVMH*)wl%v>g%Py zzO0S%&M(C(bX-yRXT?3rY(ZxXT-E+2SHK@_@Q5{rB=SN48S{h-Owq9dNDqz%PeOwy ziSTs(0s*=TRmwH!Hedb@h`}b+26AFZ8xrdyiXkpHcf+__-c^nzx^R=PJ@@T|@elXG zr29XGi9df5VQmDC396%=NMk3#X!B48cqEHd+U&7Hx(ud@3BmVII1RRK-(Inl)*Dyc zs+`2LLNu=s!s$#kJ5gxb;KGwKs2B)=`UV&8lO>7|t~coP0yoJ@@|c%4n*fxC=khE( z2?QsB;3Tg^fDoRpt5K!=5>?7opFmyrOeG>s=h#672dU|9WIDN><$^G5`WZ0s!EMls z5@$TBtH}?10b?)wJv59y2JM`PDy;;a)Dd#P;jN|wS&UmCs*4RnSI-1^=iT=zTH15M z_kUo~Nky{N0E2RPjFD|_s=hZjC%?;h;$fFhjIa#re~QVu`Gs>`Y_v+V0w@hm4m=5j zCyDSR5uQ$zKHX?Uk6pGCMjU;m($+35f%HXm`KhG&19FLdK$>w9BiQ5iLfgD6;mAjK zz>Iq~LhbNLN;xxW6~pn`>`)<^FLC(dlMwUai76&QUBgIt`ERdQv^H%0`i(HMqepY6 z%_@nVjV-tB!e;`a#0H8z5wC4yUA5uZK%NV%R7G>dmLYA+nC5dnp#-2f0+a^l3LQKM zP6EM6AUMfiB0x(JprxQxP>ek3S0ISw@gcPdd7d{W6_{&Epopnu%Lt%9R1foyTL4!r zz5yDf8lWgnIk07Q%^Iw_;TIe5k`GTzY1ez>O}D{L({?bWMW2Zcb??0oC;exp?HmSA(C@pnN;7K4nNra~p;pw^- z)!4E=IOOIpA<{BVN$XIg5HA&LJPLJ< zBcPg$wA5M}Gx~8+rlY=Xz~fQpb&z3p%T}x`BkF7p5NQT++8GNKJIx?{OjN70CgXNI zu(bM;NLtFGj{RKfSj?J+VVBTeIb$I9CqV58PKTzl4DcX02?QsJ;B;OGO8LzwQvA0v z1)V1^!x!w;dPPeHh|K1MsU7S|qk{<4)(wX{@4Q>-`=jrxNN&wv|N07aB*(%aCY(PC zv*4`wXy$?%VAcNSi1sn?-19HN4$F}Xr8if2|NRf3r8S{eh??~AcG@S}miNW$3~0Qz z)%blVI^>dUgP{GYl7lGUrd*Xkl`#*@5+H=9<0@--lGm$cH(jJ|YXy2rH>F_e?O%Y8 zjNH_`u}qW6bRncp0;KbGBhevn`soYdlg*zLY_zgr!-sJ856_2KO{*>yMAFKWqZyzW z-fWt4R&tTwjn)iL^|MY(&@_n%gqKT4jh*HUfy0U4VF_6e2uS z(cyK6AAT}r=u#G|8}hn4{pl{M#%w^82T(`_2;u4Yr4gP)4m|0qi7ryFg%W7=Eh!kY z^bH8bhoRA{joj7>AsKDpN;RsEHdGzI|J@VtpU?l}yn`X$crvSE{rU~cbi>0Bp95l` zMrjX2I+D4WAXGB}a4Vz0gDByeVAj#c-lY3|4-HNRZPH8*Hk=cR~(@9Q3ff)72`b$JRNDNlPh^v7)x$C zZ$^k#qAheQ!1z@uX#c^j=+Z}&voU4vDETDfo2qZ>fQv6$1YdpmHB@Yo;kjG3z?*Np z0e|}Av+y87_0YqQ!L!e)03!BFpmq!-uG2}K>nz~8S>2roPuDFdg%F_8 zcc2uyvTQi-{3YAusHtJHgm6D>^ znM?@6H6yJ@9msV}LmAzKz}$8wj-(KuGY8cZgg|sSj9$D>X>y>KJe``s+@;w(X?VJC zO~I(!(TKh?1rzVQb0jq>jPt^~wdTdEa@FJa1?_71S zHr9J@95|OM&@q1pEV*{M@*Y`ldGOF>MxQCg{)s8}5ATUD=1;g||AJEsW3h%A)okE% z=Kz^>am{Hpr<`S>EySS&Nt}8c^sd?pV{QlNxlQfM(}PfrU)2YP-MbS;pZ|LpIu$(+ z7GJp1;x4QucuASbF$AQWZo1t@z;N$@XXlQc${8AgM~QI>#R7(Mi9>enWgn)4ht+iO zb161-M$wt6ak*xI;Ek-Ic;gIByAYYCb@2MGU1}Uh5W*lgjfdXze+x&Tq&fV)?Qq21 zU%`Y69tWv;0{Hy(2##7C&nk&s5p8l`Ix?(2uSbyJswASwEv=da@0r&ZTN7;_WpDI1?+u?^MfnZA2AxSE*`#}^l$k`#Xf^L7)s&+} z@URm2d<`J5QQ)cr;K}^I3J#q!Co2~s(vkkEtCqqSUu@}TW4HgNAd=ayx7@l)IWW#l zOD=L$QTlXdn@1PgzrR=I1-HNMWZQG&Pr2ra0h|yrwEcA=g=o{+@sg<|VlwI}tjv*T zGCiRsV+CkVa+jeWvoen?1ZSMS5Z-_90~@z%&w^*;#(%;2KfVOqY%tT;+N$p&RifeS z%=XDjA-9%S{?yAbz~yAsHw>LmVnRwzFfWyC3t4t|*R`T6RIi5zshpTJ zVLGgPfV6hWbhi3$($=@m4fGa=y#y5A!~H$s~^VT6Y=IUwC7l1C?f(m7VNHwp(;c{U91>>c7N zXNh9uNo5pfiBhOi7s9e#ZH`@)Kk`YbBSOtqDo5t33O%I~3J zf6X<^prNr{ZBXUO1t-UAb#%?-($Bgqqz~ytKN#)bK(O{nSGjBQlxZUA)tvTdQ7ES9H@GILxy(3nP;90ci(j{tXZ>8i651VQYx=*D+M2Xuo3RL z=Rr8_2MeKPNKz>sQb(#w+K17k&W^8)yY8$Nve9r><3F;}pSx%3Owm<|RogUVel_jS zj9a33r*6GmQo>WQthz!FnMtGc-zGqbp*m=6Zi8uu9SJLz-wbcO`3`K|zM~|V)alLu z>o;tIyYIdqPCn&K7}+)o0we{4*pONa7Dk(Dm=|#63r!2$HSlEmIFhN0=y}EJTjske zwcMVFw~F?^sAK^OQVFW8gq-Sfc7bu2nH!~5o>EF0Z&>MjSX(;;rXG5vk~+F-)oc5|XWy@|viM9}W#vX!3aZCwn zlHo4u?A5G2W~Q!;&VpR*U*Cm9yC(^Qa1GCj$ICMmeA;)O&ZBsD-i8sm*kZ4j?*RYquf#i-hU zh^Qt7n2;uI@}VgVj#RKGv$I_1Qth5>DfU5b?`P4PmKi8i_j6Tpg`=$lf{~gv#2{t8 zl5u8484&dsNS2cf3k(!74$+l#(}p6Mij3?|j{}$Tjdn9|^u>x!Dh zY9@?ow`NUqch3Q?{#Xxwh0=`@KTMx#nMJ6n5&)w61)yRhF-!d9+E&rI;1uiEY#*Sq zUw4l5A^Aq6dm2sqKYZ$$-wks0=aOrOPF4n>c+2(5`rjrh8kgb=9I;r8&@QBM48wX& zpwU0J@N<^dN!2ktTB(jAfw&;V8(Js3`g`>rdGtW9Kemz(%X*^~vWNQDur4;OhB9dl zLz!-~hBmr!8Z&ehs;l`mlcr43QvyeBDwD*AunFrJkzy1Rv^+cn^merNzzxuRFzSC zfLB)B0CiRxTxydhr-z~yGwO3&-w0~JklZ^l)G*t%yVk@ha|d{R(JQLi;C9uumnsHP zB@SVWeX^;N>Z{}u;MoPo5f1Dg63eTi{o8p@=!(v9lLokU=Nj5LT&$}0K2Nd19D8Wb zl0=2oLh&(HPNj}Bi6c8NyD0&lwDduEpo;Q6KO~tHU3j7}oX% z#z;kbWB2Fl?H_p5)_Wva7>YE25QzC*d(w)?Em6@I`-rVLME#W#B9&kRuGpMS9`BF`jHrGj=J{5)m%S(9M6U}6W5TfxFp&Ir}?(s=;8xRs1l6vN=KNp9#>2q z56%QP$Ld$-LZ!c9GqDtCFc6$su zm0Xo^(XCXL3J>RvDZPAR(H00q8ltYfc?B5JPgilP-E3e7=hbBf@=`xZBXj$RE}**T zA`^&;&zF!2f?T0F}Zhu>)X0o z;zMTARl*vgqm@Iwj7pR9#yM3Mr2K}I#iWXTd!~P~8gtc^p)0?VdmU3}bD*(YMTu*~ zVEs(jcVQh;-z|#%*h*gO2%jmkHLx+#GSgk<`#0$_uSz4yFfqr>!0tbg_Jl3vH#p4!hbH5zJT>5ENJU8C z-_iP!GwZs>4Rn21*Of1RJg6ZyWKC7I_*uFaAe%EW=i3ib0g02DRT|4gm8gIxQT%Qbz(VF%PpLuT+yXzf9yGn!zWl#?6p*!w|}Y^kbrxsBqUBR~`#hH5&n zR;nE`W8BnP2kav!Cwd(gW6jCrx<_m{k<`&yerpP$DA$J$xTllIGEqyR`RX0JrRq+v}a2i$+F@@ zuc~N8;>5{dTc~pTH+aO@lk<)_S=>j4)0ElKhYkq_YnFJt@@EIp0i|}^bO>A#ps3vp zjH#qCKoiwXJw%B^lMz$$XC7~KNisQZ$UYLvSeKpq^8+Hm+W5$kW9E}2@G6ojB1AQ> zO#{jfO#LFI3QupgmNa^BV(NP!DHmwtkY=H+!@B3Qf)qdX#MAcKIh9-+pM7h9HZk5j`I)lBdUjti}2 zxzM%mZ-4>&?sPw|)|#g8)yG?prkUVkh7G<-z^PUy2}ZOao9s;0SxKtgGG!}OWR(e+ z8O52Ntr}I6yHG`Of&$K~yhmPKSJ!%UbK}tO?YpzPc#UZowST}96(fPVp&aF38Vofk zy_N?teq}~0qxHODJ=vYUkw%FlnGA3%7U+{q0ZOY@67W-cHj>$@tfY+Oq?jOtrFt0b z_AT`X8i(>iM4UDC=lk!wlY7vb)iY7#nc$5+G4?vc2iFav{aa|I-%mts1Dt7r7u7YM z(%Q9n(lb3I-2~_SL)mPTDixTFhsep9@tz#7%$L|gvB7m>Ao_Y$6?bE6U2>l%wKuJK zhfJjeE<8sRqn8LmWD&;(SGt+N`YOu5g^Z6>nq88wnNv0rIyn_NO{K`0FlXiz5-VbI z+H%aP4b5o|_q+T4{0HC1$zC!yGPsV;S(^%becmDJXnp%8)Zp4T%tf}(ac2`wg;R|wF=wAP z>3x?k@8x@CWYlg1$r8Gd#F5oa5s(qGZB{&<_(T+9bh-Rf?>i|%KHIso{Ym0C7Potr zGMARhi_8BkEiDHU8FU@-#=Ywf(M^j5dbr}@!lA!^RZ>qIS33@~n5C+)L9V8rOa-4Y zXYT{0osPSMF;Bg6iE!FnN*Iy)KAH1^xt$s7>(g?l|NGc~74rXTAuB3wn3H3y1U3Jp zGOPl2U;-uz&aN3HvpGxD3)VN$$HmJQ)$4QvK; z^8;^P9IGG4d*0@46`Cc*j`C@A_6kK%8Xf54CycPGtHtDE+^~x^hfR0$`T3i`J5neZ ziW|jCyOz&yE)CfBPigETM2Tq&3>)#&gf#H(2++hS41&Tyy0n5K6;r4xRd(n0z(UCJiGXU^cX9h&uZ`V(2EKvr(a zByMnO{irFsF1}B&a0v?T(L~bubK71 zhaws!zqH<4xSzNdYy+~E;t^JFemr|)j=FhrV_W{Y4CJb<|5X@VsFou43h$ z9AJ(>haZ=&ba4@~E7c1g|AY+JPk?ruHcr<*CZWetCpiwCHpr&Fk903QuU^AcFioht zC0Mv|?`zVctpwkF=z+cdJR*-#6>^^qh}gIad%--?D~u3PM?xf+TUm9Qf4N*Ic48|a zM`ni%bLn4lM$glpW0fFEevQYuRZ8wAkcuroY9wn7Ns@xeLr35EIWtJcNY*eEPVmZDKwpMjX~P&q+Z z$UV*XJ_S10R;?1u`Z{Yvhti}mgc|asop{^b&+m{&-qENRY=ZouvC^9t20UljF&o{64${mT{)QtR@1~otZ&!1WP4qDG`_1htcl1ELbKSo?%fyV-+lP>ATPSdI-VJu;eyKlK! zzZ+$qA=|9JEa0%!*&@tDNayn?VG5H?U*=AS>k+d?{7hk~f#@O&CTkFGGFa+K59leC zi>vLZl^{b{CkTL$j@95@>o0?!-fF4IZ2wUAZam(73&Vo<<97uU0~)zE=#_?jq@F{j z9kyxn8wWpOJJ*Jd&k8`!<8`wY-*kFr`**m_{o1x`n>N91T`legJ@ucAndz^aZWqKZ zf}kLhy6cOW%mx_VcsTAXEAU!*`w6Z+-Q8$|YCrzre#iANia7y_iO4#C^{wBr$kL@# zCu6|^6L~6bm$RjNl_!ZV_$S&KWi#Fz=cQz;%}y{QXPR+38fL|FR05ML{)wn?(y)S8 zGL`D!GvJ#JIbuHV@%PEesfu2Rw#mJx65V%r&g1FXiXb#dqj~U2zhjVIB?nD}GHzUI zzOKuS_82zyZvF}3@cUU@r6IE&SW_NFzdhiq#yov&Um;DiXvLrKYA*ZnH2b8%AFCP< zo=A-bXbb;t_^(-Ph^fmwx+x=aZxX1I}r%h&?TfchdazJ3xb6%)(lX$N#g=BX$s+Q97GV;V#pLDQ*b1e7) z*X}qe%5dVgfyb?ZjGs>;+de|PJ-b$|<|J-Khj(Kql`B4vZc0SqvBe7!Iv!xOKBFt@lGqXcNzB&J{@SXjR|W+pQSnxA#=o?E`I0+QJ&kE zqr%a@h%N+alO)@Dd2L9hn$v?fLM{W#D0nz!gsTX+c`l|TN>j%9P(;x)xJ{yo4L$lK zR^wK;!K9X}y{q?!tqYlXecAi5zG0_InQgK>_e|kht&Gdtk?$O$hQkC|tQSa71>S$lnR|6Qm{&x? z9l}wHMIxd>__t)T2EX_!hx>|_j8j$Qp}Ap;-UDUYXMX5<+19psuIkCZ&4Y};Oyscj zQXVl=n4dB(Nc(jlND0}<_8c04SnhFJl5JkjIrE+pZg)ee%s*^*rQzZ3idRKau0vBn zfFM}AOd}zXz8cj1J8qypL&xxoyl_pA4$hrZ=k3xd6&U9Q`mBBJ=<@8I;~M4MvE=zc z%FKM=9h(i7!xH3(`l2i03qSO}zY~gIS8GLx3d&v&LCC}oa9(;bdg_SV`V!QEM= zj`Ul${>$jn$grHZCE*D~U5q7}Gt|7!oTy}}Q#>Og+3=(WE#H5M#oh(Zjrd<+91Gz9CpKawVH{Xw+7 zq4*+8PQY`CPGVi%^4x=@o`S-Ly#m(;HguJb&EUEmR!0L5OYk5}7ubx&0n* zp70beKOXoqqPvkvV(07=>(t$PF{9uu|3)^|9+3UITvY?9m2^1%(e$Jv>oFPK!iGgg8an6(wMc>H z&b|MvE9kVEe97CA=^ZfZ?x+S8*_gmGR=C9ULk!|4C$Gguj9xRL%)DiGa-EQrW}nE* z*cu(rlZ9E&+|FI&mu4qP2Qep>U<}Pm?SLnPBIdaHYOEOlPuq1>`KeD^~a zkNwQsDxUHgM3_>df)}|?x&DiUYqAEeOGd6LkXZELOebV+qS7emC*%8EM4ZpDON8{) zy>`|6E`KIFLcUyi|K9&&yMw^#&Ag+FiESdm2$PldlYE7c!n8b_@Pq?4jiRMftTnEH zJqfdp*6<^R1k z>6lR5*b)`X$X2`sYElEX?k2|S)5DmOYTY39vK0>qi_^ihoh^tN4g?z*`Bv z{jN+nW9;Bf7lbSKX9U*@GIu1HoD{$dK06DK?=s+EFMmhZCd*bSBr2t71lEOC=k#sd zr>qt{6(T5SD_+j`!WcX8!`GBXc*-;9EjbK7)auOe#*JVvky<4ZdrofQ8Vx@>qUaw3 zHBr+6)L)iOE%9ZUVjkX&81U-1V6ccTfpP2B>j^~A| zhF`9YK^`JSQ#Y)*8GBPsi`x$Q1*ybpslglH#Ti=ACzG#RuA=BYZ;84 z6Ek}*!z_P&ToDHaPrrE!Bhua|*DpgIw(m`oR5xQv?&qoUY#0jJI_!ZZ-vz%=(qNQQQ z<^lUSlEtY9DNdT*`Yj7*aLu}`)J4C5lk&}SS~sYgsptTy>HUNWpw~0$2MP{@_K{J? z3m0ac43Cwk#zuN+aGr#3lEO3+*CNWu)li3Pu6NyxRYRgpktsX9U$!@Sx|BzP!BOFn zfI4abb+B@kZ^Z@#P0(xcg{CNnmcZOfd5*+C{&`=%a>=ihc~Eti%gGJY8REh8t0RJI z;(TEti@S!m>eHP=kq__up9H_d#mv0I*+1yM9-QCb ziE;|e*P<22mXNQ>{q*QovvHr}jcYNz?ii*1mEjj{G2_;?-e17+yHf!0tACqNqLDm` zyO_Tt8R_No`<1^dKiqgCxY!}BFH6Z)0|KuMoC*PtDrv3IBH!I5-{PPU z6Mt=634V(=fBo4K0C=|&Rar`J=7%d+=#Q0z+J#kCtpC=$5ZgLRE_FnW6cybk-zB?M zP(Lke6Z;vwozMThYn26fVy!hGJ=kvIVpX-*waqZ!=&168LEHp??KWCrC2N<; z`l{VQ9rH9DS((4_{FT5-sD1--dqTNH>uY?UtU4$>F_sd~>G1I`rBI&|fK ztS!X4a|G><3iqFN$JQiBvzO@GtUqYW-iGC_yz+PYj(-Du$)>5UiD!rJqLHv4Qze~`qUvBFAX+P1CF+nvabTxfDpK1^!sQFFU2 zq4U4`!Ya%pbeM*;j*dtR2k`hlbW^QEx*mNo2sc&k?_91O&?}q%V@+x4;$4Eds;mF6 zPd_a;;ql(`IdC8L<0)0CFOK<0rmrwNg%HBm;s9u+qu ziBkh2@1!mO)_j8RFJMhaQ}4)>bGjJPlEDaPWmx8g=xobAK^jSM%7ejhta0#ns?RH4 zYuvs+lxa!}nn}3i+WXA)pIP0-7&}t`x_Gn?X`R(CAB^Bss1Nt^;Dsv($OZ}1{ua|s z1mNBNUf}rS{Xjx^W0P_QHhNqmGw@F0E_C1MC~ak^%I%^5g!=?n_-1d1zlHA_@}8SU z(_ihkxAk+0NW9EKlxb}p#9DT}Lph1U)Ab1nMAfD70*-$%HHDwWqG#m;*x>F*KYRJ# z;mp@a25ot7@^2sI_D}hf6*$Yaev$IaCIKS@;v0>eksM&T1i^vLRXiA`a08t`uSrU-hitlVlplvm`M<)F+=R3OL zM!HZJAe?9=Q=Pq<00Ss4$%8p9Zprw|guc1_`Xh5R*UYG}zASOfrN~Q&Ooi+|y(Jyo4DfT3mln6T4!1K#c`uB+vAZy9mfneKD z#B!p}Wrew-r+TmXB(lSy+ZQyafy51|F9qBu90=A9*rCH_Yg9D@AfqE-yXV@}x5{4NT8lsQ~kK7esjb?X9gR?76+C#3M_c9eww zts6)O>dc6!1zZO1%qsj(P;tP5%FVL3wEK*wuKn;2|;%d z6e6k);3)p<;&5PrF~7ift040FN6vRKYj!i5T+h$u9R2)Q=jJ-0pSmH}(i&4zY`qg^ zv6{ih0B3}*d0p~j69YOoNIfk6o02&oj_Q@TckWlIl&l*^n!4LI&ne5Lb??jWAWW#V zl>mm7#r`nU{6 zz1GV4Fn3{i%hvZ+iG`8BU`m!=xO48?NDqrhmG%=@n`HEx8eCtcFbxOPRmoty5n%Za z%uY9`#g3=}-NR>Hc_)F48)$)ZVi6Q)EJeCk`=6=T8vk=<9Y4;<;ZU@jxlSpXYnQBZ z4A9n`?)e%;nc2-N;JBs?M5*PtYeC+&RRjA`)Zx~na>5e4{QIbKy)Wx+b5v~w!^&>L zPl!JRuSf1C;0W?&aJLd%A1&BBE=s4Zhm29U0jT6|yK&FGp9XE#-(=i1p7F-TQQc~j zp5V(V#oVve({`+qD2*_Ugs#EUgT)R!;>1}O!JYF#(RQ2S8$^*BW?=+Y;rE{76#ZA& zX|>-aprNY~KI{v;=qgMWtXNR+BLsnR8n3ZpH6fOe$%*`&U&n;TDjrau;Y$4{@pA`aVYW@}qL7tF+aX8!oQvy>stjTy*j@)LaV8vC{~ z;el~~8FfaQFpSYZvu;h9G1wN>uLGga)A$i<1spdp%2*&KUKzOfFRa3KnMzGj13J+c zclBIDU$q8SME&q{y@m>@3Hhq1Z#DCr5F16UtA+2mbyxG!Ji5d~G;W6g{lg91m1m{1 zDmQ_uawkt z0t{{wFgV|>`h~KI2Dclo6A?AszmaJg?^7t}eDhD&b9=_!s#6McM>Vb==UbtFM`m+8&ddUG zEq`9%GHMH?2-1W48P|qjj&j09O?kxN7q9qnP@rF_aVDXsc12#NYnV!zjD{hoek=6m z_X@A-{EhWk=y@SqndipCM~A9%&W#svFCHVrFC9tdVr~!a$m5~h()iOfZRYx=!nB9c{qeY!DU`Ryk`I6fo5&@@gS4k(fWM+2A zhLoxycuK0vOp}lb6e|L>udw&=FF62&d)}Mkv9))a=jF)gh`qQ{5?GI=xqj)2K%YJ^ z2KXGW3pn}KJ@#-h9ea}37@c~*K3>7KS)52S3g`S9?t73mGQEK>h|bhAMW zl0fi@8)zVubNnPWH(CHd+Sy>!G^$fAEI*WoCQQjEGB`;CNOM}Op~y$?LEN0E?Vs=7 z{P{u0G~ehV{>>K0zC{1tiC*}$;wt0sFv0()u*qNF(-T6S4R;!$mu1cu)m3xT1PKh` z!=es@NgLe$*3ROAwtiMv6&5sc94&(qS}%-U?y+32^H@e;Sky!j`8?&qf+=W$HT9FF zV_tVrwYquX+6*QM8Jq2H(fCaGzwLdC6C^5rPyE#Q>m_73E$K8@U7rxU^1?P1BS#~8tD^QD-#%e%3p%z zMUGpk1bp^EuI22!I|526F5vi%-Uvmc$o%m?dj6xCtiZ3U!?PVt6=l?2M&7$y^az^T%a;LR z)GFBjjZBFxIoPct)b&YkddBpxz?VsanY&SMueT!+Rc>rAJ;?9o_C`UZrtksVvG7(Y z6kl1yV=M865JmbL>pdIyi)>Pd0U@OImH_IHwYw zirz@-_~61>N#V=6u6eRGY51`+!<@yRpP|c-K9?wMJ~{4tAWGSYd#I)$mjR*rHnIWC zh;fESN~XQy!B(qQObKdgp71`nEY&(|R3LE}LcHnfn9xn{de9&n+G+oM~T2=Dr_0A=dSr_O!z zY~=joNy$T~E(#YEvMb_2$@}#P? zHS1eFLZV8@^DTPa6<9%#I?thjDmdWGkv1**t9N^|gfl8)q3C}9!dW;ES}HLLV4eLj z&&?){^^*5Rc6bvvG1ZyEpK}%#k9RX*-n-A#|1p1rf)5fFY0GLGQ?H_j0IHA^pdKql z!#<5Z2dEk8`|6cEDC^-k?|W!=TdN%@nq4#Nr|XketqXV2J|9=HMdnQadkmWnmU2<4 zOEc{eaTn2oT(z1I-ch9W0v`2k>WZE}+5iB!6b1k^ft-)QNx@Pg#VfthPMwxdKZAxf z>cyO`4}(f(nqKd3|9!#ia-H?{=k7r46gCjxYz5|A=h|ii0kS!b2t3=6rsJ|^sPQyP zWq7V_!m=;g)aScqg5m5kKOvEDhKuxeIzX1p*L`DN)eb=U`G7#e6atK_g`0J&@Q3Zq zp0U72W~Ou!`m+`9Fy*rEs{;8g&deB~u^UVJ+Jq-K7N?)Z+% z64B8hS|no1q(t~R14~VlHPz#)ulw%%Ug{#D=B2-NtK*ghrGYR$kgj~4Cl!j1jMEW2 zT=48qc}xVQeNwL8C@Mb3WkCHc(*)IN6GF6lLyLrs2GnFL*&AG xyz#!+e+~vkkIDV_?9hKtN&WvgHunCAr}Qt=QI~94D{zPoWNvJ2RDJ~!^FOKF=Y0SG literal 8910 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 z z>ro+VQ0ovDYj4 zw5jZ`0=gsik`$D#YHZsu1@oMFAb@SZ-Ph>3D2{qIy5#*-5TtkJoh?(|rb4esl#p%6 z1wHq?9NkpeVzj?4g`JBJMwcE0RcOdeJY*x*s!9My_+9fA^Ga>V4=-Vy%7(B z4qXituzk4M1!-dFM6QBq8r}wdeJ3;;S{u||P9uq026UXh273G}sjpF_$%@0jw(z{3 zqR24H))fHVH|^TCsIDJgxe^EUh7ueNkAi3|hkqjp5-@HbG{Am67ZdZo@edDt*vR{* zBn(tNZjxN>8oaxO)Hjii9ZtmZtu=t iD*o^K--v+n!e8*g7lsFQ=A2}A>|M67H78#1O8Or_BXWiS diff --git a/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-xxxhdpi/ic_launcher_release.png b/patches/src/main/resources/music/branding/afn_blue/launcher/mipmap-xxxhdpi/ic_launcher_release.png index c72ec992e7a9d62f9ba3016d2886f5fd057b1001..1004a01cb7cb9b0e126acdd2cbeb84c9b8755845 100644 GIT binary patch literal 9310 zcma)CWmjBHvz@`+EkJM$?g<_kU~rcVZh=5>cXxM}03kTRLU8xMFgU?2xVztZ-d}J( z^pSPesjgLBRb9PzMX9OCVPlYE0001Nc`!%=e((NoprOF88p~f%0RRR@dC*5K&)nlY zFHa(whoP<&mw)*T7G%9iG{YOwvfDZgftx@ZHG_|d$TA*458W9;_4{U&i<3WPT z>k@79s5Y+HWrQ-~+T=^o6jT~isxZN(izqLRxk{^SMSvbK74Uw5+gE=1eG#)g0HIEg z{T`45y?h#|_B9JyzCeq^Cj|^Vk^kxY8HhRT4l$G z)o3r%1mg<@3jQ_7M##6a*RsLnB2mTd2{37|bXbqV{rMJhTYW)t(9A88R z*t^o1=Km>TL3j%>LOlEE=60`>CG$Im4Pqpl_*=7aJS_)+6SXmw8KbOPHLzdKEj8$`T%6Vyz-JftAVT!hF%G$0 z9IPt4BJveF?KgoVskXdilsRonRn?G5zH$AxIDNhX*C-V{0Df_x1B1tUl$~64-7V~v#51-jLO+brzh}S-RfYGzYoIk+U7Z+BTk0Kc zgvk7xNbnV{tl=!+vg7!c)Px$z*5zzUwqKAJ!pSATN<07A_DQl{p_gV%Xi0ENli`|4 z!)(81^b|7=DhcJ!cuyG~XDA{}wLCULzI?wyY24Y= zU)e8-kc&z{c!PyAz+vE^YD#jDfytgSmjMj~;&%Ftw`-h@%3!j(##m#S!2RUw4&iPR zyCzo2(}l^-6sSCi7co3rWILQQuZuFkw;t3>s8>cPXJ;s<>A;0LR9pw4XYrs3m5WYT;`#tl|c zL4jWWT>QH3N#)k$R#x3m^lQQ)>dE*XG?coW$ZI;hdFvZEv<|t%48v8$IeH(dzxKT#qV_mZ z&OY?fT2h*s=wq<4jp@ohbVd%qvtl!F0UVChVz?UbL(yq#QC` zk}KG_ClxY#4GM9NK?JPRDw8|&Q`pHcL?lnW-QK=%Dn4JYXC&kE4qYw+^^^MCZb1_y z;{1%M67`8jyo14rn~@BAiw(L-kY5}b!95`;W^NlHnWFm`Ei(86KMIIV@B1npH!aGm zoWZ6@@U-!}qQb0b@)3D{HBbL_dz(SD@ko66LjX=AMCOQ@oxE)&-VNFrYn8tQi0Gru zq0~ScOu9k{?iw#CNgcP}b1o)Us8-5%MPBuCA!OP~(5)(<#)edrWEcyg2oWpwB^AVP z%#=^p57Q2mC8E?AF;zl?Lq9frZCL;pD%L( zf*)X5ly&#JOT*W%d-_7+di&j<91%r(b)vB|MNTPMZ(;E@m1(r$7HNB<42R}fViX^- zvj1(!l&*X-itEyixR&4+Jh2C^k8}3{QghuAi7*HJDesl&(8diDJw$^Wjk9*XO=oJK zD_Zv7TQ`ww^DDny?*=Y@ONTOzXrvI}EPjoPKXd_ts_g3{WW zg71;}|7roS$Yc?9auEEc?!gn;2$}^gCIV58{C>Fkgo2eVXD9c14-soJPn0WZ@Bmpq zY9a3l;)x>3P0gqZ8lz$-!_hb=g)!G~^@>yIlF!ZW!B5#blj-IphYw}yVR z4DIL5q~BouvJga$WqTp}oJU*V8?U;;M|m8 zr-S3uwWNmj9z$Ozq-+$T*EiJbfE-CMn!RwOY(g{>z+jfWkugoHEatPjWelWlQ z0`&dlE;T~(yD;%RzbD^oglz9%$Fxb(z40HBxqHYV=&{Ah`4UKJ0r+-1Ub9D*= zw@SbuH9YrH8gu}F=R}Z;M6Il!AL2`+GxlIy7s~4k^atp0&z>7AsJIZBV8cym-M=wv}UgseNLfi6RHNZS704Ys}M z0qr5x@Z?`F@kHgpk%`%%B3I=fFglUC^<2I5({G5=*KOSdG=`6gOCEWik?^qxTl2q| zl-bt&(nS8`HQSfTqq$HR_Vk7Ot9YQH_Zm^J7`@L(pop7I5D$$BH>6PrH}tvLNJ_J1h!IdK z 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/splash/drawable-hdpi/action_bar_logo_release.png b/patches/src/main/resources/music/branding/afn_blue/splash/drawable-hdpi/action_bar_logo_release.png index f4a88d418acba02ab6fcec60bca70dd3943e1dc9..fcd05103f2124678c9492b03c7a6f2c17efcaacb 100644 GIT binary patch delta 2320 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/splash/drawable-hdpi/record.png b/patches/src/main/resources/music/branding/afn_blue/splash/drawable-hdpi/record.png index aecd283f8f78fdad49bdd6fa076dcbe533ba2bc6..7380452568e081efcd3ea9b0245be37c4a22a317 100644 GIT binary patch literal 5907 zcmb7|^;Z)B*T=WP=x*r{7>owVNr!@@O2-JLQ^3(1%^3B7fOLbDl!Vk2CLu6V5ETZ3 zNIF2I@%4HCg7^L5#<}PF!#&?~&$;J(Qp`*YXsI}<0002({d>9=|7zKPgM#c|PQ|-R z0sw5w_jR=%A&T~kBXU@A#UmOaU=~KIt?Z~SZ>sFL_y_Xl9}?(F{yLhWo5NkTxi0_5 zgMOz?1M=4@TP12;Z~a0-R)1a9M=uQ4TYTyA7Zn|01Ak#1-Co%MO|%+HVYwUrU(N3p z2b5}!Xn;%re+yrWMhpG)>d6jxk792x(p{biCJGa?cHht;s1aNUW(4h$ZFWNoW_+ks z+Z;d#Oeg0=mM5Qu*8~qVVH>a?v2ujx*iz)5oGJG-d*o9xkZbWGq^xvdSra-E z%cjX#djlll?nIC%V^kgwa)`C2QveQnKn zcKf&e6_fI8sNN2S6-z3iBIbYtm1HPDd(JAJ-46OS)fIRY&JLF*gc7t=g-n7f+U0}j z{S6L0C+oIE5cC8Mq;n^97H3UWq@R}Pz4I6uhgubEMW~D&i^$L+g!Y*iT$v*!h=M(5 zvm2VX=?<4VOdt7!xM?M-c1h{oUVh7pxT`vuJ)aF20h)rMe5|UtX2=mB%5md_(I~8o zkPzzd9^&F=v?wV9^*jqm5KexUX>D(7#4LoW9lh&d=R;KNXT8la)(hG(_U`O*9*A2a`9uNaz9WD0;!@yj&47 zfgw0k28o@NC|00q# zKf_)#&UC=mPS$g_lcIi) z=7)^SAM)!0LgjZBj_kZF*&%8qG^>YN<>Xz~s9UY|*`0SWx<96CCKanpyZdscXLImw z4f4xK*JRm|VLXT~*`e6uYobvk0H?1mp%^6AMzs*jxgaE}emAq$Eh{ad6zn5<9b$14 zJF$5-Fa6Mn*%eiY5)fMytyPsWNSxOGE{e6)tv4Y%pwDitPT{?m9Vy8~TdZfBb+gAw zz~9UKFp?a1B7CIqihi2irtpU*!HmGa1C<-og)&KSUx=j`1DkcZi|?gMbt=rzhjm8Y z`g567N`e>s7Qe-?hU@X~6)4%@AUxVpTlym;xK7eDK}uthdgs3ZYJ%N`=&d6rL)FobKWf9L z21cpK=mUQ5A8CR5nGA6jf1)E4Bd+bESp*U)oCp4A}6S6N!g?RV)xa$=tTD z6jv-M6mK~xX`0BV^e;M5OAG{YCSF@H#aTH3G z;r%9YNXf_L#KR)ggr{|a_3)r){=HPoU~nAKYZpx3O3S#$+zG8%Ll6LS?`-dmFB?`b z+-HBih;G2wlsSX&tW*-*9nz+QH*|kD*>aAOEw_M+9^5iizN6aN9~q#ftSkX^ZJgfV zH*H9xOm)i(j}P19Wa(;7Y5T;=#Z_lT^a2ZqT^qvI$SMd%RRa6$!rZp7!5oH{@s4yvKT645}<|0EAF?cdS@dD}SNFvqhKuMqU{bi(O#Q>ONLni;j z0n77>r8nBv;13nnY3uGRKdnN)?lZEh;{%~QB-9Ehu4ARbJl68?6pz6Pd-gAu(;2Ia`UxRvs44mJEdCLx`+wGhO-o=VF_Eu z7T{1zbfGb?Z_)^KJEE++zcR);TH>Q|KnlG~@Rg)2(hLHLY9+AMhUeL?#A zYm#`Yo8d|;dApU5#kW-O^*&u#;72&%n>8Mj@S zZ5OfceNI~h1Siabhy%@uS(h>~B&v;0!FJIn$XPZ*X{PxF{Hnl=@7=8=L-8aFDLK08 zZoOA3j(-$%9j_rWR$`X)f9;?TK@~*G&taC4IZ6V)z-GFM^6gbUqQ|6baB-A!j*AQ! z?bu+sHWNNr>s|2?tP&5x(+r~B6P=2;#VSufHzSAOaM9=5%OC}%LG^S!kFEE&`wU0c z_vE}if>eWzTdZ2bwbCDhElXum?M(BF$M|PhZ+F*wvhE=#NPhAA0tXzj)`j}+@%k#S zy-1JxVyemde$Hl`@SB&V8v}Zc=@yw+U4HXJ!`BMC1~^UX0H0ZoIGJBQ=Um$^ux?tk z^?P?w4;t|(rhCY|CvNIaYwQv-JSdIU6KXd0^~H5dbUFZ&3aE(RsI(X@5PpFk62+I@ zVj0gGfjBzbwS?CAg6Q&JnZ{$B;(oVelXfk78V(U9$*F*<;hO{cZA!CNR$Nkf!q!cB z|9SBHxjRFujA8?x0sL2z&J^aB$%97)Pm2*ebIgNXhi4SeQ{6J!&L_vHTCT{KkS-DM zhr6A(9i7i9P3OLH!j^Sj*dZK^JeaC7AW(_+zZx@=qAQs%qcBZAhWq6{4yA6SKih(u z`8K}CCs~LWs8^be7k;>g4s+^fCI&Y>`Q%{aUQz-%P(A#RuI83quSjc{ObV`JEb)ds zY4GPWHJ6eo*87dt5`w)pQ!xJFcmNx4jnL9wSP;gXSaK(f4$bV32YpT{JNYVxi1 z_+5zF&V(hf>LVPz>lo3kl$O7n0{DYt=c_NRRh@R5@Xst8BZ?(Tmzn`>U2yW5k|*ML zwP5}DvwrASrRd~kmt0j|w63wdlVj&>Zda;Oe`8*zra|HU=M?P^cQoWYz&v;FIk2ZWRndmM5wJ@s1lGv$1z=0UH(_79;Uj(owF!)H?Do2Ery!ohk?xI!zms2Um4r(w6rdbE%qfaeJ#Uq zC^|ZY0{<(V zM7beO+yu-je0=#U0S!BtkE>BSsYcJfZrnagnavz95!*U<#oqC}NpacSu8Rq~a9t9m zPVJ3ZyCJNS(?DV0=&P58mO5U>Z(XB|bEi!aE5ERuEJA{RnIAiv!b{SR#OLxV)YHupzbK| zMjT=ad?FZ!;a^y>?GH+9kktY^Ki@w~b>VMOyr01~QK68$ld=4^V5O2m`axI#Zv9px zRvqk?;`Ak+rR@Gc7pbxkM^M}isgbsLh`FK}}& zjTDtJK0fEfflD2P=rEMu`0bCSXxlZt)_CXHkPxwAW_7(*Zpg*PA*(&j+8ePm^W)zS zj8kA^pl$isN6a2^21rC0Q)X(gUXSjXx~t3fT-(6`qsDDz2mcI2ViK zYM5y!$CF+V-ILUuf;h(iP|_(sVi$QLpbS?x@u^VE5XjVIhOgzlrp5U}=*G&YBwA@r z%^G{?e;&oA2_A7KD?dCUbvuiAcObI##ce0P)>K;1sPgfznGX}+$4_seUkWriY@dju z1E+Q$`>$Z0QGY&H@&s?a%1PA(dKJR+_;nh&TZGVz`fJ;y1iyM?ZOW_>{L=4urQRYEOosy{JHGrS$FDD>R=*d6bIs*1J%(HMZvxr(q@RyEQH4#ow_Zf;xw0Jg@thcn8^)I1lW`9VdWo#1#4(& zdCpJE8K(zx&v$TD4f=sJ&Cw--kv+G*KZ2+48+x2s&7lI`Q5^8m8><$$mMDPTE4x9P zK6&+cW@|c*sarx$#|i^+J|@@SWaCs^f5R4o-q-xv8OM|9xs6Ql_*e}Og%Zr?-US%9 zcqZdU(2uQ4KoNpbT7$3;K^4}0Ws#F}%6(y+M#vGAR`OF}3_aCO8?0GSD_a)EIjG4?S^TqSV+{M6-C@`S zb%K52SDKxL6TP%)PD%-jCLaoWC)`SkXb^xc&p^lwI1OhgBolGF-(YDrqeH|o^~EUF z7WhoU@8{GKLypATg!^r>-z-K(NcU{mzmgW}vf?WxA#>RjuMN21tU6StcTB(AyVxnJeF{6BZO80 zZm-=+dMcivRCey-sv%8vm!YA@YYjXlB-tzYm9?9-r+LUL{09P-=)8wdTOM%Ga0nUZ zcIR!_O>CHT_h)92rEf7Gi_D@YIZEIS@*K!t!Lp8O`piaE?2lT1y5q|GXEf?HPbHlQlokL{NnhqlIP)ms=nN z2|_P5{`-Bx7Ir;#i~|TyhmRIIMQgTVvZ9o81zjRp@thFOaDj-Y-01j8 zz6{u8T@sJ-bvIYHvd`0YfIpn8nu3i&v@h9mhH(Xw)1GQ-_Dt>0LbT(ok9Mf!UlyCf z9-g0Z^Sv4^?9nFhs9AKQ26K3}&)^$pMPy^ZlMWNvOWzW?U)q5j#GVYI*9_jMzyTTO zV^#5CLSUV4KYBdt2!1IdDMt`-=j86Y7O!6@cNVL(mdB1+FRmin9;O9M-3SFa%#1ERVW^waN-dG z=?3ER^&T#Px4%08f2RlEQRzIBWeVoJH7L^UBWPm4T%Z|%6#XSqou9ToulJB6jg)3W zklm@j1=Ov0ke3Fsm&>*?>nn2mC-U#L_?qM*gWfgw0j>yfc`t3oyUNQj7V&@QIHMzh z;0EJa9?omVZe?E24P>mx&9=^*wvoxT_j{ViDuQllflA*I8 zmfJ^Z0~wd7-uj-pqJjWXBK%Fl8CAd`y{ADSZ*v;?_jqG5J*W&bPRZ=5Mo@Zl6(~jG z*!X8X$ih{OICPszPMtFF*{pq{7%m%opz6PPd2kdxs4GjqT~#3DR5sThI?L{eEg4Oq zql!^cxdWG!!6cJRiD*+Yz~}e(QrGSa`ZdHlV=tkT8`nNsFj1_wj?k@9@T?hR zFTuBBwKr6}((ft)D;eW5IkLbWDcPB0N;XBIOFT=M_!Pb35&9J z@}H^)9%@}%W0{0dqNC9eODkt)IZqANe=|x3f;B-bXymr9BLAdc{gCs?ENO2TkBtKiiD9ci0z9`-6l@$e(ykkgS#&Q83E? zjAN&jzRr~?==jLF0O3Pc1EgQL7@hQbp4Is$Mq@jN~_(A zfM9oE?$0!ZkL;i!$wgtQL6QTlMn{K)#?61EQ-k2M6;k!Bp0o|Ly?U3d&$mnba18A6 zlwXF8gB%0ASZ<;#6@19dru_Q!AN0Hx1Wa@#cU!=JFIrq1RYiEx?)vEDLTplWYp-|_ zxck2>Hb5ABI+lR|sM=nk|GZK@xVykinYlD`KDBj^&llPj>$Uxc&QpI?-{sJeWU;DQ x>cM}BaBv>*a}nl0)G{ODJ%DG8|Ci?Iuc|Y##3P$c{2%NF+}AVFZPtdz{tuU8A5s7S literal 8592 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

4wquiTX7L&*W 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 NYG`3ltLOgo{{TUvQ(^!B literal 12171 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/splash/drawable-large-mdpi/record.png b/patches/src/main/resources/music/branding/afn_blue/splash/drawable-large-mdpi/record.png index 1e783ad8a6352b86a915e7f6039b97f1c4265d88..69d3e81f8c3e0702c241c19bfb2f3637a74143c2 100644 GIT binary patch literal 5969 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 literal 13004 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/splash/drawable-mdpi/record.png b/patches/src/main/resources/music/branding/afn_blue/splash/drawable-mdpi/record.png index f6880b43109f923ea54d9b261da3d7032538aa8d..332198ecf78fb86b9f43d1408213d4cdd1c71d20 100644 GIT binary patch literal 3592 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 I(Qu6UA8&P=H2?qr literal 5460 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 literal 9996 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 literal 12796 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

kEI`XskLZn7MtZ(H(p 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 diff --git a/patches/src/main/resources/music/branding/afn_blue/splash/drawable-xlarge-mdpi/record.png b/patches/src/main/resources/music/branding/afn_blue/splash/drawable-xlarge-mdpi/record.png index 9c3360029031fb7dd31ec19a27c3fac2875f1505..73a437a6a6db0c92867fcab7693ee508bfb74fad 100644 GIT binary patch literal 8439 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 literal 9996 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 literal 12796 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

kEI`XskLZn7MtZ(H(p zA~y|Vkodore1l!3U!OKc(nU~j_n5+LDQfrY5nT9x-GVV>j+>7xi|S}M(4~t+L%6*N zs$~WN&qBePa=FTGl2Z0T3ccRLi+*`Yv63FWpJ62zJMAmc^^sl2u&;)e! zT&3Yd%dqq5KDaS+aWc%hEU9P_;c@-b4Fp}5);`^l^F|>+ zaJK5ai_E(xZ`WebGnlB3gZTD+y7(v;deSzurXVf+w|nZXSHIldR>a%*SUkzz!SF_C zIk56tV!ujrh3`iq<(_V6v&l!}-UBllgWBU8IQ0~TCd2EObasSBRb-?7IijIl|9xu846 z?uIzyG{YGq>7)l>+A{Fld>e#8SU+8P`uF`1_^lc;SC;8NlXSNm^jO#3{?uEoX(LI) ze@)bQY*ukR(?m1Aeeew3`q{QpM6>-WHPA+BiVRcUplT-~q4z&cZ}|B?b*?>1waR-L zLv7h1Y`@G?)}zt}!!5&AMZc%<^w8hS>vkgXl4S2c_3v^&SWVrZ`Qk8mSN7tA!|cjQG7PaneYIi~94K12ptUrl zob5&DDqi@?^|60-jr5AyMBXV=j zSjEM5@db(v!SdCEM&pbR)#yl=7t>7xppP7+Hnvt#WsHE{PZ0>dVk|Mviw<=Vd>&yJ z_C;|LPf{3_qS`!axr>P6s`XI;w>`Ik`3tL6X8@tlwP3+LJhi2yeyb(x2}S7-Zm}n_iKVpGO9IQU$JR6EC&pYGTsS3}ZQa88%3tHyPoksK z4+A0h;$I#Hx2kRsM*iSDf0DzR5rUW((|y~B5G_Q5>-a|jbYK1AFfYVIC~z(fWrpLg zPr)Os9JCP7jDuH?DV5XjZ?j&L2(2aao_6GM&1l~G+<0t~(}D9-Q2a<*oUf=Ft@N2T zlhB0d&ryI{etow-SIIQ-YLx_}s4J zKS3By?cL6zJXe8-;OzbJO)&|Yo$biTLH6p%Dm8dx;!6&-WeVYe{@|ZwMtbhfeB`wH zpvnGA_MWWP?U_!sR7=L|FRQal944|*Q)!th`(#*Ju}&{N_Se{wd*OxVE#4oT1l6Bc zX4DHm^zgze*&azx>2r_=#YR9fv%V#^D_GiR7YgPl*{%^f_US1qU_eO7L1nn$Dw%CX zDffpfyMRSg%*yQ&@PE25b?q9UR|Q*AAr%@oJIOc1yXmovGTh%MO~}S$gHV{LQw0Ca zANdt(lYS`t7L31JH%!fyeOW15G}&8OJeAs!b9U$xCZR{|=lBKO5(MtbruIDon8R}o zg*83q6+zKpn9QJaFlOlBU5@fuPMzeu>7dvIrm<0H{RspW%2;otg>jp>%=C zp^p;nATnQq!sKuV{W=Wp6X@?140n_wv!O&vhWWEp58hOih8FUm;%PK73dNLfBuL6Z za?;qH%EIgOqIgT~PSji#t-PhA1W4;LqLOBMabs5#YBBNj7OE{O85z z7dHY944R)cJys#dspvm|3=xB*l;d3PbqTEVc0YeIURR}%yFR$_Ils!^N!S!olZn~jOLJSdw_L`sf&n4QXcxj439D5nh(?~+qS2$jm;2e!Zi zrzT!_f9_;AqH|1`3pZp)(Jw{`&BiG%^;6=E!VD>dqL@n3;%H=(L1j~4BzzkQ2$;W& zcTUAFe>58pkWN~r3Ils|L9a6G0&~gw2SzGMM6GRAvVOzQO#Dw{MWIi=TT~ws3Z&OE zvbqv+LL5=rySrDzy}74XeirthI=H>=S!F**F*V<$!Y$lUiCz4bA594Qu<}oGr1ekC z&rcx*|6;Z@tbR0lM#)ZBl^j%6nd86$sJn`7QZP2{zw*hF69%iMp>T`yin&yFecBzA z9~{yS^4tPf{8`qj zVp9Q!~lKmDPDBz@W?5F%tY@Z-J3ft5xw}nimJG-(uvL9 zee!O?I`uXJe@)=;O5~1^Ns^b*SAq|rvgxT9_DfOMVj7Q=B#n)<$ZPV1Z^)uPxZX?7 z|2yHeI(o4X;Dycz1r6t+f;kCse5f8wNbL*2Ds5BOs2webn{8 zxfCWiKGNss7cPctix=s#(*9GSBprsRbocft+gca)5R0<}7khZCOiuJcTZ~OGiy@q3oUUL*W`c=GIlt$aLM}OUYQm*ls4^@wsd-0fjDFC* z`q*nek=8wO!WGVm*CVS-jc~Z0#bpuN^~rn1S?uS0_6gs=*}zK2m#CIJD5#>Y)4R2_ zK|EOC162O|c;STHCz+r#jXx*ds%S^-j{JAPi-Y+2$firByr@3>qp%g;I=I{vqWrAO z9E+y^Z}LLr8c}J5Iv|G4WlAu1!t z>gL^(%{jw`%M~%2uo=1lENSK&F=-sfzp{5d7!DC4Ey{^EHRpN#;nuW?&WVZxSNKNd z{|z-qKN+P9{-$eI2E$c13CTtgfTaC!kPsfl=g@IJ;mgwH)+N;W2#w&xy;uXnZ7XtmVRNCfXb$p#pMH{D8Ms?El z<;WNG_Q3s8kKlcaUcg2;8B1~#p!4(CmURdfe+;MM^)s~^du z268c7V|PDd3*mCSR{kFiFCJeN*YYj~%Ff6KA|b-{4lrtYmLr0VAd?&n535B2YOL=n zLJq3f+QNQ}KC25}`-piyXU_6muzj7&pIU>he8a@TvA_}dJo$iF&CuOCideXs6&!r?-AW{g)5_`_#< zTzdcFKgw-eGCQcOP~jdnFwfshR3m`mX!8LT1?Hn^W^Ns8d zDjy@|pg@VWGR%>a{s$7lojxu2*K?~?-YG8b_S^4&518NqR7*mx9=l(o~olo ze;TJ;2~j4=6du-xtbWi;G-qoXj^HLy!)h_m{tnur6&q{ z>G;WkJqHC2sy-tF4cyM4ijmL^Dm+9B(u}B<)+94q-KcPny!>{7wEytAV^$9^p9UM) zq2Rv(uIz%)7iAhk-U?`7gkFVk>w2P0@KdWX;8Z;@#N6t42NmuW=d6Nq4BTpH4jgz6 z!f@j}fV+-$qvWth%58}^xHsm_T&4F2*GB*V+^z)x@V_ny5a1&LYC+8AK1&*^&q2uX(_yeX zpsN=|P~BDz?sFW8gViDYyRUW^=Fj_;9w~@8eGI|z)9ap(#jjR2@d5k@hzp*9>c~5P zjWTj)WT}pC-~Eu#)e80B`C34|9lvOi1^5VYkj(XB>o3^6JaX<5*I9>(G3ed5=R==~25jY*51`Qisge7Q~naJd8}Pl&bu z+`Okaxz(+Z7@+}hP0v~)g=-FfYp(Qz3hT0jt&^GA=7pU`*Zt**^^;)DK=tuV;7S`` zR~ubh2jtnuF8*Iv&HM4@gzKtpy<4r9f2=XFN$9%cJm(+|0B}?vAy3MPOT<+X{vr2P zB;K=u=t`iBFH`euM;ty3lSjHj;J4=}#t6AA`foa4UJ3oWs&31|mAQdpoA!B6B4p}$ zG|2!4k8$fw5v|Uw-+Oy!bJP9ycF-zhYMgXNwEh>_syrC}R08{CJ3=Pn%(n$YU1sc} z+qNr(utL?A%>n#Y4kN|31=iX_haXQC8;}s?2vikbpMv>CUT&@VI7S}n34yikanL!%!R&x09jMAAMb@iIClI}yqrh9TH+kwy;QK)E|OcNt; zNVM4`@U0b+Po^>)Y3Uhe)gX2(BR;}|vc_e4{vvm0Q(xKNR(=v1BI=7zI~In^{bwxY zAC-d$d>j5hR$fC(_lGToM&?++vbJ6KfRevN6_(fiG&%A{6RWL10T5H4dS0jhsC0Hp z?i2Oq>N+uDchSO67?LM>%X}~r&S(-0k8#z4Tv_k6YRX=5j?~aFhTgXT1NMrApR0MR zZ|4VMf2I8I&Qh4Pas7dikog1Sh}31~`uAQV4|neK3C%RjhPl|QkI?`}s34PbZ_93- z`i2Mf{(xz4;--)bFrFuV*d|yD`xtQ4p5=#uha+7C8vhR)i<5!Sxp2jpl#9wnLWxyeoyfp12xMTHNvB@&BZJNMJ-vgfkCc#2Lj51IRn~8u z=k~mNzsOAL@2*UnyUKg=0o%OOJ}&?aslkx=@fB4u2)vewCElnBG|4M~(bx(Z=F=XbfNxY8F(NC*-7bmw3tU5|K|Lk$sC2-dYS4tbT9J3 z9EFR2q$HuLV^2?-+q`(W%X9nH6`4@~uKJ3HzPe<#oDg9Sr&QX@)BiFoDN1Wp78$p< zRQQ8A-Z%LEgMOyGHJ-F5j~Y2uuc%1> zV0f*C9UNfTA6I~)NoH2L{cDA|6UiC*&a8jAc3L$xzh) z^PPC1&z()%jbDtjBcf>|&NtD84Pv27oSImah>x?e$y-)}Nkat8Dr6<*u5m_86lGMGsG zDEA;bHR`ET*vg-(44co zK|5}CIRu`*B7#~)K*>rCGnWp6mo-+9;7V_J+shgKr|MToo(J;_?JIyo1%oS06&THN zl%Lx>=>8eW<)9q7{YK-=H?fJ@M~oIt?06ir17!{(1}M%zyyis`4WjbqmLj z_3SjlshM2CAOeHyGDHfkvslit?+;&U7D46iFZ<*apl5tLbf0ph4BgV!Cy*LAfK9j; znu^Nr@_cM%Q%_72hg4rDhu!Ukj8j|C8k48`<+-k+wN1}VJ1snzBP>(t;UY6v(~*IO zMMPf6U6Ipt*OAE``GODL#AYEt@(2NAjUxjS5J>#Xu0^41J_9~^OCR0lRl|Wkl2Q}Y z##a<2gn$}F%B>f1a5$CLJom{M3_R5$%hD!8^4twknd(v-u*ZR+;YO6z2g_URP?j%L zvE65YN|f1OuE=(pOb)K!5gQ?Tk1Jw@Yy&%2A5$|Zq*C>CaWSAMRs-DEK>8%3suK_T zEw6`{4Mp=t7Q(il74)q8gvriSNi5A;=@F2_yWRJ(&v7@(b84o`{Rh)!$zyL@@K@#Z@% zlIN4Lc%a{B2q z*abZcZbIWh8zJ)fse6%Zf8T0Noy$d~ckvTW=!0WEV2k4xt%Bi3j4iHL`E-;~Gl4W= zn4`Lj-_ju&Go?a+G5XPJYO&$xLZZcZWN1}CNsa$fsi8$^8mb$x1%X8a)ei$RPj3@+VJ31GJA*nQ_71dY{in1bHLGg+70Cpd{gi;Gu_-}xS1qWy zvdL4XQPSRW9-^op4nnhCYJK9AT*(RtafkNzL*RdxMGye{9U=El|MsetzG=Zdv^)}M zehnVOri87o`TBh__?&fH+j77*<~gcrw6{N}WWVATP7N|lrnwtJXzSr! zSC$CA9FYMl^X{WRb#{gdG0IFc_8o)OplOeUX52V)8VX2B-+Cg)`i#ZKiR~a!RtiD6 zMOmmd*Uc)#*pgYMjxBW@teT-?a#N*~kuna~bp^`08`94cS3yon-I$G>88fq}I{@%} z%Cq~Q8*GzR5Um(p>u9T&DIfW!Ttok8(*bCFOrSqi5>kez)2j(w)Qq2$VtLUT>}nIO zJiqVpZ*p?tI<oqh~bVd?jz;1BI*T6LdzbOAj*O9S#w`N1h)joGUbK||-ldzOu%*~f<@Ja{=C#l( zj`{eeBH@WheDxAFwvK<)(tNN_>P7hlmEKsZu2u;aKF+f}nSEj#T%Vk`36nUrzHdaz z#4=SPXOlXQz^kbg)*e~DWHT7U^j+tczxd%0Uwjtgk#vboMb}0XOC|x^^rNDxg-9`u z=QoKW=y5sT5p}0At%~9&1g>wh)d}i{q^oBMq`QNITsu*{Ty+=_$>^aV0Oigc#+K$MYMLh-R`4}01rChg` z6rhm}=-ChKS92N(-4yJDz-LD(9BHeOqat6bzM%$P(H2|P-@MYFoaC=YO@)>e7BEU* zmW9-3w=F{Nd7|N&td3yYto6m1q}Owvx~n-rU+A?ptX@?%*ARZvEs^2{jMobW$`NNi z_x(kTWM8=V6Lj6<2o&ORFiwAO#WC|Nwu&wKMf*Ge2HjkgB%_G5o&7C+ajf?W0xGWq z#JWSqFu#C$&4#;(VaH|dULS7XPW&IHwjuIJQ5I?eh_R@-`2Edg7(C5tkG$}3mD+&- z9C4)t(t2qHXSQWSZH0yN&25Vhf$bzq6qJqLXYOd!*U2fN8w1qfnGuoA2e?vz&cv~s z@{a_GJKUof?xN5irBo%)Jh;Dugo{6V%a_Lve!&bs|H)q25gohyQe7bZ7puq`y{8Pol(cUZ4*`K_nv$Un z=pM$MntV>5578xCMNJtaS}`n}@KIiQ9cRW_kFO~37=7?G{s~W_4}d z8wOVb4AucEJe3A>c&C{uOumDSvC7nsvA-ANpE|K{Q8(?OZL6)&>@CAt>D94vmni9n zwg59hwfFWPOG%5&SjO$_ZC&sw()rwFBW6)kmVM}DoC?l*5=;MfU38x7!Bx6{Dyln0 z{0`rq>_+UqSiY1Lx!U;+ZM+3KR&M1$04Vix@Bb`b(aNwJ%+~oI{+V^?9fn$mjxJs# zn&(|$(Ww+!l^so%jr^y3{_Db*rnlb&1Oi=(_^K@`T5by{>tgsh%h!pyet*ccwP3i? zKq!2>Yf%p2MGw);btWDP`JU-%@Q#hX99t>uYx}7ClEGf)U)@n z_fL)?3s|h5od;TT%<1Iam!`?;Wvi&G1(wTQrm|aUVg)8doYct|mUCxN{Rw>eAAYdO z>&%`G6Lw~M0g-u7LFdXrO+z3;0Cfz8|KHwcwlt#pUMn#zw;(!1FGjVgVK+{clv31n z3M5b3sFQDt6$9=(0j54hY5-sA@gj(-HgwLj0lRglC4MA*SG7k8RB{pZtpE5H#bW&1 znvJkp;2y*wY>qPSFaojY$t zMF?CI0S$QJu==@`)_$gnSA0>~9i$jHX)#K-zEmvqixVG6JaI@)I=CDNsP}W1LEiMX zOk|dPYY*D$VgsnFJL`RP9s#> zMajuCmEu9k*;O`aBJconiL#rcWKujEskFK9rk&%(I!5Ao(B16R zG&7SKqvp9*fZnW~ba8)9;cV94045fsccSWR0g|J;6eNGCAtX=l%Q>g3Stmj*|^bLIYKXemewLZCLIc#?ikRxSXuyw$t(J zyx{qf`0u%9=#`4r(#mw|V@>Si^iY^5Zic)&d7kRl&L)V))Vr(n$bz1dgUy<1si$F7 zg5@p}U%EzJ6N6-0!#;6Br^!zzRxP2K#wkB2_2aUsC|j*tf* zjN=wx(R6_B1YvI|N{IE{DG=Hm-z2d9MJrrI{(!^@XBp3vghGw8X zzV^T5D1X`&xD3={T>j+TI}6UwrO`{DSAhOeR4Wp?Sj9EirG}fR2-xJ>8K)C%h*A0R zq9mp_-XN19WiVl>B|)|VTR-bIC!^3%A>xMkVD(e3p(35&x?|@HhZwyU$ z6poR(ri?_dYnTpB(GO`1(fKfDqVNmJ@Od{zE7r2=p~$AMnphs7GXnJZ1AH0zWm3d9 zb_IBI+P|&i za2;}wV|YCf_!8%$hdROlIlXzulc)s>n{yKxAF(|8ZdfRFPCNX~isg>oq$M&P%~_fYxhn>mWSn2TMm zFC0e|2ClvJc+;`QYd5f11S$@BRu?2A!U1YV} ze;j|Rf$Ph;)w3j_d*}LW)to(E=?Q#zBH_$M61k@sDKB)Z)?~|lK=&;Zvi8ze~8J zgNyU*^p!SVB^I|FhT~WjUW!oJllTz^43k?E8+$eGMh~2oC(U*SHvk%Udo^e`sj!d9 z80pZB&0@QpYr4g}?0M!t?yofyuJeqS1^@1%uf%c=ab|Gj}m#Ku?&x(6@J{q06*a}j2eWfc-Ui;3t zmGOSwb(AxM|I-D~{+q49Sc@WyxO6mktm{0(y)w3AYkT1^u1oLl@71!fr!yH`0rjeN zw0)82JncZdVGUWuU-SokKdmI;e~b$+%b*dAiK)?~k|*iPBD;Uqzz(;m-n ztVY{0+R7BQ`YsQYiaAP2=N0K>!L$k#LEq6=juT*Vl`_84zBg9a&nq>K6)CF~?B;ES zFwerZK`)F;s3`O!YhG)xx4F9};&t7|W%7SfTASjmwxWjrXffzP^a7fFxh7d z&*t4m7APa=ZK4EiGu1rm?#jjJo~Gno)>%)<{9 diff --git a/patches/src/main/resources/music/branding/afn_red/header/drawable-hdpi/action_bar_logo.png b/patches/src/main/resources/music/branding/afn_red/header/drawable-hdpi/action_bar_logo.png index a0e16ab45292af26e9f132d6791d3591ca0228bd..0d9dce8f7f4a9b09379c735c53e5349373f26c56 100644 GIT binary patch literal 2847 zcmV+)3*hvLP)@OxklunYLm``ZPq_WHgF zoOl%GeGCO4UBbNrOaQJ2K8Lqp0&s%&Hw5?^a2Qw$+zmVp95W@YjADgc1>6UGwupNT z@OkfVC2%dUA>qAgpdI-OLx2x}=7@U*XzzWtIQ0LaR_CLD3xV;#`@q8_e>b6!+B1eH z9z1D7od7ogKLIkOKHS5Hz|E*;$6*HW3*bLw1tmZ?;CsMb5%*pQJPGV3cQJGaeg{k~ zWYVpKtAO7)v@?O1OJSN=lP7JcO92l8mzVOu0JH<<00V$&L~COg@3UJ#Uz}AL>V2LN z(APEQ-nPOQ0%+qXQOLF*?Fu{v>;pCe*8pX3M1$vX^aX6=O5g!hGs6&NQil+2U7{Aj z!HB-LM9=~Zq7?*N$hV_`R0VK4a4)b9^$)iKUoG`v32+5!x{JZ5fYUgCKVcu&8R}9wXF@Tlc~MG{QaK8D5V@xT`|g4M)xXgaq>% z1WZP^5K(9Zj`zj`j0zcdhIPFYc!iH{Qf3eE+|gthC}a^31c65c!H7mfg0S?gQ4NBO ztzP@wcr;Kt3Ah8eG3HtIzy+u|z9qrjuEP`Zp+kqrWCCNVZNTefh1?Gny1V-Aed0fX z25&Aw=!Cj1fB)PO_y_QeHRdApd+$es)BV8XIT>Vmqw9cU8hadJ&Fz(AlH zwN5FIwg7lLV4effmW)cvc zo$@gfpt(6TKT?jG>%$h!Rr$V7`(<=X)mrFHe)jAoR4{*W=w|~H3*g-qnCZ~Aq6@0l zp^rpOKPEu9zUDSW2$!_T328AC(pG<3q*Getu8f$vEhEQukD2gFG(8!GegM;^O$+Pq z3~UEpwPV6Kyv{{8-AK~D7m|qt-u)I9$*sc-))>-z%$08F^7%sqgs0vxjPL| zlZ^=wu7ABgM7X{{hpSM{5qd@pWnw5ZW^kD?b7Lm_A-ZLVLXVh!-(qaCXs41*e?o48 z!L<_2=r%752LRG3kuc$&Y>=G+!u7TO z^$_8b5?N>98wn;oFs9#K^2BI-RDV4mq8vcCm*^dB!Mun|DImG8y#rRyxjG60QAI^x} zml5e(v7&ZP`SOKHiWxNtCjC6X+_`Zv9FS|WPx3x1E!uVp%b}NoM+r{$q|gHj^NQqq zIDSYz(&=!YTOH$bNr~KUpfV+LfBEu-Ze$mQUciqNj9Ub-dGqEZJnPYPBV;3LyYloR zMZTmWaXT7>{W75M>*#*Enl`BJSwhb9x&2cjqf;WQ0)&eJDpu6?MDwbJR7%po6Xfsr zT&zR=3zH{LPQrJib=?ttiJdLlCfXjqLQ|}@mM{@MmyDRnj?X0{ zLPms&6}8h*A9Ev`qD)eh?*^ukz5pi1=U$c()58&NP5JVLP3S7^;4$xwMwEXfKPyw= z(dME)(N64#;T6=c0nnjChlrs^u!G!W|0r^kB27t{90jyPwYEFzHhQ3u?nL0ufbmlb z;O*wN50mSHE`LmNCbWo0RG8 z^zSZUZb9GAKZSZc;HHu{0i-jYxi+vXC31m5w7%>`+yYQt)55a(Q&AJzTE}u9LVr(H z%Fkw+PyxC5V7KxUg*Q;mw=-5J0*ld@;$pJC&^~nGN4{>+C50a9zsut}-RUnR{kw#$ z8}M-ln*2GRe5>&+fbj#WOx8DR<;fSYkLsF3Xq|K>@ljqOIEel#<4U3r)^SsZa2;?i$)i&LSB>|eCa@6m{AqMiyoYYzwv(Ui?~NW5_%B*FZX$m{o{sJ* z_o2SF32)U~NTb$e4EkL+pf1Jtxg$|Cc@Q~? literal 2035 zcmZ9NdpOg5AIBF$q}yR4)EcAPA!JHeOl{g68)MYH+vz8#NeLx{Jd8+A9jKe`M=6iP zigXhtH)(_r8gs1KI+z^irrDmaT-Wo*^S-X%`}g_2KdK@StQRfftzvf&8 zEoGQ8N_j)3rlw-C7=ytW8X9Wt*a2W?XJ-u!4QDh~U0ogQb8v6~bBIJD4vjX@(6F+y z0{pM)>cEZF5D*0U+Tc&x*hEK1+wC*<_xC3d2u3Qq0s{l>3=Bd-LXH_3;SCG`d=#bc zfx%>CWYB0dI-Q=DmWI{WC+ZvfV{xSY2LOV}a@E=>Y)H zU6R-2X;YQ&~U32plQBH$e==m92-dK8Vgd1|90u%l8 zb;pxGBe9t1y%E}bhzS(YQMZi{@3G>1-EV& z7TqbicmH8|WfgK8bDfnXQ>Yq0@HotCXc6RmjynEOGesJgmxM6VcW+YOQNhICddh%jRM|Z-zTo*dgSOH=O6aJkE?kLf_BNCam31Lp1OQ=Gk!e zxxqIL1wk&uR{29I_iRRPhetu99O91dffG%r3F&cix^@v?j41Lo!KRCis-05 zo?0|LnP2@jqU{{#9D-eQgLOnHY$#l`vtT4OMV?dC{$ejP<&V4>(uFtLXTB1$=Xa$a zyP)#&cKt`ixl)!+Q8@mk_vEa1KeDgRL~0GfXPdU&W@jYN5F;MkwD;^z=wz!X#jv=v z)(6T7>FTj1+VrK8lr5*VYnhI%dhaE!b&b0U36Dm(&DOcg%I|INYWKP#8+>x9vIjB| zG)YVP;K8Xmd9%cRio2I0ODLabC7#;Dir@2|6$Ea%fs{89h6Zm&m*!=~> zyX3d(dS-WdM@ZIb_8$~#BAWeBw*Sc;)`=RJFV|MtNBXQ3-c!BvYs~`{^290aS3N@= z=53d#vhF&CtP_U1L%|#d$(n!1&|@LqD~TS{+p&bz-2!3JyHtow%UnO>@cstw+#4+p%xdw*jVkNH|N zreE?VU0qHFN!Z$*Wab(*M%TQRHx8+#r^dX!HWiTE!nGEy7_l!NK)NeT-XC%hOsi%> z<2g8eM!#uX*|k*tdXJp_<4rjc3h;kXc_l6RpR!sE=8gvt4To>kndI%)(zGw~vD4yT z_Ux`2T(Jr3oK&UW$325ym>6IW+c_6M-lYTA&7eF=lb~fgJ_zPD-3(3Sd#6U6CRg^$ ze3sKhIJ8H~jzr diff --git a/patches/src/main/resources/music/branding/afn_red/header/drawable-hdpi/logo_music.png b/patches/src/main/resources/music/branding/afn_red/header/drawable-hdpi/logo_music.png index 7907c64c6b1ca31d43277b8316bd39c1c717d48c..eaa780d34e3e7fc270291c6e9a6642b480716d74 100644 GIT binary patch literal 10257 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 Xjtt}y=s59M00000NkvXXu0mjf`z9pO literal 6052 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 e6HPREQ2qzKFi==#HVR|_0000 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 Xjtt}y=s59M00000NkvXXu0mjf`z9pO literal 6052 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 e6HPREQ2qzKFi==#HVR|_0000qzyTzg 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 YKal36U_sp@+5i9m07*qoM6N<$f;6g7NB{r; diff --git a/patches/src/main/resources/music/branding/afn_red/header/drawable-mdpi/logo_music.png b/patches/src/main/resources/music/branding/afn_red/header/drawable-mdpi/logo_music.png index 97d8379172974162b86ee5949feffaa03ce79f2d..abce8fa0666be9b96cab0c151bdcf3490a6059c4 100644 GIT binary patch literal 6369 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 literal 3827 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 diff --git a/patches/src/main/resources/music/branding/afn_red/header/drawable-mdpi/ytm_logo.png b/patches/src/main/resources/music/branding/afn_red/header/drawable-mdpi/ytm_logo.png index 97d8379172974162b86ee5949feffaa03ce79f2d..abce8fa0666be9b96cab0c151bdcf3490a6059c4 100644 GIT binary patch literal 6369 zcmV<77#`<|P)000=MNkl zd6*n!oyR}#Th-Te&-C1ra3m8#LI@!tNFWF#5X1uwt`Sz2#nsiv1yp?2T^G+)@IX*e zmR&D&S$Ee}WLJ(P8ZH9~$RXrTCYc;0Lk=d%OfqLrPj^?<{_*STuD+(b!zB9nP zVcVdToVA9ho`O}Ypt%_a2Ea7o8{dFnP}mg5$vc{a{(rmwQjcfQb|3Tnv4EaPT1b{qlDt0_)ey5s5$|0ih6l z@Pl$LhC~9^tbt^*_ywc++^-LWd((jx(GABbr(nlx+Jw32(n>=%|eiI33 zYm;}<)&_%vFft+0kkDh2)h@(c|PaP+9mm1#mKgs%K)%D}eefx5bc z*v>l-e7@{;tzp_U5}^>Y7B1wXMT=-X^;Dwu_44r5OzcVg$-pdHddrRc>XsXG%fex} z_S(`t-Ee~(V?k>oEiK&q=}!Z&ckkZ9I@NL>Z@be@69PVo6NcghG(HFemjVlcnZR_Q z4Tz+#4*>^(?LY^x8h8#EK8|BLiE+kw6OaPl0sJkn7$~7M0MM8|&IaBKd>$A9mI40( zJOMc4Jie0{XN;c?1WSN*zzX0m8Jl=YA(U>rBHh~y6>su*zZY@!}0HeE_&0s2kT&<>D$}EpQX?VAGv9v!1)B(Q)W&!`qSh|txy8xLet!scQ0Ru>RYC1p|!`Q{diEA?cs$fujCB41k zD;XVyni{a}g+LQ9is*W7AATT?&-WCND(Q~!x-`ZU!C+g^2!-Nk zy^N8O+c3>>(J!kepfvIPEAWZ&7(kWyBG3%nLMb9T_0%i@ISwc_0i~9f?9u1j%A=3Y zWOP(sMo*78%$6(>-;_8bTk!jz9itD688e!3oW6pu+T{#2HRJE=G7LEXd?C(a+$5O{ z;yAy-?>`j~2cX}77UA$AwElL{J{?D#g~d2p5txhb`<`C*sZZO$wFp<42JApAp&tYN zd2R0Gk3&2zZUT-XR$C#wU!qKE0^vNxKNhWLU|ADMCf@*r-M{s%;%(1j)|ex5oL)>b zl_pqkxtt@B;_conOcUa9@lFQ<`C|gZIG0f9)Pi=F^=<|RzFm}{lgY|NzdHmrcGLhD z01uI6%`1x<|Q+Fh&%DFE^)kw$Ax>}!9f{oZWyPIK%h{(#p7ls+~mS>gagN7!l^1I zpdCB?z(0~D9xqyee+NF<^p?3F1-?@C10Fy882AIQ>rMC6(=&^qp%ocDB^JxZwT6bE zwe>A!2q+gWA%(-aFX?zdDS7c)%Zqo3MT~*IqPkHilqxV597jZ9DTTZQG)Y?n7nP~k z*1Kli24Ft$E#O#93Jd53`i`-^7q!3-$DtnxhtDS%lnHETfJ2Aii6`KhXCz1(3Y}eX zU+(0e2;y;JSu%E?PZWR45)PC|Y$lm}tw@Vy)YS=hbPv-MgP}^87>0vznz3*bU@xCD zzaOPO`=0eL{wHt;qBoVp7T|w@-vhgW!-zO(Lqz3Oz;%dnTrI9b9GDLuL)$D&a~9jT z%jCOO-1+B=NbvicXl$HaabJ#;eIX|jTFbacM&#@`U|FNs_PdEjZzmW$i@v^5Mn|6{ zk+>%ljW>)e=W!MNRI2>_(lAkF+0`0gxl*7|C}72T7k4Psb?;pN!rKvL_VOa_4g#P3 z{RIpDQ>WW$rO<$q^AU~OI_D27A3;p>e*nHv@yN6I3gU3A#w>ju@p{XLV;D2J;DX8c zd|jCo5OCT0xky~k#cPO8HKU+c+s>vsoM?#2o)t@m;S$w0Mnm)hoZ{NH0#NF(g8$19kB0!{Zy~5>&%gBNm#=;P5#V0nv==T|@GgbINMH97 zj7pzfPLziifJ+eNxOJ>~%)^JNhJdzh>m-pdm_7TQnKHweLm;pe+m-~Z#zsjt3y0@s z>NpMz4RsI-wG}u9T@E1JYYw6>4kDZ}fH)u@0pjTvO~BRZ-xe~(HNZ2#P9U4GmrMej z2V6ricn(^(0tTVb5SFzQ%X%Eg`E6#5US}#?gK*lIyg*e8Jd0ADK(57Q+hCe=@cXaB zFy^3C6QBr(V^~%vjqDHZ$6 zewjy$T)HrJ$x}F~Q)2?#E(6MqGLH98gMG3SP+dT1rSE&PLA(BH>9?4{cczg@dXtpd8nZ}uCo<%CvNo%Y7 z)t!ro6~U1s2k7b9!u07i`CaCrm_lEvcIpt1!>(OWS9c*bH6JTc&n7>c!sok`rl$9h zNGvCna+UdF_m%Ml0&wxgpmjTez}-chhljB3QM5iir_?kT18)Uh&?v8%@o*a0rBPkl z!<9UoCPM&jxq-S_IE;rtP?sA@tv8hVzM)jJsT8Ktm}%}~j!i&u;D5%dkcU}FV6!~5 zu3^ufeZ*orGG&efqocDqd|1B9C!T*rQYpR3R7nZsSKVhSHXj6h;y+#d_F&k1ax$4 z&Xg$y(dcZVQJ6LjuDAl)+vn!AJLQyZ%$o;roI>kqghDW30{H#;mR^ix@~=rIJ2-G) z2OS-MM=F)eVIq+;m^O{Fo^#8RRW!?&!;vGG7jU1hu6x$Jhi8H- z!irm0d&Uq~`PS78r8rgRh`0iA)oh?1)kgM-~nnX(Y3u56hNx7QxbmEV zu5~pf-@5XMF^serG*G5i>P|zcx4HyY25*$Dkwq<)5|HDl^n|R>DUZjevU;`nQ6^6| zXl|aCVeOU$!^0gkAB)5Mn31o))Ds9?#{T`!^7gljtHJNj52>F~QO{aKdpn3Vm>cm` z3fkIYSeA%6tq0QiL)kYL3Yn1plEf6x=QP+k=2Fac7j71;KEe7-)E8UeOed>@H@MGKyh@_IA?N){SAveY6fRVZwBVhr5Zz zCg*sSQ>o23&OjC8Id-@!U8hX>EmNj^B=723%$)fGqoePqr)N9i@ZS@U7xz4ugIJoS zni zn)ocO)IV22K$FW=@Zd1HewNa(ESbEk|W#JL>)Gjy2d~~o#jwvAMT1OCSnJ!6RsTG z5W$fnFg%>g@<&F_;KB>xiYszW_)us=RXIV&4hP2(FZ15LDK>4op=caR>sspTe}Q5A zOU7|HI4H?*)nV+n;N}{+m@*|N-lqYNKL;>+P!y2Qq=bsbV5FQz-{B4Bt> z#|)*!KjZU3SJw+1I`q+!bz53KMN`wWKt035ux_0Mfh)(@dZuBB$ai(c`|pRx9?Mu{ z8jr%8sh-R=pRW<0&qpwr)jLK;I=J`VJ-qyK z6+h=8oRk?6mP0sMarOQZ;wqo}U@A>?^|Gd#@7(cyL+Ke>sYmj~RfTF^6Yx8#^Y$*K z+D#b(0Ws%y?~c*ex6xDH%4L_$r>?FsQx=JA<*vJ6(W0tuQ53cF>XhMB?_MZQI*#CY6%K0F@zLqFins3_>{UkV-uY?Bu}*xAX09?;stx&YJNaQ$5ca z_*t#g^Lfs|OugDwOFx2$8?Vy&7r-le%_*y938@Xm8I=!7$BPG&W8q5a=p9qW*qxoMEETVq@~*IIv-ZaLRMe31FHAjg4-$ zXfwEuM31kgh%@j#hGMoxZSz`Nif)hVPq{{rNA)i*|bUG zZ4C{rnC2-t?Ng~iOcPBwZ26SxDPvt-V))FD)va1~C$NFai6*Igj36QH(FT=~X2?(ul8+3xezF>~h4w6}{m-LeHt^YWZJsg%vDukPWEGI407ggBa;M=*>H1=oVX z#cbRND_4SLEiQQWL}D+1$+Rh>=8G@>!9ZPIB6fv_b=tDGQ>mx-#NZ~pxx>}MOF)Bz zU>F^QLWSZu7Ta8r1JNa*R0<4ZcL8x|4WZEeG&cT}X!Iid{&%FW6lNBhrUWq!V=I#R zmqjFUFR4_7p`krYnsgn3z=FKC>j?x7R215f#fLC3@Fey1SLTiR!_1xAMJ(1&YwOnw z`m3o~0igNN4I`#f_n1mK`PP-8RF9$5$J5ThRjDi9_aJar`H>xW+(qT<;-Q$1!Z3o!iqZ&{wKX$YeSNOj*~ICmug5TI5#LCN(b0oE@W2*ce_ggXoaI33@3V+AcO3u$QhJdX1YbU~=wB9ZtFe*f)gz0MWurm1x9vK`3r9J@r6gGEam z;7hE0xC7bX;CP3r2Y`=LNs|5g_1UGxvP1lSCQh72+|uBCT(MuXAOFX8t;0L(?}0I}G9hKEFs@< zwzgy@<@A(OyaaTOXRH+5BNCCYii~?TvDj*2u`>yW&ms`0!7v#2WkIkdLG&mIKBgc=`QdU4tJl*TWRRir-z-d1U&D)BV=i|xjOcVh$hh00g!a;;P* z7AA^qc8e6L=W5I{;eNk&#i zTEr_nUf7WC^D5qqwe_b2mvG+DkBTYy!_t{xRf0Z-zO zkK?(%X^1Q_oy4ChPC$nEN&GpZI01eC0a*G3*p`@hYu3P;HEet8Dek`QHeS8&J^-#; zyqJ$RHNidiz`ggv>eY;X>su^1`|R{qG>UKDd1t2E{{DVcI_9?Op@*b!-8zZ;fLH{_ jnlfQovZvumoKXBf`vJ=2L0bha00000NkvXXu0mjf1UouS literal 3827 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 diff --git a/patches/src/main/resources/music/branding/afn_red/header/drawable-xhdpi/action_bar_logo.png b/patches/src/main/resources/music/branding/afn_red/header/drawable-xhdpi/action_bar_logo.png index 01b53c316edc0c5051d4e322955973f01353fbcb..996ebdd7693a123922675fde6843014b96160a1d 100644 GIT binary patch literal 4138 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 delta 2873 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 X#P8Vwv5LG?00000NkvXXu0mjfE|pj? diff --git a/patches/src/main/resources/music/branding/afn_red/header/drawable-xhdpi/logo_music.png b/patches/src/main/resources/music/branding/afn_red/header/drawable-xhdpi/logo_music.png index 82fc6916acb09cc8799a94c0640e00b1c644b456..d460220efa64b21c52f682444f02a3dd94c6c847 100644 GIT binary patch literal 14346 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 Efi9S!XBy8~CHXyK9W!VEoqrMii0EdbNx)w6 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 V+T~OdjOqXY002ovPDHLkV1nzdB4q#o diff --git a/patches/src/main/resources/music/branding/afn_red/header/drawable-xhdpi/ytm_logo.png b/patches/src/main/resources/music/branding/afn_red/header/drawable-xhdpi/ytm_logo.png index 82fc6916acb09cc8799a94c0640e00b1c644b456..d460220efa64b21c52f682444f02a3dd94c6c847 100644 GIT binary patch literal 14346 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 Efi9S!XBy8~CHXyK9W!VEoqrMii0EdbNx)w6 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 V+T~OdjOqXY002ovPDHLkV1nzdB4q#o diff --git a/patches/src/main/resources/music/branding/afn_red/header/drawable-xxhdpi/action_bar_logo.png b/patches/src/main/resources/music/branding/afn_red/header/drawable-xxhdpi/action_bar_logo.png index 4571ff72e76c1466296e956a5e1b891365bbcf2a..440a587bc61525446060c9e29b993b637e25c692 100644 GIT binary patch literal 6920 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 literal 14712 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 literal 14712 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 diff --git a/patches/src/main/resources/music/branding/afn_red/header/drawable-xxxhdpi/logo_music.png b/patches/src/main/resources/music/branding/afn_red/header/drawable-xxxhdpi/logo_music.png index fac6da3bc8d5417f7f35539e429d7462b58705e6..09de95c092091a1b0cc43794bd142f931cee6587 100644 GIT binary patch literal 19777 zcmYIvby(D0(Dv@q-QC@t(y?@hgmj709g-{E4IRd_%}GS^rrGA*A5tdwt4Uh(my-~v zEusATGBZ|ke-Rvx{omKZ)XD&g{~q6nCjtZ!14i^udyoU||BW3{vdIq``JZXN*&wI> zH%D~zxBr{u50YV?Ft7`>4e6;p-43UL82!Cxw@wrZm9#Fu3P5W3{jPiR?v}^;%heSt zjIm+t?j25mY^$T~f0E-cz83m5xCj&{6eku(7AOCJj$Jc*)dt{#u+`QNLt%tn}Dxu2GVal2I#>&_FGIY%ie(P{IxQ4VjG&u=FSS|HO~Jv_{swqQGrN zssgZ;q3BWu; z`k&fTX%hkQDe_P?sAG68G}eB#hLUQA@!$q(A*`#=@_#=mT!l=TS#_}A9uEec;^vhx0H z)g!-3_Z|AT%Sq93fEO>Y;1relJxkq?WYkCLw<=@(|NF;O*)E`1sXG)gVUb06A5g3$ zjO;%v8jL59^Wc5Qv6mS6$PZPSk^C7Z@mA%ZE$OZcHvuSd9!Bpd3mW*MrIwMx08j5n zasFAFqNcDD?zA4X2qK-~H>jJMGc!|sk9fk%K>BBXfBJU-{qx~&iEuTfAixcXjO8fi zp9LN!D#rtokV7%@Gn$#A+uoIw zAWu*1N>`O-6sRyCCot%XmS&W>tIx(&qof`lQmO^ruQ8|P&9ASseT)9`>CQKyICBZ- zlx@SQ5u&+=^5=+J_24cVRi49_5he=-l6(xHf%E20@J*~c^W!juzvexCK?fJ%XSXrN zK7+}?ST;VEQ^%SEI7BGgk;o})HfK%L{BK4D?UaA)m;l);>X3O=56)8>T^1<>U6<}6 z>)hV}GWAt}Z6G^^k4xC*jEv7zYoG51zxboF?Woiu)_d`CqYwC1S+5Tp6pE4v3jJ8i zl{O0!X7gB8)65r7r&Jd-rlE;|hz_iib2?z(pRUJdHAQol@OIUbSmYB8t;2P#>-3#+ zO>w!BI`4~u_Rb3z4|GcjWUo>HvcM;ywY0a(LnoAgHRfQ7N7Eo*cUu@oc`DozV z=T+4W*v8(MR13fbP%X+DIEPCXuoA^PpHPrH9>fdkHA`}) za7sTd&L|7ZZ)W0ntv-v}{z1Kf_a_y0a|;bv>Wk^C@a^y_y9Nv6%!fT&jG_z3_!-{} z73z^&h!#)=3mcFSzK#^8v|h~Uh*%t-wOcT1J7EAGJa9I-JoDAx3}4MzTykuICfT#y zHZ7HXRZ2|VS;7ULj3qzdiM;Vj=28*8a~LYjY(r@y??7a1q(ObP{`<}Y`Qay-U z`h4-5`dBTA6Bpa4b!_&dZF5LKV(Z`NQqV!Rn(IACV_Ja~`wR32LKdC?VPH5G@D7|3 zzO37<{I!~@G~H8F$#SfU`POza|Bsra&317)4L`Z9eH*#!DOK5VXGt-j(?Q>itCLSH zlPadQG>6j&;ArGzk61{^3{7E-%1%y6D0%YJGQT@$*MKN)TD>M>rUP+MS4$)$KE~dh z21Ono#{0BX&|(nFwP`vLZKMqP6D^W`!1DpdWC?j9#+f;wGUtiKDdT7G$lDzOwb*KONcf(Bl$Nm74}3;6CD{~3b3whoQWckhp*un9lhr0`_75*?R`E zu^ofe$x*2D%aNS^%pOBR(l7h1t3ju1$8u#v%;7R-FZsHUAay&YiECJ~2pPYF=50B9 zv3G^gAKUCYG07bHF|g<>wWU+rFPN~Sng5)up?1^!6)~zkNcbH}vqA8mz)HSeVd^C~ zJnx^H-(KZWSerMUkn2yFY~XzeF4kA=e4b=xJRy6{|BG;Tu>;41Y@0=NB$47#V5uJK zfl+Q4wES{84TSEYITdB~%(tNtep^Awxf=nU&+ubJq5j~ZIH-nUxollc>i+%B{UW*R zJWeR6dX94B3W>}mz~(mn4hiTHws-_12qYy`dwIBLJ3S!Yu8^}$AUV!&9o zj?HrfkYpUI*fp6M!!e5O=bw8XsN2QvzkSJAD(v&sUuHSjOSFK_l~W6qr@!71%WTKd zj1WvOFXeZhJ9=+=C@PFP4q5x)B1@jJ+BtB_itjML-%yJb3VKJwozumS`LNYl>$mdz<2iLm3aJFv@OEi?jEQDW5I2q-OJVwpl9$Fj*5zO_S2kZs?y7MM+ z(_tv0$}aC@R#*9yT)y(25y`1_|GD){fVzSTVJYpHfo^$HAzTuCZzNze*2VAKDD}s# z4}$3;z66Sj>X9pu!~q~ z{-f|QkF4Z=J<3K1W+6y%5o*L3xJ@RC zA^|>8^&q`7|4sh30^@_G$i-h$ZgMrVJPwGMFtMP^0%yzHpJ&2iR!JxQ#wXGNfB=$q zU9elqO2341rdRLjx?l}Y8Wn_R`hwAe8D>^yW`Oy?MOA1Q3!myf%W3$J-Tzztg6JeWgcE57+5@!|XD)H^bt{j(@AI?7*>8K`ST9ibJ)k1ETTZ3x`my&m}>5JIphL=MuUp-~*Mmx&COl>il_ zP+e~N04(IMiD6>dJoi1Cd9A$?g_UG&Yij0zxSN<4^y|E0hZ&D*=4?%}MVAL#{ZPE{ zDLpgS>-(8U`d*Bco`A8lv8R0MlrNF&_l@Ytsd;!MIdpjCer|)F7g7?8Mn)P@lw@*w z;r=r;4O|r};7XMZ4K?-(8I%W>^4wjp@qjyWDg%L`@x1ENvI>$UlHD{4RRlytj;`V3 z;@5SDkyKwJ!Il!_m3M5759D;4NFz=VIx=c1j|m2>LCL+7Z^=u3TV)A+z)&pn_mj`6 z>8?;;=x^w^gevN`#V79W0TsF{Njia>VkU(cq-WH84Od^(l!%aUtZ*ylW7WuREGaE< z;IGQgPUW#g3aWU#q(}~eg;;$A?2og4l+Dqy;~xYwf<|a6X7C&UBgGl-dhC!wd5Nz) zr#kK%%21I5LGYs(x)4~~0cSB&%?aw~QzSe<4sW5Cxz3zoSNM2bemF9WGq#xL;E7oJ zfV!M3e7pKI>5XIA&{=jlO@;#qHLV2t2Msen?Y-OiwD>r_ zWTm*@w?Sbm`TChd>?h?>;r7EKhv3PJqXRdefyLqJiiqDEFE{Krm|i`^e&g!uyWOn| zzi17!drjd%dDrr;gOW@$Ryur&^%y)TMFL6s1U4{K8OFbiN#mDN>Za19#EzCIzZj%b`V$$`Yk4eYSJ)ZO+7AWMw-YKy5(W}TT&IMG5lKe_)w>^kd z=S8R;!{+wnl_yrwkx;xiN(KHY5NqbQ{=A9oJQJB7%S%(1LZ#>9CD8Dw zSHzD4{R=F_geO^YHrx0zYvx4{CK_;6M*qY4a6W*eK~dg}HsCd4m65fK!N2NWsZHx$ zKAX})a1bdQ{UB>N!V;eGQ>Py^d}b^C)!i&R^yrGbX*W~bx?nIn!}-nO?gZ^SX@d5$ z%ze{HTI<6tj$s}Xsa-hG%EmwrzR=eU8&wG*#5Q2x5cL^w%B0bBjtbLRf}jUttx5@D ze^IY-a!L6~>J{3W6!|ZW1n+>VbqjT%vvaRq^m5qGgC7{VCp-GbZ7pKxzJ9rf**(=G zUbL0`(?fI5+vaqkNl*cV%{~V#NYUMU<=h0@)&iCwRMqvY?~e~yW-fm&-^*;4F-qze zJOZnt^7}q=`h5{aqycP#z#Y?*CR$>A8BB_phCnO+gN>gdbaXec$9bS}sW%wYcmH7%p;fCxvKo$_+SRZc4XNijfWOn#4|u zK%@(!gKjLE%*ju04mOx zt^3bsj9#icI@Y?XDPYjcZW1wvfRcM6>z+!@H;LHaNO?y@rFdJ~KzyDFhI>PgzTJe8 zF5toGHX?Wpklp}cb}7Ya-7Xy51Kl9*gO1qs47KdjlA-AvwLWwwpbW+Xuc;WL4N9l5 zR3bnkwyus~a2{VE9N&zO=h75ST386UYF9>H9h ztkLesx|84!CnrOMXFiHjydgQM09rnY_VA*|g$Y?O)KjQUVWp z4W`9L!c_b0dIX}7wPL9utuZt6D9remBd-ANPl$Du)EI;^`$ zeIciTIwh30M!S|o7n7E0MU;pKk#{ji&nqARAL|1t`RVNXvkCGEcr*(NCqH`P9bEYe zaaY=jDY%HML27I9@#2Iz3}Efjf1DOuBlT(C0#*Fdfc~yEzvapmKRfTF=LYQkgm54oI1)7crdd=W`JCl60s*-sNz4&l zs#-jK2LnSu$B^>%8;su;9d_46E)K`@4BZyy@Jy?@6GsDC{9)X+C(!82kUgegmw8Ga zek&iOp3h(tTraQoCck=k6BeC$t8-?{flgis#yvsy*9<>;#?pg%9}{HJZq0&Ds&`d? z`K6c&3a$*J7N*%NaOpEl!;}4vHJaRggOHxJ%$C=Ge-zn{Pj&7gd7UgkHM(Op@yGeo*lZ)wX1eN31y;~6ekN6ubp@LBwesc z3$T0Icn*c+eUOGEky*v-Z65#P3r}8z>QzBw@kORMtx5l^nP0LG99LRW`S{DepUl8e zlme-`w-B^a{uY+2MIw&Pl58RG5jNz?;}Zi`Auy^Y2Z;`|FiW+F^Y^sT2O5hW8bcfl zS5%~;sxPi3OU-YCUl4_$q$7B+1WCEg6 zLK4T<@e(|=pGjykGC%zTvEEFk&K0qv z@73F1LZ$V*HIYS0Rjj|I(i;&T_W{B{eyU4F06#Q07ej(_1SydqIpbhLOBszyG3C=33wxxfQMyB6aQJE$xT&Fpc-1F;mW#we&1GSniuVxUAG9)AER{%}uL*~KMV;?{fP6V{`qc0Pp1$)75l~`blHaCs ziB#HyY~NsU8DE1pVi?pi?*w7a)^BF(h;6t%3SOqo@mJT?rA_2|OLvNwXTM0Cn_JKB zq~1#cyol5}kfLjYjV7NG6mb6yq6tFgR84HJ&m&{Y;_-jsN=i!i-kfpdV8dDbJopuI z9r0?)?nH5Q#!Uz6LiWZR^Q0!)RStYHx;ItzK_j@V2b2d;Z z_y!e&vWxvJ;a7XTStASr8n=)U^-@r~#)q5tJHydsAt5Nae5yGnx5Ova8AY(M#a7h& z+icKN_#}oplVtIQ;jA{XL!-@5e1_(0(B=iY=95l*V>Z_l8F@xCpTn%O#<(%p7a4Vu z<6}ppBJHIlLHrF3bq@cpws=n()=J5N?!9$VbkEf~*=@*yQmSzK{iS14QV~Pe;PMgj zDHHir8_)&Dt4Yq1TADXx0jiPC;TF^cO!L&hVXvHxkWdaAESTO#4`QLIs!Vio)64gu z&Cln!`W6;8lA_BPT|mwcxYK_sTdwp=O;EqcfPxWB925auiMVRuU6H51EM1jBWS=WE z+W3U4ttomWd1aO0~pt8F+kGZgbnd`k8i7xqe(tL&|N z$~lf~JZ}5jQ?cI->=oCjy_wB)3=1>`+a`U&VqtkOSI+b;Ma_bD_9Z~bOY5jI84`@5 zqbYwIS;sg+&qSZ4vxUU++8)(H9qkA4$!Dt02Wd9Bu|NCU26Hm{8(knBjC@7y8{$~> z-F*qK9DOJNHeOy(om!@vyX3?4v&vl|VVXY?R7xzDp)k1)4txHV7GPV=ss8+YsWnSx z>fv4TsMOHsy1xwB zriS^>y<(vg-E?m9+ldq6$uBI~td@h&A56idOtYky4_@A`r9uuXK&irJB9iI&wFaT% z$S>KHVDLR@4dS32uzK5=Xz5HXu|EhHQdIaUomPGDQx>!tpiq+}5XqK%RGtk5LpjuI zLL#)Y=g?;)^h19Qd!O(``sa(C&YlOWb2!%vPsOY(Ku0t(p#Jh7OP6{FB(?G15Sehp z92;BFJSKd5P9}}TNwAA$uPPdyPj?U}Ied8JrIpb{KPTq#>Y7ZUhvYA$ZcTsxR~KWH z1r$4Cy_%9&ZP=B+7!E@H8com&m8-xjkSA->dF62};%ZB-74(@qjzO=SpM`68TNbhc zTfKD#@J!OHQQF$#+MZ%`q(zI=8a-F5%@2PqP6#)sAyvq?yd$dpZd1JR`lH{V32Ksh zz!@Vs7WuGe&W+VnqwCi{J{B;+Ub_z%hfCYHLRIMyTsB5ejl(Y&<

>pbh=Y$sIZc z<6}RN#h`bYG?=5s4BIbb$EEc2vUb{bpPb-@E?9<}u_}JVC!1#(2Tt1{u;q*i9eWU5abw^&@mR~oNQyn+Mw_N;C!kn0F`8043Z{q!41qUkW(Mc=Y< z(q9qK|2bMwhBuwr9Q+95`W_F6{K0a_wo3DzDknR;2g1(8%7;WpmS#1Ipc$f2<41g< z!{K5~-JwJt=8@Ow6+Mq0r96Is$9InQM+?7ERDAuPKOVH{IF+>gzPW{i!^f;n&ZXJb zJV81Et_%CBE#pg%jC?0e*QAi2m~r(Fe>0!wZ?E>gcc?u^YQACg3xOb1zD}|kr2~1X}IIsMC zN-Gu2>5`g<-R+Rl4dryXq>=64=7O|B2ZpO^SI@G(8Z^|dUe}LT+I48u=3ux7S<3m8|;Q_h++0pg&Ok@h6o85c=I=b0LHJUvqfi!MJ%VFy9 zq&NPJY~-<8P|%Xb-B)nW^QO_pJB0f6XAd-AQ^4#a=gC0tImpPwX(3)$4g=rR_e%)t)bd}9If6YGeMrOe$nvaR>mTv9i*FdMp1eM+vE38&g4mM+?NNWg(Op*!N11a4%IFHXX-Igo8+1eto5o*3 zA{a%xKAxQ1tJApf{9Y$-#0!G^Hu9w-ACn5p?7N7aK8Ua9Jvl*IIy|>p_Cu*v3RBwm z$#|XVSR1U|k`=4LANRMpf|~+mlI<2fmrfIq-2!$GGPs_F3#q3FLcWKsBqEaPX~b>Q z=g6tBg^am50fs#~g7Z6T3Aw7=0>MInfqa4t(75g08BsW9P6LXQs&W?A1G5%n^6Egj`HBiRtp_;$&b=dup$0!dtStQg0c8f;Wi z*W>ds7gWgwWS!^Az-FX<&XKL@jLEKHMw!xf*GJV{7wP+jT%QtuO> zGx9}FU3glK^T?==UNCS44?cHu9SUnkHfleEN+q`V5~aLdr?~hJw`G)#;BfH!%ZnGL zk)Kt`ddm4g#JgXYX&bCH@ON<0oGf;lv28COORgTk)Z&;|@%( z4_1aTE8=Gzg(=lu;NWx6SLRKolfcll@|6{?b*a5yt7>@T8Ggl@ul}VGg=`PmUz!Ixuq>0FXc*9zA#(Gd=$d-zTEh z+MZEQ?G)Fh<%UQdqLU7UH(;n#j#rJo#CNE%6RA!?pFUc2Cwlt%`-J4=eTd1(Uj+%V zUm}C@-rfr=dF(l+vy-7vSgb4V$Zum~&T!jx!BH`^5nlEDG|IDN?+HX=zBv5%eWZ%6 z;deVGwoG-ilk<2nV|&&h%_BeR*5R%w9b$)LlD%7G1OaCra`e+VVmL-*h!8AEaPB;`qy^~F9m!vwdXn_?mL`bYmHG}* z1@bPS3j`HU6B=0N6DMOsTrSb+bbMIl77!fMR-x6cS5DEf#rgKiz@W?|sVgUI@WAdZ z9Gz~(I|fk1Ow*m#jO391Bxo$>gO|yk9(z+~JsHYS-@#C7sT{o%>xHyT!LVQTg-}F$ zOLZ%hZ*ZkL!CoqBwx6IFG=O$*$K|wHa7sW+^%aeX+j(laIS%uEeUBZ;;aGc3)cP%TOHuz@8NtE_gcI;segh@S4||eia3xP?8FQ$rQLo|GqyMQTHN`8i zaD*iwcD=3z`JsC(`-1K-RcQY%Z#@iO^ggSFj8H}(v!&}36cg;*-2TSTYFTLB;U`fC z!Ms4%qk481_vZF~m#f<=(GyKG7M)*zx7E(2HWeo_#wlEOv6FBDe^j+UUh@}m;*1hq zB^`V9@%FJ0wvrbYqTfGP(p9*I>Cs4~4R8F=<@hh1+i}}Fy-VsB6%#WGc7fk*k_z+M z*vqp1^VE_T!KfXs`+G~^oYhjrYB&bn@?SFcj}J#_L=M1#VFEREjTZf-wP2|bX8rN8 zEIy?AsOBbrQ?Wt}qHC51!L4nht7L{AaKXJl_wjKS@4Y)i$f;slSvEHX>R@Bmuo=VN zwbE{66dPSlr1o^{@MM$Uvw+)X1{rPH`@xtB|4({zv@Xk(M}%Zl7u(b`++kG2IW=s9TRE>QDN}(rfA8;iWMQ?f$v0&eImCC;t?QIIJQtR)YA)iw-mEPX z=^$5U!;n#f{R!($;Bs=2s`!s@!@fK(fVP-}dNntR0@j`^27@ME+~7b8j!VaNs*(3N zZ+S^1qI9lfRdyDFFVL&3H#0(TW}CF+41+)~6Pk}LtrFR0+%bDkkysjNBx(XpR1?8kLONjs=@MJx2u>Ef^MXRuB@3IXRh?Bk*z9}aA7}Qn zGKxf<+yLZmnus6j2UQ)5Oy7g=0C5PcbidHD^3nuupOVrzfmYCF@r^4u|2>qe_gsPH zxqjGB8;%^uyKL@y%2BldL&r&R7szV4?7+A2Y&+7VR6wh zIl_nIR%>yvAQq(pNn2F_qEZCl7JEh*!|%Q(Sn;c7ED%cwStv39S(m(Y#No%DW6$3< zPd95^UA2K>p-O0aZUY;v*et(&-^>nas>=oSZad@-VgH9NZ|&9i%F>a_b)lX(Q8iA?<|A~&Q#PXudFKJlTkWTSd+ z&NK3}HZ^@n&@jdO4jMS_jBDcIYibW9b&I;rt}u(s)1UnLuej7l`AlysXuBh{)7N4r zf2_Pup6+v|F>?$#ZRxGwz1?3g`F%@j_=?ac9EMK0Eo*em&MAk9PB%sES%}wcAvHBT zY^j|o1;R!bzTLgu`F=Y!MvRht{^v(nt|5pinn#Zrv-^^URV6hf7F?ak%=-up&ANu_2s_IP*3#whzsu{RF^r&_Cd%Y<*% zDe3LqpHRGF$Hp%jLjup8)`%=H_Na|*3R6O9G!UQlfpCjlrdF;V>L?oD^h?ctn>-M! z64pzhV!H-gmt}$vq!lggq7I}du&)$Yz40oH@uM9W8+18*8xIfAnFjx6(I9{cM(`7U z_rNzUVZ^2t9YkLRl-l(wPA?4KnXj`QZgaWS_Cp3nSoQO_hIQVczwc&)r5nJJ6LJQA zTZ9gv6?Ht-1Gk9Xd6)g;M!08(PN3E01?(9)>3;N1;GMSve8(g!Bx~wmY5E57mJd%=0G3eLrmw!)es-WvzqV(c{zso*lf!p0~@zF>g;edPF30v27B zZlKkMytJ4cf%MGHPb$@?)g5PF_oPZc*iQr(& zp%eg})>0g%NmetG0D+M?@sn`RyyZ8H<@4gcXNc|vj!0Zf{qn9{%S9J1;G{8o(CN#= zvM$SeCb_x3s7M{iZe4NSw`jJEF0{Iv z4~27cjZj>Mqk10iASA_j{Ivb>Q^Lo+oFQ`5hj7ikwhB>g;a_A*>BXzVD+6pE9U4V# zp$$J|f8A8#CC94DFB9zE3dh};xaISB{X|wzT@M)2fO_TBvtN+O?DF_yFqR@e(R<*- z+KznnM{ak*T;Faw6kB$E<5jv@tjR3+JzEjw7f44pAPW7;uutVwpt;8fEh239BJ$w9 z*!y9uuBEkc7mdtOh+Ob!DF+v45>|jn6{%%Mdal4P6e_}9|I(dabrWPO3{+W1erIDF zzPot_o6vCw(|dG$)*bqA?2AJxV>&Zj24Vy3V_ZtG*nc9IZ|@aSI|I++4t^iYaxbNd zeyL7mP(?b1w8RwY%6}{Co8sf=R#LT3C17P!Cx$j1$2{$$=hiv8lp$_7{*< zVYdZ?oFR1uQgoQ{nXJ;MFCdN)Q93XLFJwh0uy_7bz|v|12Qr1BNpR4*tj-Zs!esJx zyActelBnDkfK~DAsp*tH`Hg{D^IQUIfa7&RO|$$o;_GCyEiQV;u%rk8J^O2GIWbC1<75W}!pnO9f1yoaBMVr@qEi3TKUK zkOW9k+x9XjjjVL^Kvh(=FGYb?m0yl^oPJiGVcc3*6ZV$$dLd}Q_my&nDhn9o1!R1{ zR#$`|1MFh+ter=s8u8PJJCr9CNY+#7=V7Sn2&oe_oiT?TUlz5{Ac~u;{-HhXRVKH7bIfm-{NttuZRP&vo{caWUMMe@) z8=v(3y%d9n1y@8)Gkva~v7Jx**LZF%GN`Ud4ujYrj3i*{@s<7l*153d8A1}w7$?D&Qs zyd&~1$Pt8v&Nlh20S)Gl00-bDccYuz;1eIwx`1J@D+L8Cgz78Q5W-1A*US>_zmLKz?AUR&WEu#u?5e<|!%qW7uE(Av-%CTZ{H$Qz$*q5@ zbRNPj=kE1qwIhp9y70~J1$i)SY{h^4*bYfPB^uZ>8ensz(oasL>3Rk31qI`9A!-Kv z&_X|F-kB)Oiw%Z{5jJ1BYlq_#=X&y7Er3z3y{|i70fVP`63@3?ylDoiQm0|)i5vO( zD^f)rQG=NmE$xiDi5*80g+;w`Z3pSsQyASgWMTnFJ5w(vyN)WuH4xzr+1;Rr=5q$C zW?#W3+&@xAIP!=8pW`p{C(F@Z1Ra=g>`soigw23Hp>dn52p!~+&Zv83`d|bR(rZH& zd$=<+Tl|^q#rU_rIoxGFpWf?)O$H7l? zMZZA4Mhaza7&@^!@x3OHf#}iY!PFpd3gAPkN1iq74}gaw;*4M+O6HI@$C3-wPI4zE z5Beh11u&*jt?ai3+X!x@-dXkcBAbgBzVP1r;3_n$71-4u#7F`hKy$Poay3q6O?@80 z0HlQXx7Dr^bzl&3&~9#%81(8f=ZjuUP18h;NnZphvE8_h_bG!I{V_EO;Z4w2RXp{v zK7F%=^Mdyh9g#XX8pZO^sc@nUKW63xh**YS=~yIz-1fgJu;nR9P?V?|PqbRNC^F+a zwWE}S$(aiNC;+>-ykv-(N7E45+pt2q?M(+)nB9%V$$2cX20$2#+Sn+PwXo^Bbf8MNa4J>_t2N1_d84pj zNT<{MvQWjp(={z9B)HC^9`pZAMd+=2=jdolv?cQp>I)O(i0`8 z>)d;YgBE$zKgtgsr>&jSv142Zj;xXh`)WGD%Wpda`Uhrf4meBtusZ_gjH7+mS6;V8 zt!8igax|>Gl!KScJ!m4;sV&9DnjqI|FU5Tla-O>|TqAhLJgMHGKvhm!ruPbuoKZnS zvMp}Jd_!TQg46OYft5j`AX68`i2lhn(Qhys3&ib-Sjg1StJmmDH5 zIegpo4*@N&e~7o(4&fqhh14L#cbHAG3#Y{v-Qp<@?!UIA_r#1nk}kOGk1@_YA%CT| zF@KPR1>NP(x8>`|h!%JwC7Z1yGLi-)nDhp>HMeCnNDTY9_s7Gtb8!wlrOqTx<*@!& z(n*#++6HtD6bscpXlE~>r$_TJbo%{)1T(n3iulwnT@Gt7{&3?nn+MS}9pWs=-eV9~ z1)P~hUwr*TX=V;jM4bdY(KU!gQJ}3zmjA5`LqXu-@3|e1&guj*C!Qk70LQZD>O%$s z{_!HnO}ZbW`~WkZGqCyb`Wx&yRTuLy{13ntJ?dXD;W721b#y15DnEd?BYYsx(40lT&8rT%-JbAkP8Eq79X@hQN?cLI6B9O>q z`)XD9P3YD>`3Bv=O1AA5+qmBx{1oq`)3f2eMKiEaC%Yf&Kdk||Vh#m_BG^TY3uFn5 zZo==MSTv%~`kp1CQ=@8ufb9jL<0`q>V$`GZvCPyc#6)kELiE8z?}8Fo z4zw`1disA0%4#h^2LJpCqzLF8SnO)_br#}hh(t><>q7Kxq|tZ2-SUO@fvD^{Co+He zMZ3Ap1&ZKABS>aUg9Z1AlUSV-D~wpw7n6(04q=2T9u&AfnC6VOuKZ4Ud5;~462>+E zF4sOOx-cq)ipVi0Kr$)GaPa6PGy>YvjvsdjliQr&BdfQ1v$@BkQ28 z0PGQj^lD(`P6S9u{>z&3{_*f4)Z}W9lVxZEL!E1N$X=Nk@zp)O2>PRp!B~VBt?@odBj9x(owi$739Vq+ zPk)&a;^w9nzl!{#N4F4-x*4Q+PxJ)^X45aN^$Y@$tIF)~`I#k*yH6dJK0z7BE8D4HlV-KhtsNhv8!F&#NQ#TZHSB<{Z_j^qKzl zVKf5=qb;O26NxB>J#PzQb=)VtyYIu1B5V93 z>>rt2re0UEmCIJtO*6x5@NUf*B&OKHqm{)jY`%>do5`xO^IgC{ADv9)<=jcKJt9t8 z!w})27sBh@m$@Nw;3S9wM}m=K?LVhSUEFAnq^!>T-5Q@EC@Ld7XTm6~(36x!^Bf|n zPoF?ke?3?A-pbA5?vRTfv24tPxw!2tn&NWBY#U4iJxcn*@MkdTb<+JeURSg5@ZBnz zs4w(_WP|3+Q@xS>E|o*xKlY!adB%x3A0f!S=ww91cJUe9zyD?VwMza#2iFQv_@7|8g{--D^ro9VX|s4^ulbFn+WRrmjkj0ANIwk+6)uFD>x z`FqnvboSRj?u3%s_lsofhpfG;;vLsQZum<{G7I;~bW!$_8y1q|rUcFzSv=~r;P%5i zQ*j|{mY{V)I4e+;M)rQ;M<`w68wen%Wd2=MN0D=qAhGz|-7I(hGyl8Kagx&tyCIi9 z6gqmF+L64p-spX$^B{y_Y>WgHDLWkipZ@LI*fuoxW%nBDM$yY|%R^oDV^&7bmFiDQ znH`ZqQ6lulR*&%?#ZF}|o5IR2DBtD9u^Z5$)*z~XvpT%TQ&^{Rg^&x<2~aRskCz}i zBp)8TTq)E*g9$R5(%Cd@mO+!=y|#yp8>fuiR~Ipien7+-Y@qX?xWnlldXzHwPB1r5 z0_{3zS!#hw9^`!wdZX7&@+e7@h%23}z;#eComNnMKC7$*B-6v|AUSJjADcH*(MefE zs>OeNOiE2L<}CaDuK{i$?5|!T02DwG5*F7QbdmoeNG}dBdsCZ@E`7!vc#lyG^igQi zf*+ur?qRRs#@-Z(^2-8u2s>y*5Q4OhFy54IW zW^Iac@m=L;`11*pjN0_M8*!k_i4@JS`Ay@IiDTiEro1+9OQ&xB%-~C;vYL%B$h-T*c3mn&eerzs=^USe&Ow>v4lZZb6m;&v+|3I3Z!%oin*`! z$guv?@>@Noi$UD7ae$Jx{APqBuV3E#-SeKy)+EA5eElgv%aIH2v%C z3)#qiMUfk&pz`?n_`Dq3rmnEqj+O>rtzY9m9KqI1V}nP{Dj8cN{ajtcg|jy>Jf(wg zl<$J1HLNXx%-u$Ara>jEOIYz7`D&9gTW?hedJkLkXk=|?-WzQwUq)9{-AU6$^vAG3 zf2&ER5z^LewH&^EA(;HbJW8Fa)iPicE!>;ws#36&x8+F{S(GzL7k;LWxSlRfulQuE zscT`uH2$&CUQKA4wgk`Fq_K1=WZE6$s6zGMy_?+>4QInj7S-;^#f)B2{rl$Ss42vm z{QeI`>u(5HvtD(HWih-2Q~fxF+)a zQD$ELiexxUzhKJLr>pg8diC`+b(Z_`*02!4(kGe6M=ZOBPOjr)gRze@bJsSdt7u0` zh{A_*?dfOizLl5kQ^PcB=S14c+uu;?NXVUe{0mT}5WQSqjXK$=X1}%7gofn_f6X6j z8)T0eu3b~SQZU!BzE2&^H$Sxg{aYkmbI;3(=?)3eXoc@umZtQ$hw^XwIu`zLqFjk9v`{@flu`sElcitvb9NRbIBscqobM34 z+z)LVv43qg6H!`?#kWFZAuJ@LAp1m6@`d@<8C!H1wEi`lIz*42U4-U?V)MAw=Rbch zEG%!(i=}D1FDxKk8e>e^4yh6gv-vJ)9 zm4}~QY8`5vnAwcG{@8Zcno~G}o$+BWUcGWNR<|h6bTU?_smPQ-st84tofB@LS_|Gz zWwd~)109&c-4Uk2hNx=C1TPi_T{~(}TMl*y-VnKF0yidOk6FHrWl0Zy~cQ=pRTy_XR5Qkqasjr8068On_f0E-ZK1mwZ?J9+{vRtjjg;6E$fXl zj#!S}m+q!my?qwWd`E8b>C)}=6e+0G41I#WumHFQHfE|SiX)mY`Q-}TXKLk!&Onja zTPO?odr4N$ZULo9clLVF7J0TulvEF<26gLhvmIhWnQ+Ai^twh|o1GS*3w|0`I9AR&etyNRbxZ5|0)d~#|6d<>9?fRD#{oQvXsW8VSaWIZN+~*)L8W5} zs-&evtx>@>E~RwrOSClhT3S=F)0(QK)L2W>#nOvPYHDjHR4pN@mJn+)Z+g$n{4?kN zopbU$$@9GDyx-^f{XVw?#7DMmlN)U6P|mYYaeBhg5|%w@Y71}DDzNdTc{9#q(33OU zf6F5gA(A^y7~nvr#V6ne=UV*wWR7*iwB=gzgrK_t_)L3Y5? zqVdbx&?U*-(~vUppx>!Y#ScpI2c?qh&%KL+843M@yRC2GOUVey-gN-lnB}O4=Snly z#qebmNBcxBl7f&L7i)xI@*+q@9FF(r=O&RCqYGA7-QZn5yC;@b3%59MY&QK+UMR@2}6WNqRL>RpV zk=4GD1Yd8NMwgbBejuN>?eg)})RD>!AoPseU2{G3Z$Q7lOOOU>OO~m|23lKo;@$JN ztIS)$NK`d8#OEak=KGb@jhTVt3u%L%A|g*-%8PE;-&~c*wG(-$9$MuI|5PL%QL@s+ z4k+$`8^N4p{0FL%MjX9AYWxPt>BF(*_VzKoIFl=N#943ZjlN&W=UH2ay&7kt1#CJ4 zhJ|go^lOP$INSFQZw4M!Z$`3CJrCg8r&lB4!JrQ@++g7RUaI;j<)+j`mHzgbavG+Q z;Gv-yD|ldo1w!i%P`VwSPP;B}#J{)$^mEGFO&taa-v~;yo60p-ZcrbN(R6eyW3gx{ z^jPgcFNpT=eZG;Rts??8B7^}!a-!;zg-t1+zf{-T$1ZmtO8S~- zj9rc52Hzm8DQKbtoMocT_#nSSxWMRq(^5>QyEm??VLJqgI|`AeiK4e&T_ZuYwdXse zmy7I@qJfgVLY&?Rgz5Y2AoRTUNnGyIs9}XBCOk zk)J|@Gw5B+404p{L;S#3sKL&>7~bAe^aaf?XKzBueo`06R|)2wNPFp5RPcdOpxUwo zaNl{VwD#VfckK{PGSB0K6Ed`dKw}zBO?F6>C>N;%zyUHoo_pfVsq?u7Sq$Pzx0Ur6 z7H6+5z8s2$V&3-@kYi>>3E%yu*ELk~ z(GCq%rPWs_m>iP*6gR4Fs;1DP@6OixPK!vqnC&||q83XJ8C{>a?>#49`1#KB9#~u! zE3QcAYBq!;r<73JtCZ_rtj~Nq5IlCuWpz04O`F{d;y50iKG1k9Gdf!~x~!nd7nA>X z2%2F3Wr1i4{g;-a;fHWKT0}2?Pcj!QzcV zbYVI6+A7|R&24I|EDZkHnTSF#aN8?RR@G+i1_cCOP`1>DnF-L) z&FqOR#zB*ChK_a7Q+DqpO+*HPM}x+J zb{`As$F3vsqnYVO2EBEGmUFiL!^VPgOB3*lz?5u;M_;pF+36+JdEor+P5y+JF0d7b z-I`7KF>}3o=c^ZX z{+{P5B$Cx9NnJmBl1*yZ?O0bq#U%s(3lT_+QLGI81~Ku}B47QrE6eK(-v^Dk4-whc ztdMD+Xrh#NW~(j38Pg3s9^qIL;S60aSI%UloUNOlTo}FlWLR|azY4tgA#1X2uJ@2h z8QiKVpUxPJCl1mhTp&nTh~?Z?USU9Ac0At>pHAx#voqRYE>2i+qd1w18-46ON;|M+ z^%d{q(AM$i5yw1Hhv758(w4Sr?9R>#RPM(PJKoniQ`bGx;H>FFdv!-3nB0%gDK|7s zVI-g@NsBc}Bv2&v_rrF}%jY#Nrih0Sr;xQmenL}L8Fo8S?@Y4AOV+}khjQfqEgE41 zUpSuD1UW>y{<@)lOi^rc|5?QqAWWswdk>UnE@PE-;L;(8*5SQn>qT!6qlyo0jX|vaTS%UE?(i7FRiSDgd!&Kci-AGRxzaDt@|rD&m$9 zKXzwLVTF`v*1y%%zXz7}G%_$ofdaF^9Oz0e;MOF+fE);RPL(hGsr|TrwRGfvU@i|* z1&^zIAt>BqQg%i3PbcscoqHj&&LF&(pc!oExUs;y%ZNH_uEV<@xY@i9v4mojoH@x~eiBrOZfL@9qfFZps0M#SYZ9<`A-8E}fA?(Orq|Y~hsZJU^hch#l zWhq72mMVC)mU}aACy~@vGI+|4ECE#y(M*Y_J{sp;GXaWFsAy+}yN0eamNy~!OA@Y2 zrm!K)$Nu=+UwQ?d(v>h~|@8g}faBIepe3tsr^*8-*nw3S24n*DTNJW0^h{a;(ar9V8 z?YewSG!yWf7!0%p_M2o?4O2?0eH|LnKv7G|0lm)q#y~}a#`)U72*8Ar`FkiHCsj4r zgGRBXE-H;w#IkANh$YY=yFIQjxe#V zr(5xGojzG)LEQVTSh7EJ-5ATaCh0~2h#ROE)a9CYBlSYs;Fart{j%e!gg-adq~H*+ zo`B-=+V`IbuWv*07W{Yvo|sV2(}x E1IqmwegFUf literal 19307 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

>pbh=Y$sIZc z<6}RN#h`bYG?=5s4BIbb$EEc2vUb{bpPb-@E?9<}u_}JVC!1#(2Tt1{u;q*i9eWU5abw^&@mR~oNQyn+Mw_N;C!kn0F`8043Z{q!41qUkW(Mc=Y< z(q9qK|2bMwhBuwr9Q+95`W_F6{K0a_wo3DzDknR;2g1(8%7;WpmS#1Ipc$f2<41g< z!{K5~-JwJt=8@Ow6+Mq0r96Is$9InQM+?7ERDAuPKOVH{IF+>gzPW{i!^f;n&ZXJb zJV81Et_%CBE#pg%jC?0e*QAi2m~r(Fe>0!wZ?E>gcc?u^YQACg3xOb1zD}|kr2~1X}IIsMC zN-Gu2>5`g<-R+Rl4dryXq>=64=7O|B2ZpO^SI@G(8Z^|dUe}LT+I48u=3ux7S<3m8|;Q_h++0pg&Ok@h6o85c=I=b0LHJUvqfi!MJ%VFy9 zq&NPJY~-<8P|%Xb-B)nW^QO_pJB0f6XAd-AQ^4#a=gC0tImpPwX(3)$4g=rR_e%)t)bd}9If6YGeMrOe$nvaR>mTv9i*FdMp1eM+vE38&g4mM+?NNWg(Op*!N11a4%IFHXX-Igo8+1eto5o*3 zA{a%xKAxQ1tJApf{9Y$-#0!G^Hu9w-ACn5p?7N7aK8Ua9Jvl*IIy|>p_Cu*v3RBwm z$#|XVSR1U|k`=4LANRMpf|~+mlI<2fmrfIq-2!$GGPs_F3#q3FLcWKsBqEaPX~b>Q z=g6tBg^am50fs#~g7Z6T3Aw7=0>MInfqa4t(75g08BsW9P6LXQs&W?A1G5%n^6Egj`HBiRtp_;$&b=dup$0!dtStQg0c8f;Wi z*W>ds7gWgwWS!^Az-FX<&XKL@jLEKHMw!xf*GJV{7wP+jT%QtuO> zGx9}FU3glK^T?==UNCS44?cHu9SUnkHfleEN+q`V5~aLdr?~hJw`G)#;BfH!%ZnGL zk)Kt`ddm4g#JgXYX&bCH@ON<0oGf;lv28COORgTk)Z&;|@%( z4_1aTE8=Gzg(=lu;NWx6SLRKolfcll@|6{?b*a5yt7>@T8Ggl@ul}VGg=`PmUz!Ixuq>0FXc*9zA#(Gd=$d-zTEh z+MZEQ?G)Fh<%UQdqLU7UH(;n#j#rJo#CNE%6RA!?pFUc2Cwlt%`-J4=eTd1(Uj+%V zUm}C@-rfr=dF(l+vy-7vSgb4V$Zum~&T!jx!BH`^5nlEDG|IDN?+HX=zBv5%eWZ%6 z;deVGwoG-ilk<2nV|&&h%_BeR*5R%w9b$)LlD%7G1OaCra`e+VVmL-*h!8AEaPB;`qy^~F9m!vwdXn_?mL`bYmHG}* z1@bPS3j`HU6B=0N6DMOsTrSb+bbMIl77!fMR-x6cS5DEf#rgKiz@W?|sVgUI@WAdZ z9Gz~(I|fk1Ow*m#jO391Bxo$>gO|yk9(z+~JsHYS-@#C7sT{o%>xHyT!LVQTg-}F$ zOLZ%hZ*ZkL!CoqBwx6IFG=O$*$K|wHa7sW+^%aeX+j(laIS%uEeUBZ;;aGc3)cP%TOHuz@8NtE_gcI;segh@S4||eia3xP?8FQ$rQLo|GqyMQTHN`8i zaD*iwcD=3z`JsC(`-1K-RcQY%Z#@iO^ggSFj8H}(v!&}36cg;*-2TSTYFTLB;U`fC z!Ms4%qk481_vZF~m#f<=(GyKG7M)*zx7E(2HWeo_#wlEOv6FBDe^j+UUh@}m;*1hq zB^`V9@%FJ0wvrbYqTfGP(p9*I>Cs4~4R8F=<@hh1+i}}Fy-VsB6%#WGc7fk*k_z+M z*vqp1^VE_T!KfXs`+G~^oYhjrYB&bn@?SFcj}J#_L=M1#VFEREjTZf-wP2|bX8rN8 zEIy?AsOBbrQ?Wt}qHC51!L4nht7L{AaKXJl_wjKS@4Y)i$f;slSvEHX>R@Bmuo=VN zwbE{66dPSlr1o^{@MM$Uvw+)X1{rPH`@xtB|4({zv@Xk(M}%Zl7u(b`++kG2IW=s9TRE>QDN}(rfA8;iWMQ?f$v0&eImCC;t?QIIJQtR)YA)iw-mEPX z=^$5U!;n#f{R!($;Bs=2s`!s@!@fK(fVP-}dNntR0@j`^27@ME+~7b8j!VaNs*(3N zZ+S^1qI9lfRdyDFFVL&3H#0(TW}CF+41+)~6Pk}LtrFR0+%bDkkysjNBx(XpR1?8kLONjs=@MJx2u>Ef^MXRuB@3IXRh?Bk*z9}aA7}Qn zGKxf<+yLZmnus6j2UQ)5Oy7g=0C5PcbidHD^3nuupOVrzfmYCF@r^4u|2>qe_gsPH zxqjGB8;%^uyKL@y%2BldL&r&R7szV4?7+A2Y&+7VR6wh zIl_nIR%>yvAQq(pNn2F_qEZCl7JEh*!|%Q(Sn;c7ED%cwStv39S(m(Y#No%DW6$3< zPd95^UA2K>p-O0aZUY;v*et(&-^>nas>=oSZad@-VgH9NZ|&9i%F>a_b)lX(Q8iA?<|A~&Q#PXudFKJlTkWTSd+ z&NK3}HZ^@n&@jdO4jMS_jBDcIYibW9b&I;rt}u(s)1UnLuej7l`AlysXuBh{)7N4r zf2_Pup6+v|F>?$#ZRxGwz1?3g`F%@j_=?ac9EMK0Eo*em&MAk9PB%sES%}wcAvHBT zY^j|o1;R!bzTLgu`F=Y!MvRht{^v(nt|5pinn#Zrv-^^URV6hf7F?ak%=-up&ANu_2s_IP*3#whzsu{RF^r&_Cd%Y<*% zDe3LqpHRGF$Hp%jLjup8)`%=H_Na|*3R6O9G!UQlfpCjlrdF;V>L?oD^h?ctn>-M! z64pzhV!H-gmt}$vq!lggq7I}du&)$Yz40oH@uM9W8+18*8xIfAnFjx6(I9{cM(`7U z_rNzUVZ^2t9YkLRl-l(wPA?4KnXj`QZgaWS_Cp3nSoQO_hIQVczwc&)r5nJJ6LJQA zTZ9gv6?Ht-1Gk9Xd6)g;M!08(PN3E01?(9)>3;N1;GMSve8(g!Bx~wmY5E57mJd%=0G3eLrmw!)es-WvzqV(c{zso*lf!p0~@zF>g;edPF30v27B zZlKkMytJ4cf%MGHPb$@?)g5PF_oPZc*iQr(& zp%eg})>0g%NmetG0D+M?@sn`RyyZ8H<@4gcXNc|vj!0Zf{qn9{%S9J1;G{8o(CN#= zvM$SeCb_x3s7M{iZe4NSw`jJEF0{Iv z4~27cjZj>Mqk10iASA_j{Ivb>Q^Lo+oFQ`5hj7ikwhB>g;a_A*>BXzVD+6pE9U4V# zp$$J|f8A8#CC94DFB9zE3dh};xaISB{X|wzT@M)2fO_TBvtN+O?DF_yFqR@e(R<*- z+KznnM{ak*T;Faw6kB$E<5jv@tjR3+JzEjw7f44pAPW7;uutVwpt;8fEh239BJ$w9 z*!y9uuBEkc7mdtOh+Ob!DF+v45>|jn6{%%Mdal4P6e_}9|I(dabrWPO3{+W1erIDF zzPot_o6vCw(|dG$)*bqA?2AJxV>&Zj24Vy3V_ZtG*nc9IZ|@aSI|I++4t^iYaxbNd zeyL7mP(?b1w8RwY%6}{Co8sf=R#LT3C17P!Cx$j1$2{$$=hiv8lp$_7{*< zVYdZ?oFR1uQgoQ{nXJ;MFCdN)Q93XLFJwh0uy_7bz|v|12Qr1BNpR4*tj-Zs!esJx zyActelBnDkfK~DAsp*tH`Hg{D^IQUIfa7&RO|$$o;_GCyEiQV;u%rk8J^O2GIWbC1<75W}!pnO9f1yoaBMVr@qEi3TKUK zkOW9k+x9XjjjVL^Kvh(=FGYb?m0yl^oPJiGVcc3*6ZV$$dLd}Q_my&nDhn9o1!R1{ zR#$`|1MFh+ter=s8u8PJJCr9CNY+#7=V7Sn2&oe_oiT?TUlz5{Ac~u;{-HhXRVKH7bIfm-{NttuZRP&vo{caWUMMe@) z8=v(3y%d9n1y@8)Gkva~v7Jx**LZF%GN`Ud4ujYrj3i*{@s<7l*153d8A1}w7$?D&Qs zyd&~1$Pt8v&Nlh20S)Gl00-bDccYuz;1eIwx`1J@D+L8Cgz78Q5W-1A*US>_zmLKz?AUR&WEu#u?5e<|!%qW7uE(Av-%CTZ{H$Qz$*q5@ zbRNPj=kE1qwIhp9y70~J1$i)SY{h^4*bYfPB^uZ>8ensz(oasL>3Rk31qI`9A!-Kv z&_X|F-kB)Oiw%Z{5jJ1BYlq_#=X&y7Er3z3y{|i70fVP`63@3?ylDoiQm0|)i5vO( zD^f)rQG=NmE$xiDi5*80g+;w`Z3pSsQyASgWMTnFJ5w(vyN)WuH4xzr+1;Rr=5q$C zW?#W3+&@xAIP!=8pW`p{C(F@Z1Ra=g>`soigw23Hp>dn52p!~+&Zv83`d|bR(rZH& zd$=<+Tl|^q#rU_rIoxGFpWf?)O$H7l? zMZZA4Mhaza7&@^!@x3OHf#}iY!PFpd3gAPkN1iq74}gaw;*4M+O6HI@$C3-wPI4zE z5Beh11u&*jt?ai3+X!x@-dXkcBAbgBzVP1r;3_n$71-4u#7F`hKy$Poay3q6O?@80 z0HlQXx7Dr^bzl&3&~9#%81(8f=ZjuUP18h;NnZphvE8_h_bG!I{V_EO;Z4w2RXp{v zK7F%=^Mdyh9g#XX8pZO^sc@nUKW63xh**YS=~yIz-1fgJu;nR9P?V?|PqbRNC^F+a zwWE}S$(aiNC;+>-ykv-(N7E45+pt2q?M(+)nB9%V$$2cX20$2#+Sn+PwXo^Bbf8MNa4J>_t2N1_d84pj zNT<{MvQWjp(={z9B)HC^9`pZAMd+=2=jdolv?cQp>I)O(i0`8 z>)d;YgBE$zKgtgsr>&jSv142Zj;xXh`)WGD%Wpda`Uhrf4meBtusZ_gjH7+mS6;V8 zt!8igax|>Gl!KScJ!m4;sV&9DnjqI|FU5Tla-O>|TqAhLJgMHGKvhm!ruPbuoKZnS zvMp}Jd_!TQg46OYft5j`AX68`i2lhn(Qhys3&ib-Sjg1StJmmDH5 zIegpo4*@N&e~7o(4&fqhh14L#cbHAG3#Y{v-Qp<@?!UIA_r#1nk}kOGk1@_YA%CT| zF@KPR1>NP(x8>`|h!%JwC7Z1yGLi-)nDhp>HMeCnNDTY9_s7Gtb8!wlrOqTx<*@!& z(n*#++6HtD6bscpXlE~>r$_TJbo%{)1T(n3iulwnT@Gt7{&3?nn+MS}9pWs=-eV9~ z1)P~hUwr*TX=V;jM4bdY(KU!gQJ}3zmjA5`LqXu-@3|e1&guj*C!Qk70LQZD>O%$s z{_!HnO}ZbW`~WkZGqCyb`Wx&yRTuLy{13ntJ?dXD;W721b#y15DnEd?BYYsx(40lT&8rT%-JbAkP8Eq79X@hQN?cLI6B9O>q z`)XD9P3YD>`3Bv=O1AA5+qmBx{1oq`)3f2eMKiEaC%Yf&Kdk||Vh#m_BG^TY3uFn5 zZo==MSTv%~`kp1CQ=@8ufb9jL<0`q>V$`GZvCPyc#6)kELiE8z?}8Fo z4zw`1disA0%4#h^2LJpCqzLF8SnO)_br#}hh(t><>q7Kxq|tZ2-SUO@fvD^{Co+He zMZ3Ap1&ZKABS>aUg9Z1AlUSV-D~wpw7n6(04q=2T9u&AfnC6VOuKZ4Ud5;~462>+E zF4sOOx-cq)ipVi0Kr$)GaPa6PGy>YvjvsdjliQr&BdfQ1v$@BkQ28 z0PGQj^lD(`P6S9u{>z&3{_*f4)Z}W9lVxZEL!E1N$X=Nk@zp)O2>PRp!B~VBt?@odBj9x(owi$739Vq+ zPk)&a;^w9nzl!{#N4F4-x*4Q+PxJ)^X45aN^$Y@$tIF)~`I#k*yH6dJK0z7BE8D4HlV-KhtsNhv8!F&#NQ#TZHSB<{Z_j^qKzl zVKf5=qb;O26NxB>J#PzQb=)VtyYIu1B5V93 z>>rt2re0UEmCIJtO*6x5@NUf*B&OKHqm{)jY`%>do5`xO^IgC{ADv9)<=jcKJt9t8 z!w})27sBh@m$@Nw;3S9wM}m=K?LVhSUEFAnq^!>T-5Q@EC@Ld7XTm6~(36x!^Bf|n zPoF?ke?3?A-pbA5?vRTfv24tPxw!2tn&NWBY#U4iJxcn*@MkdTb<+JeURSg5@ZBnz zs4w(_WP|3+Q@xS>E|o*xKlY!adB%x3A0f!S=ww91cJUe9zyD?VwMza#2iFQv_@7|8g{--D^ro9VX|s4^ulbFn+WRrmjkj0ANIwk+6)uFD>x z`FqnvboSRj?u3%s_lsofhpfG;;vLsQZum<{G7I;~bW!$_8y1q|rUcFzSv=~r;P%5i zQ*j|{mY{V)I4e+;M)rQ;M<`w68wen%Wd2=MN0D=qAhGz|-7I(hGyl8Kagx&tyCIi9 z6gqmF+L64p-spX$^B{y_Y>WgHDLWkipZ@LI*fuoxW%nBDM$yY|%R^oDV^&7bmFiDQ znH`ZqQ6lulR*&%?#ZF}|o5IR2DBtD9u^Z5$)*z~XvpT%TQ&^{Rg^&x<2~aRskCz}i zBp)8TTq)E*g9$R5(%Cd@mO+!=y|#yp8>fuiR~Ipien7+-Y@qX?xWnlldXzHwPB1r5 z0_{3zS!#hw9^`!wdZX7&@+e7@h%23}z;#eComNnMKC7$*B-6v|AUSJjADcH*(MefE zs>OeNOiE2L<}CaDuK{i$?5|!T02DwG5*F7QbdmoeNG}dBdsCZ@E`7!vc#lyG^igQi zf*+ur?qRRs#@-Z(^2-8u2s>y*5Q4OhFy54IW zW^Iac@m=L;`11*pjN0_M8*!k_i4@JS`Ay@IiDTiEro1+9OQ&xB%-~C;vYL%B$h-T*c3mn&eerzs=^USe&Ow>v4lZZb6m;&v+|3I3Z!%oin*`! z$guv?@>@Noi$UD7ae$Jx{APqBuV3E#-SeKy)+EA5eElgv%aIH2v%C z3)#qiMUfk&pz`?n_`Dq3rmnEqj+O>rtzY9m9KqI1V}nP{Dj8cN{ajtcg|jy>Jf(wg zl<$J1HLNXx%-u$Ara>jEOIYz7`D&9gTW?hedJkLkXk=|?-WzQwUq)9{-AU6$^vAG3 zf2&ER5z^LewH&^EA(;HbJW8Fa)iPicE!>;ws#36&x8+F{S(GzL7k;LWxSlRfulQuE zscT`uH2$&CUQKA4wgk`Fq_K1=WZE6$s6zGMy_?+>4QInj7S-;^#f)B2{rl$Ss42vm z{QeI`>u(5HvtD(HWih-2Q~fxF+)a zQD$ELiexxUzhKJLr>pg8diC`+b(Z_`*02!4(kGe6M=ZOBPOjr)gRze@bJsSdt7u0` zh{A_*?dfOizLl5kQ^PcB=S14c+uu;?NXVUe{0mT}5WQSqjXK$=X1}%7gofn_f6X6j z8)T0eu3b~SQZU!BzE2&^H$Sxg{aYkmbI;3(=?)3eXoc@umZtQ$hw^XwIu`zLqFjk9v`{@flu`sElcitvb9NRbIBscqobM34 z+z)LVv43qg6H!`?#kWFZAuJ@LAp1m6@`d@<8C!H1wEi`lIz*42U4-U?V)MAw=Rbch zEG%!(i=}D1FDxKk8e>e^4yh6gv-vJ)9 zm4}~QY8`5vnAwcG{@8Zcno~G}o$+BWUcGWNR<|h6bTU?_smPQ-st84tofB@LS_|Gz zWwd~)109&c-4Uk2hNx=C1TPi_T{~(}TMl*y-VnKF0yidOk6FHrWl0Zy~cQ=pRTy_XR5Qkqasjr8068On_f0E-ZK1mwZ?J9+{vRtjjg;6E$fXl zj#!S}m+q!my?qwWd`E8b>C)}=6e+0G41I#WumHFQHfE|SiX)mY`Q-}TXKLk!&Onja zTPO?odr4N$ZULo9clLVF7J0TulvEF<26gLhvmIhWnQ+Ai^twh|o1GS*3w|0`I9AR&etyNRbxZ5|0)d~#|6d<>9?fRD#{oQvXsW8VSaWIZN+~*)L8W5} zs-&evtx>@>E~RwrOSClhT3S=F)0(QK)L2W>#nOvPYHDjHR4pN@mJn+)Z+g$n{4?kN zopbU$$@9GDyx-^f{XVw?#7DMmlN)U6P|mYYaeBhg5|%w@Y71}DDzNdTc{9#q(33OU zf6F5gA(A^y7~nvr#V6ne=UV*wWR7*iwB=gzgrK_t_)L3Y5? zqVdbx&?U*-(~vUppx>!Y#ScpI2c?qh&%KL+843M@yRC2GOUVey-gN-lnB}O4=Snly z#qebmNBcxBl7f&L7i)xI@*+q@9FF(r=O&RCqYGA7-QZn5yC;@b3%59MY&QK+UMR@2}6WNqRL>RpV zk=4GD1Yd8NMwgbBejuN>?eg)})RD>!AoPseU2{G3Z$Q7lOOOU>OO~m|23lKo;@$JN ztIS)$NK`d8#OEak=KGb@jhTVt3u%L%A|g*-%8PE;-&~c*wG(-$9$MuI|5PL%QL@s+ z4k+$`8^N4p{0FL%MjX9AYWxPt>BF(*_VzKoIFl=N#943ZjlN&W=UH2ay&7kt1#CJ4 zhJ|go^lOP$INSFQZw4M!Z$`3CJrCg8r&lB4!JrQ@++g7RUaI;j<)+j`mHzgbavG+Q z;Gv-yD|ldo1w!i%P`VwSPP;B}#J{)$^mEGFO&taa-v~;yo60p-ZcrbN(R6eyW3gx{ z^jPgcFNpT=eZG;Rts??8B7^}!a-!;zg-t1+zf{-T$1ZmtO8S~- zj9rc52Hzm8DQKbtoMocT_#nSSxWMRq(^5>QyEm??VLJqgI|`AeiK4e&T_ZuYwdXse zmy7I@qJfgVLY&?Rgz5Y2AoRTUNnGyIs9}XBCOk zk)J|@Gw5B+404p{L;S#3sKL&>7~bAe^aaf?XKzBueo`06R|)2wNPFp5RPcdOpxUwo zaNl{VwD#VfckK{PGSB0K6Ed`dKw}zBO?F6>C>N;%zyUHoo_pfVsq?u7Sq$Pzx0Ur6 z7H6+5z8s2$V&3-@kYi>>3E%yu*ELk~ z(GCq%rPWs_m>iP*6gR4Fs;1DP@6OixPK!vqnC&||q83XJ8C{>a?>#49`1#KB9#~u! zE3QcAYBq!;r<73JtCZ_rtj~Nq5IlCuWpz04O`F{d;y50iKG1k9Gdf!~x~!nd7nA>X z2%2F3Wr1i4{g;-a;fHWKT0}2?Pcj!QzcV zbYVI6+A7|R&24I|EDZkHnTSF#aN8?RR@G+i1_cCOP`1>DnF-L) z&FqOR#zB*ChK_a7Q+DqpO+*HPM}x+J zb{`As$F3vsqnYVO2EBEGmUFiL!^VPgOB3*lz?5u;M_;pF+36+JdEor+P5y+JF0d7b z-I`7KF>}3o=c^ZX z{+{P5B$Cx9NnJmBl1*yZ?O0bq#U%s(3lT_+QLGI81~Ku}B47QrE6eK(-v^Dk4-whc ztdMD+Xrh#NW~(j38Pg3s9^qIL;S60aSI%UloUNOlTo}FlWLR|azY4tgA#1X2uJ@2h z8QiKVpUxPJCl1mhTp&nTh~?Z?USU9Ac0At>pHAx#voqRYE>2i+qd1w18-46ON;|M+ z^%d{q(AM$i5yw1Hhv758(w4Sr?9R>#RPM(PJKoniQ`bGx;H>FFdv!-3nB0%gDK|7s zVI-g@NsBc}Bv2&v_rrF}%jY#Nrih0Sr;xQmenL}L8Fo8S?@Y4AOV+}khjQfqEgE41 zUpSuD1UW>y{<@)lOi^rc|5?QqAWWswdk>UnE@PE-;L;(8*5SQn>qT!6qlyo0jX|vaTS%UE?(i7FRiSDgd!&Kci-AGRxzaDt@|rD&m$9 zKXzwLVTF`v*1y%%zXz7}G%_$ofdaF^9Oz0e;MOF+fE);RPL(hGsr|TrwRGfvU@i|* z1&^zIAt>BqQg%i3PbcscoqHj&&LF&(pc!oExUs;y%ZNH_uEV<@xY@i9v4mojoH@x~eiBrOZfL@9qfFZps0M#SYZ9<`A-8E}fA?(Orq|Y~hsZJU^hch#l zWhq72mMVC)mU}aACy~@vGI+|4ECE#y(M*Y_J{sp;GXaWFsAy+}yN0eamNy~!OA@Y2 zrm!K)$Nu=+UwQ?d(v>h~|@8g}faBIepe3tsr^*8-*nw3S24n*DTNJW0^h{a;(ar9V8 z?YewSG!yWf7!0%p_M2o?4O2?0eH|LnKv7G|0lm)q#y~}a#`)U72*8Ar`FkiHCsj4r zgGRBXE-H;w#IkANh$YY=yFIQjxe#V zr(5xGojzG)LEQVTSh7EJ-5ATaCh0~2h#ROE)a9CYBlSYs;Fart{j%e!gg-adq~H*+ zo`B-=+V`IbuWv*07W{Yvo|sV2(}x E1IqmwegFUf literal 19307 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 q_)_gXIh@oSbh_I{x literal 4083 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 literal 2410 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 diff --git a/patches/src/main/resources/music/branding/afn_red/launcher/mipmap-mdpi/ic_launcher_release.png b/patches/src/main/resources/music/branding/afn_red/launcher/mipmap-mdpi/ic_launcher_release.png index ebf57c2c0b205b4e44f80b036497eef4cb28eaba..056110fb3dabb2aec8773a94a266b5ed596866d2 100644 GIT binary patch delta 2729 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 delta 1647 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 literal 5383 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 R=f?m5002ovPDHLkV1gtKzvch{ diff --git a/patches/src/main/resources/music/branding/afn_red/launcher/mipmap-xxhdpi/adaptiveproduct_youtube_music_foreground_color_108.png b/patches/src/main/resources/music/branding/afn_red/launcher/mipmap-xxhdpi/adaptiveproduct_youtube_music_foreground_color_108.png index 84d1d81cb146e5050159f960b015ed89644e5e97..88ad126c4454ca6413990d38101f4a3f9b6e21f4 100644 GIT binary patch literal 6842 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 literal 11374 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 diff --git a/patches/src/main/resources/music/branding/afn_red/launcher/mipmap-xxxhdpi/ic_launcher_release.png b/patches/src/main/resources/music/branding/afn_red/launcher/mipmap-xxxhdpi/ic_launcher_release.png index 0894c72f307756b1018d115f5765b649c9793a58..9450ec944a8abad03e3a25a45f3e9bd3f3f83d05 100644 GIT binary patch literal 8511 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 literal 8160 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 diff --git a/patches/src/main/resources/music/branding/afn_red/splash/drawable-hdpi/record.png b/patches/src/main/resources/music/branding/afn_red/splash/drawable-hdpi/record.png index b9de7c89c35ba9ce7439589e925d478a45be14ab..2faa8665ba265203ab9b1d3a0911ae2e8bf1f6aa 100644 GIT binary patch literal 8301 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 literal 6797 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 diff --git a/patches/src/main/resources/music/branding/afn_red/splash/drawable-large-hdpi/record.png b/patches/src/main/resources/music/branding/afn_red/splash/drawable-large-hdpi/record.png index 5859963e75b5e3d9e1fcc8c11f824cd5521dc1eb..7cc75e66cced7324cf08afc1dc41b35facdf5b2b 100644 GIT binary patch literal 14341 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 Xy-kTNZrg!ppfGs4`njxgN@xNA%IEL! diff --git a/patches/src/main/resources/music/branding/afn_red/splash/drawable-large-mdpi/record.png b/patches/src/main/resources/music/branding/afn_red/splash/drawable-large-mdpi/record.png index 61d466154e16a122e6581c4d46bdef60a6cf740d..190464c85f7c305489b68a8e366b059317848346 100644 GIT binary patch literal 8684 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 literal 9039 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 BC6)jH diff --git a/patches/src/main/resources/music/branding/afn_red/splash/drawable-large-xhdpi/record.png b/patches/src/main/resources/music/branding/afn_red/splash/drawable-large-xhdpi/record.png index 5b34f7983d83ea610edf7e4e2cf0c1948817d8d8..b9bba9b879dc28a4fc8a1720cba7e1aa1f23a52e 100644 GIT binary patch literal 18972 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

`&#q&PWTOX6)CRX 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 diff --git a/patches/src/main/resources/music/branding/afn_red/splash/drawable-mdpi/record.png b/patches/src/main/resources/music/branding/afn_red/splash/drawable-mdpi/record.png index 03547727e22305c8a7b288708308a623c754bb68..3622cd9c3d39b825ef275e6435001159266dc051 100644 GIT binary patch literal 5445 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 LNkvXXu0mjfP6HJ7 diff --git a/patches/src/main/resources/music/branding/afn_red/splash/drawable-xhdpi/record.png b/patches/src/main/resources/music/branding/afn_red/splash/drawable-xhdpi/record.png index 176c876cd26f1242fc2bdf044b98f4884fc3c38e..ad72d53142b8d1a26ce578d8a0df94dd785ee264 100644 GIT binary patch literal 10663 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 Nnu<2KPRaKD{{ba<+hG6z literal 11634 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 diff --git a/patches/src/main/resources/music/branding/afn_red/splash/drawable-xlarge-hdpi/record.png b/patches/src/main/resources/music/branding/afn_red/splash/drawable-xlarge-hdpi/record.png index dbb56cc2d7932e9cfb5e2cddab8fe96c14cb2278..87afd219685eeb25a9ef03cd9f1817953aa3cc3f 100644 GIT binary patch literal 16568 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 TXdd`S0*bp(Q-d-+=eYk5yC~Z< literal 23779 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�GCctG9 z%xNh3h`OIBeQEzsep!3Lf7CtcyW2(Mr_}}D6_e%Ab_OFZbNx;1nOlAiHZ}&vq-q2k zg?XEXshMS&c!iOVn5t6dRkE+aTvUO@`n61 zj8g~bm+HRbjx8`pJ3~?}ACbk7;}B9Aww^)44B5Y$vt)Z4d)+7!RjR}*I)_%DP@A7v zKFMFspy~M^@;6o2)VMs@OTN5aMCkR*HH___{fWz^>2fG2YL{)IMQw*;1!{`V+dk+r zK$@GtQ(n0{IC{%+-2tz>2c!o3ZxdhH*>_VbEiiZ3)Z$}wsYFX*7Wm-2OF;EpIQloW zmO{TiL&C5tIqy2WyE4)=K8@qS`J)WC^=9pO})6_ig7K!@Xd^NkawgC zkKXH!lC$DU=sC%8m8oQXu$j?)9^gDI~q&cVogs0^EGZ&gk zD>)OS`YDlc|43?mvA+kLm&}KTvINS(TWd&$%G6hL#J>{fd4wypD*$xLG<{?m9+zGo zhh0EAaQs#CyZv-yJrDT>xjn2mFGQ}a2+b!J*p8*C>@{ya?&?9$jYRvc-MCbj2+MSx zBE|QLfM!EeD+uu?d8cc5y0k)FjUN_zx(mqYKho`~72yU<66M5b(8OV<^BFK>UPI;X zlt=M5w@)RqV#?u*i-|gKXUCj)bxTuafklT}f$uPnjb7(ysHEGZV-FASP_3bu3-PQz zty%GfE~G1uG|gjr>-k*+eLFn+a=G5(ko#aLM!Ox-)LVD8u=I_u1GZ2hs`o-!vj)4zf7`ff7jcB0_QhXZ6C={E+a=Y3NtLFz58* zJ{th7tY*T{0%Neaz3uIEL7I#eu#uXKiS)ijkE75Mal(J!^=xNx0gfl3&OI*oHz7wU+6+$HtE7gQqn_tk|@mb_`fv%SXim%sPdy}0eu!?|Rn+8D)I&too4 zukl1R8f?fbW!TvJO16FMoB;ivCGRmYI7nEzJ)>z?@J#G>Lk`i{}&-MlvS zSv^Aex~(QC$(tnIhOc~84kxA*nOFRq9+gI?GM%9RwSCk!mc0Lk4?}eg?x4fFd%;_! zVAPbjqzhPtnq8T2=cA;`oD3)Ydq=DSef;DhX;j%Ya&d+cPLC&qv8~7PGM5SnZdbCv zLcF{>TVfQ7osty^f5N@fAIH`HeovQ1chf&v;%|poj;1oU60pRZK|^l5|)t9wch5)*0TkD+SJ@7JBKf>u^Vxo22~Jj z%8xIVRfHnV_8~G`UdUY0uM>fBu=(5u-^F9@HH0hZXIFwBenmns-nk1?qX z@{ETLl&1+RbdcK;F&bLslR>XP0<8!L5%F-2qA}4{Tj(lDYWBnyD6y~!vwDpFkAJ^_ z-&*^tt7(x+j(=fG>PRBS{9Fu2Hb(L{vuu)rw@Ig+65&nAsLdO0T~RWuwIBUic0}Us@nWJ2M{Z5oHuC(&6u6Qor#G` zhW29~--%*J@uVYF0KMrozB5(@?J^c4aOYsZ-l=)fe)Mz(G7jgxQEq&?Aht>i}rJm$A3Md{7YwjxwRxn#c#sVtDf zf^tPto=l7`UH^$|s7t=SlgiLvAX5-Z%loG#$5FG-SH6ZCBa{@+V(*WVcTJ*#fQEc% zSzommQBQ2Z=0>;tJ4@j2E7rut2g$X?m7=x9*KgmB!n_ThnPv}GI9WUazd?A~tiakc zMc~tTG-i>r>mEKFUeK*29DN^4x7Xe(a<>RW(+ND9!s z3x0E;sJv8t|rlGRyq z@`R(r+OqYrs+z!t*k!})^OK3RB^!vk`9fsmc&S4#F;3n=R`=nw5cgv_+_mJdCY<3< z<&neoH~1dsk?)PNzRGN1EpC(8Y*x*ZRIeI1Drr09w0;hd@-I{Xxk;o0e@S;nw?Eo# zN?ZO?!M;d?`|p8o7j|73-~B|gQ1b5o)Z<}OD+b1Z$ag7H3>|T{>FYB4=ZA;AT zB0XR5#Kn6`xZM&A>tx?t=aO#b-{2@hKWKstOzxcZC2A$>v7{Y#KG)RUUqXH1J$S!n zsb>JkYfTzcovQF}%OV3Y936!oZ~m9l<9zlfmE$E8L9_HiyF{td6j|U+h@P~BKNH+F zPx4VJ3Py#?(|0Xu4xddx)FUTN1lZi!gm9`sRa^sI$1=KTGZw>D>z|WfaE;|clB8Sn zndXg_J*&&~gH7qa?gEB40|A~28jGG`acXfVW>MiGLpdij&E1L8h2U$q7DKF)pV80K zqvDMtA3|a>0pNK)oIO;r+L&8`=a+-Jrb&VI1mreD^&1`kZ>g9F(J$W4(>Wmu)=UaC z_S&%h7woL8lLHdFAT4Di)fBbA$CK&{Id_Gc0e;>$cXNVKv!!_K=HiAY*{A8MrJ?Yz z;PIzCjr;ac%;xlGeMHUDRJ_Std53YEYDq|`>Llm0s^q=tDtNv)Ab;VQ#T2;R6tv@;e^j*AWo8_mCMVJ!~uZiV^7r zXdY}J;s`d}LJasjuir2?n^x`(W+U-k5XCt;bZIiNCwxkkcB~Xieg<4j02r@qMx%g*sL_%*Sg`~{2S^o3|9VrTsYWy`2s%Jsvd}P0B6L;p?-2#6>@{jqsyY0v7OGY-+WR*T zt{1XZf)-aBg8~U1EsuvF3h+rn+R*oA6C<@6PAT7Sd!`&%?Ib#E#V7_E4My5E!!T5Y z{#X{$s{DO$mo!LOi>2xCdGan;*hB#k>Rrqa%Sq!em89a@&Ehvl|6KUNQ-)C`3cMWP zXyqZiE%2>7Y!>kx!7-=55Z;=x+Ot?ol*UD36Xi6Ry3!}hkUE+2^^UFrDm9F6AZP5_jP+8D25xT=x~F6TY@@WFuf z9OU^ZX?|}>SN>gsvxm06Pn_Elsb3)dF>>>i|90=Zq2btLnKDBKIs{ZRrF<9OF2l}} z>@5XmKrvrmSh9FJ^g^eAFNAFC411;%$wKd4{F~PmXf@X3AKyZdB)yqpjwunScck)O{pa8#EC#HOUvF-?4yRke zd`61uHbv?2tZj$&=Y0{fue)B~pP>(F&-2J7)ut;=G^=WnYZy1Di5SXow~bBl9)&8| z_7MQR4Yi6G;M0En4On$=^%kk#o+9RyFR!kSD!dsPciZ26QLaxMWuPdWNJN$GLln#j z{#?tl4Z1#8TNaWXOI1py_P3O14AE!D-uk^femG`0_S#s=xDxv`cZ7|G@*}K@ z2(MqvDx8p_%j38P@O&l3zEMnePmRB3gp);K2eeIyDG1&?%tDh&j z6}rUPVpe_YYF<32M?f^Fs?`S)GbRqiP1lD3B(Q+ zQx32_$S<%p({tfa7>rv_cN76i;114vtjLqoKxrEi2QIWx3FNix!wzsa!`sz`z=CZ& zx+b2gtPV7%0lTuxzoxirWSUzaWnow|yZDWnvh%4h%=~OWH^!6Oid44Jw6^IJ_8&-> zA|nMaYvoq%k3vWgH|?+p31zdnnqwSN)H{bQFO5xK^-KJKnaTt+eBm!Kz0!}2+n1z( z87{&`p(4dP$t{N|CUapD2774m?6-)Xi0ip*y34oiBMUDz;f`l(y`?r>(%^JH zgDNRNo1EbV>gbQ827?UR>IeQHK=IeoPTKFRrS`?dFx@D=s`>F$tDSy`k5#+&x7JYY z%p3gec|K}nN~Q;YPl;G-(rJU%o|`TCoBDQDr@AwbH+QtFkglM!=9&MEZkk#B{kmz- z-Bd)DuC1##ROe8i_b`etP`LnY9p_SAW03s*h#`a%@TjaXIMm>2*V3$!1MMFg4HJN# z_B)ToM@63-Ezf&t(IqiMX6q?qG+p--dBRVlj|-=gn0Z z!+cIAt3a(Q7!z;YCK;nPZSUfpd8v&}Xa88^w{xla#I`9_zXtt&$7-n0r?fFFZVwCP zWeyh_#2|nA{m$CRRSbxmN?1fHpn*3_C1qvDAT6`wTj=ugz658PMkv1r;ec~75Wt+m zoNHQ)S*{zQ#ydWH3_lyilQlu`y667lb0(YH@@D_imdGK!OL_d6^n(M z5#*udP+;s2qqQp&OiGQ7x;y87qLi!(%J)StO9Ac~4Obn$XOj{9)IuKeLi?=7xM}X6 z%G;lq!PDRlk)R~@4S6a zjUeD()*hs01i0?X7{!Vrh3Vy`v*5W7}`maRa_k)@8Q4Qb9D;@0XXs`ZOtGF+ayoM&2)1l}W z@Y^FatT?B47oc1TcW|M~ZP!N76$aI<>t33J!8u$N`53_`#gOB>zwrP1R?NYU05kN2 z=bR&Jg4o{D*I&z86EbY3G#UR91t|& z^SA$^rt+VPEeV`F&ppX(h1D$UoP|BZ!9g<810ZZit3uPj#QmFmHt)McKAQTFdn6wg@7nD zb?ne{2)EAmG8PB$75Ua_AyIxc1O8g4j>7nVT6*1kv4!r2IE){KaKyP~%DE?29sW$9 z!u_Sc4%4Db%P-cISFfqCGbJl<socr`D&@HLMoox8y=^h$ZZR{6j(c_ovIsbh357DA# zg)|%_0rTUZIz8CJ>Waka>DI34oPY1O%WuP^z$4ZB)eErDFk|xvBHy+;w~BkM&!*#y7?J$`lXZgEI^*?~50(s*$)-V};s9{+=UXI8a?}%&MS~ z^Qf&KhE$C{T>?hp3wb~1+aQ@zPP2Vwh$iJ;z?o}&3QBurN;zwtUMT1f~jy20g+!Y3{-^X^$9mMuYG)tSHG~(v1bb_lf}Ga{;e3N#e#5(}b|Y`gqUX2V zw`Usm8+;vu1`sFktCn`eE_JkTh%pk8sC@Jak6xKuX?Y$Co~<|Z*2+|8Rq(j7sw((KcR$n0F$Zh%fn;fFW0usM`RpST`*BM%^pqT$ zb_8>SZy*0)D3r9~ewr))07~d1t)PX!^_>8#M;Lh!()nC6DIGj%8`>v$x3EHTRB0J% z#9r^Dyi>x`S!OSm3^61MGNDuxTidolF4htcM;Kcf`a>)CW4zTDP8Siben|}<1#yznBMi-f*uUWT&i}S+J144@k{OmaFH39t zQNS%TRkEQPJ0V|tIi4C5KUbB^F*{lN{S-!Gb#qDl{ zii0h>HZd-wxjP(Nj+zedPu!p^&5rgx3lY4wfldj~+VT0^;@TtN;jr^sF7C<+;{o^+ z>{&q>iiCD0Xkb%pt!W1w{;30$6mOsOxOPf0>=F9x{lMkZ&sBG6Sroj>m?$@ys91-i zIr)QCz)2(WSSZRCDv+rjcL_lHtW}ped0lsnZwETo0$#~;v zoL|(m{+}z&FI#w*LY0N(fATEi5=9EuHo?-0>+%I<8Ch2uiuU8j;)M~zPcN%&eN<}9 z#@b?$h$SicGdX%?2VbsXwRJ|xO$`e)pJ})<=+fA$>#F)EuoJWbp3&UT4qcKQxWtOl z{l)hYbkoK8?ucKz4zD@|(pDKEeTpTISi&#c!J2Fc&s2Y+m3-g6XiO$b@j}oboHH?U zh}ZWtJ?U@V?I!6BzUa-xu)0De= z(LyPaLRX3&{utyvX2NP2%2g^y*5o3)$Zayv1tl*7nR@$&Gc=se8&K9u#9V_+vDoS< z5-aS;ehpe7Gwsz7_vO#-k@aIamGZYU*fw6X#?h!`m{536HiYaXgkeJL?R0wL;A+7s zx8=zkFG2v$Ac-`X^Chsy=lw`M;SC%AFIBn;rS{u z7WSK{)JD1w3}#F3ictxgDUJdCFbH9a$5#yGr8h&MlTIT&BfCuW{^r0~M*2if$I8i1 z6*|)TDBM1^w^Hfvya`ohBREe;PuQ)dt4YLU&47#;bWB7S)QgYA0IwOnna7F}7K1dS zT#9%2Cl*n-Y4825hTfY#8vJ(F`)hJF90d^MVNlf@zIlp};0i+uz@@9Yn8LgMv{v6o zW!><3@8jAugXU(N%7avXQhS;Cr^oJ{L*5c>DHzp{-5Vx6^{>a7zbU1^3v!svL| z15fVRI2_Xy%H%4p>8ls_A9@1heP2&B#J$&$>M2UUPw!c5kpCB!(+jXIXz@6~ zW+Tjf*VfE;L-5CUhxHO<>7Mh&MZ4(#7D+>bFiyNcz}_3SAL>1_Ts~R9AG99T15npl zYZDZaRK*iWEz@w=_gWPpXJY<#Iry8&DmH5rtlR?=UmZ;Rm?Wvbl&X@Z`BwPtE&xDGQKfI=5T)+g4>kxX9sC2^$V1xIAzfHjGS%+y{xwM ziN7b91??jIwx1?|4Nn+9)o(#I%XS`|^KxBVcoxO}n?Fi;am`!El%!Hw%c>?;>>Z@G zPsZwdlpC86p!NM3qi6Z$w@gFD-!`AE)HoLRk$SXf!OMB^lYy5W@OImY%Kby;RmG zvBw=F=f}FYB;iZDZ(+wRNIG0RMZUso-D9sORC}`9URHvZ2!8j+NVAT=b4&0o(`*=qrSi4_}q~u%Sw=`Y*1P2bY z6Mg>*MS+DxTpn)&ncj%1Rg*)Mxm*(F5BnTajsN{cL|VReea%8Y%SAiCDOBVbkgtnt z^6hqS^DDuW)APNdi^K7I88uR)U7qYiq9LlrnQ;IY%(#+MtGSl%-=A68Lyx_8^_0C{_+f&Q?<7Cm1bf|tl3N{=V-EAG zDiS=FpjT#(%#gLY_gay^Rd#c)jCp;e=_{E>2y`b-jdYgf++(w}cw{QD{Eu?BoRwy5p>R~lD; z(5Rp!<$$kTCM-C4m$mVO^?|U9Vy>lRw*mDKq3XxtedU2PkiE)ue)15f3wlO;#c!hNf(eo(NlK4 z_92QI`ouZT97RcnzwNGSm^7Tz^kg$Rmc*fwBytsfI^ijv$-)9~Mhuo3*wX%)7i+bE zeFQnTf<}W1I&A#NOz&GBP%)6_>uV@k>tYMWN9zEXEpe&nYRlvrN#d;<-4c8Fp(>Rk z#d$Ob2brf+g*3Tt3@|lMV|26ut>w^XpqK2_)_jzNR~k{WgG0DL)TG8}GyM89HrA<& z^U`1NqW>^MNoDXMnV09PUulG6ER0VMi+qQ?Ni>&$eI9Lm6U!qvlJpS{@<(pG5Div{ zf6bo74G=nExB3!OqDTsR4A8eqPRg+3$_rVrfmw1#632JE=kUSM-JX$6BcFM&<$rK)2 z(}NkLkN=n_PG>4(1snV=+Rb)}mm*YXw#AO(A1&$>FQm_ePbcf#WM69r?gPqIz>-dV zZF--1Kt}#SAYYA@fIITFLvL(}Dd;loIwc4Hm*C>rim%dgdSd*V>8NAy&JZ0g_e!a< zOx3lGh!$DgOwZbaRs@^?X)|wfGC7^-hgfZmpWFA3l@j0L;S$}VES-yWb@l2<(hw zqYpNUlxxn{UOp2NHofO+kp9)m#2_FsU&L0jNr%}e6JQ^wFqC>8T3F-jKg%`ccDscV zG*FE71H`EY*T*_G1t-99DmY=VTGuCzIT?UfvG8d=gqkgjv%Sl{!9Z(_8I@%JhP{bc zk7t@1Y3DI0!q)ZV&otrLM~TP|EhO2yt3%hLB4^#q7IsZIdF8wDsfVJTQ4f)yvE5%g z?i@l_3U!2u;N%OQdnnf%Wd=B%oaZi|?JZH@k|te?%T>mql=>PV87mktqqF@ISsiIn zQVzhAunciUhHZ_(2vhkKYAID?_0|!!mo04Tx72O8<`L`Fsz}fZA`AJ~E%WomloT^W zkX|w$*G_wzqWFRu4w<=Mx3jma#79}*%$Sq&A$Og3qKQjd2heKmnp*#6Gr4nJIh z<xT^&rx7RFdIa;U zP&#P$w;N-Jo}QkhxkGRb0m+8lHA2l;-K(B1y{f74iY$^(g=Qm1`wK@*SaL6VeGQ+< zjn!frCLRxrEp4bH?0~q*In1cUAYD)G14Oda53S|#MHe8@0;*|&YzAV&P$a`OMmRHx zkDZ;*F-FRM?+7wm!V+7sci-J5(Rq%C%|nc5Lhkp0+fF#TfKZRVnH9gpUeBE#%vHN= zTHlAC@%D?$VInbNNr&se2ulv0pToz&V{Zd)(0w;fn|-ESm%?ljh__)q=+pfB7?^$6 z2YCyJ4qJb|+^hJXJvkP`l8Ox={|MI=l%(s(c@b0I;YG9UKzKxQ6LbCflu~$nw8fV= z9*AFs<+3z#NapUv);U-7f(qeG1KaOea9R|%kU*mZVUijrmd(gu!)^RLJPgDBL}t8z z#gVAbH~B3Uu(->UI4Qlyu5O1Hy$W`D_DBGhy_RgLLS7> zp7TOXI}oqYKo?XEK!($&ePt{RA#sPDVweVVOHy_#^q;$5H|b3nq-?!t??3zwjPU*J z>xpVeGI|Kd=8F9Cwb?t@dwFBe;sNd}J+{jdl35ZtQnQ2Wp~WkYGzRhAAt_dVsdcVC zVrX-GszZw0TkiLBDmjJ?p(ahsos;`NlKe?vbvS|e*FOm(%I%N-#68=_&l~y^VAJP; z-IMCyH;>zV(<%=tr%GQU1p9Y&{A%y~DAAoTj(B2<44(D8o51@-Jx_u54ql755CS^5 zQ_M>qo+yE;uS+bhS0OxT!cwI(8)Fw~TGp{~lO}qtm#;d+txA-IMR~NEF1VeQw$ zZi!jIxbAh=tpWR+IKvL6P;GoMS34qFdNb@1Xi|hEZ)=hr($j($Qk+Xq&5{Te9b0Tf z;aku%Yjv%|rVe$^E9yF6{}?_w3UI}fI<9ifT?I-}`zV^ZQZeDiz!{e)CMKssU4kB` zzgy`-L9S=$T9ZOMyDI69Tt z^|4bCd6sGy0JRu$_r>(3T`0#GbDvQ_n6+D$t{(x#(|i=TaIdu)vEW2Z06iY9+YnlF z)C~XVB+Kl_BVSjR&CcXfd24Qp^`_y&ADAaj2-=4tk>wLqf;3x&A%1Aem~aQvEUUPL zL|MG6b)ChVCTn-eWpI+7@bPT*qK;t95l1YlH~^aU0ovdc|3}l((OH`$C6}bKw>M(p zat(>SZOx04v9EszeUHAcznzT?N;5?;6rm8%+FVzM;mO4&wX)UeR49?awnI4s);-gU zAypY;z6vur^HUzx(c~m6+b#5z;UiYYU%%dw5k-oDaGe*$NSl4`%Kv<+4q156^dJ5Y zskl!~A!~HdQ_mBP6&luk3hs^Fjd9%WW0aQ{-tJ294K@n>@lr(iU0WSdilI&5&YSr9 zuq0IEIop&~hMJ7}Tgs)}!0toTuy9|TK5bh2Xx0^fY^;IDapU~^dDeXP3P|3CR7R{*-DqAkC47E3?YLl@r`lS#g_ZiUNXAJRklL|kG@^MhV=^3=Z*fb|Mn04`dJu7PPiBdj%DCN9DgX%KZ zvQ_s_pz49mq>X^Iy}k&liPe-HKQJ*!aiyfF>54_x$7s1WnZ9qI!iZB5J$5TMpR3We z-11|dHL7#hRn;If9|RxbMh$C54yTWpYZ9F17uLO(clsXrv9dMRz61MD_emx#vUe&3B1^vyqjDmJy?(IV<2pl;h7MY)WUT98 z{6?QLi;dW^Bn@d(nOYG6{V-!jDDIzLg3a?Fqkl(Odkb{+j>_y3o$wpEylh|T@S#LT zg{1;n*{Q~8g_ONMe#tlNKoBTW1TK+)Ozop3oRg2*ZuXp^9eM<%oX0^=!u&zDH$_)Mg5HIQ&pKVk!@; zrsz47{#IGm3iVm z?JwAe*tr*e3mdR%Q%|6(9|iMR(y;3X{duh(RlhYANlp$r2X+ZQ%hH8L6b4buSk=mE%xHs`XnHr;-y$U57Cb(@ zTdU27M<*)03+O7K602B1j4uC8un0QH^vPz!S8D{$W zdEA?*+A4Wepv{$3o4v}z=r^4(7}qb(#QC|Us4U8XP`k7=0qlN#^7-{^sbo!3iS~qQ z6>U8r{6$yxvKlld3~80$3#Jd{?0f0MZ276u?;oG)r*Rx@CpwYF(?V{(^zTH+-1k&S z{FN+G!9T&l_qDF0ZRH;Y1#&LD!Jo&cd&(a8tst5nM~~|@<=)+_zxLDlpTyEGbHOr3 zYg``qlTxeENt+#eHUWdPa-_z7S+2(bG{aI9Ne!|cdUL-(wUolQ&fR|~aiP|{xCu3; zI%KA6WZQfY*YcwCBCM-@N7b>*Iq1D$Pot>F-aMPDE7G8TQ zbQ>}tAe`LZ+Nsbp-xzU4_4YluF?jmCpJ0_%Nr~z{~5EHD9 zW5|)SE8vLhNuV)lT+hy*s!IQ@sW%(5sAVnU=iiqH+4_3STUDFfGHqgU&!P93PI2$$ z21?Q^kN5M&myGuVzPKT`YG2{2WvHm%5gHCwWOZ(#X7o5qEek$N6)AFf4K*6cqYyUx%8-+#DO~N@p^mZp6$uLbhb)pP_74~1mC_I=Lxtr=4pZSWvH`=`z9iTuuG=euH}3Z(_D_(kMWr3yYS(u$;;oy^+5Fn>YH-T0 zJ*AKRhsTeIlzEhCDR@qU#U*M5++qKQAUP+m$jbBO@|87YT+$k0dE_ukVAXUAK_Trk zXPHCC^#%s`@aZnchd!-#^T+!?Zh2?xV}uINT($qYK}Fw_WH!sxo{_`irg+%7EIw~u z<+QikKX7g_ZOMbMxx{@Fq$4Z${UQMtIcrnj5C5WiO5kh&%s?nIGzgeGOmd|>DqL)#6dMm#(rVLe!4a4%X1LL}v@Hh(Yy^;c*>g0;Xl`Dd~D z0V6`(qYbTuku&Iozbk{2D4{G0s#W>sOol~jC&j8PcC}nMc{SX#nOqf0(B)qU_>>*a zKNn7<$O$2?XQ(M5Q$!!slAJv8fSjAPR2GObRM6xUThm`tz`-;<`>!bZAD>lXwIziY zX1u!q0bLmDPsqK5)lFxHnU9Sj*4SK6GC5@sI?f#K61P0sM&*T+aK3;S}+g|c;q z3|;sQkHn4yxUvcWj|f~lAwzy)7;@&)PV~?1UMw%FIUP*VFOqiW-Qia^g2>0ZkPYdD zoAZ;bvk8<0X+s@;0E0%RA>7i{7s6cf|7qo_zoKxTE~Q8#xF8|9(j_3$NG~ZR;3AE5 zcXvp)NPj5F1!;+0Qo0*~Wd)>R=>?Yf?)yKy=R7~oJTd3Yob%kdbMyTbYYlka;TT>m zUBG>r_GO_qx@4!hZH4Tj0SZWqI(w%m?`8Q%;o-IG()8a6I0Ye{z)T%bo4>D&-DGpT!dJnQ^LQcMaE=;#pRpAt>08cGyf6+F5 zPtxW`FR9`CMvvelnO3Gw?K5UV>yTIC(ZZ)eAGu-N-u8GFf>LG>R-HWhs&t z{ml8#2~kAes}2shy&Uv1^Z#!RVxL^yy?FCBOpEs@S$5^Gbo^6?w76)tc^Ko)Z9M#1tNNEzsY}e>PfjcKahVDgw;GUQQEQ<=gnISM(;)E!+%` z-FxE)crV5*GD zeaSajaIjHdV;|&lrT%wdB(=+U+)0?cCT;o2J|v6#XVXT5HYiOczn>u_b=mWICYd*t zC}ezP8n>$RzGCFfy>!f(+8UlSc43iqG3{X@hp#6fvkyhV_3UjJjo3|-yG`@IPphK4 zrc=w<$q+ma?ew*9EJ^mLBhrz|-_IwA`EX^+7tyMm_`=i1MSJ`?3W~1DEc|0~<6kvw zEu@m;Xi->684WCvhJt8UgWp+7Pek}iaOhli`|P!t7BPrFV&0o9t<9?aKCUIgjRwx50-1y&ru-iDs*LG>MHPh62 zd`wcsP}EQmMvxM&I>9^ozK0ce zz`3fapG=uAyWL>wmEX7j_N9b>FFW54ng!b#E57bk5({7jCyK?`VvZru!}EKYsd-M} zihqswi*z+pXTsA>IlolIjo;4eq1dG3&HcK?Ez=uc@!zdQ#(X{)S%k0u*l*%BO;DCH zTAP4A0eNU}>Sf@2$Q46#;EM9(MFyX8x=9yYc<1e&@pSI~n9yBZ3rrH?eA`TrHBZ=# z4?6e{1juxm7p=6a;1;&XS-QO_a#gB68}%ROvtVhBiKVUb>oLv|@+*9Xp$^vPZfoB^ zIC9Mkk8($d)(&<(>VIi8=1>$ylqZtU{+JQd@Z~QK47|@Vy!~^iiLw`ui#0k>OL%WyaCC1OGFDD}^Jd3d917nh^^n(hE-O&ZVVuyzbF#NVIxr+akD{+ET zdYT(MZ<~2!u6yh~c3Q|z?S50cym2#Cy!1qO>Kh&r8c@1tybK}*{LY)|ipMR;aNh&o z;CQV=zg`#1?*pLTee5&E_KYtsdi*Kpe_q783F0t}mp7;cH;dOmA`XCiNN9iNP8XYt z%&&ncT@Sgh?zxV|P5St(IRX>5IAV1gt8h}IF!LY^_9n1Y-TZnUW;#sf*K0jjt0Si6 z>q*zd&rS>FZ?kQ{>Z`iEr6E*+=kJcTlSxS+SI)TaF3{{PT$)Nzg9}LZ$f`?Y@Y6|; z-EnAwgUXK|N}qCWxHHmWuLO$kXkIE0n)*z?W!Y$3xew)=OEO7*X z;;hEGBmSR*dIm_kYJ8bvKUk>?IsFKaWQLVULRWd)$0IiBOA;+ak|h@UtOX8xY%4N(KOoY6SvM$W&PECsn{F5d7Du% zPlo(Y|AP=_Y60@Jx&l;CH*ZE<5`uVdD-CG1xKiuR4S5~TLwbaVY{ z$B+P<1-eB)`02U?+LfwygT+3pvtN^bP~~s& zS0msv@}~FGxonG2juieWvj51YtKpZmpfDWSbP>*!akp2CEuFUJH9;i`I$N%<+!s9H zCX$oW^r>?bUe|Y_)HcGU(Ly%X4?D~2$7;U)zXh^0ETPz$H$3zE%;67jWZrsxot_rE zX+HW8=!+!c@~>m+Id$1TDseO^U3Dt`sBpVL;IC`^*Jyu4eQIwuVI#r|8Dwm{+wQ^V z+k;|i_!Z#!W&Y!lu0as-a82PH>fcv*;qn%X70qh?>pywBY0>H}R_ew+uO&q&-`Cy4 z%%4Twy$nW3!5>AfJg@1y?&rU>6xA55Rds@iQV&q=VE^(948*#n^-q z{z>{NvV^JJ^pI#23{va1#W48zs){H#sja@!i_dB6TluA-7Pm9g_JUFw*TC_t{v?9S z)h&Rh>mL61RP^0afT3|FFQ4wPc_*4#jeE0cB`GY7&i`X94v}+wi_O>p^`3CrlrJu4 ztY~HU_g-+`hV&p)nue4n`!PyjyY+Z!2F2qZ?@$luj})%sE@#P_K8H!esR7^0Eo*;5 z-vvbEw09WH?RRYDtu&a^;+HT~&VQS?{Z}!cENC$N^BX!%esj}aN!fash@cSce>xG< z=ZV4ixgHJbPZg6JpRzg}`fb=AeZPk65$YYXEQ%zPkS|Tv*uAupOm;3tE=GXR?`@{8_OsJ~rq@6xw z;2StP6_7Qc`k`I+j*m59c-1;yB1(i!vR(TzO+29#9*Uk#(PUF8OVY0H8qE(7kT42K z6%7Xmiiy`(xv;$EM(%f6GBiIKZXLEy*a&FzLeZfMIr;*yIWzy9Rb#42Qe?X5*Fmo% zW%fS@edU5pIfK~{;kH1CDwkKPa^{HCFv-Hz4{UM8I^~pN_+kpralHntbl@uPziBCj z+!Rx#rn;xJU-e?cKpc8VSj(eG^6k{NYm8lM=n{__|>H;a4tIh{Vb#h65Yw(Wk|}fR6M1W4HpCxwVr)v7g^IpkbM9SdU~U2O-EG^fvL< z5tS204sge3)^kv#9jDwnue<#q13iSD=f9rr)I2I&h$-7k@YpvXLOKB>&}?bHkNPYy z8#mOjoI)pAe0(~WW!cpg&*-xN|FA1+_Ddk7bQTYE09l4!8|qW7D|HL<0d;d@mh zY1t7Ys@4Ot*lUulm0x2lM`qCq?$0SJ8?&^dL$A$q{^XcA`DhFNi zq~~}g0kckPa^XyW&P!sJN8acRhw7XX*X2oXyxv}nzgR7hwZEKTY7W@6KUx-b?^_bD z0$HQz({?KyQH(E6)!0^Er~;_C(wo99BhAl?GUp&bN|xYpD#;4qCkTmob9 zy?g$}JzXXCu}p^om-r72MaGa-^v656?Ecln$=1CqNuRHq9I)00FnnU7;P2-Hx*HhS z@8+c#4s9ObbZ-;iOStG;u=h+PqW6D>>&Kf-ymhX{*JCD=5zjlIT-3T6(NqKtJJeio zDE!d3L^~UiNE4=lP(!emCOVCX8LY*!r(?NJL`}5ipnC!gY+Kkk0rnZADWhIBuh*YY zlF=h5EH2AtG2Jp|MuDZSp;HWso~*w++`OA$Ciqt<0doIzz>aA+5fvtb^Ug>0TKt=7 zo_nQI?_1mEqUEpNauHk7jdu*16{lx+`IPnCRLogn>i%Jl-qG;07g2XX{)FjP4U|BN z=?7SA>ec{L{&+hH=9WZ1-Q-V}pA{d^u(njEH z$Ekuy-1^D;D6nOCS*G9-LL(e8BxK|0SMRji28ksh3 z;`MtYOP0k?EPHgVsLmxPot@FKq5M!V&991eIN7cAKe6Pu({uyzGg?I*c!AIE7zNsl zB(9xabg{B;8)kQPZ|N~0@l}8WZUm^$`m4^K&Nb8{>a=lE0#l1twg^7?h%63(G?4g# z{RS1{(-VfWnPj`Z32{7g<-@Xuq8vckqjseONCAz zb+78QI88R{4X<2&y!52h=)e6Ad?cjf)58SN2yMwf6?g=ng|ur9$FJivM?n4H%aq)LyU`)7-&}%Y2!%T-p?6CH1t207CKKJi=+}ZJ zb+^Rp&{r*Y7qQnN4~r5B#Ksn0M{2a=n2z#O%-bTdCjq#t_742Fxv_X#Iy#M6qb;Cv z+AYCR;wxTv-wVF`vSiN8bsrgDq{hu1kXXKl5y zkR{i^m432N&!Fs{lCB>Bo)qnc?x5U~DSt(j(r?KVsYh#LXsT^%w4+Uebrc zDXeBuZm}L#Gp5tC=b?_)N$z`G>yO8ljUfJ?x+}sb9;JYtfbK$?Yq?v!815)cP=3TQFK19p#NG4dQEaj3_mT@-I4|`=BKMl>{xNgia!Z@Eh-KJ zwOs?E3QT7f(afy(v#T)Z0BXHjW;i1_=fvqO#2|E?>Gve3)spOE37Or?Xj&YTwKeYU zM;yjOE7Sl{Y$1LOimdDIIAGlY9U_hvTOOOV72et7FJw+~OCND`yWQjaC&=NcW)=7h4nQ zn)&S650sT-Qh%CXm+~Hcs`-^w6lDd`=?+4;r2PG{jYG#4`U-~ippmQ_a7s{KaAu!} zi)4F%4&(WBh6qf$z-TSq?DD{yfVdk9hc*URm9*idV_R*BJaBk$|zCg(`Q|HtuPxOjZKElSfS@}eIc!Xbe=Bg}DIE=6@+^NQ*R4Nd;`(#cqD=j;T; z4_Tf{qCWysI+#r9DUWv3fYJWZA8R78d}>1 z@Hr1}%ou+H4(GRT5{o!lhCUi6xu!hy^`8RXOB3Bg3&LPxPj8)dxe5kfKjhB0t(QKW zGHydrN$dA~!L2jE|(a~cZHOxR%@{Y7X z2w|l*D8NB+%VYliH<}pE4*EqkY?X*1sIg4r>D%JJtI(g+HHNB)f9!d!e=-MR%KhkkQThaBR9rvS6G^ZU8{sW;n@-FaBDSKsw{k%)vI@8lWQLjOTt670BAR7k%;D=f< z2yGkG@L%HPM$+(fJ8%VSG-Cy%Y9tqrPmq+*8Lt_E_7>4Y#}4u6e^HJ{d{*q5de6d% z#_GnjjJS0iw(LY2g~4`U$ctfbLL~j3)qC+ZV6JoOMANYK{tKeU&YOLpK$j7#vxyGY zVkb&>XfCdy9mj?FGW7l`|4no_n7)n9>R>u^lfx}qpD>2#^g^uealca@K-Yc4d+i(Q|1hQLLH#UW}4 z&5b4>nTh0I2Bg>m=Xrr8=m21c1PKq)=daM|iWqi6cuyl7O#s|({c+rX(EV)Txy9kD zDlT_}uy`*2oiL+`ws~j2RJLG=Nhtsaa|N1K?FMb-p*xLCYhu@rV-Yzm{mqy1 ztrZLFG^O+d{gX?aa;4tL9B|-Hie_2v+Fh~6oworNHym9>xK5l#;>>(1;}9$49p?vZ zL1CwjC+?##;yu%B!5#deiH6Fc(5Bw`Fw1TxL8c-zn~^08H5ZcD&2iQ;ZboKY!dfiU zhLOzSK=cM%FupQYt~gaSgmLHqlN!cr2uo0Ip1I=_FDu$v05BfS4h^EKTt7dME`-s2 z2#;NdKksfwJuv(%->)9nuTeYMF$FCc*#dGW{Me!U+MKp|QZRl}z;QaTiWNuu$w&5Ab#Vm6dp7eRCvx zz`y+i52Rrh+HY62PgykXrtvC&iuy72L|e6Yj{04@BC$cU1dulC z|H4|bPpGW&yafG8aYX+Z*C!=%fLDAt0qq@!u}l2a{NTI?c!+H8b*bdo{;Be2O;arj zDVa7TTF2+y6rvu13xh<)n)-l47*xXNpeQwvWO>*N6@wITPalX!pnMRAYG-W{@Ajc~ zH;TXEmR;|n7Rx8kgGA!vF6fKMA%xcu zS{gwfrZltLpaV(RIN{OBC8v0Sc%ahAP-pkh{VN01bqe^ay#FJ)z5w*qoF3ws zHTwp1=v+PDs!(3$_Qdcl^&%z*!EX+=>m_O(UMy=k6LaQB*XWyDJsEfh{$RG*EFuN5 zU;d45(pKw?1@dp}?K)R|q=wK_3hDxaj$ol<$re-^|Ut{4s8DilJa2gD8bZ{NS7h zgMQdpweJr-;lie?6&rqvO8rA`%DpPPD%a)|!?mW`w(p9q{|(ZZ{h^@7xIR4Z%7`mZ7qQ6)S^|a&bdf8BlC~6C;FF6yEy@QY~%i|BMZX+@EjY~(@Z(!kG#||32EzL_u z^Mf@NcwgQ$Jo7p(Hs7$J*E)@7SKkV z74g`ZD{<@ueR7Ew3o6sO%ZC3JRyz~@-(k#;sJhk1{w4AZ?uaRkI$7jHx}Xm)`y)@x nuNFQV_6ZRGKdtusM|_cNi=l{mGFgmxIhKl|rb4ZpS@{0|wZ_u- diff --git a/patches/src/main/resources/music/branding/afn_red/splash/drawable-xlarge-mdpi/record.png b/patches/src/main/resources/music/branding/afn_red/splash/drawable-xlarge-mdpi/record.png index 176c876cd26f1242fc2bdf044b98f4884fc3c38e..ad72d53142b8d1a26ce578d8a0df94dd785ee264 100644 GIT binary patch literal 10663 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 Nnu<2KPRaKD{{ba<+hG6z literal 11634 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 diff --git a/patches/src/main/resources/music/branding/afn_red/splash/drawable-xxhdpi/record.png b/patches/src/main/resources/music/branding/afn_red/splash/drawable-xxhdpi/record.png index dbb56cc2d7932e9cfb5e2cddab8fe96c14cb2278..a04c1560cc17420804e7555dbf4b69798dc8c31e 100644 GIT binary patch literal 16411 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�GCctG9 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 From 0639b559b1248b495487fde5a3ba64c26699b465 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 26 Mar 2025 21:03:35 +0900 Subject: [PATCH 36/77] fix(YouTube - Spoof streaming data): Add patch option `Use iOS client` and add user dialog for warning --- .../innertube/client/YouTubeAppClient.kt | 54 ++++++++++++++++++- .../extension/shared/patches/PatchStatus.java | 4 ++ .../spoof/SpoofStreamingDataPatch.java | 16 ++++++ .../shared/settings/BaseSettings.java | 1 + .../video/CustomPlaybackSpeedPatch.java | 12 ++--- .../ReVancedPreferenceFragment.java | 18 +++++-- .../extension/youtube/utils/VideoUtils.java | 4 +- .../streamingdata/SpoofStreamingDataPatch.kt | 31 ++++++++--- .../youtube/settings/host/values/arrays.xml | 14 +++++ .../youtube/settings/host/values/strings.xml | 16 ++++-- .../youtube/settings/xml/revanced_prefs.xml | 10 +++- 11 files changed, 155 insertions(+), 25 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeAppClient.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeAppClient.kt index 4c0ddbbda..bbd1ba9e9 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeAppClient.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/client/YouTubeAppClient.kt @@ -1,6 +1,7 @@ package app.revanced.extension.shared.innertube.client import android.os.Build +import app.revanced.extension.shared.patches.PatchStatus import app.revanced.extension.shared.settings.BaseSettings import app.revanced.extension.shared.utils.PackageUtils import org.apache.commons.lang3.ArrayUtils @@ -11,6 +12,24 @@ import java.util.Locale */ object YouTubeAppClient { // IOS + /** + * Video not playable: Paid / Movie / Private / Age-restricted + * Note: Audio track available + */ + private const val PACKAGE_NAME_IOS = "com.google.ios.youtube" + + /** + * The hardcoded client version of the iOS app used for InnerTube requests with this client. + * + * It can be extracted by getting the latest release version of the app on + * [the App Store page of the YouTube app](https://apps.apple.com/us/app/youtube-watch-listen-stream/id544007664/), + * in the `What’s New` section. + */ + private val CLIENT_VERSION_IOS = if (forceAVC()) + "17.40.5" + else + "20.10.4" + private const val DEVICE_MAKE_IOS = "Apple" private const val OS_NAME_IOS = "iOS" @@ -31,6 +50,7 @@ object YouTubeAppClient { "13_7" else "18_3_2" + private val USER_AGENT_IOS = iOSUserAgent(PACKAGE_NAME_IOS, CLIENT_VERSION_IOS) // IOS UNPLUGGED @@ -183,7 +203,6 @@ object YouTubeAppClient { * Example: 'com.google.ios.youtube/16.38.2 (iPhone9,4; U; CPU iOS 14_7_1 like Mac OS X; en_AU)' * Source: https://github.com/mitmproxy/mitmproxy/issues/4836. */ - @Suppress("SameParameterValue") private fun iOSUserAgent( packageName: String, clientVersion: String @@ -194,8 +213,15 @@ object YouTubeAppClient { return BaseSettings.SPOOF_STREAMING_DATA_IOS_FORCE_AVC.get() } + private fun useIOS(): Boolean { + return PatchStatus.SpoofStreamingDataIOS() && BaseSettings.SPOOF_STREAMING_DATA_TYPE_IOS.get() + } + fun availableClientTypes(preferredClient: ClientType): Array { - val availableClientTypes = ClientType.CLIENT_ORDER_TO_USE + val availableClientTypes = if (useIOS()) + ClientType.CLIENT_ORDER_TO_USE_IOS + else + ClientType.CLIENT_ORDER_TO_USE if (ArrayUtils.contains(availableClientTypes, preferredClient)) { val clientToUse: Array = arrayOfNulls(availableClientTypes.size) @@ -340,6 +366,21 @@ object YouTubeAppClient { "iOS TV Force AVC" else "iOS TV" + ), + IOS_DEPRECATED( + id = 5, + deviceMake = DEVICE_MAKE_IOS, + deviceModel = DEVICE_MODEL_IOS, + osName = OS_NAME_IOS, + osVersion = OS_VERSION_IOS, + userAgent = USER_AGENT_IOS, + clientVersion = CLIENT_VERSION_IOS, + supportsCookies = false, + clientName = "IOS", + friendlyName = if (forceAVC()) + "iOS Force AVC" + else + "iOS" ); companion object { @@ -350,6 +391,15 @@ object YouTubeAppClient { IOS_UNPLUGGED, ANDROID_VR, ) + + val CLIENT_ORDER_TO_USE_IOS: Array = arrayOf( + ANDROID_VR_NO_AUTH, + ANDROID_UNPLUGGED, + ANDROID_CREATOR, + IOS_UNPLUGGED, + IOS_DEPRECATED, + ANDROID_VR, + ) } } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/PatchStatus.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/PatchStatus.java index 8282eadf5..74632f8c1 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/PatchStatus.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/PatchStatus.java @@ -11,4 +11,8 @@ public class PatchStatus { // Replace this with true If the Spoof streaming data patch succeeds in YouTube. return false; } + + public static boolean SpoofStreamingDataIOS() { + return false; + } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java index 9b087b276..fdfdbabc0 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java @@ -11,16 +11,20 @@ import java.util.LinkedHashMap; import java.util.Map; import app.revanced.extension.shared.innertube.client.YouTubeAppClient.ClientType; +import app.revanced.extension.shared.patches.PatchStatus; import app.revanced.extension.shared.patches.spoof.requests.StreamingDataRequest; import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.shared.utils.ResourceUtils; import app.revanced.extension.shared.utils.Utils; @SuppressWarnings("unused") public class SpoofStreamingDataPatch extends BlockRequestPatch { private static final boolean SPOOF_STREAMING_DATA_SKIP_RESPONSE_ENCRYPTION = SPOOF_STREAMING_DATA && BaseSettings.SPOOF_STREAMING_DATA_SKIP_RESPONSE_ENCRYPTION.get(); + private static final boolean SPOOF_STREAMING_DATA_TYPE_IOS = + PatchStatus.SpoofStreamingDataIOS() && BaseSettings.SPOOF_STREAMING_DATA_TYPE_IOS.get(); /** * Any unreachable ip address. Used to intentionally fail requests. @@ -206,6 +210,18 @@ public class SpoofStreamingDataPatch extends BlockRequestPatch { return videoFormat; } + public static String[] getEntries() { + return SPOOF_STREAMING_DATA_TYPE_IOS + ? ResourceUtils.getStringArray("revanced_spoof_streaming_data_type_ios_entries") + : ResourceUtils.getStringArray("revanced_spoof_streaming_data_type_entries"); + } + + public static String[] getEntryValues() { + return SPOOF_STREAMING_DATA_TYPE_IOS + ? ResourceUtils.getStringArray("revanced_spoof_streaming_data_type_ios_entry_values") + : ResourceUtils.getStringArray("revanced_spoof_streaming_data_type_entry_values"); + } + public static final class AudioStreamLanguageOverrideAvailability implements Setting.Availability { @Override public boolean isAvailable() { diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java b/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java index 71fe7fbba..992c18370 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java @@ -43,6 +43,7 @@ public class BaseSettings { "revanced_spoof_streaming_data_ios_force_avc_user_dialog_message"); public static final BooleanSetting SPOOF_STREAMING_DATA_SKIP_RESPONSE_ENCRYPTION = new BooleanSetting("revanced_spoof_streaming_data_skip_response_encryption", TRUE, true); public static final BooleanSetting SPOOF_STREAMING_DATA_STATS_FOR_NERDS = new BooleanSetting("revanced_spoof_streaming_data_stats_for_nerds", TRUE); + public static final BooleanSetting SPOOF_STREAMING_DATA_TYPE_IOS = new BooleanSetting("revanced_spoof_streaming_data_type_ios", FALSE, true, "revanced_spoof_streaming_data_type_ios_user_dialog_message"); // Client type must be last spoof setting due to cyclic references. public static final EnumSetting SPOOF_STREAMING_DATA_TYPE = new EnumSetting<>("revanced_spoof_streaming_data_type", YouTubeAppClient.ClientType.ANDROID_VR, true); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/CustomPlaybackSpeedPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/CustomPlaybackSpeedPatch.java index cca3c4ff4..83e343397 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/CustomPlaybackSpeedPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/CustomPlaybackSpeedPatch.java @@ -75,30 +75,30 @@ public class CustomPlaybackSpeedPatch { return isCustomPlaybackSpeedEnabled() ? 0 : original; } - public static String[] getListEntries() { + public static String[] getEntries() { return isCustomPlaybackSpeedEnabled() ? customSpeedEntries : defaultSpeedEntries; } - public static String[] getListEntryValues() { + public static String[] getEntryValues() { return isCustomPlaybackSpeedEnabled() ? customSpeedEntryValues : defaultSpeedEntryValues; } - public static String[] getTrimmedListEntries() { + public static String[] getTrimmedEntries() { if (playbackSpeedEntries == null) { - final String[] playbackSpeedWithAutoEntries = getListEntries(); + final String[] playbackSpeedWithAutoEntries = getEntries(); playbackSpeedEntries = Arrays.copyOfRange(playbackSpeedWithAutoEntries, 1, playbackSpeedWithAutoEntries.length); } return playbackSpeedEntries; } - public static String[] getTrimmedListEntryValues() { + public static String[] getTrimmedEntryValues() { if (playbackSpeedEntryValues == null) { - final String[] playbackSpeedWithAutoEntryValues = getListEntryValues(); + final String[] playbackSpeedWithAutoEntryValues = getEntryValues(); playbackSpeedEntryValues = Arrays.copyOfRange(playbackSpeedWithAutoEntryValues, 1, playbackSpeedWithAutoEntryValues.length); } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index 0fa29e929..34ebdb184 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -1,6 +1,7 @@ package app.revanced.extension.youtube.settings.preference; import static com.google.android.apps.youtube.app.settings.videoquality.VideoQualitySettingsActivity.setToolbarLayoutParams; +import static app.revanced.extension.shared.settings.BaseSettings.SPOOF_STREAMING_DATA_TYPE; import static app.revanced.extension.shared.settings.preference.AbstractPreferenceFragment.showRestartDialog; import static app.revanced.extension.shared.settings.preference.AbstractPreferenceFragment.updateListPreferenceSummary; import static app.revanced.extension.shared.utils.ResourceUtils.getXmlIdentifier; @@ -56,6 +57,7 @@ import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; +import app.revanced.extension.shared.patches.spoof.SpoofStreamingDataPatch; import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.settings.BooleanSetting; import app.revanced.extension.shared.settings.EnumSetting; @@ -118,8 +120,12 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { Setting.privateSetValueFromString(setting, listPreference.getValue()); } if (setting.equals(DEFAULT_PLAYBACK_SPEED)) { - listPreference.setEntries(CustomPlaybackSpeedPatch.getListEntries()); - listPreference.setEntryValues(CustomPlaybackSpeedPatch.getListEntryValues()); + listPreference.setEntries(CustomPlaybackSpeedPatch.getEntries()); + listPreference.setEntryValues(CustomPlaybackSpeedPatch.getEntryValues()); + } + if (setting.equals(SPOOF_STREAMING_DATA_TYPE)) { + listPreference.setEntries(SpoofStreamingDataPatch.getEntries()); + listPreference.setEntryValues(SpoofStreamingDataPatch.getEntryValues()); } if (!(mPreference instanceof app.revanced.extension.youtube.settings.preference.SegmentCategoryListPreference)) { updateListPreferenceSummary(listPreference, setting); @@ -305,8 +311,12 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { editTextPreference.setText(setting.get().toString()); } else if (preference instanceof ListPreference listPreference) { if (setting.equals(DEFAULT_PLAYBACK_SPEED)) { - listPreference.setEntries(CustomPlaybackSpeedPatch.getListEntries()); - listPreference.setEntryValues(CustomPlaybackSpeedPatch.getListEntryValues()); + listPreference.setEntries(CustomPlaybackSpeedPatch.getEntries()); + listPreference.setEntryValues(CustomPlaybackSpeedPatch.getEntryValues()); + } + if (setting.equals(SPOOF_STREAMING_DATA_TYPE)) { + listPreference.setEntries(SpoofStreamingDataPatch.getEntries()); + listPreference.setEntryValues(SpoofStreamingDataPatch.getEntryValues()); } if (!(preference instanceof app.revanced.extension.youtube.settings.preference.SegmentCategoryListPreference)) { updateListPreferenceSummary(listPreference, setting); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java index 5f614c62b..9df7bb1f6 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java @@ -193,8 +193,8 @@ public class VideoUtils extends IntentUtils { } public static void showPlaybackSpeedDialog(@NonNull Context context) { - final String[] playbackSpeedEntries = CustomPlaybackSpeedPatch.getTrimmedListEntries(); - final String[] playbackSpeedEntryValues = CustomPlaybackSpeedPatch.getTrimmedListEntryValues(); + final String[] playbackSpeedEntries = CustomPlaybackSpeedPatch.getTrimmedEntries(); + final String[] playbackSpeedEntryValues = CustomPlaybackSpeedPatch.getTrimmedEntryValues(); final float playbackSpeed = VideoInformation.getPlaybackSpeed(); final int index = Arrays.binarySearch(playbackSpeedEntryValues, String.valueOf(playbackSpeed)); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt index 0befb7493..c1982140f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt @@ -8,6 +8,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.booleanOption import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable import app.revanced.patches.shared.extension.Constants.PATCHES_PATH @@ -60,12 +61,23 @@ val spoofStreamingDataPatch = bytecodePatch( versionCheckPatch, ) + val useIOSClient by booleanOption( + key = "useIOSClient", + default = false, + title = "Use iOS client", + description = "Add setting to set iOS client (Deprecated) as default client.", + ) + execute { var settingArray = arrayOf( "SETTINGS: SPOOF_STREAMING_DATA" ) + var patchStatusArray = arrayOf( + "SpoofStreamingData" + ) + // region Get replacement streams at player requests. hookBuildRequest("$EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V") @@ -343,14 +355,21 @@ val spoofStreamingDataPatch = bytecodePatch( settingArray += "SETTINGS: SKIP_RESPONSE_ENCRYPTION" } + if (useIOSClient == true) { + settingArray += "SETTINGS: USE_IOS_DEPRECATED" + patchStatusArray += "SpoofStreamingDataIOS" + } + // endregion - findMethodOrThrow("$PATCHES_PATH/PatchStatus;") { - name == "SpoofStreamingData" - }.replaceInstruction( - 0, - "const/4 v0, 0x1" - ) + patchStatusArray.forEach { methodName -> + findMethodOrThrow("$PATCHES_PATH/PatchStatus;") { + name == methodName + }.replaceInstruction( + 0, + "const/4 v0, 0x1" + ) + } addPreference( settingArray, diff --git a/patches/src/main/resources/youtube/settings/host/values/arrays.xml b/patches/src/main/resources/youtube/settings/host/values/arrays.xml index 366f7c424..e0efdc769 100644 --- a/patches/src/main/resources/youtube/settings/host/values/arrays.xml +++ b/patches/src/main/resources/youtube/settings/host/values/arrays.xml @@ -415,6 +415,20 @@ ANDROID_UNPLUGGED IOS_UNPLUGGED + + @string/revanced_spoof_streaming_data_type_entry_android_vr + @string/revanced_spoof_streaming_data_type_entry_android_vr_no_auth + @string/revanced_spoof_streaming_data_type_entry_android_unplugged + @string/revanced_spoof_streaming_data_type_entry_ios_unplugged + @string/revanced_spoof_streaming_data_type_entry_ios_deprecated + + + ANDROID_VR + ANDROID_VR_NO_AUTH + ANDROID_UNPLUGGED + IOS_UNPLUGGED + IOS_DEPRECATED + diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 13936985f..df11d645f 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -2187,8 +2187,8 @@ Tap the continue button and allow optimization changes." Android VR "Android VR (No auth)" - "iOS -(PoToken required)" + "iOS +(Deprecated)" "iOS TV (Login required)" Spoofing side effects @@ -2196,10 +2196,20 @@ Tap the continue button and allow optimization changes." • Stable volume is not available. • Disable forced auto audio tracks is not available. • Kids videos may not play when logged out or in incognito mode." - • There may be playback issues (PoToken required). + • Whole ASNs/IP ranges may be blocked by the server. "• Stable volume is not available. • Movies or paid videos may not play. • Kids videos may not play when logged out or in incognito mode." + Use iOS client + "iOS client added to available clients. + +WARNING: iOS client is deprecated. Any issues that arise while using it are at your own risk." + iOS client not added to available clients. + "When requesting YouTube API endpoints using iOS, you will need the Auth tokens issued by the iOS device and the PoTokens issued by iOSGuard. + +This means that streaming requests via iOS will be missing both the Auth tokens and the PoTokens, and the server may consider the user as a bot and block the entire ASN/IP range. + +USE AT YOUR OWN RISK!" Force iOS AVC (H.264) Video codec is forced to AVC (H.264). Video codec is determined automatically. diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index f75bc168d..f857250e9 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -836,7 +836,7 @@ @@ -845,7 +845,13 @@ SETTINGS: SKIP_RESPONSE_ENCRYPTION --> + + + + Reproductor Añade un botón de siguiente al minireproductor diff --git a/patches/src/main/resources/music/translations/it-rIT/strings.xml b/patches/src/main/resources/music/translations/it-rIT/strings.xml index df5a9d0e6..083615f6a 100644 --- a/patches/src/main/resources/music/translations/it-rIT/strings.xml +++ b/patches/src/main/resources/music/translations/it-rIT/strings.xml @@ -100,7 +100,49 @@ Limitazioni: Nascondi il menu Aiuto & feedback Nascondi il menu Non interessato Nascondi Aggiungi al menu Selezione rapida + Nascondi il menu Riproduci successivo + Nascondi il menu Qualità + Nascondi il menu Rimuovi della libreria + Nascondi il menu Rimuovi della playlist + Nascondi il menu Segnala + Nascondi il menu Salva episodio per dopo + Nascondi il menu Salva nella libreria + Nascondi il menu Salva nella playlist + Nascondi il menu Condivisione + Nascondi il menu Riproduzione casuale + Nascondi il menu Orario di spegnimento + Nascondi il menu Avvia radio + Nascondi il menu Statistiche per nerd + Nascondi il menu Iscriviti / Annulla Iscrizione + Nascondi dal menu Sblocca dalla selezione rapida + Nascondi il menu Visualizza crediti brano + Continua a guardare + Continua il video dall\'orario corrente quando si passa a YouTube. + Guarda su YouTube + Url video non valido. + Sostituisci il menu Ignora coda + Sostituisce il menu Ignora coda con il menu Guarda su YouTube. + Sostituisci il menu Segnala + Sostituisce il menu Segnala con il menu Velocità di riproduzione. + Mantieni Segnala nei commenti + Mantiene intatto il menu Segnala nella sezione commenti. + Generale + Cambia la pagina iniziale + Seleziona in quale pagina si apre l\'app. + Predefinito + Classifiche + Episodi per Dopo + Esplora + Cronologia + Libreria + Musica Piaciuta + Podcast + Esempi + Cerca + Sottoscrizioni + Disattiva il reindirizzamento Non mi piace + Disabilita il reindirizzamento alla traccia successiva quando si fa clic sul pulsante Non mi piace. Disabilita i sottotitoli automatici forzati Sottotitoli automatici forzati disabilitati. Abilita la modalità orizzontale @@ -110,46 +152,345 @@ Limitazioni: Modifica i filtri personalizzati Filtra i nomi dei componenti separati da righe. + Filtro personalizzato non valido: %s. Nasconde lo scaffale dei pulsanti Nasconde lo scaffale dei pulsanti dalla home page e da Explorer. + Nascondi scaffale carosello Nasconde lo scaffale del carosello dalla home page e da Explorer. Nascondi il bottone cast Nascondo il pulsante cast nella parte superiore della homepage e in cima al riproduttore. + Nascondi barra categoria + Nasconde la barra della categoria. + Nascondi il pulsante fluttuante + Nasconde il pulsante fluttuante nella scheda Libreria. + Nascondi pulsante Cronologia + Nasconde il pulsante Cronologia nella barra degli strumenti. + Nascondi pulsante Notifiche + Nasconde il pulsante Notifiche nella barra degli strumenti. + Nascondi lo scaffale della scheda playlist + Nasconde lo scaffale della scheda playlist nel feed. + Nascondi scaffale Esempi + Nasconde lo scaffale Esempi nel feed. + Nascondi il pulsante Cerca + Nasconde il pulsante Cerca nella barra degli strumenti. + Nascondi il pulsante Ricerca sonora + Nasconde il pulsante di ricerca sonora nella barra di ricerca. + Nascondi il pulsante Tocca per aggiornare + Nascondi il pulsante Tocca per aggiornare. + Nascondi il pulsante di ricerca vocale + Nasconde il pulsante di ricerca vocale nella barra di ricerca. + Ripristina la vecchia scheda Libreria + Ripristina la scheda Libreria al vecchio stile. (Sperimentale) + Rimuovi la finestra di dialogo sulla discrezione dello spettatore + "Rimuove la finestra di dialogo sulla discrezione dello spettatore. +Questo non aggira la restrizione di età. Semplicemente la accetta automaticamente." Versione dell\'app falsificata + "Falsifica la versione client con una versione precedente. + +• Ciò cambierà l'aspetto dell'app, ma potrebbero verificarsi effetti collaterali sconosciuti. +• Se disabilitato in seguito, la vecchia interfaccia utente potrebbe rimanere finché i dati dell'app non vengono cancellati." + Falsifica destinazione della versione app + Seleziona la destinazione falsificata della versione app. + 6.42.55 - Disabilita i testi in tempo reale + 7.16.53 - Ripristina la vecchia barra d\'azione + Versione dell\'app da falsificare non valida: %s. + Barra di navigazione + Abilita colore personalizzato nella barra di navigazione + Imposta il colore della barra di navigazione. + Valore personalizzato del colore nella barra di navigazione + Digita il codice esadecimale del colore nella barra di navigazione. + Valore del colore nella barra di navigazione non valido. + Nascondi il pulsante Home + Nasconde il pulsante Home. + Nasconde il pulsante Esempi + Nasconde il pulsante Esempi. + Nascondi il pulsante Esplora + Nasconde il pulsante Esplora. + Nascondi il pulsante Raccolta + Nasconde il pulsante Raccolta. + Nascondi il pulsante Aggiorna + Nasconde il pulsante Aggiorna. + Nascondi la barra di navigazione + Nasconde la barra di navigazione. Nascondi etichetta di navigazione + Nasconde l\'etichetta sotto ogni pulsante di navigazione. + Sostituisci il pulsante Esempi + Sostituisce il pulsante Esempi con il pulsante Cerca. + Sostituisci il pulsante Aggiorna + Sostituisce il pulsante Aggiorna con il pulsante Impostazioni. + Informazioni sul pulsante Sostituisci + "Questa funzionalità è sperimentale. +Ci sono delle limitazioni strutturali della patch, poiché Attività come Ricerca e Impostazioni in YouTube Music non sono pubbliche. + +Problemi noti: +• Quando un'attività sostituita come Ricerca e Impostazioni viene chiusa, si apre la pagina iniziale. + +Fai clic per aprire le impostazioni \"Modifica pagina iniziale\"." + Lettore + Aggiungi il pulsante successivo nel miniplayer + Aggiunge un pulsante traccia successiva al miniplayer. + Aggiungi il pulsante precedente nel miniplayer + Aggiunge un pulsante traccia precedente al miniplayer. + Cambia il colore del miniplayer + Cambia il colore del miniplayer in modo che corrisponda al lettore a schermo intero. + Cambia il colore di sfondo del lettore + Cambia il colore di sfondo del lettore con un colore personalizzato. + Colore primario di sfondo del lettore + "Digita il codice esadecimale del colore primario dello sfondo del lettore. + +Se possibile usa colori scuri, poiché l'app non supporta temi chiari." + Colore secondario di sfondo del lettore + "Digita il codice esadecimale del colore secondario dello sfondo del lettore. + +Se possibile usa colori scuri, poiché l'app non supporta temi chiari." + Colore di sfondo lettore non valido. + Cambia la posizione della barra di ricerca + Sposta la barra di ricerca sotto il pulsante play. + Disabilita gestualità dal miniplayer + Disabilita lo scorrimento per cambiare le tracce nel miniplayer. + Disabilita gestualità dal lettore + Disabilita lo scorrimento per cambiare le tracce nel lettore. + Abilita miniplayer forzato + Abilita il miniplayer forzato quando si passa a una nuova traccia. + Abilita lo scorrimento per chiudere il miniplayer + Abilita lo scorrimento verso il basso per chiudere il miniplayer. + Abilita barra di ricerca spessa + "Abilita la barra di ricerca spessa. + +Limitazioni: i segmenti SponsorBlock non vengono mostrati nella barra di ricerca." Abilita la modalità zen Aggiunge una sfumatura grigia al riproduttore video per ridurre l\'affaticamento degli occhi. + Abilita la modalità Zen nei podcast + Abilita la modalità Zen nei podcast. + Nascondi linee guida del canale + Nasconde le linee guida del canale in cima alla sezione commenti. + Nascondi filtro sovrapposizione doppio tocco + Nasconde la sovrapposizione scura che appare quando si tocca due volte per cercare. + Nascondi i pulsanti Timestamp e Emoji + Nasconde i pulsanti emoji e timestamp durante la digitazione dei commenti. + Nascondi il pulsante Condividi a schermo intero + Nasconde il pulsante Condividi nel lettore a schermo intero. + Nascondi l\'interruttore Brano / Video + Nasconde l\'interruttore Brano / Video nel lettore. Ricorda lo stato di ripetizione Ricorda lo stato della ripetizione. Ricorda lo stato della riproduzione casuale Ricorda lo stato della riproduzione casuale. + Ripristina i vecchi pannelli popup dei commenti + Ripristina i pannelli popup dei commenti al vecchio stile. + Ripristina lo sfondo del vecchio lettore + Ripristina lo sfondo del lettore al vecchio stile. + Ripristina l\'interfaccia del vecchio lettore + "Ripristina l'interfaccia del lettore al vecchio stile. +Alcune funzionalità potrebbero non funzionare correttamente nell'interfaccia del vecchio lettore." + Menu delle Impostazioni + Nascondi il menu Centro Famiglia + Nascondi il menu Generale + Nascondi il menu Riproduzione + Nascondi il menu Salvataggio dati + Nascondi il menu Download & archiviazione + Nascondi il menu Notifiche + Nascondi il menu Privacy & dati + Nascondi il menu Raccomandazioni + Nascondi il menu Ottieni Music premium + Nascondi il menù Informazioni + Video Modifica velocità di riproduzione personalizzate Aggiungi o modifica le velocità di riproduzione disponibili + Ricorda le modifiche alla velocità di riproduzione + Ricorda l\'ultima velocità di riproduzione selezionata. + Mostra una notifica toast + Mostra una notifica toast quando viene cambiata la velocità di riproduzione predefinita. + Ricorda le modifiche alla qualità video + Ricorda l\'ultima qualità video selezionata. + Mostra una notifica toast + Mostra una notifica toast quando viene cambiata la qualità di riproduzione predefinita. Velocità di riproduzione personalizzate non valide. Ripristina i valori predefiniti. + Velocità di riproduzione personalizzate non valide. + Modifica della velocità predefinita in %s. + Modifica della qualità predefinita dei dati mobili in %s. + Impossibile impostare la qualità. + Modifica della qualità Wi-Fi predefinita in %s. + Restituisci YouTube Dislike + Abilita Restituisci YouTube Dislike Mostra il numero di \"Non mi piace\" dei video. \"Non mi piace\" in percentuale Al posto del numero di \"Non mi piace\", viene mostrata la percentuale dei Non mi piace. Pulsante \"Mi piace\" compatto Nasconde il separatore del pulsante \"Mi piace\". + Mostra i Mi piace stimati + Mostra il conteggio dei Mi piace stimati dei video. + Mostra una notifica toast se l\'API non è disponibile + Mostra una notifica toast se l\'API Restituisci YouTube Dislike non è disponibile. Informazioni + ReturnYouTubeDislike.com I dati vengono forniti dall\'API Return YouTube Dislike. Tocca qui per saperne di più. + Dislikes temporaneamente non disponibili (API scaduta). + Dislikes non disponibili (stato %d). \"Non mi piace\" non disponibile (limite API client raggiunto) + Dislikes non disponibili (%s). + Nascosto + Restituisci il nome utente di YouTube + Abilita Restituisci il nome utente di YouTube + Sostituisce gli handles con i nomi utente nei commenti. + Formato di visualizzazione + Seleziona il formato di visualizzazione del nome utente. + Nome utente + Nome utente (@handle) + \@handle (Nome utente) + Chiave API dati YouTube + La chiave sviluppatore per utilizzare l\'API v3 dei dati YouTube. + Informazioni sulla chiave API dei dati YouTube + "È richiesta una chiave sviluppatore YouTube Data API v3 per sostituire gli handle con i nomi utente. + +La quota giornaliera per le chiavi API nel piano gratuito è di 10.000 e 1 quota viene utilizzata per sostituire un handle con un nome utente per 1 commento. + +Fai clic per vedere come emettere una chiave API." + Emetti la chiave sviluppatore YouTube Data API v3 + 1. Vai su <a href=%1$s>Crea un nuovo progetto</a>.<br>2. Fai clic su <b>CREA</b>pulsante.<br>3. Vai su <a href=%2$s>YouTube Data API v3</a>.<br>4. Fai clic sul pulsante <b>ABILITA</b>pulsante.<br>5. Fai clic su <b>CREA CREDENZIALI</b>pulsante.<br>6. Seleziona l\'opzione <b>Dati pubblici</b>opzioni.<br>7. Fai clic su <b>PROSSIMO</b>pulsante.<br>8. Copia la chiave API.<br><br>※ La chiave API non dovrebbe mai essere condivisa con altri, quindi non è inclusa nelle impostazioni di importazione/esportazione. + SponsorBlock + Abilita SponsorBlock + SponsorBlock è un sistema di crowdsourcing per saltare parti fastidiose dei video di YouTube. + Mostra una notifica toast se l\'API non è disponibile + Mostra una notifica toast se l\'API SponsorBlock non è disponibile. + Mostra una notifica toast quando si salta automaticamente + Mostra una notifica toast quando un segmento viene saltato automaticamente. + Modifica l\'URL dell\'API + L\'indirizzo usato da SponsorBlock per contattare il server. Non cambiarlo a meno che tu non sappia cosa stai facendo. + Reimposta l\'URL dell\'API. + URL API non valido. + URL API modificato. + Modifica il comportamento dei segmenti + Sponsor + Promozioni a pagamento, referral a pagamento e pubblicità diretta. Non per autopromozione o ringraziamenti gratuiti a cause, creatori, siti web o prodotti di loro gradimento. + Promozione non retribuita / Autopromozione + Simile a Sponsor, eccetto per la promozione non retribuita o autopromozione. Include sezioni su merchandising, donazioni o informazioni su chi ha collaborato con loro. + Promemoria interazione (Iscriviti) + Una breve promemoria per mettere mi piace, iscriversi o seguirli su altre piattaforme durante la visione. Se è lungo o riguarda qualcosa di specifico, dovrebbe essere considerato autopromozione. + Animazione di Intermezzo / Introduzione + Intervallo senza contenuto sostanziale, come pause, scene statiche o ripetute che non includono transizioni contenenti informazioni. + Schede finali / Crediti + I crediti o quando appaiono le schede finali. Non per conclusioni con informazioni. + Anteprima / Riepilogo / Gancio + Raccolta di clip che mostrano cosa sta succedendo o cosa è successo nel video o in altri video di una serie, dove tutte le informazioni vengono ripetute altrove. + Riempitivo Tangente / Scherzi + Scene tangenziali aggiunte solo come riempitivo o umorismo che non sono necessarie per comprendere il contenuto principale del video. Non include segmenti che forniscono contesto o dettagli di background. + Musica: Sezione non musicale + Da utilizzare solo nei video musicali. Sezioni di video musicali senza musica, che non siano già coperte da un\'altra categoria. + Sponsor saltato. + Autopromozione saltata. + Promemoria indesiderato saltato. + Introduzione saltata. + Intermezzo saltato. + Intermezzo saltato. + Conclusione saltata. + Anteprima saltata. + Anteprima saltata. + Riepilogo saltato. + Riempitivo saltato. + Sezione non musicale saltata. + Segmenti multipli saltati. + Salta automaticamente + Disabilita + SponsorBlock temporaneamente non disponibile. + SponsorBlock temporaneamente non disponibile (Stato: %d). + SponsorBlock temporaneamente non disponibile (API scaduta). + Colore: + Colore modificato. + Colore ripristinato. + Codice colore non valido. + Resetta colore + I dati sono forniti dall\'API di SponsorBlock. Tocca qui per saperne di più e vedere i download per altre piattaforme. + Informazioni + sponsor.ajay.app + Varie Importa/Esporta Importa o esporta le impostazioni come testo. + Esporta le impostazioni in un file + Importa le impostazioni da un file + Importa / Esporta le impostazioni come testo + Esportazione impostazioni fallita. + Impostazioni esportate con successo. Importa Copia + Importazione fallita: %s. Ripristino impostazioni ai valori predefiniti Impostazioni %d importate + Reimposta + Impostazioni copiate negli appunti. + Aggira le restrizioni regionali delle immagini + Ignora il dominio bloccato in alcune regioni in modo che le miniature della playlist, gli avatar del canale, ecc. possano essere ricevuti. + Cambia foglio di condivisione + Sostituisce il foglio di condivisione in-app con il foglio di condivisione di sistema. + Disabilita animazione di avvio Cairo + Disabilita l\'animazione di avvio Cairo all\'avvio dell\'applicazione. + Disabilita audio DRC + Disabilita DRC (Compressione Gamma Dinamica) applicato all\'audio. + Disabilita video musicali nell\'album + "Quando un utente non premium riproduce una canzone inclusa in un album, a volte viene riprodotto il video musicale al posto della canzone ufficiale. + +Trova la canzone ufficiale se viene rilevato un video musicale in riproduzione da un album. + +Limitazioni: I video per bambini potrebbero non essere reindirizzati." + Tipo di reindirizzamento + Specifica come reindirizzare alla canzone ufficiale. + Reindirizzamento + Tocca l\'interruttore Brano / Video + Tocca e tieni premuto l\'interruttore Brano / Video + Disabilita il protocollo QUIC + "Disabilita il protocollo QUIC di CronetEngine." Abilita la registrazione del debug Stampa il registro di debug. + Abilita la registrazione di debug del buffer + Include il buffer nel registro di debug. Abilita il codec opus "Abilita il codec Opus 250/251 durante la riproduzione dell'audio." + Sanitizza i link di condivisione + Sanifica i link di condivisione rimuovendo i parametri di tracciamento. + Falsifica client + Falsifica il client per prevenire problemi di riproduzione. + Client predefinito + Definisce un client predefinito per la falsificazione. + Android Music 4.27.53 + Android Music 5.29.53 + iOS Music 6.21 + iOS Music 7.04 + Falsifica i parametri del lettore + "Falsifica il parametro del lettore per evitare problemi di riproduzione. + +Effetto collaterale: +• A volte i sottotitoli si trovano nella parte superiore del lettore anziché in quella inferiore." + Guarda il tipo di cronologia + "• Originale: segue le impostazioni della cronologia delle visualizzazioni dell'account Google, ma la cronologia delle visualizzazioni potrebbe non funzionare a causa di DNS o VPN. +• Sostituisci dominio: segue le impostazioni della cronologia delle visualizzazioni dell'account Google. +• Blocca cronologia delle visualizzazioni: la cronologia delle visualizzazioni è bloccata." + Originale + Sostituisci dominio + Blocca la cronologia delle visualizzazioni + Apri le impostazioni predefinite dell\'app + Per aprire i link di YouTube Music in RVX Music, abilita Apri link supportati e abilita tutti gli indirizzi web supportati. + Apri le impostazioni GmsCore + Per ricevere notifiche in RVX Music, abilita Cloud Messaging. + GmsCore non è installato, installalo. + Azione necessaria + "GmsCore non ha il permesso di funzionare in background. + +Segui la guida \"Don't kill my app!\" per il tuo dispositivo e applica le istruzioni alla tua installazione di GmsCore. + +Questo è necessario affinché l'app funzioni." + Apri sito web + "Le ottimizzazioni della batteria di GmsCore devono essere disattivate per evitare problemi. + +Disattivare le ottimizzazioni della batteria per GmsCore non influirà negativamente sull'utilizzo della batteria. + +Tocca il pulsante Continua e consenti le modifiche di ottimizzazione." + Continua diff --git a/patches/src/main/resources/music/translations/ja-rJP/strings.xml b/patches/src/main/resources/music/translations/ja-rJP/strings.xml index 841b47b0e..4089a8a93 100644 --- a/patches/src/main/resources/music/translations/ja-rJP/strings.xml +++ b/patches/src/main/resources/music/translations/ja-rJP/strings.xml @@ -172,6 +172,8 @@ プレイリストシェルフを非表示にします。 サンプルシェルフを非表示 フィードからサンプルシェルフを非表示にします。 + 検索ボタンを非表示 + ツールバーの検索ボタンを非表示にします。 サウンドサーチボタンを非表示 検索バーのサウンドサーチボタンを非表示にします。 「タップして更新」ボタンを非表示 @@ -192,6 +194,7 @@ 偽装するバージョンを選択してください。 6.42.55 - リアルタイムの歌詞を無効化 7.16.53 - 古いアクションバーを復元 + 無効な偽装アプリバージョンです: %s ナビゲーションバー カスタムナビゲーションバーの色を有効にする diff --git a/patches/src/main/resources/music/translations/pl-rPL/strings.xml b/patches/src/main/resources/music/translations/pl-rPL/strings.xml index d0657797c..9581e2a19 100644 --- a/patches/src/main/resources/music/translations/pl-rPL/strings.xml +++ b/patches/src/main/resources/music/translations/pl-rPL/strings.xml @@ -173,13 +173,13 @@ Ograniczenia: Ukryj półkę z samplami Ukrywa półke z samplami na stronie głównej. Ukryj przycisk wyszukiwania - Ukrywa przycisk wyszukiwania w pasku narzędzi. + Ukrywa przycisk wyszukiwania z paska narzędzi. Ukryj przycisk od rozpoznawania piosenek - Ukrywa przycisk od rozpoznawania piosenek w pasku wyszukiwania. + Ukrywa przycisk od rozpoznawania piosenek z paska wyszukiwania. Ukryj przycisk \'Stuknij, aby zaktualizować\' Ukrywa przycisk \'Stuknij, aby zaktualizować\'. Ukryj przycisk od wyszukiwania głosowego - Ukrywa przycisk od wyszukiwania głosowego w pasku wyszukiwania. + Ukrywa przycisk od wyszukiwania głosowego z paska wyszukiwania. Włącz stary styl półek biblioteki Przywraca zakładkę biblioteki do starego stylu. (Eksperymentalne) Usuń okno dialogowe treści ograniczonej do oglądania diff --git a/patches/src/main/resources/youtube/translations/ar/strings.xml b/patches/src/main/resources/youtube/translations/ar/strings.xml index e3bd5e2f6..46a5d5620 100644 --- a/patches/src/main/resources/youtube/translations/ar/strings.xml +++ b/patches/src/main/resources/youtube/translations/ar/strings.xml @@ -19,6 +19,38 @@ "لم يتم تثبيت %1$s. الرجاء تنزيل %2$s من الموقع." %s لم يتم تثبيته. الرجاء تثبيته. + إضافة إلى قائمة الانتظار + إضافة إلى قائمة الانتظار وفتح قائمة الانتظار + إضافة إلى قائمة الانتظار وتشغيل الفيديو + أداة التنزيل الخارجي + فتح قائمة الانتظار + قائمة الإنتظار + إزالة من قائمة الانتظار + إزالة من قائمة الانتظار وفتح قائمة الانتظار + إزالة قائمة الانتظار + حفظ قائمة الانتظار + "بدلاً من فتح برنامج تنزيل خارجي، افتح نافذة مدير قائمة الانتظار. + +يمكنك أيضًا فتح مدير قائمة الانتظار بالضغط باستمرار على زر الرجوع في شريط التنقل. + +هذه الميزة لا تزال قيد التطوير، لذا قد لا تعمل معظم الميزات. + +يرجى استخدامها لأغراض تصحيح الأخطاء فقط." + مطلوب تسجيل الدخول + مدير قائمة الانتظار غير متاح (%s). + تعذر التعرف على قائمة التشغيل + قائمة الانتظار فارغة + تعذر التعرف على الفيديو + فشل في إضافة الفيديو. + فشل في إنشاء قائمة الانتظار. + فشل في حذف قائمة الانتظار. + فشل في إزالة الفيديو. + فشل في حفظ قائمة الانتظار. + تم إضافة الفيديو بنجاح. + تم إنشاء قائمة الانتظار بنجاح. + تم حذف قائمة الانتظار بنجاح. + تم إزالة الفيديو بنجاح. + تم حفظ قائمة الانتظار بنجاح في \'%s\'. لغة RVX لغة التطبيق @@ -343,9 +375,6 @@ تعطيل تأثيرات الحركة تم تعطيل تأثيرات الحركة. تم تمكين تأثيرات الحركة. - تعطيل شريط الحالة الشفاف - شريط الحالة غير شفاف. - شريط الحالة معتم أو شفاف. تمكين شاشة التحميل المتدرجة تم تمكين شاشة التحميل المتدرجة الملونة. تم تعطيل شاشة التحميل المتدرجة الملونة. @@ -378,6 +407,23 @@ • فتح فيديوهات Shorts في المشغل العادي. • تنظيم الخلاصة حسب المواضيع والقنوات. • لا يمكن فتح وصف الفيديو عند إيقاف تشغيل Spoof' Streaming Data'." + تعطيل تحديثات التخطيط + لن يتم تحديث التخطيط بواسطة الخادم. + سيتم تحديث التخطيط بواسطة الخادم. + "يعود تصميم التطبيق إلى التصميم الذي كان عليه عند تثبيته لأول مرة. + +قد لا تعود بعض تصميمات الخادم إلى حالتها الأصلية. + +تشمل التغييرات ما يلي: +• قد لا تعمل المكونات في قائمة المشغل المنبثقة (أو الإعدادات ذات الصلة). +• لا تظهر الأرقام المتحركة. +• يتم استخدام علامة تبويب المكتبة. +• قد لا يعمل قسم الموسيقى في وصف الفيديو. +• قد لا يظهر زر تبديل الحساب في علامة تبويب المكتبة. استخدم إعداد 'تفعيل شريط البحث العريض في علامة التبويب أنت'." + تعطيل شريط الحالة الشفاف + شريط الحالة غير شفاف. + شريط الحالة معتم أو شفاف. + بالنسبة لبعض الـ ROM الخاصة بالشركة المصنعة التي تعمل بنظام Android 12 أو أحدث، قد يؤدي تمكين هذه الميزة إلى جعل شريط التنقل في النظام شفافًا. إصدار تطبيق وهمي تم تغيير اصدار التطبيق لم يتم تغيير اصدار التطبيق @@ -434,6 +480,9 @@ تجاوز زر تنزيل الفيديو يفتح زر تنزيل الفيديو الأصلي أداة التنزيل الخارجية. يفتح زر تنزيل الفيديو أداة التنزيل الأصلية داخل التطبيق. + مدير قائمة الانتظار + يفتح زر تنزيل الفيديو الأصلي مدير قائمة الانتظار. + يفتح زر تنزيل الفيديو الأصلي أداة التنزيل الخارجية لديك. اسم حزمة تنزيل قائمة التشغيل اسم الحزمة لتطبيق التنزيل الخارجي المثبت لديك، مثل YTDLnis. @@ -1065,6 +1114,8 @@ انقر لكتم صوت الفيديو الحالي. انقر مرة أخرى لإلغاء الكتم. عرض زر التنزيل الخارجي انقر لتشغيل برنامَج التنزيل الخارجي. + مدير قائمة الانتظار + بدلًا من تشغيل برنامج تنزيل خارجي، افتح مدير قائمة الانتظار. عرض مربع زر حوار السرعة "انقر لفتح مربع حوار السرعة. انقر مع الاستمرار لضبط سرعة التشغيل على 1.0x. انقر مع الاستمرار مرة أخرى لإعادة ضبط السرعة الافتراضية." @@ -1431,10 +1482,14 @@ أدنى قيمة لإيماءة السطوع تعمل على تنشيط السطوع التلقائي. أدنى قيمة لإيماءة السطوع لا تعمل على تنشيط السطوع التلقائي. تمكين التحكم بالسطوع عن طريق إيماءة التمرير - تم تمكين التحكم بمستوى السطوع عن طريق الإيماءة. + "تم تمكين ميزة التمرير السريع لضبط سطوع الشاشة بالكامل. + + اضبط السطوع بالتمرير عموديًا على يسار الشاشة." تم تعطيل التحكم بمستوى السطوع عن طريق الإيماءة. تمكين التحكم بالصوت عن طريق إيماءة التمرير - تم تمكين التحكم بمستوى الصوت عن طريق الإيماءة. + "تم تمكين ميزة التمرير على كامل الشاشة للتحكم في مستوى الصوت. + +اضبط مستوى الصوت بالتمرير عموديًا على يمين الشاشة." تم تعطيل التحكم بمستوى الصوت عن طريق الإيماءة. تمكين حفظ واستعادة السطوع حفظ واستعادة السطوع عند الخروج أو الدخول إلى وضع ملء الشاشة. @@ -1448,10 +1503,20 @@ إيماءات التمرير في وضع قفل الشاشة تم تمكين إيماءات التمرير في وضع شاشة القفل. تم تعطيل إيماءات التمرير في وضع شاشة القفل. - شفافية خلفية واجهة إيماءة التمرير - شفافية خلفية واجهة التمرير. مقدار حد التمرير الحد الأقصى للتمرير قبل اكتشاف الإيماءة. + واجهة التمرير السريع البديلة + يتم استخدام واجهة المستخدم البديلة. + يتم استخدام واجهة المستخدم القديمة. + تمكين النمط البسيط + تم تمكين نمط الواجهة البسيط. + تم تعطيل نمط الواجهة الأدنى. + عرض الواجهة الدائرية + يتم عرض الواجهة الدائرية. + يتم عرض الواجهة الأفقية. + تعتيم خلفية واجهة التمرير السريع + قيمة الشفافية بين 0-100. + يجب أن تكون شفافية التمرير بين 0-100. حجم نص واجهة إيماءة التمرير حجم النص في واجهة التمرير. حجم واجهة إيماءة التمرير @@ -1684,6 +1749,7 @@ عرض زر التخطي عرض في شريط تقدم الفيديو تعطيل + الشفافية: اللون: تم تغيير اللون. إعادة ضبط اللون. @@ -1750,6 +1816,8 @@ اعتراض تغيير الفئة لا توجد مقاطع للتصويت عليها. + + %1$s إلى %2$s اختر فئة المقطع الفئة معطلة في الإعدادات. تمكين الفئة للإرسال. مقطع SponsorBlock جديد @@ -1869,8 +1937,8 @@ Android VR "Android VR (بدون مصادقة)" - "iOS -(يتطلب PoToken)" + "iOS +(مُهمَل)" "iOS TV (يتطلب تسجيل الدخول)" التأثيرات الجانبية للتزييف @@ -1878,10 +1946,20 @@ • مستوى الصوت الثابت غير متاح. • لا يتوفر تعطيل المقطع الصوتي التلقائي المفروض. • قد لا يتم تشغيل الفيديوهات المخصصة للأطفال عند تسجيل الخروج أو في وضع التصفح المتخفي." - • قد تكون هناك مشكلات في التشغيل (يتطلب PoToken). + • قد يتم حظر نطاقات ASNs/IP بالكامل بواسطة الخادم. "• مستوى الصوت الثابت غير متوفر. • قد لا يتم تشغيل الأفلام أو الفيديوهات المدفوعة. • قد لا يتم تشغيل الفيديوهات المخصصة للأطفال عند تسجيل الخروج أو في وضع التصفح المتخفي." + استخدام عميل iOS + "تمت إضافة عميل iOS إلى العملاء المتاحين. + +تحذير: عميل iOS قديم. أي مشاكل قد تظهر أثناء استخدامه تكون على مسؤوليتك الخاصة." + لم يتم إضافة عميل iOS إلى العملاء المتاحين. + "عند طلب YouTube API Endpoints باستخدام iOS، ستحتاج إلى رموز المصادقة الصادرة عن جهاز iOS ورموز PoTokens الصادرة عن iOSGuard. + +هذا يعني أن طلبات البث عبر iOS ستفتقد رموز المصادقة ورموز PoTokens، وقد يعتبر الخادم المستخدم برنامجًا آليًا بوت ويحظر نطاق ASN/IP بالكامل. + +استخدمه على مسؤوليتك الخاصة!" فرض iOS AVC (H.264) يتم فرض ترميز الفيديو على AVC (H.264). يتم تحديد ترميز الفيديو تلقائيًا. diff --git a/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml b/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml index a495f4501..fe1f1c84e 100644 --- a/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml +++ b/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml @@ -320,9 +320,6 @@ Анимация при стартиране на приложението Новата начална анимация е изключена. Новата начална анимация е включена. - Деактивирайте полупрозрачната лента на прогреса - Лентата на прогреса е непрозрачна. - Лентата на прогреса е непрозрачна или полупрозрачна. Градиентен екрана за зареждане Екранът за зареждане с градиент е активиран. Екранът за зареждане с градиент е деактивиран. @@ -337,6 +334,9 @@ Действие на кликване върху точка за предаване на живо "Каналът се отваря, когато се щракне върху пръстена на живо." Потокът на живо се отваря, когато се щракне върху пръстена на живо. + Деактивирайте полупрозрачната лента на прогреса + Лентата на прогреса е непрозрачна. + Лентата на прогреса е непрозрачна или полупрозрачна. Променете версията на приложението Подправена версия Не подправена версия @@ -1328,10 +1328,10 @@ Когато намалите яркостта с жест до минимум, се активира автоматична яркост. Когато намалите яркостта с жест до минимум, автоматичната яркост Не се активира. Задаване на яркост чрез плъзгане - Задаването на яркост чрез плъзгане е включено. + "Задаването на яркост чрез плъзгане е включено." Задаването на яркост чрез плъзгане е изключено. Настройване на звука чрез плъзгане - Настройването на звука чрез плъзгане е включено. + "Настройването на звука чрез плъзгане е включено." Настройването на звука чрез плъзгане е изключено. Вкл. запазване и възстановяване на яркост Запазване и възстаовяване яркостта при включване или изключване на цял екран. @@ -1345,8 +1345,6 @@ Плъзне в режим Заключен екран Жестовете за плъзгане са активирани в режим „Заключен екран“. Жестовете за плъзгане са деактивирани в режим „Заключен екран“. - Видимост на фона на плъзгащите контроли - Видимостта на фона на плъзгащите контроли. Праг на величината на плъзгане Амплитудата на движение, разпозната като жест. Размер на текста при плъзгане @@ -1644,6 +1642,7 @@ Отрицателен вот Промяна на категорията Няма сегменти, за които да гласувате. + Изберете категорията на частта Категорията е изкл. в настройките. Вкл. я за да можете да изпратите. Нова част в SponsorBlock @@ -1752,8 +1751,6 @@ Android VR "Android VR (Няма удостоверение)" - "iOS -(Необходим PoToken)" "iOS (Необходим вход)" Ефекти от замяната @@ -1761,7 +1758,6 @@ • Не е наличен стабилен звук. • Деактивиране на принудителни автоматични аудио записи не е налично. • Детските видеоклипове може да не се възпроизвеждат, когато сте излезли или сте в режим инкогнито." - • Възможно е да има проблеми с възпроизвеждането (необходим е PoToken). "• Филми или платени видеоклипове може да не се възпроизвеждат. • Детските видеоклипове може да не се възпроизвеждат, когато сте излезли или сте в режим инкогнито." Принудително AVC (H.264) за iOS diff --git a/patches/src/main/resources/youtube/translations/de-rDE/strings.xml b/patches/src/main/resources/youtube/translations/de-rDE/strings.xml index 00a572af5..10259962b 100644 --- a/patches/src/main/resources/youtube/translations/de-rDE/strings.xml +++ b/patches/src/main/resources/youtube/translations/de-rDE/strings.xml @@ -1093,10 +1093,10 @@ Bekannte Probleme: Da dies eine Funktion in der Entwicklungsphase von Google ist Wenn die Helligkeit durch Wischen 0 erreicht wird, wird die automatische Helligkeit aktiviert. Auch wenn die Helligkeit durch Wischen auf 0 gesetzt wird, ist die automatische Helligkeit nicht aktiviert. Aktivierung der Helligkeitsgesten - Helligkeit Wischen ist aktiviert + "Helligkeit Wischen ist aktiviert" Helligkeit Wischen ist deaktiviert Aktiviere Lautstärkegesten - Lautstärkegeste ist aktiviert + "Lautstärkegeste ist aktiviert" Lautstärkegeste ist deaktiviert Aktiviere Drücken-zu-Wischgeste Berühren und halten, um die Wischgeste zu aktivieren. @@ -1105,8 +1105,6 @@ Bekannte Probleme: Da dies eine Funktion in der Entwicklungsphase von Google ist Haptisches Feedback ist aktiviert. Haptisches Feedback ist deaktiviert. Wischgesten sind im Sperrbildschirmmodus deaktiviert. - Wischen Hintergrund Sichtbarkeit - Die Sichtbarkeit des Wischen Overlay-Hintergrunds Wischgrößen-Schwellenwert Der Schwellenwert für das Wischen Wischüberlagerung Textgröße @@ -1352,6 +1350,7 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Negativ bewerten Kategorie ändern Es gibt keine Segmente zur Abstimmung + Wähle eine Segmentkategorie aus Category is disabled in settings. Enable category to submit. Neues SponsorBlock Segment diff --git a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml index c22ab86c9..e7d129fcc 100644 --- a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml +++ b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml @@ -449,9 +449,6 @@ Playlists Απενεργοποίηση εφέ εκκίνησης εφαρμογής Το εφέ εκκίνησης της εφαρμογής είναι απενεργοποιημένο. Το εφέ εκκίνησης της εφαρμογής είναι ενεργοποιημένο. - Απενεργοποίηση διαφανούς γραμμής κατάστασης - Η γραμμή κατάστασης δεν είναι διαφανής. - Η διαφάνεια της γραμμής κατάστασης ορίζεται αυτόματα. Διαβαθμισμένη οθόνη φόρτωσης Η οθόνη φόρτωσης θα έχει σταδιακές αποχρώσεις φόντο. Η οθόνη φόρτωσης θα έχει στατική απόχρωση φόντο. @@ -497,6 +494,9 @@ Playlists • Οι αριθμοί προβολών & «Μου αρέσει» δεν κινούνται αυξανόμενοι εκθετικά. • Η καρτέλα «Βιβλιοθήκη» θα επαναφερθεί. • Το κουμπί εναλλαγής λογαριασμού μπορεί να μην εμφανίζεται στην καρτέλα «Βιβλιοθήκη». Χρησιμοποιήστε την ρύθμιση «Ευρεία γραμμή αναζήτησης στο «Εσείς»»." + Απενεργοποίηση διαφανούς γραμμής κατάστασης + Η γραμμή κατάστασης δεν είναι διαφανής. + Η διαφάνεια της γραμμής κατάστασης ορίζεται αυτόματα. Παραποίηση έκδοσης εφαρμογής Η έκδοση παραποιείται. Η έκδοση δεν παραποιείται. @@ -1567,10 +1567,10 @@ Playlists Η χαμηλότερη τιμή της χειρονομίας φωτεινότητας ενεργοποιεί την αυτόματη φωτεινότητα. Η χαμηλότερη τιμή της χειρονομίας φωτεινότητας δεν ενεργοποιεί την αυτόματη φωτεινότητα. Έλεγχος σάρωσης για Φωτεινότητα - Η αλλαγή φωτεινότητας με χειρονομία σάρωσης στην αριστερή πλευρά της οθόνης είναι ενεργοποιημένη. + "Η αλλαγή φωτεινότητας με χειρονομία σάρωσης στην αριστερή πλευρά της οθόνης είναι ενεργοποιημένη." Η αλλαγή φωτεινότητας με χειρονομία σάρωσης στην αριστερή πλευρά της οθόνης είναι απενεργοποιημένη. Έλεγχος σάρωσης για Ένταση Ήχου - Η αλλαγή έντασης ήχου με χειρονομία σάρωσης στη δεξιά πλευρά της οθόνης είναι ενεργοποιημένη. + "Η αλλαγή έντασης ήχου με χειρονομία σάρωσης στη δεξιά πλευρά της οθόνης είναι ενεργοποιημένη." Η αλλαγή έντασης ήχου με χειρονομία σάρωσης στη δεξιά πλευρά της οθόνης είναι απενεργοποιημένη. Αποθήκευση και επαναφορά φωτεινότητας Η φωτεινότητα αποθηκεύεται και επαναφέρεται κατά την έξοδο ή την είσοδο σε πλήρη οθόνη. @@ -1584,8 +1584,6 @@ Playlists Χρήση στη λειτουργία «Οθόνη κλειδώματος» Οι χειρονομίες σάρωσης είναι ενεργοποιημένες στη λειτουργία «Οθόνη κλειδώματος». Οι χειρονομίες σάρωσης είναι απενεργοποιημένες στη λειτουργία «Οθόνη κλειδώματος». - Ορατότητα φόντου σάρωσης - Η ορατότητα του φόντου σάρωσης στο παρασκήνιο. Κατώτατο όριο μεγέθους σάρωσης Ελάχιστο πλάτος κίνησης αναγνωρίσιμο ως χειρονομία σάρωσης. Μέγεθος κειμένου φόντου σάρωσης @@ -1884,6 +1882,7 @@ Playlists Αρνητική ψήφος Αλλαγή κατηγορίας Δεν υπάρχουν τμήματα προς ψήφιση. + Επιλέξτε την κατηγορία τμήματος Η κατηγορία είναι απενεργοποιημένη στις ρυθμίσεις. Ενεργοποιήστε την κατηγορία για υποβολή. Νέο τμήμα SponsorBlock @@ -2005,8 +2004,6 @@ Playlists Android VR "Android VR (χωρίς auth)" - "iOS -(Απαιτείται αναγνωριστικό PoToken)" "iOS TV (Απαιτείται σύνδεση)" Παρενέργειες παραποίησης @@ -2014,7 +2011,6 @@ Playlists • Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη. • Η λειτουργία «Απενεργοποίηση υποχρεωτικών κομματιών ήχου» δεν είναι διαθέσιμη. • Τα βίντεο για παιδιά ενδέχεται να μην αναπαράγονται αν είστε αποσυνδεμένοι ή σε λειτουργία ανώνυμης περιήγησης." - • Ενδέχεται να υπάρχουν προβλήματα αναπαραγωγής (Απαιτείται αναγνωριστικό PoToken). "• Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη. • Οι ταινίες ή τα επί πληρωμή βίντεο ενδέχεται να μην αναπαράγονται. • Τα βίντεο για παιδιά ενδέχεται να μην αναπαράγονται αν είστε αποσυνδεμένοι ή σε λειτουργία ανώνυμης περιήγησης." diff --git a/patches/src/main/resources/youtube/translations/es-rES/strings.xml b/patches/src/main/resources/youtube/translations/es-rES/strings.xml index 4cff24e5b..478023eeb 100644 --- a/patches/src/main/resources/youtube/translations/es-rES/strings.xml +++ b/patches/src/main/resources/youtube/translations/es-rES/strings.xml @@ -482,9 +482,6 @@ Limitación: Es posible que el botón Atrás de la barra de herramientas no func Desactivar animación de bienvenida La animación de bienvenida está desactivada. La animación de bienvenida está activada. - Desactivar barra de estado translúcida - La barra de estado es opaca. - La barra de estado es opaca o translúcida. Activar pantalla de carga de degradado La pantalla de carga de degradado está activada. La pantalla de carga de degradado está desactivada. @@ -529,6 +526,10 @@ Los cambios incluyen: • Se utiliza la pestaña Biblioteca. • La sección Música de la descripción del vídeo puede no funcionar. • El botón de cambio de cuenta puede no aparecer en la pestaña Biblioteca. Utilice la función 'Activar barra de búsqueda ancha en la pestaña Tú'." + Desactivar barra de estado translúcida + La barra de estado es opaca. + La barra de estado es opaca o translúcida. + Para algunas ROM de fabricantes que ejecutan Android 12+, activar esta función puede hacer que la barra de navegación del sistema sea transparente. Falsificar versión de la app Versión falsificada Versión no falsificada @@ -1583,10 +1584,10 @@ No hay márgenes en la parte superior e inferior del reproductor." El valor más bajo del gesto de brillo activa el brillo automático. El valor más bajo del gesto de brillo no activa el brillo automático. Activar gesto de brillo - El control del brillo al deslizar está activado. + "El control del brillo al deslizar está activado." El control del brillo al deslizar está desactivado. Activar gesto de volumen - El control del volumen al deslizar está activado. + "El control del volumen al deslizar está activado." El control del volumen al deslizar está desactivado. Activar guardar y restaurar brillo Guarda y restaura el brillo al salir o entrar en pantalla completa. @@ -1600,10 +1601,20 @@ No hay márgenes en la parte superior e inferior del reproductor." Gestos deslizantes en modo \"Bloquear pantalla\" Los gestos deslizantes están activados en el modo \"Bloquear pantalla\". Los gestos deslizantes están desactivados en el modo \"Bloquear pantalla\". - Visibilidad de fondo de deslizamiento - La visibilidad del fondo de superposición de deslizamiento. Umbral de magnitud de deslizamiento La cantidad de umbral para que ocurra el deslizamiento. + Interfaz de usuario alternativa de superposición de deslizamiento + Se utiliza una interfaz de usuario alternativa. + Se utiliza la interfaz de usuario heredada. + Activar estilo minimalista + El estilo de superposición mínimo está activado. + El estilo de superposición mínimo está desactivado. + Mostrar superposición circular + La superposición circular está visible. + La superposición horizontal está visible. + Opacidad de fondo de superposición de deslizamiento + Valor de opacidad entre 0-100. + La opacidad de deslizamiento debe estar entre 0-100. Tamaño del texto de superposición de deslizamiento El tamaño del texto para la superposición de deslizamiento. Tamaño de pantalla de superposición deslizante @@ -1834,6 +1845,7 @@ Toca para ver cómo crear una clave de API." Mostrar botón de omitir Mostrar en barra de progreso Desactivado + Opacidad: Color: Color cambiado. Color restablecido. @@ -1900,6 +1912,8 @@ Toca para ver cómo crear una clave de API." Voto negativo Cambiar categoría No hay segmentos por los cuales votar. + + De %1$s a %2$s Selecciona la categoría del segmento La categoría está desactivada en los ajustes. Activa la categoría para enviar. Nuevo segmento de SponsorBlock @@ -2017,8 +2031,8 @@ Pulsa el botón de continuar y desactiva las optimizaciones de la batería."Android VR "Android VR (Sin autentificación)" - "iOS -(PoToken requerido)" + "iOS +(Obsoleto)" "iOS TV (Inicio de sesión requerido)" Efectos secundarios de falsificación @@ -2026,9 +2040,19 @@ Pulsa el botón de continuar y desactiva las optimizaciones de la batería." - • Puede haber problemas de reproducción (PoToken requerido). + • El servidor puede bloquear ASN/rangos de IP completos. "• Es posible que las películas o los vídeos de pago no se reproduzcan. • Es posible que los vídeos infantiles no se reproduzcan al cerrar la sesión o en modo incógnito." + Utilizar cliente iOS + "El cliente iOS se ha añadido a los clientes disponibles. + +ADVERTENCIA: El cliente iOS está obsoleto. Cualquier problema que surja al utilizarlo es bajo tu propia responsabilidad." + El cliente iOS no se ha añadido a los clientes disponibles. + "Al solicitar puntos finales de la API de YouTube mediante iOS, necesitarás los tokens de autenticación emitidos por el dispositivo iOS y los PoTokens emitidos por iOSGuard. + +Esto significa que las solicitudes de streaming a través de iOS carecerán tanto de los tokens de autenticación como de los PoTokens, y el servidor puede considerar al usuario como un bot y bloquear todo el rango ASN/IP. + +¡UTILÍZALO BAJO TU PROPIO RIESGO!" Forzar iOS AVC (H.264) El códec de vídeo es AVC (H.264). El códec de vídeo se determina automáticamente. diff --git a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml index 128b6f4c9..8f75ed08f 100644 --- a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml +++ b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml @@ -19,6 +19,38 @@ "%1$s n'est pas installé. Veuillez télécharger %2$s à partir du site web." %s n\'est pas installé. Veuillez l’installer. + Ajouter à la file d\'attente + Ajouter à la file d\'attente et ouvrir la file d\'attente + Ajouter à la file d\'attente et lire la vidéo + Téléchargeur externe + Ouvrir la file d\'attente + File d\'attente + Retirer de la file d\'attente + Retirer de la file d\'attente et ouvrir la file d\'attente + Retirer de la file d\'attente + Enregistrer la file d’attente + "Au lieu d’ouvrir un téléchargeur externe, ouvrez la boîte de dialogue du gestionnaire de file d’attente. + +Vous pouvez également accéder au gestionnaire de file d’attente en maintenant appuyé le bouton de retour situé sur la barre de navigation. + +Cette fonctionnalité est encore en cours de développement, donc la plupart des options risquent de ne pas fonctionner. + +Veuillez l’utiliser exclusivement à des fins de débogage." + Connexion requise + Gestionnaire de file d\'attente indisponible (%s). + Impossible d\'identifier la playlist + La file d\'attente est vide + Impossible d\'identifier la vidéo + Échec de l\'ajout de la vidéo. + Échec de la création de la file d\'attente. + Échec de la suppression de la file d\'attente. + Échec de la suppression de la vidéo. + Échec de l\'enregistrement de la file d\'attente. + Vidéo ajoutée avec succès. + File d\'attente créée avec succès. + File d\'attente supprimée avec succès. + Vidéo supprimée avec succès. + File d\'attente enregistrée avec succès dans \'%s\'. Langue RVX Langue de l\'application "Amharique @@ -453,9 +485,6 @@ Limitation : Le bouton Retour de la barre d'outils peut ne pas fonctionner."Désact. l\'animation de démarrage L\'animation de démarrage est désactivé. L\'animation de démarrage est activé. - Désactiver la barre de notification translucide - La barre de notification est opaque. - La barre de notification est opaque ou translucide. Activer dégradé pendant le chargement Le dégradé pendant l\'écran de chargement est activé. Le dégradé pendant l\'écran de chargement est désactivé. @@ -489,6 +518,22 @@ Mise en page automobile - Les Shorts s'ouvrent dans le lecteur normal. - Le flux est organisé par thèmes et par chaînes. - La description de la vidéo ne peut pas être ouverte lorsque l'option « Falsifier les données de diffusion en direct » est désactivée." + Désactiver les mises à jour de la mise en page + La mise en page ne sera pas mise à jour par le serveur. + La mise en page sera mise à jour par le serveur. + "La mise en page de l'application revient à celle utilisée lors de sa première installation. + +Certaines mises en page côté serveur pourraient ne pas être rétablies. + +Les modifications incluent : +• Les composants du menu déroulant du lecteur (ou les paramètres associés) pourraient ne pas fonctionner. +• L'animation en temps réel des nombres ne sont pas animés. +• L'onglet 'Bibliothèque' est utilisé. +• La section 'Musique' de la description des vidéos pourrait ne pas fonctionner. +• Le bouton 'Changer de compte' pourrait ne pas apparaître dans l'onglet 'Bibliothèque'. Veuillez utiliser le paramètre 'Activer la barre de recherche large dans l'onglet Vous'." + Désactiver la barre de notification translucide + La barre de notification est opaque. + La barre de notification est opaque ou translucide. Falsifier la version de l\'app Version falsifiée Version non falsifiée @@ -545,6 +590,9 @@ Certains composants peuvent ne pas être masqués." Remplacer le bouton de téléchargement de la vidéo Le bouton \'Télécharger\' natif ouvre votre téléchargeur externe. Le bouton \'Télécharger\' natif ouvre le téléchargeur de l\'appli. + Gestionnaire de file d’attente + Le bouton \'Télécharger\' natif ouvre le gestionnaire de file d\'attente. + Le bouton \'Télécharger\' natif ouvre votre téléchargeur externe. Nom du paquet du téléchargeur de la playlist Nom de package du téléchargeur externe installé, telle que YTDLnis. @@ -1176,6 +1224,8 @@ Appuyez longuement pour copier l'horodatage de la vidéo." Appuyez pour couper le son de la vidéo en cours. Appuyez à nouveau pour rétablir le son. Aff. bouton téléchargement externe Appuyez pour lancer le téléchargeur externe. + Gestionnaire de file d’attente + Au lieu de lancer un téléchargeur externe, ouvrez le gestionnaire de file d\'attente. Afficher bouton \'Vitesse de lecture\' "Appuyez pour ouvrir des paramètres de vitesse Appuyez longuement pour revenir à la vitesse de lecture à 1.0x. Appuyez longuement à nouveau rétablir les vitesses par défaut." @@ -1543,10 +1593,10 @@ Pas de marges en haut et en bas du lecteur." La valeur la plus basse du geste de luminosité active la luminosité automatique. La valeur la plus basse du geste de luminosité désactive la luminosité automatique. Activer les gestes de luminosité - Les gestes de luminosité sont activé. + "Les gestes de luminosité sont activé." Les gestes de luminosité sont désactivé. Activer les gestes de volume - Les gestes de volume sont activé. + "Les gestes de volume sont activé." Les gestes de volume sont désactivé. Activer enregistr. et restaur. de la luminosité Enregistrer et restaurer la luminosité en quittant ou en entrant en plein écran. @@ -1560,8 +1610,6 @@ Pas de marges en haut et en bas du lecteur." Gestes en mode \'Écran verrouillé\' Les contrôles par gestes sont activés en mode \'Écran verrouillé\'. Les contrôles par gestes sont désactivés en mode \'Écran verrouillé\'. - Visibilité du voile lors des gestes - La visibilité de l\'opacité du voile lors des gestes. Intensité des gestes Seuil de déclenchement pour que le geste de balayage se produise. Taille du texte superposé @@ -1861,6 +1909,7 @@ Cliquez ici pour découvrir comment créer une clé API." Voter contre Changer de catégorie Il n\'y a aucun segments pour lesquels voter. + Choisissez la catégorie du segment La catégorie est désactivée dans les paramètres. Activez la catégorie pour soumettre. Nouveau segment SponsorBlock @@ -1980,8 +2029,6 @@ Cliquez sur le bouton Continuer et autorisez les modifications d'optimisations." Android VR "Android VR (sans authentification)" - "iOS -(PoToken requis)" "iOS TV (Connexion requise)" Effets inconnus de la falsification @@ -1989,7 +2036,6 @@ Cliquez sur le bouton Continuer et autorisez les modifications d'optimisations." • Le volume stable n'est pas disponible. • La désactivation forcée des pistes audio automatiques n'est pas disponible. • Les vidéos pour enfants peuvent ne pas être lues en cas de déconnexion ou en mode incognito." - • Il peut y avoir des problèmes de lecture (PoToken required). "• Les films ou vidéos payantes peut ne pas être lus. • Les vidéos pour enfants peuvent ne pas être lues en cas de déconnexion ou en mode incognito." Forcer le codec AVC de iOS (H.264) diff --git a/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml b/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml index bf38e1057..73a578469 100644 --- a/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml +++ b/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml @@ -343,9 +343,6 @@ Korlátozás: Előfordulhat, hogy az eszköztár Vissza gombja nem működik."Indító animáció letiltása Az indító animáció le van tiltva. Az indító animáció engedélyezett. - Átlátszó állapotsor letiltása - Az állapotsor nem átlátszó. - Az állapotsor nem átlátszó vagy átlátszó. Színátmenetes betöltési képernyő engedélyezése A színátmenetes betöltési képernyő engedélyezett. A színátmenetes betöltési képernyő le van tiltva. @@ -377,6 +374,9 @@ Autóipari elrendezés • A shortok a normál lejátszóban nyílnak meg. • A hírfolyam témák és csatornák szerint van rendezve. • A videó leírása nem nyitható meg, ha az 'Adatfolyam hamisítása' ki van kapcsolva." + Átlátszó állapotsor letiltása + Az állapotsor nem átlátszó. + Az állapotsor nem átlátszó vagy átlátszó. Alkalmazásverzió hamisítása Verzió hamisítás Verzió nincs hamisítva @@ -1427,10 +1427,10 @@ Nincs margó a lejátszó tetején és alján." A gesztus vezérlés legkisebb értékénél az automatikus fényerő bekapcsol. A gesztus vezérlés legkisebb értékénél az automatikus fényerő nem kapcsol be. Fényerő gesztus vezérlés engedélyezése - A fényerő gesztus vezérlés engedélyezett. + "A fényerő gesztus vezérlés engedélyezett." A fényerő gesztus vezérlés le van tiltva. Hangerő gesztus vezérlés engedélyezése - A hangerő gesztus vezérlés engedélyezett. + "A hangerő gesztus vezérlés engedélyezett." A hangerő gesztus vezérlés le van tiltva. A fényerő mentésének és visszaállításának engedélyezése A fényerő mentése és visszaállítása teljes képernyőből való kilépéskor vagy belépéskor. @@ -1444,8 +1444,6 @@ Nincs margó a lejátszó tetején és alján." Gesztus vezérlések a képernyő lezárása módban A gesztus vezérlések engedélyezettek a képernyő lezárása módban. A gesztus vezérlések le vannak tiltva a képernyő lezárása módban. - Gesztus vezérlés átfedésének láthatósága - A gesztus vezérlés átfedésének láthatósága. Gesztus vezérlés küszöbértéke A gesztus vezérléshez szükséges küszöbérték. Gesztus vezérlés átfedésének szövegmérete @@ -1746,6 +1744,7 @@ Kattintson az API-kulcs kiadás folyamatának megtekintéséhez." Leszavazás Kategória módosítása Nincsen szakasz, amire szavazni lehet. + Válassza ki a szakasz kategóriáját A kategória letiltva a beállításokban. Engedélyezze a beküldéshez. Új SponsorBlock szakasz @@ -1865,8 +1864,6 @@ Kattintson a folytatás gombra és kapcsolja ki az akkumulátor optimalizáláso Android VR "Android VR (Nincs hitelesítés)" - "iOS -(PoToken szükséges)" "iOS TV (Belépés szükséges)" Hamisítás mellékhatásai @@ -1874,7 +1871,6 @@ Kattintson a folytatás gombra és kapcsolja ki az akkumulátor optimalizáláso • A stabil hangerő nem áll rendelkezésre. • A kényszerített automatikus hangsávok letiltása nem elérhető. • Előfordulhat, hogy a gyerekeknek szánt tartalmat nem lehet lejátszani, ha ki van jelentkezve vagy inkognitó módban van." - • Lejátszási problémák lehetnek (PoToken szükséges). "• A stabil hangerő nem érhető el. • Előfordulhat, hogy a filmeket vagy a fizetős videókat nem lehet lejátszani. • Előfordulhat, hogy a gyerekeknek szánt tartalmat nem lehet lejátszani, ha ki van jelentkezve vagy inkognitó módban van." diff --git a/patches/src/main/resources/youtube/translations/id-rID/strings.xml b/patches/src/main/resources/youtube/translations/id-rID/strings.xml index f8cda0f09..cffad2782 100644 --- a/patches/src/main/resources/youtube/translations/id-rID/strings.xml +++ b/patches/src/main/resources/youtube/translations/id-rID/strings.xml @@ -384,6 +384,7 @@ Keterbatasan: Tombol Kembali pada bilah alat mungkin tidak berfungsi." + diff --git a/patches/src/main/resources/youtube/translations/in/strings.xml b/patches/src/main/resources/youtube/translations/in/strings.xml index f8cda0f09..cffad2782 100644 --- a/patches/src/main/resources/youtube/translations/in/strings.xml +++ b/patches/src/main/resources/youtube/translations/in/strings.xml @@ -384,6 +384,7 @@ Keterbatasan: Tombol Kembali pada bilah alat mungkin tidak berfungsi." + diff --git a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml index 8ad850239..13f33e4c6 100644 --- a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml +++ b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml @@ -19,6 +19,38 @@ "%1$s non è installato. Si prega di scaricare %2$s dal sito web." %s non è installato. Per favore installalo. + Aggiungi alla coda + Aggiungi alla coda e aprila + Aggiungi alla coda e riproduci il video + Downloader esterno + Apri la coda + Coda + Rimuovi dalla coda + Rimuovi dalla coda e aprila + Rimuovi la coda + Salva la coda + "Invece di aprire un downloader esterno, apri la finestra di dialogo del gestore delle code. + +Puoi anche aprire il gestore delle code tenendo premuto il pulsante Indietro sulla barra di navigazione. + +Questa impostazione è ancora in fase di sviluppo, pertanto la maggior parte delle funzionalità potrebbe non funzionare. + +Usala solo per scopi di debug." + Accesso richiesto + Gestore delle code non disponibile (%s) + Impossibile identificare la playlist + La coda è vuota + Identificazione dell video non riuscito + Aggiunta del video non riuscita + Creazione della coda non riuscita + Eliminazione della coda non riuscita + Rimozione del video non riuscita + Salvataggio della coda non riuscito + Video aggiunto con successo + Coda creata con successo + Coda eliminata con successo + Video rimosso con successo + Coda salvata con successo in \'%s\' Lingua di RVX Lingua dell\'app "Amarico @@ -451,9 +483,6 @@ Nota: il pulsante Indietro della barra degli strumenti potrebbe non funzionare." Disattiva l\'animazione di avvio L\'animazione di avvio è disattivata. L\'animazione di avvio è attivata. - Disattiva la barra di stato traslucida - La barra di stato è opaca. - La barra di stato è opaca o traslucida. Attiva la schermata di caricamento gradiente La schermata di caricamento gradiente è attivata. La schermata di caricamento gradiente è disattivata. @@ -498,6 +527,9 @@ Le modifiche includono: • Viene usata la scheda Raccolta. • La sezione Musica nella descrizione dei video potrebbe non funzionare. • Il pulsante Cambia Account potrebbe essere nascosto nella scheda Raccolta. Usa l'impostazione \"Attiva la barra di ricerca estesa nella scheda Tu\"." + Disattiva la barra di stato traslucida + La barra di stato è opaca. + La barra di stato è opaca o traslucida. Attiva il camuffamento della versione dell\'app Il camuffamento della versione dell\'app è attivato. Il camuffamento della versione dell\'app è disattivato. @@ -554,6 +586,9 @@ Nota: alcuni componenti potrebbero non essere nascosti." Sovrascrivi il pulsante Scarica Video Il pulsante Scarica Video nativo apre il downloader esterno. Il pulsante Scarica Video nativo apre il downloader nativo. + Gestore delle code + Il pulsante Scarica Video nativo apre il gestore delle code. + Il pulsante Scarica Video nativo apre il downloader esterno. Nome del pacchetto del downloader esterno delle playlist Il nome del pacchetto dell\'app di download esterna installata, ad esempio YTDLnis. @@ -1189,6 +1224,8 @@ Tocca e tieni premuto per copiare il timestamp del video." Tocca di nuovo per riattivare l\'audio. Mostra il pulsante Downloader Esterno Tocca per avviare il downloader esterno. + Gestore delle code + Invece di aprire un downloader esterno, apri la finestra di dialogo del gestore delle code. Mostra il pulsante Velocità di Riproduzione "Tocca per aprire la finestra della velocità di riproduzione Tocca e tieni premuto per impostare la velocità di riproduzione a 1x. @@ -1549,10 +1586,10 @@ Note: Il valore più basso del gesto della luminosità attiva la luminosità automatica. Il valore più basso del gesto della luminosità non attiva la luminosità automatica. Attiva il gesto della luminosità - Il gesto della luminosità è attivato. + "Il gesto della luminosità è attivato." Il gesto della luminosità è disattivato. Attiva il gesto del volume - Il gesto del volume è attivato. + "Il gesto del volume è attivato." Il gesto del volume è disattivato. Attiva il salvataggio e il ripristino della luminosità Salva e ripristina la luminosità uscendo ed entrando a schermo intero. @@ -1566,8 +1603,6 @@ Note: Attiva i gesti di trascinamento in modalità Blocca Schermo I gesti di trascinamento in modalità Blocca Schermo sono attivati. I gesti di trascinamento in modalità Blocca Schermo sono disattivati. - La visibilità dello sfondo del trascinamento - La visibilità dello sfondo in sovrapposizione durante il trascinamento. Il limite di ampiezza del trascinamento Il limite di ampiezza entro cui deve avvenire il trascinamento. La dimensione del testo del trascinamento @@ -1867,6 +1902,7 @@ Tocca qui per vedere come emettere una chiave API." Voto negativo Cambia la categoria Non ci sono segmenti per cui votare. + Scegli la categoria del segmento La categoria è disattivata nelle impostazioni. Attiva la categoria da inviare. Nuovo segmento SponsorBlock @@ -1984,8 +2020,6 @@ Tocca il pulsante Continua e consenti le modifiche di ottimizzazione." Android VR "Android VR (Nessun accesso richiesto)" - "iOS -(PoToken richiesto)" "iOS TV (Accesso richiesto)" Effetti collaterali del camuffamento @@ -1993,7 +2027,6 @@ Tocca il pulsante Continua e consenti le modifiche di ottimizzazione." • Il volume stabile non funziona. • La disattivazione delle tracce audio automatiche forzate non funziona. • I video per bambini potrebbero non essere riprodotti se si è disconnessi o navigando in incognito." - • Ci potrebbero essere problemi di riproduzione (PoToken richiesto). "• Il volume stabile non funziona. • I film o i video a pagamento potrebbero non essere riproducibili. • I video per bambini potrebbero non essere riprodotti se si è disconnessi o navigando in incognito." diff --git a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml index c3e2aa758..53217d1c1 100644 --- a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml +++ b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml @@ -19,8 +19,95 @@ "%1$s はインストールされていません。 ウェブサイトから %2$s をダウンロードしてください。" %s はインストールされていません。インストールしてください。 + キューに追加 + キューに追加してキューを開く + キューに追加して動画を再生 + 外部ダウンローダー + キューを開く + キュー + キューから削除 + キューから削除してキューを開く + キューを削除 + キューを保存 + "外部ダウンローダーを開く代わりに、キューマネージャーダイアログを開きます。 + +ナビゲーションバーの戻るボタンを長押ししてキューマネージャーを開くこともできます。 + +この機能はまだ開発中であるため、ほとんどの機能が動作しない可能性があります。 + +デバッグ目的でのみ使用してください。" + ログインが必要です。 + キューマネージャーは利用できません (%s)。 + プレイリストを識別できませんでした。 + キューは空です + 動画を識別できませんでした + 動画を追加できませんでした。 + キューを作成できませんでした。 + キューを削除できませんでした。 + 動画を削除できませんでした。 + キューを保存できませんでした。 + 動画を追加しました。 + キューを作成しました。 + キューを削除しました。 + 動画を削除しました。 + キューは「%s」に保存されました。 YouTube と Revanced Extended 設定の言語 アプリの設定言語に従う + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" 広告 終了画面の商品バナーを非表示 @@ -345,9 +432,6 @@ DeArrow の詳細については、ここをタップしてください。"スプラッシュアニメーションを無効化 YouTube 起動時のスプラッシュアニメーションを無効にします。 YouTube 起動時のスプラッシュアニメーションを無効にします。 - 半透明なステータスバーを無効化 - ステータスバーを不透明にします。 - ステータスバーを不透明にします。 グラデーションの読み込み画面を有効化 アプリ起動時や動画の読み込み画面などでグラデーションを有効化します。 アプリ起動時や動画の読み込み画面などでグラデーションを有効化します。 @@ -382,6 +466,23 @@ DeArrow の詳細については、ここをタップしてください。" + レイアウトの更新を無効化 + サーバー側によるレイアウトの更新を無効化します。 + サーバー側によるレイアウトの更新を無効化します。 + "アプリのレイアウトは初回インストール時の状態に戻ります。 + +一部のサーバー側のレイアウトは初回インストール時の状態に戻らない可能性があります。 + +主な変更点: +・プレーヤー‎内のフライアウトメニュー(及び/または関連設定)のコンポーネントが動作しない可能性があります。 +・数字の回転アニメーションが無効になります。 +・[マイページ]タブではなく[ライブラリ]タブが使用されます。 +・概要欄の音楽セクションが動作しない可能性があります。 +・[ライブラリ]タブでアカウント切り替えボタンが表示されない可能性があります。 +→「[マイページ]タブで幅の広い検索バーを有効化」設定を使用してください。" + 半透明なステータスバーを無効化 + ステータスバーを不透明にします。 + ステータスバーを不透明にします。 アプリのバージョンを偽装 アプリのバージョンを偽装できます。 アプリのバージョンを偽装できます。 @@ -399,8 +500,10 @@ DeArrow の詳細については、ここをタップしてください。"18.33.40 - ショートの古いアクションバーを復元 18.38.45 - 以前のデフォルトの画質の動作を復元 18.48.39 - リアルタイムで更新される再生回数と高評価数を無効化 + 19.01.34 - 概要欄のインタラクションを無効化 19.26.42 - ナビゲーションとツールバーで Cairo アイコンを無効化 19.33.37 - 古い再生速度のフライアウトパネルを復元 + 無効な偽装アプリバージョンです: %s 「アカウント」メニュー 「アカウント」メニューと「マイページ」タブで要素を非表示または表示します。 @@ -436,6 +539,9 @@ DeArrow の詳細については、ここをタップしてください。"「オフライン」ボタンを置換 「オフライン」ボタンで外部ダウンローダーを開きます。 「オフライン」ボタンで外部ダウンローダーを開きます。 + 「オフライン」ボタンでキューマネージャーを開く + 「オフライン」ボタンで外部キューマネージャーを開きます。 + 「オフライン」ボタンで外部キューマネージャーを開きます。 プレイリストの外部ダウンローダーのパッケージ名 NewPipe や YTDLnis などの、インストールされている外部ダウンローダーアプリのパッケージ名です。 @@ -587,7 +693,7 @@ DeArrow の詳細については、ここをタップしてください。"ヘッダー付きの幅広い検索バーを有効化 ヘッダー付きの幅広い検索バーを有効化します。 ヘッダー付きの幅広い検索バーを有効化します。 - マイページ タブで幅広い検索バーを有効化 + [マイページ] タブで幅の広い検索バーを有効化 "[マイページ] タブで幅広い検索バーを有効化します。 注意: @@ -1065,6 +1171,8 @@ DeArrow の詳細については、ここをタップしてください。"タップすると現在の動画の音声をミュートにします。もう一度タップするとミュートを解除します。 外部ダウンローダーボタンを表示 タップすると外部ダウンローダーが起動します。 + 「オフライン」ボタンでキューマネージャーを開く + 外部ダウンローダーを起動する代わりに、キューマネージャーを開きます。 再生速度のダイアログボタンを表示 "タップすると再生速度のダイアログが開きます。 長押しすると再生速度を 1.0 倍にリセットします。もう一度長押しするとデフォルトの再生速度に戻ります。" @@ -1103,7 +1211,7 @@ DeArrow の詳細については、ここをタップしてください。"ホワイトリストに登録されています。 再生速度 SponsorBlock - チャンネル情報の読み込みに失敗しました。 + チャンネル情報を読み込めませんでした。 再生速度を %s 倍速にリセットしました。 ボタンの状態を変更するには、長押ししてください。 タイムスタンプをクリップボードにコピーしました。 (%s) @@ -1360,10 +1468,8 @@ DeArrow の詳細については、ここをタップしてください。"フライアウトメニューのカスタムアクションを有効化 "フライアウトメニューでカスタムアクションを使用できるようにします。 -注意: -・YouTube のバージョンが 18.49.37 以前に偽装されている場合は機能しません。 -・ライブ配信では機能しません。" - フライアウトメニューでカスタムアクションを使用できるようにします。\n\n注意: \n・YouTube のバージョンが 18.49.37 以前に偽装されている場合は機能しません。\n・ライブ配信では機能しません。 +注意: ライブ配信では機能しません。" + フライアウトメニューでカスタムアクションを使用できるようにします。\n\n注意: ライブ配信では機能しません。 ツールバーのカスタムアクションを有効化 "ツールバーでカスタムアクションを使用できるようにします。 @@ -1430,10 +1536,10 @@ DeArrow の詳細については、ここをタップしてください。"スワイプして明るさを 0 にして、明るさの自動調節を有効化します。 スワイプして明るさを 0 にして、明るさの自動調節を有効化します。 明るさのジェスチャーを有効化 - 明るさのスワイプコントロールを有効化します。 + "明るさのスワイプコントロールを有効化します。" 明るさのスワイプコントロールを有効化します。 音量ジェスチャーを有効化 - 音量のスワイプコントロールを有効化します。 + "音量のスワイプコントロールを有効化します。" 音量のスワイプコントロールを有効化します。 明るさの保存と復元を有効化 全画面表示を終了 / 開始した際に明るさを保存/復元します。 @@ -1447,8 +1553,6 @@ DeArrow の詳細については、ここをタップしてください。"「画面のロック」時のスワイプジェスチャーを有効化 スワイプジェスチャーを「画面のロック」モードで有効化します。 スワイプジェスチャーを「画面のロック」モードで有効化します。 - スワイプオーバーレイの背景の透明度 - スワイプオーバーレイの背景の透明度です。 スワイプ可能な領域のしきい値 スワイプとして検出する量のしきい値です。 スワイプオーバーレイのテキストサイズ @@ -1728,27 +1832,28 @@ API キーの発行方法については、ここをタップしてください SponsorBlock 設定の JSON は、ReVanced Extended やその他の SponsorBlock プラットフォームにインポート/エクスポートできます。 ReVanced Extended や他のプラットフォームの SponsorBlock にインポート/エクスポート可能な SponsorBlock 設定の JSON です。これにはプライベートユーザー ID が含まれています。共有する際は十分注意してください。 設定は正常にインポートされました。 - インポート失敗: %s - エクスポート失敗: %s + インポートできませんでした: %s + エクスポートできませんでした: %s この設定には SponsorBlock のプライベートユーザー ID が含まれています。\n\nユーザー ID はパスワードのようなものであるため、誰とも共有しないようにしてください。\n 今後表示しない SponsorBlock は一時的に利用できません。 SponsorBlock は一時的に利用できません。(ステータス %d) SponsorBlock は一時的に利用できません。(API がタイムアウトしました) - セグメントを送信できません: %s + セグメントを送信できませんでした: %s SponsorBlock は一時的に停止しています。 - セグメントを送信できません (ステータス: %1$d %2$s) - セグメントを送信できません\nレート制限 (同じユーザー / IP からの送信が多すぎます) + セグメントを送信できませんでした (ステータス: %1$d %2$s) + セグメントを送信できませんでした。\nレート制限 (同じユーザー / IP からの送信が多すぎます) セグメントを送信できません: %s セグメントを送信できません。\n既に存在します。 セグメントは正常に送信されました - セグメントを評価できません (API がタイムアウトしました) - セグメントの評価を送信できません (ステータス: %1$d %2$s) - セグメントの評価を送信できません: %s + セグメントの評価を送信できませんでした (API がタイムアウトしました) + セグメントの評価を送信できませんでした (ステータス: %1$d %2$s) + セグメントの評価を送信できませんでした: %s 賛成 反対 カテゴリーを変更 評価できるセグメントがありません + セグメントのカテゴリを選択してください カテゴリーは設定で無効になっています。送信するにはカテゴリーを有効にしてください。 新しい SponsorBlock セグメント @@ -1846,11 +1951,11 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に テキストとしてインポート/エクスポート テキストとしてインポート/エクスポート 設定をテキストとしてインポートまたはエクスポートします。 - 設定のエクスポートに失敗しました。 + 設定をエクスポートできませんでした。 設定は正常にエクスポートされました。 インポート コピー - 設定のインポートに失敗しました。 + 設定をインポートできませんでした。 設定をデフォルトにリセットしました。 設定は正常にインポートされました。 リセット @@ -1868,8 +1973,6 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に Android VR "Android VR (認証なし)" - "iOS -(PoToken が必要)" "iOS TV (Google アカウントへのログインが必要)" ストリーミングデータを偽装することによる副作用 @@ -1877,7 +1980,6 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に ・「一定音量」は利用できません。 ・「音声トラックの強制を無効化」は利用できません。 ・ログインをしていない場合やシークレットモードでは、子供向け動画は再生できない可能性があります。" - ・動画が再生できない可能性があります(PoToken が必要です)。 "・「一定音量」は利用できません。 ・映画や有料動画は再生できない可能性があります。 ・ログインをしていない場合やシークレットモードでは、子供向け動画は再生できない可能性があります。" diff --git a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml index 48747bc40..4350d1e5d 100644 --- a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml +++ b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml @@ -19,16 +19,16 @@ "%1$s 가 설치되어 있지 않습니다. 웹사이트에서 %2$s 를 다운로드하세요." %s가 설치되지 않았습니다. 설치하세요. - 현재 재생목록에 추가하기 + 현재 재생목록에 추가 현재 재생목록에 추가하고 현재 재생목록 열기 - 현재 재생목록에 추가하고 동영상 재생하기 + 현재 재생목록에 추가하고 동영상 재생 외부 다운로더 현재 재생목록 열기 현재 재생목록 - 현재 재생목록에서 제거하기 + 현재 재생목록에서 제거 현재 재생목록에서 제거하고 현재 재생목록 열기 - 현재 재생목록 제거하기 - 현재 재생목록 저장하기 + 현재 재생목록 제거 + 현재 재생목록 저장 "외부 다운로더가 아닌 현재 재생목록 관리자 다이얼로그를 실행할 수 있습니다. 시스템 네비게이션 바에서 '뒤로 가기' 버튼을 길게 눌러서 현재 재생목록 관리자를 실행할 수도 있습니다. @@ -51,115 +51,115 @@ 현재 재생목록을 \'%s\'에 성공적으로 저장하였습니다. RVX 언어 앱 언어 - "Amharic + "암하라어 አማርኛ" - "Arabic + "아랍어 العربية" - "Azerbaijani + "아제르바이잔어 Azərbaycan" - "Belarusian + "벨라루스어 беларуская" - "Bulgarian + "불가리아어 Български" - "Bengali + "뱅골어 বাংলা" - "Catalan + "카탈로니아어 Català" - "Czech + "체코어 Čeština" - "Danish + "덴마크어 Dansk" - "German + "독일어 Deutsch" - "Greek + "그리스어 Ελληνικά" - "English + "영어 English" - "Spanish + "스페인어 Español" - "Estonian + "에스토니아어 Eesti" - "Persian + "페르시아어 فارسی" - "Finnish + "핀란드어 Suomi" - "French + "프랑스어 Français" - "Gujarati + "구자라트어 ગુજરાતી" - "Hebrew + "히브리어 עברי" - "Hindi + "힌디어 हिन्दी" - "Croatian + "크로아티아어 Hrvatski" - "Hungarian + "헝가리어 Magyar" - "Indonesian + "인도네시아어 Indonesia" - "Italian + "이탈리아어 Italiano" - "Japanese + "일본어 日本語" - "Kazakh + "카자흐어 Қазақ тілі" - "Korean + "한국어 한국어" - "Lithuanian + "리투아니아어 Lietuvių" - "Latvian + "라트비아어 Latviešu" - "Macedonian + "마케도니아어 Македонски" - "Mongolian + "몽골어 Монгол" - "Marathi + "마라티어 मराठी" - "Malay + "말레이어 Melayu" - "Burmese + "버마어 ဗမာ" - "Dutch + "네덜란드어 Nederlands" - "Odia + "오리야어 ଓଡ଼ିଆ" - "Punjabi + "펀잡어 ਪੰਜਾਬੀ" - "Polish + "폴란드어 Polski" - "Portuguese + "포르투갈어 Português" - "Romanian + "루마니아어 Română" - "Russian + "러시아어 Русский" - "Slovak + "슬로바키아어 Slovenčina" - "Albanian + "알바니아어 Shqip" - "Slovene + "슬로베니아어 Slovenščina" - "Serbian + "세르비아어 Српски" - "Swedish + "스웨덴어 Svenska" - "Swahili + "스와힐리어 Kiswahili" - "Tamil + "타밀어 தமிழ்" - "Telugu + "텔루구어 తెలుగు" - "Thai + "태국어 ไทย" - "Turkish + "터키어 Türkçe" - "Ukrainian + "우크라이나어 Українська" - "Urdu + "우르두어 اردو" - "Vietnamese + "베트남어 Tiếng Việt" - "Chinese + "중국어 中文" 광고 @@ -486,9 +486,6 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 스플래시 애니메이션 비활성화하기 앱을 시작할 때, 스플래시 애니메이션을 비활성화합니다. 앱을 시작할 때, 스플래시 애니메이션을 활성화합니다. - 반투명 상태바 비활성화하기 - 상태바가 불투명합니다. - 상태바가 불투명하거나 반투명합니다. 그라데이션 색상 로딩 화면 활성화하기 그라데이션 색상 로딩 화면을 활성화합니다. 그라데이션 색상 로딩 화면을 비활성화합니다. @@ -535,6 +532,10 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." • 보관함 탭이 사용됩니다. • 동영상 설명에서 음악 섹션이 작동되지 않을 수 있습니다. • 보관함 탭에서 계정 전환 버튼이 표시되지 않을 수 있습니다. '내 페이지에서 넓은 검색창 활성화하기' 설정을 사용하세요." + 반투명 상태바 비활성화하기 + 상태바가 불투명합니다. + 상태바가 불투명하거나 반투명합니다. + Android 12+가 설치되어 있는 일부 제조사 ROM의 경우에는 이 기능을 활성화하면 시스템 네비게이션 바가 투명해질 수 있습니다. 앱 버전 변경하기 앱 버전을 변경합니다. 앱 버전을 변경하지 않습니다. @@ -588,8 +589,8 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 기본 동영상 오프라인 저장 버튼으로 외부 다운로더를 실행할 수 있습니다. 기본 동영상 오프라인 저장 버튼으로 기본 다운로더를 실행할 수 있습니다. (YouTube Premium 기능) 현재 재생목록 관리자 - 기본 동영상 오프라인 저장 버튼으로 현재 재생목록 관리자를 실행합니다. - 기본 동영상 오프라인 저장 버튼으로 외부 다운로더를 실행합니다. + 기본 동영상 오프라인 저장 버튼으로 현재 재생목록 관리자를 실행할 수 있습니다. + 기본 동영상 오프라인 저장 버튼으로 외부 다운로더를 실행할 수 있습니다. 재생목록 외부 다운로더 앱 패키지명 YTDLnis와 같은 설치된 외부 다운로더 앱 패키지명을 설정하세요. @@ -1596,10 +1597,10 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 전체 화면에서 스와이프하여 밝기가 0이 되면 자동 밝기를 활성화합니다. 전체 화면에서 스와이프하여 밝기가 0이 되더라도 자동 밝기를 활성화하지 않습니다. 스와이프 제스처로 밝기 조절 활성화하기 - 전체 화면 왼쪽에서 위로/아래로 스와이프하여 밝기 조절합니다. + "전체 화면 왼쪽에서 위로/아래로 스와이프하여 밝기 조절합니다." 전체 화면 왼쪽에서 위로/아래로 스와이프하여 밝기 조절하지 않습니다. 스와이프 제스처로 볼륨 조절 활성화하기 - 전체 화면 오른쪽에서 위로/아래로 스와이프하여 볼륨 조절합니다. + "전체 화면 오른쪽에서 위로/아래로 스와이프하여 볼륨 조절합니다." 전체 화면 오른쪽에서 위로/아래로 스와이프하여 볼륨 조절하지 않습니다. 화면 밝기 값 저장 및 복원 활성화하기 전체 화면에서 나가거나 들어갈 때마다 화면 밝기 값을 저장 및 복원합니다. @@ -1613,10 +1614,20 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 잠금 화면에서 스와이프 제스처 활성화하기 잠금 화면에서 스와이프 제스처를 활성화합니다. 잠금 화면에서 스와이프 제스처를 비활성화합니다. - 스와이프 오버레이 배경 투명도 - 스와이프 오버레이 배경 투명도 값을 지정할 수 있습니다. 스와이프 한계치 제스처 인식을 위해 얼마나 스와이프를 해야 할지를 지정할 수 있습니다. + 스와이프 오버레이 대체 UI + 대체 UI를 사용합니다. + 기존 UI를 사용합니다. + 최소화된 스타일 활성화하기 + 최소화된 오버레이 스타일을 활성화합니다. + 최소화된 오버레이 스타일을 비활성화합니다. + 원형 조절 오버레이 표시하기 + 원형 조절 오버레이를 표시합니다. + 바형 조절 오버레이를 표시합니다. + 스와이프 오버레이 배경 불투명도 + 스와이프 불투명도 값은 0-100 사이여야 합니다. + 스와이프 불투명도 값은 0-100 사이여야 합니다. 스와이프 오버레이 텍스트 크기 스와이프 오버레이 텍스트 크기를 지정할 수 있습니다. 스와이프 오버레이 화면 크기 @@ -1847,6 +1858,7 @@ API Key를 발급받는 방법을 보려면 여기를 누르세요." 건너뛰기 버튼 표시하기 재생바에만 표시하기 사용 안 함 + 불투명도: 색상: 설정한 색상을 적용하였습니다. 색상을 초기화하였습니다. @@ -1913,6 +1925,8 @@ API Key를 발급받는 방법을 보려면 여기를 누르세요." 싫어요 카테고리 변경 투표할 구간이 없습니다. + + %1$s ~ %2$s 구간 카테고리를 선택하세요. 이 카테고리는 비활성화되어 있습니다. 제출하려면 설정에서 활성화해야 합니다. 새로운 SponsorBlock 구간 @@ -2032,8 +2046,8 @@ GmsCore 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 Android VR "Android VR (인증 없음)" - "iOS -(PoToken이 요구됨)" + "iOS +(폐기 예정)" "iOS TV (로그인이 요구됨)" 알려진 문제점 @@ -2044,12 +2058,22 @@ GmsCore 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 • VR은 Kids // TV는 재생목록과 음악 동영상에서 다른 클라이언트가 사용될 수 있습니다. • TV는 AV1 코덱이 지원되지 않습니다. • 인증 없음: 사용자 로그인 정보를 사용하지 않음" - • 동영상 재생 문제가 발생할 수 있습니다 (PoToken이 요구됨).\n• 영화, 유료, 비공개 그리고 연령 제한 동영상에서 다른 클라이언트가 사용될 수 있습니다. + • 서버에서 전체 ASNs/IP 범위를 차단할 수 있습니다. "• 안정적인 볼륨을 사용할 수 없습니다. • 영화 또는 유료 동영상이 재생되지 않을 수 있습니다. • 사용자가 로그인을 하지 않았거나 시크릿 모드에서는 Kids 동영상이 재생되지 않을 수 있습니다. • 음악 동영상에서 다른 클라이언트가 사용될 수 있습니다. • AV1 코덱이 지원되지 않습니다." + iOS 클라이언트 사용하기 + "사용 가능한 기본 클라이언트에 iOS 클라이언트가 추가되었습니다. + +경고: iOS 클라이언트는 폐기될 예정입니다. 사용 중 발생하는 모든 문제는 사용자의 책임입니다." + 사용 가능한 기본 클라이언트에 iOS 클라이언트가 추가되지 않습니다. + "iOS를 사용하여 YouTube API 엔드포인트를 요청할 때는 iOS 기기에서 발급된 Auth Token과 iOSGuard에 의해 발급된 PoTokens가 필요합니다. + +즉, iOS를 통한 스트리밍 요청에는 Auth Token과 PoTokens가 모두 누락되며, 서버는 사용자를 봇으로 간주하여 전체 ASN/IP 범위를 차단할 수 있습니다. + +당신의 위험을 감수하고 사용하세요!" iOS AVC (H.264) 강제로 활성화하기 동영상 코덱을 AVC (H.264)로 강제로 활성화합니다.\n\n• 일부 VP9 코덱 동영상에서 제거되었던 화질 값이 표시될 수 있습니다.\n• 최대 화질 값이 1080p이므로, 초고화질 동영상을 재생할 수 없습니다.\n• HDR 동영상을 재생할 수 없습니다. 동영상 코덱을 자동으로 결정합니다.\n\n• 예전에 업로드된 동영상을 재생했는데 VP9 코덱 응답을 받았을 경우, 일부 화질값이 제거되어 360p와 1080p(Premium 기능)만 선택가능할 수 있거나 화질 메뉴를 선택불가능할 수 있습니다. @@ -2067,7 +2091,7 @@ AVC의 최대 화질 값은 1080p이고, OPUS 코덱을 사용불가 및 HDR 동 전문 통계에서 표시하기 스트리밍 데이터를 가져오는 데 사용되는 클라이언트가 전문 통계에서 표시됩니다.\n\n• 만약 선택한 기본 클라이언트가 재생할 수 없는 동영상을 재생하려하거나 클라이언트 재생 문제가 발생하면, 그 문제를 해결하기 위해 다른 클라이언트가 사용되는 경우도 있기 때문에 전문 통계에서 다르게 표시될 수 있습니다. 스트리밍 데이터를 가져오는 데 사용되는 클라이언트가 전문 통계에서 숨겨집니다.\n\n• 만약 선택한 기본 클라이언트가 재생할 수 없는 동영상을 재생하려하거나 클라이언트 재생 문제가 발생하면, 그 문제를 해결하기 위해 다른 클라이언트가 사용되는 경우도 있기 때문에 전문 통계에서 다르게 표시될 수 있습니다. - Android VR 기본 오디오 스트림 언어 + VR 기본 오디오 스트림 언어 PoToken & VisitorData PoToken 등록하기 diff --git a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml index a41c9b431..4cb59d164 100644 --- a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml +++ b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml @@ -19,6 +19,38 @@ "%1$s nie jest zainstalowany. Pobierz %2$s ze strony internetowej." %s nie jest zainstalowany. Proszę go zainstalować. + Dodaj do kolejki + Dodaj do kolejki i otwórz kolejkę + Dodaj do kolejki i odtwórz film + Zewnętrzna aplikacja od pobierania + Otwórz kolejkę + Kolejka + Usuń z kolejki + Usuń z kolejki i otwórz kolejkę + Usuń kolejkę + Zapisz kolejkę + "Zamiast otwierać zewnętrzną aplikację od pobierania, otwiera okno menedżera kolejki. + +Możesz również otworzyć menedżer kolejek poprzez kliknięcie i przytrzymanie przycisku cofania na pasku nawigacyjnym. + +Funkcja jest nadal rozwijana, więc większość funkcji może nie działać. + +Proszę używać tej funkcji wyłącznie w celach debugowania." + Wymagane logowanie + Menedżer kolejki jest niedostępny (%s). + Nie można zidentyfikować playlisty + Kolejka jest pusta + Nie można zidentyfikować filmu + Nie udało się dodać filmu. + Nie udało się utworzyć kolejki. + Nie udało się usunąć kolejki. + Nie udało się usunąć filmu. + Nie udało się zapisać kolejki. + Pomyślnie dodano film. + Pomyślnie utworzono kolejkę. + Pomyślnie usunięto kolejkę. + Pomyślnie usunięto film. + Pomyślnie zapisano kolejkę do \'%s\'. Język RVX Język aplikacji "Amharski @@ -453,9 +485,6 @@ Ograniczenie: Przycisk wstecz na pasku narzędzi może nie działać." Animacja uruchamiania aplikacji Wyłączona Włączona - Półprzezroczystość paska statusu - Wyłączona - Włączona Kolorowy ekran ładowania Włączony Wyłączony @@ -502,6 +531,9 @@ Zmiany zawierają: • Zakładka biblioteki jest używana • Sekcja muzyki w opisie filmu może nie działać • Przycisk od przełączania konta może się nie pojawiać w zakładce biblioteki. Użyj ustawienia 'Szeroki pasek wyszukiwania w zakładce Ty'" + Półprzezroczystość paska statusu + Wyłączona + Włączona Oszukiwanie wersji aplikacji Włączone Wyłączone @@ -558,6 +590,9 @@ Niektóre komponenty mogą nie być ukryte." Metoda pobierania filmów Zewnętrzna aplikacja Natywne pobieranie + Menedżer kolejki + Natywny przycisk od pobierania otworzy menedżer kolejki + Natywny przycisk od pobierania otworzy zewnętrzną aplikację od pobierania Nazwa pakietu aplikacji od pobierania (playlisty) Nazwa pakietu zainstalowanej zewnętrznej aplikacji od pobierania, takiej jak YTDLnis. @@ -1191,6 +1226,8 @@ Stuknij i przytrzymaj, by skopiować czas filmu." Stuknij, by wyciszyć bieżący film. Stuknij ponownie, by odciszyć film. Przycisk do pobierania Stuknij, by otworzyć aplikacje od pobierania. + Menedżer kolejki + Zamiast otwierać zewnętrzną aplikację od pobierania, otwiera menedżera kolejki. Przycisk od prędkości "Stuknij, by zmienić prędkość odtwarzania. Stuknij i przytrzymaj, by zmienić prędkość odtwarzania na 1.0x. Stuknij i przytrzymaj ponownie, by zresetować do domyślnej prędkości." @@ -1556,10 +1593,10 @@ Ograniczenia: Najniższa wartość jasności aktywowana przesuwaniem włącza automatyczną jasność Najniższa wartość jasności aktywowana przesuwaniem nie włącza automatycznej jasności Zmienianie jasności przesuwaniem - Włączone + "Włączone" Wyłączone Zmienianie głośności przesuwaniem - Włączone + "Włączone" Wyłączone Zapisuj i przywracaj jasność podczas zamykania lub wchodzenia w tryb pełnoekranowy Tak @@ -1573,8 +1610,6 @@ Ograniczenia: Przesuwanie podczas trybu blokady ekranu Włączone Wyłączone - Widoczność tła przesuwania - Widoczność tła nakładki przesuwania Minimalna długość przesunięcia Minimalna długość przesunięcia Rozmiar tekstu nakładki przesuwania @@ -1874,6 +1909,7 @@ Kliknij, by zobaczyć, jak zgłosić klucz API." Głos przeciw Zmień kategorię Brak segmentów, na które można zagłosować. + Wybierz kategorię segmentu Ta kategoria jest wyłączona w ustawieniach. Włącz kategorię, aby móc wysłać ten segment. Nowy segment SponsorBlock @@ -1993,8 +2029,6 @@ Stuknij przycisk kontynuacji i zezwól na zmiany w optymalizacji." Android VR "Android VR (Bez autoryzacji)" - "iOS -(Wymagany PoToken)" "iOS TV (Wymagane zalogowanie)" Efekty uboczne oszukiwania @@ -2002,7 +2036,6 @@ Stuknij przycisk kontynuacji i zezwól na zmiany w optymalizacji." • Stabilna głośność nie jest dostępna • Automatyczne wymuszenie ścieżki dźwiękowej nie jest dostępne • Filmy dla dzieci mogą się nie odtwarzać będąc zalogowanym lub w trybie incognito" - • Mogą wystąpić problemy z odtwarzaniem (wymagany PoToken) "• Stabilna głośność nie jest dostępna • Filmy kinowe lub płatne mogą się nie odtwarzać • Filmy dla dzieci mogą się nie odtwarzać będąc zalogowanym lub w trybie incognito" diff --git a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml index 5199a8307..7da22d7dc 100644 --- a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml +++ b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml @@ -338,9 +338,6 @@ Limitação: O botão voltar na barra de ferramentas pode não funcionar."Desativar animação inicial A animação inicial está desativada. A animação do inicial está ativada. - Desativar barra de status transparente - A barra de status está opaca. - A barra de status está opaca ou transparente. Ativar tela de carregamento gradiente A tela de carregamento gradiente está ativada. A tela de carregamento gradiente está desativada. @@ -372,6 +369,9 @@ Automotivo layout • Shorts abertos no reprodutor regular. • O feed é organizado por tópicos e canais. • A descrição do vídeo não pode ser aberta quando o 'Falsificar dados de reprodução' está desligado." + Desativar barra de status transparente + A barra de status está opaca. + A barra de status está opaca ou transparente. Falsificar versão do aplicativo Versão falsificada Versão não falsificada @@ -1416,10 +1416,10 @@ Sem margens na parte superior e inferior do reprodutor." O menor valor do gesto de brilho ativa o brilho automático. O menor valor do gesto de brilho não ativa o brilho automático. Ativar gesto de brilho - O gesto de brilho está ativado. + "O gesto de brilho está ativado." O gesto de brilho está desativado. Ativar gesto de volume - O gesto de volume está ativado. + "O gesto de volume está ativado." O gesto de volume está desativado. Ativar salvar e restaurar brilho Salvar e restaurar o brilho ao sair ou entrar em tela cheia. @@ -1433,8 +1433,6 @@ Sem margens na parte superior e inferior do reprodutor." Gestos de deslize no modo \'Tela de bloqueio\' Os gestos de deslize estão ativados no modo \'Tela de bloqueio\'. Os gestos de deslize estão desativados no modo \'Tela de bloqueio\'. - Visibilidade do fundo de gestos - A visibilidade do fundo da sobreposição de gestos. Limite de magnitude de deslize A quantidade de limite para que o deslize ocorra. Tamanho do texto da sobreposição de gestos @@ -1733,6 +1731,7 @@ Clique para ver como emitir uma chave de API." Voto negativo Alterar categoria Não há segmentos para votar. + Escolha a categoria do segmento A categoria está desativada nas configurações. Ative a categoria para enviar. Novo segmento SponsorBlock @@ -1850,8 +1849,6 @@ Toque no botão continuar e desative as otimizações da bateria." Android VR "Android VR (Sem autenticação)" - "iOS -(requer PoToken)" "iOS TV (é necessário logar)" Efeitos colaterais da falsificação @@ -1859,7 +1856,6 @@ Toque no botão continuar e desative as otimizações da bateria." • Volume estável não está disponível. • Desativar faixas de áudio automático forçadas não estão disponíveis. • Os vídeos para crianças podem não reproduzir quando desconectado ou em modo incógnito." - • Pode haver problemas de reprodução (PoToken necessário). "• Filmes ou vídeos pagos podem não reproduzir. • Os vídeos para crianças podem não ser reproduzidos quando desconectado ou em modo incógnito." Forçar iOS AVC (H.264) diff --git a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml index 1dfb72ae5..30bfe5d92 100644 --- a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml +++ b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml @@ -19,6 +19,38 @@ "%1$s не установлен. Пожалуйста, скачайте %2$s с сайта." %s не установлен. Установите его. + Добавить в очередь + Добавить в очередь и открыть очередь + Добавить в очередь и воспроизвести видео + Внешний загрузчик + Открыть очередь + Очередь + Удалить из очереди + Удалить из очереди и открыть очередь + Удалить очередь + Сохранить очередь + "Вместо открытия внешнего загрузчика открывается диалог управления очередью. + +Также можно открыть управление нажатием и удерживанием кнопки назад на панели навигации. + +Эта функция все ещё находится в процессе разработки, поэтому большинство функций не работает. + +Пожалуйста, используйте её только для отладки." + Требуется авторизация + Управление очередью недоступно (%s). + Не удалось идентифицировать список воспроизведения + Очередь пустая + Не удалось идентифицировать видео + Не удалось добавить видео. + Не удалось создать очередь. + Не удалось удалить очередь. + Не удалось удалить видео. + Не удалось сохранить очередь. + Видео добавлено успешно. + Очередь создана успешно. + Очередь удалена успешно. + Видео удалено успешно. + Очередь была успешно сохранена до: \'%s\'. Язык RVX Язык приложения "Амхарский @@ -463,9 +495,6 @@ Shorts Анимированная заставка Анимированная заставка отключена. Анимированная заставка включена. - Полупрозрачность строки состояния - Полупрозрачность включена. - Полупрозрачность отключена. Переливающийся экран загрузки Переливающийся экран загрузки включен. Переливающийся экран загрузки отключен. @@ -509,6 +538,9 @@ Shorts • Используется вкладка Библиотека. • Секция Музыка в описании видео может не работать. • Кнопка переключения аккаунта может не появляться во вкладке Библиотека. Используйте настройки 'Включить широкую панель поиска на вкладке Вы'." + Полупрозрачность строки состояния + Полупрозрачность включена. + Полупрозрачность отключена. Подмена версии приложения Версия приложения подменена Версия приложения не подменена @@ -565,6 +597,9 @@ Shorts Действие кнопки \"Скачать\" для видео Кнопка \"Скачать\" открывает внешний загрузчик. Кнопка \"Скачать\" использует внутренний загрузчик. + Управление очередью + Кнопка загрузки видео открывает управление очередью. + Кнопка загрузки видео открывает внешний загрузчик. Внешний загрузчик для плейлиста, название пакета Например: NewPipe или YTDLnis, или др. (Для плейлиста). @@ -1200,6 +1235,8 @@ Shorts Нажатия кнопки, отключает/включает звук текущего видео. Кнопка внешний загрузчик Запустить внешний загрузчик. + Управление очередью + Вместо запуска внешнего загрузчика открывается управление очередью. Кнопка скорости воспроизведения "Нажать - открытие окна скорости. Нажать и удерживать - скорость воспроизведения в 1.0x." @@ -1570,10 +1607,10 @@ Shorts При снижении яркости жестом до минимума активируется автояркость. При снижении яркости жестом до минимума автояркость не активируется. Управление яркостью жестом - Управление яркостью жестом включено. + "Управление яркостью жестом включено." Управление яркостью жестом отключено. Управление громкостью жестом - Громкость жестом включено. + "Громкость жестом включено." Громкость жестом отключено. Сохранение и восстановление яркости Сохранять и восстанавливать яркость при переключениях полного экрана. @@ -1587,8 +1624,6 @@ Shorts Жесты в режиме \"Блокировка экрана\" Жесты в режиме \"Блокировка экрана\" включены. Жесты в режиме \"Блокировка экрана\" отключены. - Видимость фона жестов - Видимость фона наложения при жесте. Порог величины жеста Амплитуда движения распознаваемая как жест. Размер текста при жесте @@ -1891,6 +1926,7 @@ Shorts Проголосовать против Изменить категорию Нет сегментов для голосования. + Выберите категорию сегмента Эта категория отключена в настройках. Включите ее для отправки сегмента. Новый сегмент SponsorBlock @@ -2009,8 +2045,6 @@ Shorts Android VR "Android VR (Без автора)" - "iOS -(Необходим PoToken)" "iOS (Необходим вход)" Эффекты от подмены @@ -2018,7 +2052,6 @@ Shorts • Стабильная громкость недоступна. • Отключить принудительные авто звуковые дорожки недоступна. • Детские видео не могут воспроизводиться в режиме инкогнито или выхода." - • Возможно проблемы (требуется PoToken). "• Фильмы или платные видео могут не воспроизводиться. • Детские видео могут не воспроизводиться при выходе из системы или в режиме инкогнито." Принудительно iOS, AVC (H.264) diff --git a/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml b/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml index 85187d99c..707f6fb05 100644 --- a/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml +++ b/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml @@ -334,9 +334,6 @@ Sınırlama: Araç çubuğundaki geri butonu çalışmayabilir." Açılış animasyonunu devre dışı bırak Açılış animasyonu etkin değil. Açılış animasyonu etkin. - Yarı saydam durum çubuğunu devre dışı bırak. - Durum çubuğu opak. - Durum çubuğu opak veya yarı saydam. Gradyan yükleme ekranını etkinleştir Gradyan yükleme ekranı etkin Gradyan yükleme ekranı devre dışı @@ -353,6 +350,9 @@ Sınırlama: Araç çubuğundaki geri butonu çalışmayabilir." Kısıtlamalar: Shorts canlı yayını 'Shorts'u normal oynatıcıda aç' ayarı nedeniyle normal oynatıcıda açıldığında kanal açılmaz." Canlı halkaya tıklandığında canlı yayın açılır. + Yarı saydam durum çubuğunu devre dışı bırak. + Durum çubuğu opak. + Durum çubuğu opak veya yarı saydam. Uygulama Versiyonunu taklit et Sürüm taklit ediliyor Sürüm taklit edilmiyor @@ -1185,10 +1185,10 @@ Bilinen sorunlar: Parlaklık hareketinin en düşük değeri otomatik parlaklığı etkinleştirir. Parlaklık hareketinin en düşük değeri otomatik parlaklığı etkinleştirmez. Kaydırarak parlaklığı ayarla - Video tam ekrandayken, ekranın solunu kaydırarak ekran parlaklığını ayarlama açık + "Video tam ekrandayken, ekranın solunu kaydırarak ekran parlaklığını ayarlama açık" Video tam ekrandayken, ekranın solunu kaydırarak ekran parlaklığını ayarlama kapalı Kaydırarak sesi ayarla - Video tam ekrandayken, ekranın sağını kaydırarak sesi ayarlama açık + "Video tam ekrandayken, ekranın sağını kaydırarak sesi ayarlama açık" Video tam ekrandayken, ekranın sağını kaydırarak sesi ayarlama kapalı Kaydetmeyi ve parlaklığı geri yüklemeyi etkinleştir Tam ekrandan çıkarken veya tam ekrana girerken parlaklığı kaydedin ve geri yükleyin. @@ -1202,8 +1202,6 @@ Bilinen sorunlar: \'Kilit ekranı\' modundaki kaydırma hareketleri Kaydırma hareketleri \'Kilit ekranı\' modunda etkindir. Kaydırma hareketleri \'Kilit ekranı\' modunda devre dışıdır. - Kaydırma arka plan şeffaflığı - Kaydırma arka planının şeffaflık değeri Kaydırma büyüklük eşiği Kaydırma işleminin gerçekleşmesi için eşik miktarı Kaydırma metin boyutu @@ -1442,6 +1440,7 @@ Bir örnek görmek için buraya dokunun. Olumsuz oy ver Kategoriyi değiştir Oylanabilecek bir kısım yok. + Kategori seçin Ayarlarda kategori devre dışı bırakıldı. Göndermek için kategoriyi etkinleştir. Yeni SponsorBlock segmenti diff --git a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml index 8f488794a..410053cd2 100644 --- a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml +++ b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml @@ -485,9 +485,6 @@ Вимкнути сплеш анімацію Сплеш анімацію вимкнено. Сплеш анімацію увімкнено. - Вимкнути напівпрозорість рядка стану - Рядок стану непрозорий. - Рядок стану непрозорий чи напівпрозорий. Увімкнути градієнт екрану завантаження Градієнт екрану завантаження увімкнено. Градієнт екрану завантаження вимкнено. @@ -534,6 +531,9 @@ • Використовується вкладку Бібліотека. • Секція Музика опису відео може не працювати. • Кнопка перемикання облікового запису може не з'являтися у вкладці Бібліотека. Використовуйте налаштування 'Увімкнути широку панель пошуку у вкладці Ви'." + Вимкнути напівпрозорість рядка стану + Рядок стану непрозорий. + Рядок стану непрозорий чи напівпрозорий. Підробити версію програми Версію підроблено Версію не підроблено @@ -1592,10 +1592,10 @@ Нижнє значення жесту яскравості активує автояскравість. Нижнє значення жесту яскравості не активує автояскравість. Увімкнути зміну яскравості жестом - Зміну яскравості жестом увімкнено. + "Зміну яскравості жестом увімкнено." Зміну яскравості жестом вимкнено. Увімкнути зміну гучності жестом - Зміну гучності жестом увімкнено. + "Зміну гучності жестом увімкнено." Зміну гучності жестом вимкнено. Увімкнути збереження та відновлення яскравості Зберігається та відновлюється яскравість при переході з/до повноекранного режиму. @@ -1609,10 +1609,11 @@ Жести переміщення в режимі \'Блокування екрана\' Жести переміщення увімкнено в режимі \'Блокування екрана\'. Жести переміщення вимкнено в режимі \'Блокування екрана\'. - Видимість фону при жесті - Видимість фону панелі при жесті Поріг величини жесту Мінімальна амплітуда руху, що розпізнається як жест + Альтернативний інтерфейс жесту + Використовується альтернативний інтерфейс. + Використовується старий інтерфейс. Розмір шрифту панелі Розмір шрифту в панелі при жесті Розмір екрана накладки проведення @@ -1909,6 +1910,7 @@ Проголосувати «проти» Змінити категорію Немає сегментів для голосування + Вибрати категорію сегмента Категорія вимкнена у налаштуваннях. Увімкніть категорію, щоб надіслати. Новий сегмент Спонсорблок @@ -2024,8 +2026,6 @@ Android VR "Android VR (Без авторизації)" - "iOS -(Потрібен PoToken)" "iOS TV (Потрібна авторизація)" Побічні ефекти імітування @@ -2033,7 +2033,6 @@ • Стабілізація гучності недоступна. • Вимкнення примусових авто звукових доріжок недоступне. • Відео для дітей можуть не відтворюватися коли вийшли з системи або в анонімному режимі." - • Можуть бути проблеми з відтворенням (Потрібен PoToken). "• Стабілізація гучності недоступна. • Фільми та платні відео можуть не відтворюватися. • Відео для дітей можуть не відтворюватися коли вийшли з системи або в анонімному режимі." diff --git a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml index 8450f5ce8..1a89faa6b 100644 --- a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml +++ b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml @@ -19,6 +19,38 @@ "Có vẻ như %1$s chưa được cài đặt. Vui lòng tải xuống %2$s từ trang web." Hiện %s chưa được cài đặt. Hãy cài đặt và thử lại. + Thêm vào hàng chờ + Thêm vào hàng chờ và xem hàng chờ + Thêm vào hàng chờ và phát video + Trình tải xuống bên ngoài + Xem hàng chờ + Hàng chờ + Xóa khỏi hàng chờ + Xóa khỏi hàng chờ và xem hàng chờ + Xoá hàng chờ + Lưu hàng chờ + "Thay vì mở trình tải xuống bên ngoài, khi tương tác sẽ mở hộp thoại quản lý hàng chờ. + +Ngoài ra, bạn cũng có thể mở quản lý hàng chờ bằng cách nhấn và giữ nút quay lại trên thanh điều hướng. + +Nhưng tính năng này vẫn còn đang trong quá trình phát triển, vì vậy phần lớn các tính năng có thể chưa hoạt động. + +Vui lòng chỉ sử dụng cho mục đích gỡ lỗi." + Yêu cầu đăng nhập + Quản lý hàng chờ không khả dụng (%s). + Không xác định được danh sách phát + Hàng chờ trống + Không xác định được video + Không thể thêm video. + Không thể tạo hàng chờ. + Không thể xoá hàng chờ. + Không thể xoá video. + Không thể lưu hàng chờ. + Thêm video thành công. + Tạo hàng chờ thành công. + Xoá hàng chờ thành công. + Xoá video thành công. + Lưu hàng chờ thành công thành \"%s\". Ngôn ngữ trong cài đặt RVX Theo ứng dụng @@ -343,9 +375,6 @@ Hạn chế: Nút Quay lại trên thanh công cụ có thể không hoạt đ Tắt hoạt ảnh khi ứng dụng khởi chạy Hoạt ảnh khi ứng dụng khởi chạy đã tắt. Hoạt ảnh khi ứng dụng khởi chạy được bật. - Vô hiệu hoá thanh trạng thái trong suốt - Thanh trạng thái không còn trong suốt. - Thanh trạng thái có thể trong suốt hoặc không. Màn hình tải hiệu ứng gradient Màn hình tải hiệu ứng gradient đã bật. Màn hình tải hiệu ứng gradient đã tắt. @@ -392,6 +421,9 @@ Các thay đổi bao gồm: • Thẻ Thư viện được hiển thị thay vì thẻ Bạn. • Phần Âm nhạc trong mô tả video có thể không hoạt động. • Nút chuyển đổi tài khoản có thể không xuất hiện trong thẻ Thư viện. Hãy sử dụng tuỳ chọn \"Thanh tìm kiếm rộng trong thẻ Bạn\"." + Vô hiệu hoá thanh trạng thái trong suốt + Thanh trạng thái không còn trong suốt. + Thanh trạng thái có thể trong suốt hoặc không. Giả mạo phiên bản ứng dụng Phiên bản được giả mạo Phiên bản không được giả mạo @@ -448,6 +480,9 @@ Một số mục có thể không bị ẩn." Ghi đè nút tải xuống video Khi thao tác với nút tải xuống video sẽ mở trình tải xuống bên ngoài của bạn. Khi thao tác với nút tải xuống video sẽ mở trình tải xuống được tích hợp sẵn của Youtube. + Quản lý hàng chờ + Khi tương tác với nút tải xuống video sẽ mở hộp thoại quản lý hàng chờ của bạn. + Khi tương tác với nút tải xuống video sẽ mở trình tải xuống bên ngoài của bạn. Tên gói trình tải xuống danh sách phát Chọn hoặc nhập tên gói ứng dụng trình tải xuống đã được cài đặt trên thiết bị của bạn, chẳng hạn như YTDLnis. @@ -1077,6 +1112,8 @@ Nhấn và giữ để sao chép dấu thời gian." Nhấn để tắt tiếng của video hiện tại. Nhấn lần nữa để bật trở lại. Nút Trình tải xuống bên ngoài Nhấn để khởi chạy trình tải xuống bên ngoài. + Quản lý hàng chờ + Thay vì mở trình tải xuống bên ngoài, khi tương tác sẽ mở hộp thoại quản lý hàng chờ. Nút Tốc độ phát "Nhấn để mở hộp thoại Tốc độ phát. Nhấn và giữ để đặt lại tốc độ phát video (1.0x). Nhấn và giữ lần nữa để đặt lại về tốc độ mặc định đã đặt." @@ -1441,10 +1478,10 @@ Không còn lề trên và dưới trong trình phát." Chế độ độ sáng tự động sẽ được bật khi vuốt độ sáng về mức tổi thiểu. Chế độ độ sáng tự động sẽ không được bật khi vuốt độ sáng về mức tổi thiểu. Vuốt điều chỉnh độ sáng - Cử chỉ vuốt điều chỉnh độ sáng đã bật. + "Cử chỉ vuốt điều chỉnh độ sáng đã bật." Cử chỉ vuốt điều chỉnh độ sáng đã tắt. Vuốt điều chỉnh âm lượng - Cử chỉ vuốt điều chỉnh âm lượng đã bật. + "Cử chỉ vuốt điều chỉnh âm lượng đã bật." Cử chỉ vuốt điều chỉnh âm lượng đã tắt. Lưu độ sáng Lưu độ sáng khi thoát ra hoặc vào chế độ toàn màn hình. @@ -1458,8 +1495,6 @@ Không còn lề trên và dưới trong trình phát." Vuốt ở chế độ Khoá màn hình Cử chỉ vuốt đã bật ở chế độ Khoá màn hình. Vuốt ở chế độ Khoá màn hình đã tắt. - Độ trong suốt lớp phủ - Độ trong suốt của nền khi thực hiện cử chỉ vuốt. Độ rộng ngưỡng vuốt Độ rộng của ngưỡng vuốt để thực hiện cử chỉ vuốt. Kích thước văn bản trên lớp phủ @@ -1759,6 +1794,7 @@ Nhấp vào đây để xem các bước phát hành khóa API." Phản đối Đổi danh mục Không có phân đoạn nào để bình chọn. + Chọn danh mục phân đoạn Danh mục đã tắt trong cài đặt. Bật danh mục để gửi. Đoạn SponsorBlock mới @@ -1878,8 +1914,6 @@ Nhấn vào Tiếp tục và cho phép thay đổi lựa chọn tối ưu hoá p Android VR "Android VR (Không xác thực)" - "iOS -(Yêu cầu PoToken)" "iOS TV (Yêu cầu Đăng nhập)" Hạn chế @@ -1887,7 +1921,6 @@ Nhấn vào Tiếp tục và cho phép thay đổi lựa chọn tối ưu hoá p • Âm lượng ổn định không khả dụng. • Tắt Bản âm thanh tự động không khả dụng. • Video dành cho trẻ em có thể không phát được khi bạn đã đăng xuất hoặc bật chế độ ẩn danh." - • Có thể xảy ra sự cố phát (Không khuyến khích). "• Âm lượng ổn định không khả dụng. • Phim hoặc video trả phí có thể không phát được. • Video dành cho trẻ em có thể không phát được khi bạn đã đăng xuất hoặc bật chế độ ẩn danh." diff --git a/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml b/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml index 1ac78882e..4b4e753dc 100644 --- a/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml @@ -1208,10 +1208,10 @@ 亮度手势的最低值会启用自动亮度调节 亮度手势的最低值不会启用自动亮度调节 启用滑动控制亮度 - 滑动控制亮度已启用 + "滑动控制亮度已启用" 滑动控制亮度已禁用 音量手势 - 滑动控制音量已启用 + "滑动控制音量已启用" 滑动控制音量已禁用 启用保存和恢复亮度 退出/进入全屏时保存和恢复亮度 @@ -1225,8 +1225,6 @@ 在“锁定屏幕”模式下滑动手势 在“锁定屏幕”模式下启用滑动手势 在“锁定屏幕”模式下禁用滑动手势 - 滑动背景透明度 - 滑动叠加层背景透明度 滑动幅度阈值 防误触的滑动幅度阈值 滑动叠加层上的文本大小 @@ -1507,6 +1505,7 @@ 反对 更改类别 没有可供投票的片段 + 选择片段类别 类别在设置中被禁用请启用类别以提交 新的 SponsorBlock 片段 diff --git a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml index ffcfb0a68..1e51233a0 100644 --- a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml @@ -19,8 +19,150 @@ "未安裝 %1$s。 請從網站下載 %2$s。" 未安裝 %s。請安裝該應用程式。 + 加入佇列清單 + 加到佇列並打開佇列 + 加入佇列並播放影片 + 外部下載器 + 開啟佇列 + 佇列 + 從佇列中移除 + 從佇列中移除並打開佇列 + 移除佇列 + 儲存佇列 + "不要開啟外部下載器,而是開啟佇列管理器對話方塊。 + +您也可以按住導覽列上的返回按鈕來開啟佇列管理器。 + +此功能仍在開發中,因此大多數功能可能無法使用。 + +請僅將其用於調試目的。" + 需要登入 + 佇列管理器不可用 (%s)。 + 無法辨識播放列表 + 佇列為空 + 無法辨識影片 + 新增影片失敗。 + 無法建立佇列。 + 刪除佇列失敗。 + 刪除影片失敗。 + 保存佇列失敗。 + 影片添加成功。 + 佇列已成功建立。 + 佇列已成功刪除。 + 影片已成功移除。 + 佇列已成功儲存至 ‘%s’。 RVX 語言 應用程式語言 + "阿姆哈拉語 +አማርኛ" + "阿拉伯語 +العربية" + "亞塞拜然語 +Azərbaycan" + "白俄羅斯語 +беларуская" + "保加利亞語 +Български" + "孟加拉语 +বাংলা" + "加泰隆尼亞語 +Català" + "捷克語 +Čeština" + "丹麥語 +Dansk" + "德語 +Deutsch" + "希臘語 +Ελληνικά" + "英語 +English" + "西班牙語 +Español" + "愛沙尼亞語 +Eesti" + "波斯語 +فارسی" + "芬蘭語 +Suomi" + "法語 +Français" + "古吉拉特語 +ગુજરાતી" + "希伯來語 +עברי" + "印地語 +हिन्दी" + "克羅埃西亞語 +Hrvatski" + "匈牙利語 +Magyar" + "印尼語 +Indonesia" + "義大利語 +Italiano" + "日語 +日本語" + "哈薩克語 +Қазақ тілі" + "韓語 +한국어" + "立陶宛語 +Lietuvių" + "拉脫維亞語 +Latviešu" + "馬其頓語 +Македонски" + "蒙語 +Монгол" + "馬拉地語 +मराठी" + "馬來語 +Melayu" + "緬甸語 +ဗမာ" + "荷蘭語 +Nederlands" + "奧迪亞語 +ଓଡ଼ିଆ" + "旁遮普語 +ਪੰਜਾਬੀ" + "波蘭語 +Polski" + "葡萄牙語 +Português" + "羅馬尼亞語 +Română" + "俄語 +Русский" + "斯洛伐克語 +Slovenčina" + "阿爾巴尼亞語 +Shqip" + "斯洛維尼亞語 +Slovenščina" + "塞爾維亞語 +Српски" + "瑞典語 +Svenska" + "斯瓦希里語 +Kiswahili" + "泰米爾語 +தமிழ்" + "泰盧固語 +తెలుగు" + "泰語 +ไทย" + "土耳其語 +Türkçe" + "烏克蘭語 +Українська" + "烏爾都語 +اردو" + "越南語 +Tiếng Việt" + "中文 +中文" 廣告 隱藏片尾商店橫幅 @@ -339,9 +481,6 @@ 停用啟動動畫 啟動動畫已停用 啟動動畫已啟用 - 停用半透明狀態列 - 狀態列不透明。 - 狀態列是不透明或半透明的。 啟用漸變載入畫面 漸變載入畫面已啟用 漸變載入畫面已停用 @@ -373,6 +512,22 @@ • 常規播放器中的短影片開啟。 • 資訊流依主題和頻道進行組織。 • 關閉「偽裝串流資料」時無法開啟影片說明。" + 禁用佈局更新 + 伺服器不會更新佈局。 + 佈局將由伺服器更新。 + "應用程式佈局恢復為首次安裝時使用的佈局。 + +某些伺服器端佈局可能無法復原。 + +變化包括: +• 播放器彈出式選單中的元件(或相關設定)可能無法正常運作。 +• 滾動數字不是動畫。 +• 已使用庫標籤頁。 +• 影片描述的音樂部分可能無法運作。 +• 帳戶切換按鈕可能不會出現在庫標籤頁上。使用「在您的標籤頁中啟用寬搜尋列」設定。" + 停用半透明狀態列 + 狀態列不透明。 + 狀態列是不透明或半透明的。 偽裝應用程式版本 已偽裝版本 未偽裝版本 @@ -381,17 +536,19 @@ 這將改變應用程式的外觀和功能,但可能會出現未知的副作用。 如果稍後關閉,建議清除應用程式資料以防止 UI 錯誤。" - 編輯欺騙應用程式版本 - 輸入欺騙的應用程式版本目標 - 欺騙應用程式版本目標 + 編輯偽裝應用程式版本 + 輸入偽裝的應用程式版本目標。 + 偽裝應用程式版本目標 17.41.37 - 恢復舊版的播放清單 18.05.40 - 恢復舊版留言輸入方塊 18.17.43 - 恢復舊版播放器彈出式面板 18.33.40 - 恢復舊的 Shorts 頁籤 18.38.45 - 恢復舊版預設影片畫質 18.48.39 - 停用即時更新「觀看次數」和「喜歡次數」 + 19.01.34 - 禁用影片描述互動 19.26.42 - 停用導航和工具列中的開羅圖標 19.33.37 - 恢復舊的播放速度彈出面板 + 無效的偽裝應用程式版本: %s。 帳戶選單 隱藏或顯示帳戶選單和你的內容分頁中的元素。 @@ -427,6 +584,9 @@ 覆蓋影片下載按鈕 原生影片下載按鈕可開啟你的外部下載器。 原生影片下載按鈕可開啟本機應用程式內下載器。 + 佇列管理器 + 原生影片下載按鈕開啟佇列管理器。 + 原生影片下載按鈕開啟您的外部下載器。 播放清單下載器套件名稱 你安裝的外部下載器應用程式的套件名稱,例如 YTDLnis。 @@ -1058,6 +1218,8 @@ 點選可將目前影片靜音。 再次點擊即可取消靜音。 外部下載按鈕 點擊以打開外部下載器 + 佇列管理器 + 不要啟動外部下載程序,而是開啟佇列管理器。 播放速度按鈕 "點擊選擇影片播放速度 長按設定預設播放速度(1.0x)" @@ -1354,7 +1516,6 @@ "自訂操作在彈出式選單中啟用。 限制: -• 如果應用程式版本被欺騙為18.49.37 或更早版本,則不起作用。 • 不適用於直播。" 彈出式選單中禁用自訂操作。 在工具列中啟用自訂操作 @@ -1418,10 +1579,10 @@ 亮度手勢的最低值會啟用自動亮度調節 亮度手勢的最低值會啟動自動亮度。 啟用滑動控制亮度 - 滑動控制亮度已啟用 + "滑動控制亮度已啟用" 滑動控制亮度已停用 音量手勢 - 滑動控制音量已啟用 + "滑動控制音量已啟用" 滑動控制音量已停用 啟用儲存和還原亮度 退出或進入全螢幕時儲存和還原亮度。 @@ -1435,8 +1596,6 @@ 在「鎖定螢幕」模式下滑動手勢 在「鎖定螢幕」模式下啟用滑動手勢 在「鎖定螢幕」模式下停用滑動手勢 - 滑動背景透明度 - 滑動疊加層背景透明度 滑動幅度閾值 防誤觸的滑動幅度閾值 滑動疊加層上的檔案大小 @@ -1741,6 +1900,7 @@ 反對 更改類別 沒有可供投票的片段 + 選擇片段類別 類別在設定中被停用請啟用類別以提交 新的 SponsorBlock 片段 @@ -1859,8 +2019,6 @@ Android VR "Android VR (無授權)" - "iOS -(需要 PoToken)" "iOS TV (需要登入)" 偽裝副作用 @@ -1868,7 +2026,6 @@ • 無法獲得穩定的音量。 • 停用強制自動音軌無法使用。 • 登出或處於隱身模式時可能無法播放兒童影片。" - • 可能有播放問題 (需要PoToken)。 "• 電影或付費影片可能無法播放。 • 登出或處於隱身模式時可能無法播放兒童影片。" 強制 iOS AVC (H.264) From f3abc04812b75cdd710aa63c5fd263d75c41f3ed Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Wed, 26 Mar 2025 21:33:40 +0900 Subject: [PATCH 39/77] bump 5.6.1-dev.2 --- README.md | 86 ++++++++++++++++++++-------------------- gradle.properties | 2 +- patches.json | 99 +++++++++++++++++++++++++++-------------------- 3 files changed, 100 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index f171d803f..0e4c0c0d6 100644 --- a/README.md +++ b/README.md @@ -85,48 +85,48 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `Bitrate default value` | Sets the audio quality to 'Always High' when you first install the app. | 6.20.51 ~ 8.10.51 | -| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 6.20.51 ~ 8.10.51 | -| `Certificate spoof` | Enables YouTube Music to work with Android Auto by spoofing the YouTube Music certificate. | 6.20.51 ~ 8.10.51 | -| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 6.20.51 ~ 8.10.51 | -| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 6.20.51 ~ 8.10.51 | -| `Custom branding icon for YouTube Music` | Changes the YouTube Music app icon to the icon specified in patch options. | 6.20.51 ~ 8.10.51 | -| `Custom branding name for YouTube Music` | Changes the YouTube Music app name to the name specified in patch options. | 6.20.51 ~ 8.10.51 | -| `Custom header for YouTube Music` | Applies a custom header in the top left corner within the app. | 6.20.51 ~ 8.10.51 | -| `Dark theme` | Changes the app's dark theme to the values specified in patch options. | 6.20.51 ~ 8.10.51 | -| `Disable Cairo splash animation` | Adds an option to disable Cairo splash animation. | 7.06.54 ~ 8.10.51 | -| `Disable DRC audio` | Adds an option to disable DRC (Dynamic Range Compression) audio. | 6.20.51 ~ 8.10.51 | -| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 6.20.51 ~ 8.10.51 | -| `Disable dislike redirection` | Adds an option to disable redirection to the next track when clicking the Dislike button. | 6.20.51 ~ 8.10.51 | -| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 6.20.51 ~ 8.10.51 | -| `Disable music video in album` | Adds option to redirect music videos from albums for non-premium users. | 6.20.51 ~ 8.10.51 | -| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 6.20.51 ~ 8.10.51 | -| `Enable debug logging` | Adds an option to enable debug logging. | 6.20.51 ~ 8.10.51 | -| `Enable landscape mode` | Adds an option to enable landscape mode when rotating the screen on phones. | 6.20.51 ~ 8.10.51 | -| `Flyout menu components` | Adds options to hide or change flyout menu components. | 6.20.51 ~ 8.10.51 | -| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 6.20.51 ~ 8.10.51 | -| `Hide account components` | Adds options to hide components related to the account menu. | 6.20.51 ~ 8.10.51 | -| `Hide action bar components` | Adds options to hide action bar components and replace the offline download button with an external download button. | 6.20.51 ~ 8.10.51 | -| `Hide ads` | Adds options to hide ads. | 6.20.51 ~ 8.10.51 | -| `Hide layout components` | Adds options to hide general layout components. | 6.20.51 ~ 8.10.51 | -| `Hide overlay filter` | Removes, at compile time, the dark overlay that appears when player flyout menus are open. | 6.20.51 ~ 8.10.51 | -| `Hide player overlay filter` | Removes, at compile time, the dark overlay that appears when single-tapping in the player. | 6.20.51 ~ 8.10.51 | -| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 6.20.51 ~ 8.10.51 | -| `Player components` | Adds options to hide or change components related to the player. | 6.20.51 ~ 8.10.51 | -| `Remove background playback restrictions` | Removes restrictions on background playback, including for kids videos. | 6.20.51 ~ 8.10.51 | -| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 6.20.51 ~ 8.10.51 | -| `Restore old style library shelf` | Adds an option to return the Library tab to the old style. | 6.20.51 ~ 8.10.51 | -| `Return YouTube Dislike` | Adds an option to show the dislike count of songs using the Return YouTube Dislike API. | 6.20.51 ~ 8.10.51 | -| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 6.20.51 ~ 8.10.51 | -| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 6.20.51 ~ 8.10.51 | -| `Settings for YouTube Music` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 6.20.51 ~ 8.10.51 | -| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as non-music sections. | 6.20.51 ~ 8.10.51 | -| `Spoof app version` | Adds options to spoof the YouTube Music client version. This can be used to restore old UI elements and features. | 6.51.53 ~ 7.16.53 | -| `Spoof player parameter` | Adds options to spoof player parameter to allow playback. | 6.20.51 ~ 8.10.51 | -| `Translations for YouTube Music` | Add translations or remove string resources. | 6.20.51 ~ 8.10.51 | -| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 6.20.51 ~ 8.10.51 | -| `Visual preferences icons for YouTube Music` | Adds icons to specific preferences in the settings. | 6.20.51 ~ 8.10.51 | -| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 6.20.51 ~ 8.10.51 | +| `Bitrate default value` | Sets the audio quality to 'Always High' when you first install the app. | 6.20.51 ~ 8.10.52 | +| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 6.20.51 ~ 8.10.52 | +| `Certificate spoof` | Enables YouTube Music to work with Android Auto by spoofing the YouTube Music certificate. | 6.20.51 ~ 8.10.52 | +| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 6.20.51 ~ 8.10.52 | +| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 6.20.51 ~ 8.10.52 | +| `Custom branding icon for YouTube Music` | Changes the YouTube Music app icon to the icon specified in patch options. | 6.20.51 ~ 8.10.52 | +| `Custom branding name for YouTube Music` | Changes the YouTube Music app name to the name specified in patch options. | 6.20.51 ~ 8.10.52 | +| `Custom header for YouTube Music` | Applies a custom header in the top left corner within the app. | 6.20.51 ~ 8.10.52 | +| `Dark theme` | Changes the app's dark theme to the values specified in patch options. | 6.20.51 ~ 8.10.52 | +| `Disable Cairo splash animation` | Adds an option to disable Cairo splash animation. | 7.06.54 ~ 8.10.52 | +| `Disable DRC audio` | Adds an option to disable DRC (Dynamic Range Compression) audio. | 6.20.51 ~ 8.10.52 | +| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 6.20.51 ~ 8.10.52 | +| `Disable dislike redirection` | Adds an option to disable redirection to the next track when clicking the Dislike button. | 6.20.51 ~ 8.10.52 | +| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 6.20.51 ~ 8.10.52 | +| `Disable music video in album` | Adds option to redirect music videos from albums for non-premium users. | 6.20.51 ~ 8.10.52 | +| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 6.20.51 ~ 8.10.52 | +| `Enable debug logging` | Adds an option to enable debug logging. | 6.20.51 ~ 8.10.52 | +| `Enable landscape mode` | Adds an option to enable landscape mode when rotating the screen on phones. | 6.20.51 ~ 8.10.52 | +| `Flyout menu components` | Adds options to hide or change flyout menu components. | 6.20.51 ~ 8.10.52 | +| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 6.20.51 ~ 8.10.52 | +| `Hide account components` | Adds options to hide components related to the account menu. | 6.20.51 ~ 8.10.52 | +| `Hide action bar components` | Adds options to hide action bar components and replace the offline download button with an external download button. | 6.20.51 ~ 8.10.52 | +| `Hide ads` | Adds options to hide ads. | 6.20.51 ~ 8.10.52 | +| `Hide layout components` | Adds options to hide general layout components. | 6.20.51 ~ 8.10.52 | +| `Hide overlay filter` | Removes, at compile time, the dark overlay that appears when player flyout menus are open. | 6.20.51 ~ 8.10.52 | +| `Hide player overlay filter` | Removes, at compile time, the dark overlay that appears when single-tapping in the player. | 6.20.51 ~ 8.10.52 | +| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 6.20.51 ~ 8.10.52 | +| `Player components` | Adds options to hide or change components related to the player. | 6.20.51 ~ 8.10.52 | +| `Remove background playback restrictions` | Removes restrictions on background playback, including for kids videos. | 6.20.51 ~ 8.10.52 | +| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 6.20.51 ~ 8.10.52 | +| `Restore old style library shelf` | Adds an option to return the Library tab to the old style. | 6.20.51 ~ 8.10.52 | +| `Return YouTube Dislike` | Adds an option to show the dislike count of songs using the Return YouTube Dislike API. | 6.20.51 ~ 8.10.52 | +| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 6.20.51 ~ 8.10.52 | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 6.20.51 ~ 8.10.52 | +| `Settings for YouTube Music` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 6.20.51 ~ 8.10.52 | +| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as non-music sections. | 6.20.51 ~ 8.10.52 | +| `Spoof app version` | Adds options to spoof the YouTube Music client version. This can be used to restore old UI elements and features. | 6.51.53 ~ 8.10.52 | +| `Spoof player parameter` | Adds options to spoof player parameter to allow playback. | 6.20.51 ~ 8.10.52 | +| `Translations for YouTube Music` | Add translations or remove string resources. | 6.20.51 ~ 8.10.52 | +| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 6.20.51 ~ 8.10.52 | +| `Visual preferences icons for YouTube Music` | Adds icons to specific preferences in the settings. | 6.20.51 ~ 8.10.52 | +| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 6.20.51 ~ 8.10.52 | ### [📦 `com.reddit.frontpage`](https://play.google.com/store/apps/details?id=com.reddit.frontpage) @@ -187,7 +187,7 @@ Example: "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] diff --git a/gradle.properties b/gradle.properties index 05834439c..2f5dfd87a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official kotlin.jvm.target.validation.mode = IGNORE -version = 5.6.1-dev.1 +version = 5.6.1-dev.2 diff --git a/patches.json b/patches.json index c016eadaa..e37037588 100644 --- a/patches.json +++ b/patches.json @@ -55,7 +55,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -95,7 +95,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -133,7 +133,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -242,7 +242,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -284,7 +284,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -435,7 +435,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [ @@ -550,7 +550,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [ @@ -659,7 +659,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [ @@ -692,7 +692,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [ @@ -764,7 +764,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -786,7 +786,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -808,7 +808,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -849,7 +849,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -897,7 +897,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -975,7 +975,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1069,7 +1069,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1109,7 +1109,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1167,7 +1167,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1195,7 +1195,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1260,7 +1260,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [ @@ -1442,7 +1442,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1468,7 +1468,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1517,7 +1517,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1645,7 +1645,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1705,7 +1705,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1768,7 +1768,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -1942,7 +1942,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2110,7 +2110,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2172,7 +2172,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2229,7 +2229,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2269,7 +2269,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2291,7 +2291,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2336,7 +2336,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2377,7 +2377,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2552,7 +2552,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [ @@ -2708,7 +2708,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2765,7 +2765,10 @@ "compatiblePackages": { "com.google.android.apps.youtube.music": [ "6.51.53", - "7.16.53" + "7.16.53", + "7.25.53", + "8.05.51", + "8.10.52" ] }, "options": [] @@ -2809,7 +2812,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -2834,7 +2837,17 @@ "19.47.53" ] }, - "options": [] + "options": [ + { + "key": "useIOSClient", + "title": "Use iOS client", + "description": "Add setting to set iOS client (Deprecated) as default client.", + "required": false, + "type": "kotlin.Boolean", + "default": false, + "values": null + } + ] }, { "name": "Swipe controls", @@ -3000,7 +3013,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [ @@ -3051,7 +3064,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] @@ -3143,7 +3156,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [ @@ -3181,7 +3194,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.51" + "8.10.52" ] }, "options": [] From 8169ccacc26fc5fb1052e756b7323c3fb82742c9 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:09:31 +0900 Subject: [PATCH 40/77] refactor: Use map instead of list to lookup resource ids --- .../utils/resourceid/SharedResourceIdPatch.kt | 268 ++------ .../utils/resourceid/SharedResourceIdPatch.kt | 8 +- .../shared/mapping/ResourceMappingPatch.kt | 80 +-- .../utils/resourceid/SharedResourceIdPatch.kt | 618 ++++-------------- .../kotlin/app/revanced/util/BytecodeUtils.kt | 5 +- 5 files changed, 212 insertions(+), 767 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt index fd21eb157..86224d8af 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt @@ -9,9 +9,8 @@ import app.revanced.patches.shared.mapping.ResourceType.ID import app.revanced.patches.shared.mapping.ResourceType.LAYOUT import app.revanced.patches.shared.mapping.ResourceType.STRING import app.revanced.patches.shared.mapping.ResourceType.STYLE -import app.revanced.patches.shared.mapping.get +import app.revanced.patches.shared.mapping.getResourceId import app.revanced.patches.shared.mapping.resourceMappingPatch -import app.revanced.patches.shared.mapping.resourceMappings var accountSwitcherAccessibility = -1L private set @@ -126,217 +125,58 @@ internal val sharedResourceIdPatch = resourcePatch( dependsOn(resourceMappingPatch) execute { - accountSwitcherAccessibility = resourceMappings[ - STRING, - "account_switcher_accessibility_label", - ] - actionBarLogo = resourceMappings[ - DRAWABLE, - "action_bar_logo", - ] - actionBarLogoRingo2 = resourceMappings[ - DRAWABLE, - "action_bar_logo_ringo2", - ] - bottomSheetRecyclerView = resourceMappings[ - LAYOUT, - "bottom_sheet_recycler_view" - ] - buttonContainer = resourceMappings[ - ID, - "button_container" - ] - buttonIconPaddingMedium = resourceMappings[ - DIMEN, - "button_icon_padding_medium" - ] - chipCloud = resourceMappings[ - LAYOUT, - "chip_cloud" - ] - colorGrey = resourceMappings[ - COLOR, - "ytm_color_grey_12" - ] - darkBackground = resourceMappings[ - ID, - "dark_background" - ] - designBottomSheetDialog = resourceMappings[ - LAYOUT, - "design_bottom_sheet_dialog" - ] - elementsContainer = resourceMappings[ - ID, - "elements_container" - ] - endButtonsContainer = resourceMappings[ - ID, - "end_buttons_container" - ] - floatingLayout = resourceMappings[ - ID, - "floating_layout" - ] - historyMenuItem = resourceMappings[ - ID, - "history_menu_item" - ] - inlineTimeBarAdBreakMarkerColor = resourceMappings[ - COLOR, - "inline_time_bar_ad_break_marker_color" - ] - inlineTimeBarProgressColor = resourceMappings[ - COLOR, - "inline_time_bar_progress_color" - ] - interstitialsContainer = resourceMappings[ - ID, - "interstitials_container" - ] - isTablet = resourceMappings[ - BOOL, - "is_tablet" - ] - likeDislikeContainer = resourceMappings[ - ID, - "like_dislike_container" - ] - mainActivityLaunchAnimation = resourceMappings[ - LAYOUT, - "main_activity_launch_animation" - ] - menuEntry = resourceMappings[ - LAYOUT, - "menu_entry" - ] - miniPlayerDefaultText = resourceMappings[ - STRING, - "mini_player_default_text" - ] - miniPlayerMdxPlaying = resourceMappings[ - STRING, - "mini_player_mdx_playing" - ] - miniPlayerPlayPauseReplayButton = resourceMappings[ - ID, - "mini_player_play_pause_replay_button" - ] - miniPlayerViewPager = resourceMappings[ - ID, - "mini_player_view_pager" - ] - modernDialogBackground = resourceMappings[ - DRAWABLE, - "modern_dialog_background" - ] - musicNotifierShelf = resourceMappings[ - LAYOUT, - "music_notifier_shelf" - ] - musicTasteBuilderShelf = resourceMappings[ - LAYOUT, - "music_tastebuilder_shelf" - ] - namesInactiveAccountThumbnailSize = resourceMappings[ - DIMEN, - "names_inactive_account_thumbnail_size" - ] - offlineSettingsMenuItem = resourceMappings[ - ID, - "offline_settings_menu_item" - ] - playerOverlayChip = resourceMappings[ - ID, - "player_overlay_chip" - ] - playerViewPager = resourceMappings[ - ID, - "player_view_pager" - ] - privacyTosFooter = resourceMappings[ - ID, - "privacy_tos_footer" - ] - qualityAuto = resourceMappings[ - STRING, - "quality_auto" - ] - remixGenericButtonSize = resourceMappings[ - DIMEN, - "remix_generic_button_size" - ] - searchButton = resourceMappings[ - LAYOUT, - "search_button" - ] - slidingDialogAnimation = resourceMappings[ - STYLE, - "SlidingDialogAnimation" - ] - tapBloomView = resourceMappings[ - ID, - "tap_bloom_view" - ] - text1 = resourceMappings[ - ID, - "text1" - ] - toolTipContentView = resourceMappings[ - LAYOUT, - "tooltip_content_view" - ] - topEnd = resourceMappings[ - ID, - "TOP_END" - ] - topStart = resourceMappings[ - ID, - "TOP_START" - ] - topBarMenuItemImageView = resourceMappings[ - ID, - "top_bar_menu_item_image_view" - ] - tosFooter = resourceMappings[ - ID, - "tos_footer" - ] - touchOutside = resourceMappings[ - ID, - "touch_outside" - ] - trimSilenceSwitch = resourceMappings[ - ID, - "trim_silence_switch" - ] - varispeedUnavailableTitle = resourceMappings[ - STRING, - "varispeed_unavailable_title" - ] - ytFillSamples = resourceMappings[ - DRAWABLE, - "yt_fill_samples_vd_theme_24", - ] - ytFillYouTubeMusic = resourceMappings[ - DRAWABLE, - "yt_fill_youtube_music_vd_theme_24", - ] - ytOutlineSamples = resourceMappings[ - DRAWABLE, - "yt_outline_samples_vd_theme_24", - ] - ytOutlineYouTubeMusic = resourceMappings[ - DRAWABLE, - "yt_outline_youtube_music_vd_theme_24", - ] - ytmLogo = resourceMappings[ - DRAWABLE, - "ytm_logo", - ] - ytmLogoRingo2 = resourceMappings[ - DRAWABLE, - "ytm_logo_ringo2", - ] + accountSwitcherAccessibility = getResourceId(STRING, "account_switcher_accessibility_label") + actionBarLogo = getResourceId(DRAWABLE, "action_bar_logo") + actionBarLogoRingo2 = getResourceId(DRAWABLE, "action_bar_logo_ringo2") + bottomSheetRecyclerView = getResourceId(LAYOUT, "bottom_sheet_recycler_view") + buttonContainer = getResourceId(ID, "button_container") + buttonIconPaddingMedium = getResourceId(DIMEN, "button_icon_padding_medium") + chipCloud = getResourceId(LAYOUT, "chip_cloud") + colorGrey = getResourceId(COLOR, "ytm_color_grey_12") + darkBackground = getResourceId(ID, "dark_background") + designBottomSheetDialog = getResourceId(LAYOUT, "design_bottom_sheet_dialog") + elementsContainer = getResourceId(ID, "elements_container") + endButtonsContainer = getResourceId(ID, "end_buttons_container") + floatingLayout = getResourceId(ID, "floating_layout") + historyMenuItem = getResourceId(ID, "history_menu_item") + inlineTimeBarAdBreakMarkerColor = getResourceId(COLOR, "inline_time_bar_ad_break_marker_color") + inlineTimeBarProgressColor = getResourceId(COLOR, "inline_time_bar_progress_color") + interstitialsContainer = getResourceId(ID, "interstitials_container") + isTablet = getResourceId(BOOL, "is_tablet") + likeDislikeContainer = getResourceId(ID, "like_dislike_container") + mainActivityLaunchAnimation = getResourceId(LAYOUT, "main_activity_launch_animation") + menuEntry = getResourceId(LAYOUT, "menu_entry") + miniPlayerDefaultText = getResourceId(STRING, "mini_player_default_text") + miniPlayerMdxPlaying = getResourceId(STRING, "mini_player_mdx_playing") + miniPlayerPlayPauseReplayButton = getResourceId(ID, "mini_player_play_pause_replay_button") + miniPlayerViewPager = getResourceId(ID, "mini_player_view_pager") + modernDialogBackground = getResourceId(DRAWABLE, "modern_dialog_background") + musicNotifierShelf = getResourceId(LAYOUT, "music_notifier_shelf") + musicTasteBuilderShelf = getResourceId(LAYOUT, "music_tastebuilder_shelf") + namesInactiveAccountThumbnailSize = getResourceId(DIMEN, "names_inactive_account_thumbnail_size") + offlineSettingsMenuItem = getResourceId(ID, "offline_settings_menu_item") + playerOverlayChip = getResourceId(ID, "player_overlay_chip") + playerViewPager = getResourceId(ID, "player_view_pager") + privacyTosFooter = getResourceId(ID, "privacy_tos_footer") + qualityAuto = getResourceId(STRING, "quality_auto") + remixGenericButtonSize = getResourceId(DIMEN, "remix_generic_button_size") + searchButton = getResourceId(LAYOUT, "search_button") + slidingDialogAnimation = getResourceId(STYLE, "SlidingDialogAnimation") + tapBloomView = getResourceId(ID, "tap_bloom_view") + text1 = getResourceId(ID, "text1") + toolTipContentView = getResourceId(LAYOUT, "tooltip_content_view") + topEnd = getResourceId(ID, "TOP_END") + topStart = getResourceId(ID, "TOP_START") + topBarMenuItemImageView = getResourceId(ID, "top_bar_menu_item_image_view") + tosFooter = getResourceId(ID, "tos_footer") + touchOutside = getResourceId(ID, "touch_outside") + trimSilenceSwitch = getResourceId(ID, "trim_silence_switch") + varispeedUnavailableTitle = getResourceId(STRING, "varispeed_unavailable_title") + ytFillSamples = getResourceId(DRAWABLE, "yt_fill_samples_vd_theme_24") + ytFillYouTubeMusic = getResourceId(DRAWABLE, "yt_fill_youtube_music_vd_theme_24") + ytOutlineSamples = getResourceId(DRAWABLE, "yt_outline_samples_vd_theme_24") + ytOutlineYouTubeMusic = getResourceId(DRAWABLE, "yt_outline_youtube_music_vd_theme_24") + ytmLogo = getResourceId(DRAWABLE, "ytm_logo") + ytmLogoRingo2 = getResourceId(DRAWABLE, "ytm_logo_ringo2") } } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt index 8fcffa95d..4f8faec53 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt @@ -2,9 +2,8 @@ package app.revanced.patches.reddit.utils.resourceid import app.revanced.patcher.patch.resourcePatch import app.revanced.patches.shared.mapping.ResourceType.STRING -import app.revanced.patches.shared.mapping.get +import app.revanced.patches.shared.mapping.getResourceId import app.revanced.patches.shared.mapping.resourceMappingPatch -import app.revanced.patches.shared.mapping.resourceMappings var screenShotShareBanner = -1L private set @@ -15,9 +14,6 @@ internal val sharedResourceIdPatch = resourcePatch( dependsOn(resourceMappingPatch) execute { - screenShotShareBanner = resourceMappings[ - STRING, - "screenshot_share_banner_title", - ] + screenShotShareBanner = getResourceId(STRING, "screenshot_share_banner_title") } } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt index f48e8f201..4e881a0e8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt @@ -1,72 +1,52 @@ package app.revanced.patches.shared.mapping +import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.resourcePatch import org.w3c.dom.Element -import java.util.Collections -import java.util.concurrent.Executors -import java.util.concurrent.TimeUnit -// TODO: Probably renaming the patch/this is a good idea. -lateinit var resourceMappings: List - private set +data class ResourceElement(val type: String, val name: String, val id: Long) + +private lateinit var resourceMappings: MutableMap + +private fun setResourceId(type: String, name: String, id: Long) { + resourceMappings[type + name] = ResourceElement(type, name, id) +} + +fun getResourceId(resourceType: ResourceType, name: String) = + getResourceId(resourceType.value, name) + +/** + * @return A resource id of the given resource type and name. + * @throws PatchException if the resource is not found. + */ +fun getResourceId(type: String, name: String) = resourceMappings[type + name]?.id + ?: -1L val resourceMappingPatch = resourcePatch( description = "resourceMappingPatch" ) { - val threadCount = Runtime.getRuntime().availableProcessors() - val threadPoolExecutor = Executors.newFixedThreadPool(threadCount) - - val resourceMappings = Collections.synchronizedList(mutableListOf()) - execute { - // Save the file in memory to concurrently read from it. - val resourceXmlFile = get("res/values/public.xml").readBytes() + document("res/values/public.xml").use { document -> + val resources = document.documentElement.childNodes + val resourcesLength = resources.length + resourceMappings = HashMap(2 * resourcesLength) - for (threadIndex in 0 until threadCount) { - threadPoolExecutor.execute thread@{ - document(resourceXmlFile.inputStream()).use { document -> + for (i in 0 until resourcesLength) { + val node = resources.item(i) as? Element ?: continue + if (node.nodeName != "public") continue - val resources = document.documentElement.childNodes - val resourcesLength = resources.length - val jobSize = resourcesLength / threadCount + val nameAttribute = node.getAttribute("name") + if (nameAttribute.startsWith("APKTOOL")) continue - val batchStart = jobSize * threadIndex - val batchEnd = jobSize * (threadIndex + 1) - element@ for (i in batchStart until batchEnd) { - // Prevent out of bounds. - if (i >= resourcesLength) return@thread + val typeAttribute = node.getAttribute("type") + val id = node.getAttribute("id").substring(2).toLong(16) - val node = resources.item(i) - if (node !is Element) continue - - val nameAttribute = node.getAttribute("name") - val typeAttribute = node.getAttribute("type") - - if (node.nodeName != "public" || nameAttribute.startsWith("APKTOOL")) continue - - val id = node.getAttribute("id").substring(2).toLong(16) - - resourceMappings.add(ResourceElement(typeAttribute, nameAttribute, id)) - } - } + setResourceId(typeAttribute, nameAttribute, id) } } - - threadPoolExecutor.also { it.shutdown() }.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS) - - app.revanced.patches.shared.mapping.resourceMappings = resourceMappings } } -operator fun List.get(type: String, name: String) = resourceMappings.firstOrNull { - it.type == type && it.name == name -}?.id ?: -1L - -operator fun List.get(resourceType: ResourceType, name: String) = - get(resourceType.value, name) - -data class ResourceElement(val type: String, val name: String, val id: Long) - enum class ResourceType(val value: String) { ATTR("attr"), BOOL("bool"), diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index 56194df98..08816a3d8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -11,9 +11,8 @@ import app.revanced.patches.shared.mapping.ResourceType.LAYOUT import app.revanced.patches.shared.mapping.ResourceType.STRING import app.revanced.patches.shared.mapping.ResourceType.STYLE import app.revanced.patches.shared.mapping.ResourceType.XML -import app.revanced.patches.shared.mapping.get +import app.revanced.patches.shared.mapping.getResourceId import app.revanced.patches.shared.mapping.resourceMappingPatch -import app.revanced.patches.shared.mapping.resourceMappings var accountSwitcherAccessibility = -1L private set @@ -268,497 +267,128 @@ internal val sharedResourceIdPatch = resourcePatch( dependsOn(resourceMappingPatch) execute { - accountSwitcherAccessibility = resourceMappings[ - STRING, - "account_switcher_accessibility_label" - ] - actionBarRingo = resourceMappings[ - LAYOUT, - "action_bar_ringo" - ] - actionBarRingoBackground = resourceMappings[ - LAYOUT, - "action_bar_ringo_background" - ] - adAttribution = resourceMappings[ - ID, - "ad_attribution" - ] - appearance = resourceMappings[ - STRING, - "app_theme_appearance_dark" - ] - appRelatedEndScreenResults = resourceMappings[ - LAYOUT, - "app_related_endscreen_results" - ] - autoNavPreviewStub = resourceMappings[ - ID, - "autonav_preview_stub" - ] - autoNavScrollCancelPadding = resourceMappings[ - DIMEN, - "autonav_scroll_cancel_padding" - ] - autoNavToggle = resourceMappings[ - ID, - "autonav_toggle" - ] - backgroundCategory = resourceMappings[ - STRING, - "pref_background_and_offline_category" - ] - badgeLabel = resourceMappings[ - ID, - "badge_label" - ] - bar = resourceMappings[ - LAYOUT, - "bar" - ] - barContainerHeight = resourceMappings[ - DIMEN, - "bar_container_height" - ] - bottomBarContainer = resourceMappings[ - ID, - "bottom_bar_container" - ] - bottomSheetFooterText = resourceMappings[ - ID, - "bottom_sheet_footer_text" - ] - bottomSheetRecyclerView = resourceMappings[ - LAYOUT, - "bottom_sheet_recycler_view" - ] - bottomUiContainerStub = resourceMappings[ - ID, - "bottom_ui_container_stub" - ] - captionToggleContainer = resourceMappings[ - ID, - "caption_toggle_container" - ] - castMediaRouteButton = resourceMappings[ - LAYOUT, - "castmediaroutebutton" - ] - cfFullscreenButton = resourceMappings[ - ID, - "cf_fullscreen_button" - ] - channelListSubMenu = resourceMappings[ - LAYOUT, - "channel_list_sub_menu" - ] - compactLink = resourceMappings[ - LAYOUT, - "compact_link" - ] - compactListItem = resourceMappings[ - LAYOUT, - "compact_list_item" - ] - componentLongClickListener = resourceMappings[ - ID, - "component_long_click_listener" - ] - contentPill = resourceMappings[ - LAYOUT, - "content_pill" - ] - controlsLayoutStub = resourceMappings[ - ID, - "controls_layout_stub" - ] - darkBackground = resourceMappings[ - ID, - "dark_background" - ] - darkSplashAnimation = resourceMappings[ - ID, - "dark_splash_animation" - ] - designBottomSheet = resourceMappings[ - ID, - "design_bottom_sheet" - ] - donationCompanion = resourceMappings[ - LAYOUT, - "donation_companion" - ] - drawerContentView = resourceMappings[ - ID, - "drawer_content_view" - ] - drawerResults = resourceMappings[ - ID, - "drawer_results" - ] - easySeekEduContainer = resourceMappings[ - ID, - "easy_seek_edu_container" - ] - editSettingsAction = resourceMappings[ - STRING, - "edit_settings_action" - ] - endScreenElementLayoutCircle = resourceMappings[ - LAYOUT, - "endscreen_element_layout_circle" - ] - endScreenElementLayoutIcon = resourceMappings[ - LAYOUT, - "endscreen_element_layout_icon" - ] - endScreenElementLayoutVideo = resourceMappings[ - LAYOUT, - "endscreen_element_layout_video" - ] - emojiPickerIcon = resourceMappings[ - ID, - "emoji_picker_icon" - ] - expandButtonDown = resourceMappings[ - LAYOUT, - "expand_button_down" - ] - fab = resourceMappings[ - ID, - "fab" - ] - fadeDurationFast = resourceMappings[ - INTEGER, - "fade_duration_fast" - ] - filterBarHeight = resourceMappings[ - DIMEN, - "filter_bar_height" - ] - floatyBarTopMargin = resourceMappings[ - DIMEN, - "floaty_bar_button_top_margin" - ] - fullScreenButton = resourceMappings[ - ID, - "fullscreen_button" - ] - fullScreenEngagementAdContainer = resourceMappings[ - ID, - "fullscreen_engagement_ad_container" - ] - fullScreenEngagementOverlay = resourceMappings[ - LAYOUT, - "fullscreen_engagement_overlay" - ] - fullScreenEngagementPanel = resourceMappings[ - ID, - "fullscreen_engagement_panel_holder" - ] - horizontalCardList = resourceMappings[ - LAYOUT, - "horizontal_card_list" - ] - imageOnlyTab = resourceMappings[ - LAYOUT, - "image_only_tab" - ] - inlineTimeBarColorizedBarPlayedColorDark = resourceMappings[ - COLOR, - "inline_time_bar_colorized_bar_played_color_dark" - ] - inlineTimeBarLiveSeekAbleRange = resourceMappings[ - COLOR, - "inline_time_bar_live_seekable_range" - ] - inlineTimeBarPlayedNotHighlightedColor = resourceMappings[ - COLOR, - "inline_time_bar_played_not_highlighted_color" - ] - insetOverlayViewLayout = resourceMappings[ - ID, - "inset_overlay_view_layout" - ] - interstitialsContainer = resourceMappings[ - ID, - "interstitials_container" - ] - insetElementsWrapper = resourceMappings[ - LAYOUT, - "inset_elements_wrapper" - ] - menuItemView = resourceMappings[ - ID, - "menu_item_view" - ] - metaPanel = resourceMappings[ - ID, - "metapanel" - ] - miniplayerMaxSize = resourceMappings[ - DIMEN, - "miniplayer_max_size", - ] - modernMiniPlayerClose = resourceMappings[ - ID, - "modern_miniplayer_close" - ] - modernMiniPlayerExpand = resourceMappings[ - ID, - "modern_miniplayer_expand" - ] - modernMiniPlayerForwardButton = resourceMappings[ - ID, - "modern_miniplayer_forward_button" - ] - modernMiniPlayerOverlayActionButton = resourceMappings[ - ID, - "modern_miniplayer_overlay_action_button" - ] - modernMiniPlayerRewindButton = resourceMappings[ - ID, - "modern_miniplayer_rewind_button" - ] - musicAppDeeplinkButtonView = resourceMappings[ - ID, - "music_app_deeplink_button_view" - ] - notificationBigPictureIconWidth = resourceMappings[ - DIMEN, - "notification_big_picture_icon_width" - ] - offlineActionsVideoDeletedUndoSnackbarText = resourceMappings[ - STRING, - "offline_actions_video_deleted_undo_snackbar_text" - ] - playerCollapseButton = resourceMappings[ - ID, - "player_collapse_button" - ] - playerControlPreviousButtonTouchArea = resourceMappings[ - ID, - "player_control_previous_button_touch_area" - ] - playerControlNextButtonTouchArea = resourceMappings[ - ID, - "player_control_next_button_touch_area" - ] - playerVideoTitleView = resourceMappings[ - ID, - "player_video_title_view" - ] - posterArtWidthDefault = resourceMappings[ - DIMEN, - "poster_art_width_default" - ] - qualityAuto = resourceMappings[ - STRING, - "quality_auto" - ] - quickActionsElementContainer = resourceMappings[ - ID, - "quick_actions_element_container" - ] - reelDynRemix = resourceMappings[ - ID, - "reel_dyn_remix" - ] - reelDynShare = resourceMappings[ - ID, - "reel_dyn_share" - ] - reelFeedbackLike = resourceMappings[ - ID, - "reel_feedback_like" - ] - reelFeedbackPause = resourceMappings[ - ID, - "reel_feedback_pause" - ] - reelFeedbackPlay = resourceMappings[ - ID, - "reel_feedback_play" - ] - reelForcedMuteButton = resourceMappings[ - ID, - "reel_player_forced_mute_button" - ] - reelPlayerFooter = resourceMappings[ - LAYOUT, - "reel_player_dyn_footer_vert_stories3" - ] - reelPlayerRightPivotV2Size = resourceMappings[ - DIMEN, - "reel_player_right_pivot_v2_size" - ] - reelRightDislikeIcon = resourceMappings[ - DRAWABLE, - "reel_right_dislike_icon" - ] - reelRightLikeIcon = resourceMappings[ - DRAWABLE, - "reel_right_like_icon" - ] - reelTimeBarPlayedColor = resourceMappings[ - COLOR, - "reel_time_bar_played_color" - ] - reelVodTimeStampsContainer = resourceMappings[ - ID, - "reel_vod_timestamps_container" - ] - reelWatchPlayer = resourceMappings[ - ID, - "reel_watch_player" - ] - relatedChipCloudMargin = resourceMappings[ - LAYOUT, - "related_chip_cloud_reduced_margins" - ] - rightComment = resourceMappings[ - DRAWABLE, - "ic_right_comment_32c" - ] - scrimOverlay = resourceMappings[ - ID, - "scrim_overlay" - ] - seekEasyHorizontalTouchOffsetToStartScrubbing = resourceMappings[ - DIMEN, - "seek_easy_horizontal_touch_offset_to_start_scrubbing" - ] - seekUndoEduOverlayStub = resourceMappings[ - ID, - "seek_undo_edu_overlay_stub" - ] - settingsFragment = resourceMappings[ - XML, - "settings_fragment" - ] - settingsFragmentCairo = resourceMappings[ - XML, - "settings_fragment_cairo" - ] - slidingDialogAnimation = resourceMappings[ - STYLE, - "SlidingDialogAnimation" - ] - subtitleMenuSettingsFooterInfo = resourceMappings[ - STRING, - "subtitle_menu_settings_footer_info" - ] - suggestedAction = resourceMappings[ - LAYOUT, - "suggested_action" - ] - tapBloomView = resourceMappings[ - ID, - "tap_bloom_view" - ] - titleAnchor = resourceMappings[ - ID, - "title_anchor" - ] - toolbarContainerId = resourceMappings[ - ID, - "toolbar_container" - ] - toolTipContentView = resourceMappings[ - LAYOUT, - "tooltip_content_view" - ] - totalTime = resourceMappings[ - STRING, - "total_time" - ] - touchArea = resourceMappings[ - ID, - "touch_area" - ] - videoQualityBottomSheet = resourceMappings[ - LAYOUT, - "video_quality_bottom_sheet_list_fragment_title" - ] - varispeedUnavailableTitle = resourceMappings[ - STRING, - "varispeed_unavailable_title" - ] - verticalTouchOffsetToEnterFineScrubbing = resourceMappings[ - DIMEN, - "vertical_touch_offset_to_enter_fine_scrubbing" - ] - verticalTouchOffsetToStartFineScrubbing = resourceMappings[ - DIMEN, - "vertical_touch_offset_to_start_fine_scrubbing" - ] - videoQualityUnavailableAnnouncement = resourceMappings[ - STRING, - "video_quality_unavailable_announcement" - ] - videoZoomSnapIndicator = resourceMappings[ - ID, - "video_zoom_snap_indicator" - ] - voiceSearch = resourceMappings[ - ID, - "voice_search" - ] - youTubeControlsOverlaySubtitleButton = resourceMappings[ - LAYOUT, - "youtube_controls_overlay_subtitle_button" - ] - youTubeLogo = resourceMappings[ - ID, - "youtube_logo" - ] - ytCallToAction = resourceMappings[ - ATTR, - "ytCallToAction" - ] - ytFillBell = resourceMappings[ - DRAWABLE, - "yt_fill_bell_black_24" - ] - ytOutlineLibrary = resourceMappings[ - DRAWABLE, - "yt_outline_library_black_24" - ] - ytOutlineMoonZ = resourceMappings[ - DRAWABLE, - "yt_outline_moon_z_vd_theme_24" - ] - ytOutlinePictureInPictureWhite = resourceMappings[ - DRAWABLE, - "yt_outline_picture_in_picture_white_24" - ] - ytOutlineVideoCamera = resourceMappings[ - DRAWABLE, - "yt_outline_video_camera_black_24" - ] - ytOutlineXWhite = resourceMappings[ - DRAWABLE, - "yt_outline_x_white_24" - ] - ytPremiumWordMarkHeader = resourceMappings[ - ATTR, - "ytPremiumWordmarkHeader" - ] - ytTextSecondary = resourceMappings[ - ATTR, - "ytTextSecondary", - ] - ytStaticBrandRed = resourceMappings[ - ATTR, - "ytStaticBrandRed", - ] - ytWordMarkHeader = resourceMappings[ - ATTR, - "ytWordmarkHeader" - ] - ytYoutubeMagenta = resourceMappings[ - COLOR, - "yt_youtube_magenta", - ] + accountSwitcherAccessibility = getResourceId(STRING, "account_switcher_accessibility_label") + actionBarRingo = getResourceId(LAYOUT, "action_bar_ringo") + actionBarRingoBackground = getResourceId(LAYOUT, "action_bar_ringo_background") + adAttribution = getResourceId(ID, "ad_attribution") + appearance = getResourceId(STRING, "app_theme_appearance_dark") + appRelatedEndScreenResults = getResourceId(LAYOUT, "app_related_endscreen_results") + autoNavPreviewStub = getResourceId(ID, "autonav_preview_stub") + autoNavScrollCancelPadding = getResourceId(DIMEN, "autonav_scroll_cancel_padding") + autoNavToggle = getResourceId(ID, "autonav_toggle") + backgroundCategory = getResourceId(STRING, "pref_background_and_offline_category") + badgeLabel = getResourceId(ID, "badge_label") + bar = getResourceId(LAYOUT, "bar") + barContainerHeight = getResourceId(DIMEN, "bar_container_height") + bottomBarContainer = getResourceId(ID, "bottom_bar_container") + bottomSheetFooterText = getResourceId(ID, "bottom_sheet_footer_text") + bottomSheetRecyclerView = getResourceId(LAYOUT, "bottom_sheet_recycler_view") + bottomUiContainerStub = getResourceId(ID, "bottom_ui_container_stub") + captionToggleContainer = getResourceId(ID, "caption_toggle_container") + castMediaRouteButton = getResourceId(LAYOUT, "castmediaroutebutton") + cfFullscreenButton = getResourceId(ID, "cf_fullscreen_button") + channelListSubMenu = getResourceId(LAYOUT, "channel_list_sub_menu") + compactLink = getResourceId(LAYOUT, "compact_link") + compactListItem = getResourceId(LAYOUT, "compact_list_item") + componentLongClickListener = getResourceId(ID, "component_long_click_listener") + contentPill = getResourceId(LAYOUT, "content_pill") + controlsLayoutStub = getResourceId(ID, "controls_layout_stub") + darkBackground = getResourceId(ID, "dark_background") + darkSplashAnimation = getResourceId(ID, "dark_splash_animation") + designBottomSheet = getResourceId(ID, "design_bottom_sheet") + donationCompanion = getResourceId(LAYOUT, "donation_companion") + drawerContentView = getResourceId(ID, "drawer_content_view") + drawerResults = getResourceId(ID, "drawer_results") + easySeekEduContainer = getResourceId(ID, "easy_seek_edu_container") + editSettingsAction = getResourceId(STRING, "edit_settings_action") + endScreenElementLayoutCircle = getResourceId(LAYOUT, "endscreen_element_layout_circle") + endScreenElementLayoutIcon = getResourceId(LAYOUT, "endscreen_element_layout_icon") + endScreenElementLayoutVideo = getResourceId(LAYOUT, "endscreen_element_layout_video") + emojiPickerIcon = getResourceId(ID, "emoji_picker_icon") + expandButtonDown = getResourceId(LAYOUT, "expand_button_down") + fab = getResourceId(ID, "fab") + fadeDurationFast = getResourceId(INTEGER, "fade_duration_fast") + filterBarHeight = getResourceId(DIMEN, "filter_bar_height") + floatyBarTopMargin = getResourceId(DIMEN, "floaty_bar_button_top_margin") + fullScreenButton = getResourceId(ID, "fullscreen_button") + fullScreenEngagementAdContainer = getResourceId(ID, "fullscreen_engagement_ad_container") + fullScreenEngagementOverlay = getResourceId(LAYOUT, "fullscreen_engagement_overlay") + fullScreenEngagementPanel = getResourceId(ID, "fullscreen_engagement_panel_holder") + horizontalCardList = getResourceId(LAYOUT, "horizontal_card_list") + imageOnlyTab = getResourceId(LAYOUT, "image_only_tab") + inlineTimeBarColorizedBarPlayedColorDark = getResourceId(COLOR, "inline_time_bar_colorized_bar_played_color_dark") + inlineTimeBarLiveSeekAbleRange = getResourceId(COLOR, "inline_time_bar_live_seekable_range") + inlineTimeBarPlayedNotHighlightedColor = getResourceId(COLOR, "inline_time_bar_played_not_highlighted_color") + insetOverlayViewLayout = getResourceId(ID, "inset_overlay_view_layout") + interstitialsContainer = getResourceId(ID, "interstitials_container") + insetElementsWrapper = getResourceId(LAYOUT, "inset_elements_wrapper") + menuItemView = getResourceId(ID, "menu_item_view") + metaPanel = getResourceId(ID, "metapanel") + miniplayerMaxSize = getResourceId(DIMEN, "miniplayer_max_size") + modernMiniPlayerClose = getResourceId(ID, "modern_miniplayer_close") + modernMiniPlayerExpand = getResourceId(ID, "modern_miniplayer_expand") + modernMiniPlayerForwardButton = getResourceId(ID, "modern_miniplayer_forward_button") + modernMiniPlayerOverlayActionButton = getResourceId(ID, "modern_miniplayer_overlay_action_button") + modernMiniPlayerRewindButton = getResourceId(ID, "modern_miniplayer_rewind_button") + musicAppDeeplinkButtonView = getResourceId(ID, "music_app_deeplink_button_view") + notificationBigPictureIconWidth = getResourceId(DIMEN, "notification_big_picture_icon_width") + offlineActionsVideoDeletedUndoSnackbarText = getResourceId(STRING, "offline_actions_video_deleted_undo_snackbar_text") + playerCollapseButton = getResourceId(ID, "player_collapse_button") + playerControlPreviousButtonTouchArea = getResourceId(ID, "player_control_previous_button_touch_area") + playerControlNextButtonTouchArea = getResourceId(ID, "player_control_next_button_touch_area") + playerVideoTitleView = getResourceId(ID, "player_video_title_view") + posterArtWidthDefault = getResourceId(DIMEN, "poster_art_width_default") + qualityAuto = getResourceId(STRING, "quality_auto") + quickActionsElementContainer = getResourceId(ID, "quick_actions_element_container") + reelDynRemix = getResourceId(ID, "reel_dyn_remix") + reelDynShare = getResourceId(ID, "reel_dyn_share") + reelFeedbackLike = getResourceId(ID, "reel_feedback_like") + reelFeedbackPause = getResourceId(ID, "reel_feedback_pause") + reelFeedbackPlay = getResourceId(ID, "reel_feedback_play") + reelForcedMuteButton = getResourceId(ID, "reel_player_forced_mute_button") + reelPlayerFooter = getResourceId(LAYOUT, "reel_player_dyn_footer_vert_stories3") + reelPlayerRightPivotV2Size = getResourceId(DIMEN, "reel_player_right_pivot_v2_size") + reelRightDislikeIcon = getResourceId(DRAWABLE, "reel_right_dislike_icon") + reelRightLikeIcon = getResourceId(DRAWABLE, "reel_right_like_icon") + reelTimeBarPlayedColor = getResourceId(COLOR, "reel_time_bar_played_color") + reelVodTimeStampsContainer = getResourceId(ID, "reel_vod_timestamps_container") + reelWatchPlayer = getResourceId(ID, "reel_watch_player") + relatedChipCloudMargin = getResourceId(LAYOUT, "related_chip_cloud_reduced_margins") + rightComment = getResourceId(DRAWABLE, "ic_right_comment_32c") + scrimOverlay = getResourceId(ID, "scrim_overlay") + seekEasyHorizontalTouchOffsetToStartScrubbing = getResourceId(DIMEN, "seek_easy_horizontal_touch_offset_to_start_scrubbing") + seekUndoEduOverlayStub = getResourceId(ID, "seek_undo_edu_overlay_stub") + settingsFragment = getResourceId(XML, "settings_fragment") + settingsFragmentCairo = getResourceId(XML, "settings_fragment_cairo") + slidingDialogAnimation = getResourceId(STYLE, "SlidingDialogAnimation") + subtitleMenuSettingsFooterInfo = getResourceId(STRING, "subtitle_menu_settings_footer_info") + suggestedAction = getResourceId(LAYOUT, "suggested_action") + tapBloomView = getResourceId(ID, "tap_bloom_view") + titleAnchor = getResourceId(ID, "title_anchor") + toolbarContainerId = getResourceId(ID, "toolbar_container") + toolTipContentView = getResourceId(LAYOUT, "tooltip_content_view") + totalTime = getResourceId(STRING, "total_time") + touchArea = getResourceId(ID, "touch_area") + videoQualityBottomSheet = getResourceId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title") + varispeedUnavailableTitle = getResourceId(STRING, "varispeed_unavailable_title") + verticalTouchOffsetToEnterFineScrubbing = getResourceId(DIMEN, "vertical_touch_offset_to_enter_fine_scrubbing") + verticalTouchOffsetToStartFineScrubbing = getResourceId(DIMEN, "vertical_touch_offset_to_start_fine_scrubbing") + videoQualityUnavailableAnnouncement = getResourceId(STRING, "video_quality_unavailable_announcement") + videoZoomSnapIndicator = getResourceId(ID, "video_zoom_snap_indicator") + voiceSearch = getResourceId(ID, "voice_search") + youTubeControlsOverlaySubtitleButton = getResourceId(LAYOUT, "youtube_controls_overlay_subtitle_button") + youTubeLogo = getResourceId(ID, "youtube_logo") + ytCallToAction = getResourceId(ATTR, "ytCallToAction") + ytFillBell = getResourceId(DRAWABLE, "yt_fill_bell_black_24") + ytOutlineLibrary = getResourceId(DRAWABLE, "yt_outline_library_black_24") + ytOutlineMoonZ = getResourceId(DRAWABLE, "yt_outline_moon_z_vd_theme_24") + ytOutlinePictureInPictureWhite = getResourceId(DRAWABLE, "yt_outline_picture_in_picture_white_24") + ytOutlineVideoCamera = getResourceId(DRAWABLE, "yt_outline_video_camera_black_24") + ytOutlineXWhite = getResourceId(DRAWABLE, "yt_outline_x_white_24") + ytPremiumWordMarkHeader = getResourceId(ATTR, "ytPremiumWordmarkHeader") + ytTextSecondary = getResourceId(ATTR, "ytTextSecondary") + ytStaticBrandRed = getResourceId(ATTR, "ytStaticBrandRed") + ytWordMarkHeader = getResourceId(ATTR, "ytWordmarkHeader") + ytYoutubeMagenta = getResourceId(COLOR, "yt_youtube_magenta") } } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index 18edf0a80..1e5910f03 100644 --- a/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/patches/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -17,9 +17,8 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableClass import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable -import app.revanced.patches.shared.mapping.get +import app.revanced.patches.shared.mapping.getResourceId import app.revanced.patches.shared.mapping.resourceMappingPatch -import app.revanced.patches.shared.mapping.resourceMappings import app.revanced.util.Utils.printWarn import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -134,7 +133,7 @@ internal fun MutableMethod.addInstructionsAtControlFlowLabel( * @see [indexOfFirstResourceIdOrThrow], [indexOfFirstLiteralInstructionReversed] */ fun Method.indexOfFirstResourceId(resourceName: String): Int { - val resourceId = resourceMappings["id", resourceName] + val resourceId = getResourceId("id", resourceName) if (resourceId == -1L) { printWarn("Could not find resource type: id name: $name") return -1 From 98d362ad93fd22628b16b615ae45534f827a8504 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:12:18 +0900 Subject: [PATCH 41/77] feat(YouTube Music): Add support version `8.12.53`, drop support version `8.10.52` --- .../components/AccountComponentsPatch.kt | 58 +++++++++++++++---- .../music/account/components/Fingerprints.kt | 21 +++---- .../patches/music/ads/general/Fingerprints.kt | 2 - .../misc/splash/CairoSplashAnimationPatch.kt | 23 +++----- .../patches/music/misc/splash/Fingerprints.kt | 4 +- .../components/PlayerComponentsPatch.kt | 8 ++- .../music/utils/compatibility/Constants.kt | 2 +- .../utils/resourceid/SharedResourceIdPatch.kt | 3 + 8 files changed, 77 insertions(+), 44 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt index f15dc184b..2ac49689b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt @@ -4,23 +4,27 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.extension.Constants.ACCOUNT_CLASS_DESCRIPTOR import app.revanced.patches.music.utils.patch.PatchList.HIDE_ACCOUNT_COMPONENTS +import app.revanced.patches.music.utils.resourceid.channelHandle import app.revanced.patches.music.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus import app.revanced.patches.music.utils.settings.addPreferenceWithIntent import app.revanced.patches.music.utils.settings.addSwitchPreference import app.revanced.patches.music.utils.settings.settingsPatch -import app.revanced.util.fingerprint.matchOrThrow import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow +import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Suppress("unused") @@ -84,17 +88,49 @@ val accountComponentsPatch = bytecodePatch( } // account switcher - namesInactiveAccountThumbnailSizeFingerprint.matchOrThrow().let { - it.method.apply { - val targetIndex = it.patternMatch!!.startIndex - val targetRegister = getInstruction(targetIndex).registerA + val textViewField = with ( + channelHandleFingerprint + .methodOrThrow(namesInactiveAccountThumbnailSizeFingerprint) + ) { + val literalIndex = indexOfFirstLiteralInstructionOrThrow(channelHandle) + getInstruction( + indexOfFirstInstructionOrThrow(literalIndex) { + opcode == Opcode.IPUT_OBJECT && + getReference()?.type == "Landroid/widget/TextView;" + }, + ).getReference() + } - addInstructions( - targetIndex, """ - invoke-static {v$targetRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Z)Z - move-result v$targetRegister - """ - ) + namesInactiveAccountThumbnailSizeFingerprint.methodOrThrow().apply { + var hook = false + + implementation!!.instructions + .withIndex() + .filter { (_, instruction) -> + val reference = + (instruction as? ReferenceInstruction)?.reference + instruction.opcode == Opcode.IGET_OBJECT && + reference is FieldReference && + reference == textViewField + } + .map { (index, _) -> index } + .forEach { index -> + val insertIndex = index - 1 + if (!hook && getInstruction(insertIndex).opcode == Opcode.IF_NEZ) { + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $ACCOUNT_CLASS_DESCRIPTOR->hideHandle(Z)Z + move-result v$insertRegister + """ + ) + hook = true + } + } + + if (!hook) { + throw PatchException("Could not find TextUtils.isEmpty() index") } } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/account/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/account/components/Fingerprints.kt index 8af714611..bb28af644 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/account/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/account/components/Fingerprints.kt @@ -1,11 +1,11 @@ package app.revanced.patches.music.account.components import app.revanced.patches.music.utils.resourceid.accountSwitcherAccessibility +import app.revanced.patches.music.utils.resourceid.channelHandle import app.revanced.patches.music.utils.resourceid.menuEntry import app.revanced.patches.music.utils.resourceid.namesInactiveAccountThumbnailSize import app.revanced.patches.music.utils.resourceid.tosFooter import app.revanced.util.fingerprint.legacyFingerprint -import com.android.tools.smali.dexlib2.Opcode internal val accountSwitcherAccessibilityLabelFingerprint = legacyFingerprint( name = "accountSwitcherAccessibilityLabelFingerprint", @@ -14,6 +14,12 @@ internal val accountSwitcherAccessibilityLabelFingerprint = legacyFingerprint( literals = listOf(accountSwitcherAccessibility) ) +internal val channelHandleFingerprint = legacyFingerprint( + name = "channelHandleFingerprint", + returnType = "V", + literals = listOf(channelHandle), +) + internal val menuEntryFingerprint = legacyFingerprint( name = "menuEntryFingerprint", returnType = "V", @@ -24,19 +30,6 @@ internal val namesInactiveAccountThumbnailSizeFingerprint = legacyFingerprint( name = "namesInactiveAccountThumbnailSizeFingerprint", returnType = "V", parameters = listOf("L", "Ljava/lang/Object;"), - opcodes = listOf( - Opcode.IF_NEZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.GOTO, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_EQZ - ), literals = listOf(namesInactiveAccountThumbnailSize) ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/ads/general/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/ads/general/Fingerprints.kt index a70e8e57a..8c05ff53a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/ads/general/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/ads/general/Fingerprints.kt @@ -97,8 +97,6 @@ internal val showDialogCommandFingerprint = legacyFingerprint( name = "showDialogCommandFingerprint", returnType = "V", opcodes = listOf( - Opcode.IF_EQ, - Opcode.IGET_OBJECT, Opcode.INVOKE_VIRTUAL, Opcode.IGET, // get dialog code ), diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt index 92c0a5d30..c2e71c3bf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/CairoSplashAnimationPatch.kt @@ -24,7 +24,7 @@ import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_METHOD_DESCRIPTOR = @@ -41,7 +41,7 @@ val cairoSplashAnimationPatch = bytecodePatch( "7.16.53", "7.25.53", "8.05.51", - "8.10.52", + "8.12.53", ), ) @@ -57,7 +57,7 @@ val cairoSplashAnimationPatch = bytecodePatch( return@execute } else if (!is_7_20_or_greater) { cairoSplashAnimationConfigFingerprint.injectLiteralInstructionBooleanCall( - 45635386L, + CAIRO_SPLASH_ANIMATION_FEATURE_FLAG, EXTENSION_METHOD_DESCRIPTOR ) } else { @@ -69,18 +69,13 @@ val cairoSplashAnimationPatch = bytecodePatch( opcode == Opcode.INVOKE_VIRTUAL && getReference()?.name == "setContentView" } + 1 - val viewStubFindViewByIdIndex = indexOfFirstInstructionOrThrow(literalIndex) { - val reference = getReference() - opcode == Opcode.INVOKE_VIRTUAL && - reference?.name == "findViewById" && - reference.definingClass != "Landroid/view/View;" - } + val freeIndex = indexOfFirstInstructionOrThrow(insertIndex, Opcode.CONST) val freeRegister = - getInstruction(viewStubFindViewByIdIndex).registerD - val jumpIndex = indexOfFirstInstructionReversedOrThrow( - viewStubFindViewByIdIndex, - Opcode.IGET_OBJECT - ) + getInstruction(freeIndex).registerA + val jumpIndex = indexOfFirstInstructionOrThrow(insertIndex) { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.parameterTypes?.firstOrNull() == "Ljava/lang/Runnable;" + } + 1 addInstructionsWithLabels( insertIndex, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/Fingerprints.kt index 05fbdf843..0c04718df 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/splash/Fingerprints.kt @@ -5,6 +5,8 @@ import app.revanced.patches.music.utils.resourceid.mainActivityLaunchAnimation import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.indexOfFirstLiteralInstruction +internal const val CAIRO_SPLASH_ANIMATION_FEATURE_FLAG = 45635386L + /** * This fingerprint is compatible with YouTube Music v7.06.53+ */ @@ -20,7 +22,7 @@ internal val cairoSplashAnimationConfigFingerprint = legacyFingerprint( if (is_7_20_or_greater) { method.indexOfFirstLiteralInstruction(mainActivityLaunchAnimation) >= 0 } else { - method.indexOfFirstLiteralInstruction(45635386) >= 0 + method.indexOfFirstLiteralInstruction(CAIRO_SPLASH_ANIMATION_FEATURE_FLAG) >= 0 } } ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt index c39664845..a14bb20e7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt @@ -746,15 +746,21 @@ val playerComponentsPatch = bytecodePatch( val freeRegister = getInstruction(bottomSheetBehaviorIndex).registerD + val getFieldIndex = bottomSheetBehaviorIndex - 2 + val getFieldReference = getInstruction(getFieldIndex).reference + val getFieldInstruction = getInstruction(getFieldIndex) + addInstructionsWithLabels( - bottomSheetBehaviorIndex - 2, + getFieldIndex + 1, """ invoke-static {}, $PLAYER_CLASS_DESCRIPTOR->enableSwipeToDismissMiniPlayer()Z move-result v$freeRegister if-nez v$freeRegister, :dismiss + iget-object v${getFieldInstruction.registerA}, v${getFieldInstruction.registerB}, $getFieldReference """, ExternalLabel("dismiss", getInstruction(bottomSheetBehaviorIndex + 1)) ) + removeInstruction(getFieldIndex) } ?: throw PatchException("Could not find targetMethod") } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt index f190da103..eb3882209 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/compatibility/Constants.kt @@ -16,7 +16,7 @@ internal object Constants { "7.16.53", // This is the latest version that supports the 'Spoof app version' patch. "7.25.53", // This is the last supported version for 2024. "8.05.51", // This was the latest version supported by the previous RVX patch. - "8.10.52", // This is the latest version supported by the RVX patch. + "8.12.53", // This is the latest version supported by the RVX patch. ) ) } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt index 86224d8af..3e7d4187b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt @@ -24,6 +24,8 @@ var buttonContainer = -1L private set var buttonIconPaddingMedium = -1L private set +var channelHandle = -1L + private set var chipCloud = -1L private set var colorGrey = -1L @@ -131,6 +133,7 @@ internal val sharedResourceIdPatch = resourcePatch( bottomSheetRecyclerView = getResourceId(LAYOUT, "bottom_sheet_recycler_view") buttonContainer = getResourceId(ID, "button_container") buttonIconPaddingMedium = getResourceId(DIMEN, "button_icon_padding_medium") + channelHandle = getResourceId(ID, "channel_handle") chipCloud = getResourceId(LAYOUT, "chip_cloud") colorGrey = getResourceId(COLOR, "ytm_color_grey_12") darkBackground = getResourceId(ID, "dark_background") From a235c84e19b0cf3079a65807922afea125decbc8 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:14:17 +0900 Subject: [PATCH 42/77] feat(Reddit): Add support version `2025.12.0`, drop support version `2025.05.1` --- .../revanced/patches/reddit/utils/compatibility/Constants.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt index 9589f9dd7..52276f40b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt @@ -10,7 +10,7 @@ internal object Constants { REDDIT_PACKAGE_NAME, setOf( "2024.17.0", // This is the last version that can be patched without anti-split. - "2025.05.1", // This is the latest version supported by the RVX patch. + "2025.12.0", // This is the latest version supported by the RVX patch. ) ) } \ No newline at end of file From 4f911d9a553c546bd48317d919444a647790d73b Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:16:21 +0900 Subject: [PATCH 43/77] fix(YouTube - Spoof streaming data): No toast message is shown even if fetch fails --- .../patches/spoof/requests/StreamingDataRequest.kt | 11 +++++++++-- .../youtube/settings/host/values/strings.xml | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt index 018bb48d5..3c992b00b 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt @@ -7,6 +7,7 @@ import app.revanced.extension.shared.innertube.requests.InnerTubeRequestBody.get import app.revanced.extension.shared.innertube.requests.InnerTubeRoutes.GET_STREAMING_DATA import app.revanced.extension.shared.settings.BaseSettings import app.revanced.extension.shared.utils.Logger +import app.revanced.extension.shared.utils.StringRef.str import app.revanced.extension.shared.utils.Utils import java.io.BufferedInputStream import java.io.ByteArrayOutputStream @@ -132,7 +133,12 @@ class StreamingDataRequest private constructor( return cache[videoId] } - private fun handleConnectionError(toastMessage: String, ex: Exception?) { + private fun handleConnectionError( + toastMessage: String, + ex: Exception?, + showToast: Boolean = false, + ) { + if (showToast) Utils.showToastShort(toastMessage) Logger.printInfo({ toastMessage }, ex) } @@ -233,7 +239,8 @@ class StreamingDataRequest private constructor( } } - handleConnectionError("Could not fetch any client streams", null) + handleConnectionError(str("revanced_spoof_streaming_data_failed_forbidden"), null, true) + handleConnectionError(str("revanced_spoof_streaming_data_failed_forbidden_suggestion"), null, true) return null } } diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index df11d645f..0b04f7072 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -2228,6 +2228,8 @@ AVC has a maximum resolution of 1080p, Opus audio codec is not available, and vi Client used to fetch streaming data is shown in Stats for nerds. Client used to fetch streaming data is hidden in Stats for nerds. VR default audio stream language + Could not fetch any client streams. + You may not be logged in. PoToken / VisitorData From 82ceb8aa763ff051f3e1280a234cfe18cff58d83 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:21:17 +0900 Subject: [PATCH 44/77] fix(YouTube Music - Disable music video in album): The redirect wait time may be too short. --- .../patches/misc/AlbumMusicVideoPatch.java | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/AlbumMusicVideoPatch.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/AlbumMusicVideoPatch.java index e275463d1..6c228af1a 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/AlbumMusicVideoPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/misc/AlbumMusicVideoPatch.java @@ -7,15 +7,12 @@ import androidx.annotation.NonNull; import java.util.LinkedHashMap; import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; import app.revanced.extension.music.patches.misc.requests.PlaylistRequest; import app.revanced.extension.music.settings.Settings; import app.revanced.extension.music.shared.VideoInformation; import app.revanced.extension.music.utils.VideoUtils; -import app.revanced.extension.shared.settings.BaseSettings; import app.revanced.extension.shared.utils.Logger; -import app.revanced.extension.shared.utils.Utils; @SuppressWarnings("unused") public class AlbumMusicVideoPatch { @@ -40,7 +37,7 @@ public class AlbumMusicVideoPatch { private static final String YOUTUBE_MUSIC_ALBUM_PREFIX = "OLAK"; - private static final AtomicBoolean isVideoLaunched = new AtomicBoolean(false); + private static volatile boolean isVideoLaunched = false; @NonNull private static volatile String playerResponseVideoId = ""; @@ -100,14 +97,6 @@ public class AlbumMusicVideoPatch { if (request == null) { return; } - // This hook is always called off the main thread, - // but this can later be called for the same video id from the main thread. - // This is not a concern, since the fetch will always be finished - // and never block the main thread. - // But if debugging, then still verify this is the situation. - if (BaseSettings.ENABLE_DEBUG_LOGGING.get() && !request.fetchCompleted() && Utils.isCurrentlyOnMainThread()) { - Logger.printException(() -> "Error: Blocking main thread"); - } String songId = request.getStream(); if (songId.isEmpty()) { Logger.printDebug(() -> "Official song not found, videoId: " + videoId); @@ -149,17 +138,16 @@ public class AlbumMusicVideoPatch { private static void openMusic(@NonNull String songId) { try { - isVideoLaunched.compareAndSet(false, true); - // The newly opened video is not a music video. // To prevent fetch requests from being sent, set the video id to the newly opened video VideoUtils.runOnMainThreadDelayed(() -> { + isVideoLaunched = true; playerResponseVideoId = songId; currentVideoId = songId; VideoUtils.openInYouTubeMusic(songId); - }, 1000); + VideoUtils.runOnMainThreadDelayed(() -> isVideoLaunched = false, 3000); + }, 1500); - VideoUtils.runOnMainThreadDelayed(() -> isVideoLaunched.compareAndSet(true, false), 2500); } catch (Exception ex) { Logger.printException(() -> "openMusic failure", ex); } @@ -191,7 +179,7 @@ public class AlbumMusicVideoPatch { * Injection point. */ public static boolean hideSnackBar() { - return DISABLE_MUSIC_VIDEO_IN_ALBUM && isVideoLaunched.get(); + return DISABLE_MUSIC_VIDEO_IN_ALBUM && isVideoLaunched; } } From bf9ba0b1efabcad50235fca6989e2b3196f26a0a Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:31:25 +0900 Subject: [PATCH 45/77] refactor(YouTube - Video playback): Add support for Shorts.. - Add 'Speed dialog' setting to Shorts custom actions - Add default quality settings and default playback speed settings for Shorts - Remove deprecated settings - 'Reject software AV1 codec response', 'Enable Shorts default playback speed' - Reorder video categories --- .../patches/shorts/CustomActionsPatch.java | 5 + .../youtube/patches/video/AV1CodecPatch.java | 35 ---- .../patches/video/PlaybackSpeedPatch.java | 155 ++++++++++++------ .../patches/video/VideoQualityPatch.java | 97 +++++++---- .../extension/youtube/settings/Settings.java | 39 +++-- .../ReVancedPreferenceFragment.java | 5 +- .../ReVancedSettingsPreference.java | 14 ++ .../extension/youtube/utils/VideoUtils.java | 1 + .../information/VideoInformationPatch.kt | 107 +++++++++--- .../youtube/video/playback/Fingerprints.kt | 44 ++--- .../video/playback/VideoPlaybackPatch.kt | 49 +++--- .../youtube/settings/host/values/strings.xml | 107 +++++++----- .../youtube/settings/xml/revanced_prefs.xml | 51 +++--- 13 files changed, 435 insertions(+), 274 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java index 9b76a935c..7dfdf27e8 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java @@ -296,6 +296,11 @@ public final class CustomActionsPatch { true ) ), + SPEED_DIALOG( + Settings.SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG, + "yt_outline_play_arrow_half_circle_black_24", + () -> VideoUtils.showPlaybackSpeedDialog(contextRef.get()) + ), REPEAT_STATE( Settings.SHORTS_CUSTOM_ACTIONS_REPEAT_STATE, "yt_outline_arrow_repeat_1_black_24", diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/AV1CodecPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/AV1CodecPatch.java index 71f5dd9d6..8cf4980d1 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/AV1CodecPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/AV1CodecPatch.java @@ -1,17 +1,10 @@ package app.revanced.extension.youtube.patches.video; -import static app.revanced.extension.shared.utils.StringRef.str; - -import app.revanced.extension.shared.utils.Logger; -import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.settings.Settings; @SuppressWarnings("unused") public class AV1CodecPatch { - private static final int LITERAL_VALUE_AV01 = 1635135811; - private static final int LITERAL_VALUE_DOLBY_VISION = 1685485123; private static final String VP9_CODEC = "video/x-vnd.on2.vp9"; - private static long lastTimeResponse = 0; /** * Replace the SW AV01 codec to VP9 codec. @@ -22,32 +15,4 @@ public class AV1CodecPatch { public static String replaceCodec(String original) { return Settings.REPLACE_AV1_CODEC.get() ? VP9_CODEC : original; } - - /** - * Replace the SW AV01 codec request with a Dolby Vision codec request. - * This request is invalid, so it falls back to codecs other than AV01. - *

- * Limitation: Fallback process causes about 15-20 seconds of buffering. - * - * @param literalValue literal value of the codec - */ - public static int rejectResponse(int literalValue) { - if (!Settings.REJECT_AV1_CODEC.get()) - return literalValue; - - Logger.printDebug(() -> "Response: " + literalValue); - - if (literalValue != LITERAL_VALUE_AV01) - return literalValue; - - final long currentTime = System.currentTimeMillis(); - - // Ignore the invoke within 20 seconds. - if (currentTime - lastTimeResponse > 20000) { - lastTimeResponse = currentTime; - Utils.showToastShort(str("revanced_reject_av1_codec_toast")); - } - - return LITERAL_VALUE_DOLBY_VISION; - } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java index 5211c6a47..7ad27b152 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java @@ -3,39 +3,73 @@ package app.revanced.extension.youtube.patches.video; import static app.revanced.extension.shared.utils.StringRef.str; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import org.apache.commons.lang3.BooleanUtils; +import app.revanced.extension.shared.settings.BooleanSetting; +import app.revanced.extension.shared.settings.FloatSetting; import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.patches.utils.PatchStatus; import app.revanced.extension.youtube.patches.video.requests.MusicRequest; import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.shared.ShortsPlayerState; import app.revanced.extension.youtube.shared.VideoInformation; import app.revanced.extension.youtube.whitelist.Whitelist; @SuppressWarnings("unused") public class PlaybackSpeedPatch { + private static final FloatSetting DEFAULT_PLAYBACK_SPEED = + Settings.DEFAULT_PLAYBACK_SPEED; + private static final FloatSetting DEFAULT_PLAYBACK_SPEED_SHORTS = + Settings.DEFAULT_PLAYBACK_SPEED_SHORTS; + private static final boolean DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC = Settings.DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC.get(); private static final long TOAST_DELAY_MILLISECONDS = 750; private static long lastTimeSpeedChanged; + private static float lastSelectedPlaybackSpeed = 1.0f; + + private static volatile String channelId = ""; + private static volatile String videoId = ""; private static boolean isLiveStream; + private static volatile String channelIdShorts = ""; + private static volatile String videoIdShorts = ""; + private static boolean isLiveStreamShorts; + /** * Injection point. */ public static void newVideoStarted(@NonNull String newlyLoadedChannelId, @NonNull String newlyLoadedChannelName, @NonNull String newlyLoadedVideoId, @NonNull String newlyLoadedVideoTitle, final long newlyLoadedVideoLength, boolean newlyLoadedLiveStreamValue) { - isLiveStream = newlyLoadedLiveStreamValue; - Logger.printDebug(() -> "newVideoStarted: " + newlyLoadedVideoId); + if (isShorts()) { + channelIdShorts = newlyLoadedChannelId; + videoIdShorts = newlyLoadedVideoId; + isLiveStreamShorts = newlyLoadedLiveStreamValue; - final float defaultPlaybackSpeed = getDefaultPlaybackSpeed(newlyLoadedChannelId, newlyLoadedVideoId); - Logger.printDebug(() -> "overridePlaybackSpeed: " + defaultPlaybackSpeed); + Logger.printDebug(() -> "newVideoStarted: " + newlyLoadedVideoId); + } else { + channelId = newlyLoadedChannelId; + videoId = newlyLoadedVideoId; + isLiveStream = newlyLoadedLiveStreamValue; - VideoInformation.overridePlaybackSpeed(defaultPlaybackSpeed); + Logger.printDebug(() -> "newShortsVideoStarted: " + newlyLoadedVideoId); + } + } + + /** + * Injection point. + */ + public static void newShortsVideoStarted(@NonNull String newlyLoadedChannelId, @NonNull String newlyLoadedChannelName, + @NonNull String newlyLoadedVideoId, @NonNull String newlyLoadedVideoTitle, + final long newlyLoadedVideoLength, boolean newlyLoadedLiveStreamValue) { + channelIdShorts = newlyLoadedChannelId; + videoIdShorts = newlyLoadedVideoId; + isLiveStreamShorts = newlyLoadedLiveStreamValue; + + Logger.printInfo(() -> "newShortsVideoStarted: " + newlyLoadedVideoId); } /** @@ -65,17 +99,34 @@ public class PlaybackSpeedPatch { /** * Injection point. */ - public static float getPlaybackSpeedInShorts(final float playbackSpeed) { - if (VideoInformation.lastPlayerResponseIsShort() && - Settings.ENABLE_DEFAULT_PLAYBACK_SPEED_SHORTS.get() - ) { - float defaultPlaybackSpeed = getDefaultPlaybackSpeed(VideoInformation.getChannelId(), null); - Logger.printDebug(() -> "overridePlaybackSpeed in Shorts: " + defaultPlaybackSpeed); + public static float getPlaybackSpeed(float playbackSpeed) { + boolean isShorts = isShorts(); + String currentChannelId = isShorts ? channelIdShorts : channelId; + String currentVideoId = isShorts ? videoIdShorts : videoId; + boolean currentVideoIsLiveStream = isShorts ? isLiveStreamShorts : isLiveStream; + boolean currentVideoIsWhitelisted = Whitelist.isChannelWhitelistedPlaybackSpeed(currentChannelId); + boolean currentVideoIsMusic = !isShorts && isMusic(); - return defaultPlaybackSpeed; + if (currentVideoIsLiveStream || currentVideoIsWhitelisted || currentVideoIsMusic) { + Logger.printDebug(() -> "changing playback speed to: 1.0"); + VideoInformation.setPlaybackSpeed(1.0f); + return 1.0f; } - return playbackSpeed; + float defaultPlaybackSpeed = isShorts ? DEFAULT_PLAYBACK_SPEED_SHORTS.get() : DEFAULT_PLAYBACK_SPEED.get(); + + if (defaultPlaybackSpeed < 0) { + float finalPlaybackSpeed = isShorts ? playbackSpeed : lastSelectedPlaybackSpeed; + VideoInformation.overridePlaybackSpeed(finalPlaybackSpeed); + Logger.printDebug(() -> "changing playback speed to: " + finalPlaybackSpeed); + return finalPlaybackSpeed; + } else { + if (isShorts) { + VideoInformation.setPlaybackSpeed(defaultPlaybackSpeed); + } + Logger.printDebug(() -> "changing playback speed to: " + defaultPlaybackSpeed); + return defaultPlaybackSpeed; + } } /** @@ -86,51 +137,61 @@ public class PlaybackSpeedPatch { */ public static void userSelectedPlaybackSpeed(float playbackSpeed) { try { - if (PatchStatus.RememberPlaybackSpeed() && - Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.get()) { - // With the 0.05x menu, if the speed is set by integrations to higher than 2.0x - // then the menu will allow increasing without bounds but the max speed is - // still capped to under 8.0x. - playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f); + boolean isShorts = isShorts(); + if (PatchStatus.RememberPlaybackSpeed()) { + BooleanSetting rememberPlaybackSpeedLastSelectedSetting = isShorts + ? Settings.REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED + : Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED; + FloatSetting playbackSpeedSetting = isShorts + ? DEFAULT_PLAYBACK_SPEED_SHORTS + : DEFAULT_PLAYBACK_SPEED; + BooleanSetting showToastSetting = isShorts + ? Settings.REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED_TOAST + : Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_TOAST; - // Prevent toast spamming if using the 0.05x adjustments. - // Show exactly one toast after the user stops interacting with the speed menu. - final long now = System.currentTimeMillis(); - lastTimeSpeedChanged = now; + if (rememberPlaybackSpeedLastSelectedSetting.get()) { + // With the 0.05x menu, if the speed is set by integrations to higher than 2.0x + // then the menu will allow increasing without bounds but the max speed is + // still capped to under 8.0x. + playbackSpeed = Math.min(playbackSpeed, CustomPlaybackSpeedPatch.PLAYBACK_SPEED_MAXIMUM - 0.05f); - final float finalPlaybackSpeed = playbackSpeed; - Utils.runOnMainThreadDelayed(() -> { - if (lastTimeSpeedChanged != now) { - // The user made additional speed adjustments and this call is outdated. - return; - } + // Prevent toast spamming if using the 0.05x adjustments. + // Show exactly one toast after the user stops interacting with the speed menu. + final long now = System.currentTimeMillis(); + lastTimeSpeedChanged = now; - if (Settings.DEFAULT_PLAYBACK_SPEED.get() == finalPlaybackSpeed) { - // User changed to a different speed and immediately changed back. - // Or the user is going past 8.0x in the glitched out 0.05x menu. - return; - } - Settings.DEFAULT_PLAYBACK_SPEED.save(finalPlaybackSpeed); + final float finalPlaybackSpeed = playbackSpeed; + Utils.runOnMainThreadDelayed(() -> { + if (lastTimeSpeedChanged != now) { + // The user made additional speed adjustments and this call is outdated. + return; + } + if (playbackSpeedSetting.get() == finalPlaybackSpeed) { + // User changed to a different speed and immediately changed back. + // Or the user is going past 8.0x in the glitched out 0.05x menu. + return; + } + playbackSpeedSetting.save(finalPlaybackSpeed); - if (!Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_TOAST.get()) { - return; - } - Utils.showToastShort(str("revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x"))); - }, TOAST_DELAY_MILLISECONDS); + if (showToastSetting.get()) { + Utils.showToastShort(str(isShorts ? "revanced_remember_playback_speed_toast_shorts" : "revanced_remember_playback_speed_toast", (finalPlaybackSpeed + "x"))); + } + }, TOAST_DELAY_MILLISECONDS); + } + } else if (!isShorts){ + lastSelectedPlaybackSpeed = playbackSpeed; } } catch (Exception ex) { Logger.printException(() -> "userSelectedPlaybackSpeed failure", ex); } } - private static float getDefaultPlaybackSpeed(@NonNull String channelId, @Nullable String videoId) { - return (isLiveStream || Whitelist.isChannelWhitelistedPlaybackSpeed(channelId) || isMusic(videoId)) - ? 1.0f - : Settings.DEFAULT_PLAYBACK_SPEED.get(); + private static boolean isShorts() { + return !ShortsPlayerState.getCurrent().isClosed(); } - private static boolean isMusic(@Nullable String videoId) { - if (DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC && videoId != null) { + private static boolean isMusic() { + if (DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC && !videoId.isEmpty()) { try { MusicRequest request = MusicRequest.getRequestForVideoId(videoId); final boolean isMusic = request != null && BooleanUtils.toBoolean(request.getStream()); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java index 45d84038c..d4769d084 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java @@ -9,13 +9,16 @@ import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.shared.PlayerType; +import app.revanced.extension.youtube.shared.ShortsPlayerState; import app.revanced.extension.youtube.shared.VideoInformation; @SuppressWarnings("unused") public class VideoQualityPatch { private static final int DEFAULT_YOUTUBE_VIDEO_QUALITY = -2; - private static final IntegerSetting mobileQualitySetting = Settings.DEFAULT_VIDEO_QUALITY_MOBILE; - private static final IntegerSetting wifiQualitySetting = Settings.DEFAULT_VIDEO_QUALITY_WIFI; + private static final IntegerSetting shortsQualityMobile = Settings.DEFAULT_VIDEO_QUALITY_MOBILE_SHORTS; + private static final IntegerSetting shortsQualityWifi = Settings.DEFAULT_VIDEO_QUALITY_WIFI_SHORTS; + private static final IntegerSetting videoQualityMobile = Settings.DEFAULT_VIDEO_QUALITY_MOBILE; + private static final IntegerSetting videoQualityWifi = Settings.DEFAULT_VIDEO_QUALITY_WIFI; @NonNull public static String videoId = ""; @@ -35,12 +38,11 @@ public class VideoQualityPatch { public static void newVideoStarted(@NonNull String newlyLoadedChannelId, @NonNull String newlyLoadedChannelName, @NonNull String newlyLoadedVideoId, @NonNull String newlyLoadedVideoTitle, final long newlyLoadedVideoLength, boolean newlyLoadedLiveStreamValue) { - if (PlayerType.getCurrent() == PlayerType.INLINE_MINIMAL) - return; - if (videoId.equals(newlyLoadedVideoId)) - return; - videoId = newlyLoadedVideoId; - setVideoQuality(Settings.SKIP_PRELOADED_BUFFER.get() ? 250 : 750); + if (PlayerType.getCurrent() != PlayerType.INLINE_MINIMAL && + !videoId.equals(newlyLoadedVideoId)) { + videoId = newlyLoadedVideoId; + setVideoQuality(750); + } } /** @@ -53,42 +55,67 @@ public class VideoQualityPatch { ); } - private static void setVideoQuality(final long delayMillis) { - final int defaultQuality = Utils.getNetworkType() == Utils.NetworkType.MOBILE - ? mobileQualitySetting.get() - : wifiQualitySetting.get(); + private static void setVideoQuality(long delayMillis) { + boolean isShorts = isShorts(); + IntegerSetting defaultQualitySetting = Utils.getNetworkType() == Utils.NetworkType.MOBILE + ? isShorts ? shortsQualityMobile : videoQualityMobile + : isShorts ? shortsQualityWifi : videoQualityWifi; - if (defaultQuality == DEFAULT_YOUTUBE_VIDEO_QUALITY) - return; + int defaultQuality = defaultQualitySetting.get(); - Utils.runOnMainThreadDelayed(() -> { - final int qualityToUseFinal = VideoInformation.getAvailableVideoQuality(defaultQuality); - Logger.printDebug(() -> "Changing video quality to: " + qualityToUseFinal); - VideoInformation.overrideVideoQuality(qualityToUseFinal); - }, delayMillis - ); + if (defaultQuality != DEFAULT_YOUTUBE_VIDEO_QUALITY) { + Utils.runOnMainThreadDelayed(() -> { + final int qualityToUseFinal = VideoInformation.getAvailableVideoQuality(defaultQuality); + Logger.printDebug(() -> "Changing video quality to: " + qualityToUseFinal); + VideoInformation.overrideVideoQuality(qualityToUseFinal); + }, delayMillis + ); + } } private static void userSelectedVideoQuality(final int defaultQuality) { - if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) - return; - if (defaultQuality == DEFAULT_YOUTUBE_VIDEO_QUALITY) - return; + if (defaultQuality != DEFAULT_YOUTUBE_VIDEO_QUALITY) { + boolean isShorts = isShorts(); + final Utils.NetworkType networkType = Utils.getNetworkType(); + String networkTypeMessage = networkType == Utils.NetworkType.MOBILE + ? str("revanced_remember_video_quality_mobile") + : str("revanced_remember_video_quality_wifi"); - final Utils.NetworkType networkType = Utils.getNetworkType(); + if (isShorts) { + if (Settings.REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED.get()) { + IntegerSetting defaultQualitySetting = networkType == Utils.NetworkType.MOBILE + ? shortsQualityMobile + : shortsQualityWifi; - switch (networkType) { - case NONE -> { - Utils.showToastShort(str("revanced_remember_video_quality_none")); - return; + defaultQualitySetting.save(defaultQuality); + + if (Settings.REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED_TOAST.get()) { + Utils.showToastShort(str( + "revanced_remember_video_quality_toast_shorts", + networkTypeMessage, (defaultQuality + "p") + )); + } + } + } else { + if (Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) { + IntegerSetting defaultQualitySetting = networkType == Utils.NetworkType.MOBILE + ? videoQualityMobile + : videoQualityWifi; + + defaultQualitySetting.save(defaultQuality); + + if (Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST.get()) { + Utils.showToastShort(str( + "revanced_remember_video_quality_toast", + networkTypeMessage, (defaultQuality + "p") + )); + } + } } - case MOBILE -> mobileQualitySetting.save(defaultQuality); - default -> wifiQualitySetting.save(defaultQuality); } + } - if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST.get()) - return; - - Utils.showToastShort(str("revanced_remember_video_quality_" + networkType.getName(), defaultQuality + "p")); + private static boolean isShorts() { + return !ShortsPlayerState.getCurrent().isClosed(); } } \ No newline at end of file diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index ae6f3fea3..da959b002 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -498,12 +498,13 @@ public class Settings extends BaseSettings { public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL = new BooleanSetting("revanced_shorts_custom_actions_copy_video_url", FALSE, true); public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER = new BooleanSetting("revanced_shorts_custom_actions_external_downloader", FALSE, true); public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO = new BooleanSetting("revanced_shorts_custom_actions_open_video", FALSE, true); + public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG = new BooleanSetting("revanced_shorts_custom_actions_speed_dialog", FALSE, true); public static final BooleanSetting SHORTS_CUSTOM_ACTIONS_REPEAT_STATE = new BooleanSetting("revanced_shorts_custom_actions_repeat_state", FALSE, true); public static final BooleanSetting ENABLE_SHORTS_CUSTOM_ACTIONS_FLYOUT_MENU = new BooleanSetting("revanced_enable_shorts_custom_actions_flyout_menu", FALSE, true, - parentsAny(SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL, SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL_TIMESTAMP, SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER, SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO, SHORTS_CUSTOM_ACTIONS_REPEAT_STATE)); + parentsAny(SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL, SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL_TIMESTAMP, SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER, SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO, SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG, SHORTS_CUSTOM_ACTIONS_REPEAT_STATE)); public static final BooleanSetting ENABLE_SHORTS_CUSTOM_ACTIONS_TOOLBAR = new BooleanSetting("revanced_enable_shorts_custom_actions_toolbar", FALSE, true, - parentsAny(SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL, SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL_TIMESTAMP, SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER, SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO, SHORTS_CUSTOM_ACTIONS_REPEAT_STATE)); + parentsAny(SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL, SHORTS_CUSTOM_ACTIONS_COPY_VIDEO_URL_TIMESTAMP, SHORTS_CUSTOM_ACTIONS_EXTERNAL_DOWNLOADER, SHORTS_CUSTOM_ACTIONS_OPEN_VIDEO, SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG, SHORTS_CUSTOM_ACTIONS_REPEAT_STATE)); // Experimental Flags public static final BooleanSetting ENABLE_TIME_STAMP = new BooleanSetting("revanced_enable_shorts_time_stamp", FALSE, true); @@ -550,30 +551,38 @@ public class Settings extends BaseSettings { public static final FloatSetting SWIPE_BRIGHTNESS_VALUE = new FloatSetting("revanced_swipe_brightness_value", -1.0f, false, false); - // PreferenceScreen: Video - public static final FloatSetting DEFAULT_PLAYBACK_SPEED = new FloatSetting("revanced_default_playback_speed", -2.0f); - public static final IntegerSetting DEFAULT_VIDEO_QUALITY_MOBILE = new IntegerSetting("revanced_default_video_quality_mobile", -2); - public static final IntegerSetting DEFAULT_VIDEO_QUALITY_WIFI = new IntegerSetting("revanced_default_video_quality_wifi", -2); + // PreferenceScreen: Video - Codec public static final BooleanSetting DISABLE_HDR_VIDEO = new BooleanSetting("revanced_disable_hdr_video", FALSE, true); + public static final BooleanSetting DISABLE_VP9_CODEC = new BooleanSetting("revanced_disable_vp9_codec", FALSE, true); + public static final BooleanSetting REPLACE_AV1_CODEC = new BooleanSetting("revanced_replace_av1_codec", FALSE, true); + + // PreferenceScreen: Video - Playback speed + public static final FloatSetting DEFAULT_PLAYBACK_SPEED = new FloatSetting("revanced_default_playback_speed", -2.0f); + public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", TRUE); + public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_playback_speed_last_selected_toast", TRUE, parent(REMEMBER_PLAYBACK_SPEED_LAST_SELECTED)); + public static final FloatSetting DEFAULT_PLAYBACK_SPEED_SHORTS = new FloatSetting("revanced_default_playback_speed_shorts", -2.0f); + public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_shorts_last_selected", TRUE); + public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_playback_speed_shorts_last_selected_toast", TRUE, parent(REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED)); public static final BooleanSetting ENABLE_CUSTOM_PLAYBACK_SPEED = new BooleanSetting("revanced_enable_custom_playback_speed", FALSE, true); public static final BooleanSetting CUSTOM_PLAYBACK_SPEED_MENU_TYPE = new BooleanSetting("revanced_custom_playback_speed_menu_type", FALSE, parent(ENABLE_CUSTOM_PLAYBACK_SPEED)); public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds", "0.25\n0.5\n0.75\n1.0\n1.25\n1.5\n1.75\n2.0\n2.25\n2.5", true, parent(ENABLE_CUSTOM_PLAYBACK_SPEED)); - public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", TRUE); - public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_playback_speed_last_selected_toast", TRUE, parent(REMEMBER_PLAYBACK_SPEED_LAST_SELECTED)); + + // PreferenceScreen: Video - Video quality + public static final IntegerSetting DEFAULT_VIDEO_QUALITY_MOBILE = new IntegerSetting("revanced_default_video_quality_mobile", -2); + public static final IntegerSetting DEFAULT_VIDEO_QUALITY_WIFI = new IntegerSetting("revanced_default_video_quality_wifi", -2); public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", TRUE); public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_video_quality_last_selected_toast", TRUE, parent(REMEMBER_VIDEO_QUALITY_LAST_SELECTED)); + public static final IntegerSetting DEFAULT_VIDEO_QUALITY_MOBILE_SHORTS = new IntegerSetting("revanced_default_video_quality_mobile_shorts", -2, true); + public static final IntegerSetting DEFAULT_VIDEO_QUALITY_WIFI_SHORTS = new IntegerSetting("revanced_default_video_quality_wifi_shorts", -2, true); + public static final BooleanSetting REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_shorts_last_selected", TRUE); + public static final BooleanSetting REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED_TOAST = new BooleanSetting("revanced_remember_video_quality_shorts_last_selected_toast", TRUE, parent(REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED)); public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE, true); - // Experimental Flags - public static final BooleanSetting DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC = new BooleanSetting("revanced_disable_default_playback_speed_music", FALSE, true); - public static final BooleanSetting DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC_TYPE = new BooleanSetting("revanced_disable_default_playback_speed_music_type", FALSE, true, parent(DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC)); - public static final BooleanSetting ENABLE_DEFAULT_PLAYBACK_SPEED_SHORTS = new BooleanSetting("revanced_enable_default_playback_speed_shorts", FALSE); public static final BooleanSetting SKIP_PRELOADED_BUFFER = new BooleanSetting("revanced_skip_preloaded_buffer", FALSE, true, "revanced_skip_preloaded_buffer_user_dialog_message"); public static final BooleanSetting SKIP_PRELOADED_BUFFER_TOAST = new BooleanSetting("revanced_skip_preloaded_buffer_toast", TRUE); public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true); - public static final BooleanSetting DISABLE_VP9_CODEC = new BooleanSetting("revanced_disable_vp9_codec", FALSE, true); - public static final BooleanSetting REPLACE_AV1_CODEC = new BooleanSetting("revanced_replace_av1_codec", FALSE, true); - public static final BooleanSetting REJECT_AV1_CODEC = new BooleanSetting("revanced_reject_av1_codec", FALSE, true); + public static final BooleanSetting DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC = new BooleanSetting("revanced_disable_default_playback_speed_music", FALSE, true); + public static final BooleanSetting DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC_TYPE = new BooleanSetting("revanced_disable_default_playback_speed_music_type", FALSE, true, parent(DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC)); // PreferenceScreen: Miscellaneous public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index 34ebdb184..d183dbae2 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -10,6 +10,7 @@ import static app.revanced.extension.shared.utils.Utils.getChildView; import static app.revanced.extension.shared.utils.Utils.isSDKAbove; import static app.revanced.extension.shared.utils.Utils.showToastShort; import static app.revanced.extension.youtube.settings.Settings.DEFAULT_PLAYBACK_SPEED; +import static app.revanced.extension.youtube.settings.Settings.DEFAULT_PLAYBACK_SPEED_SHORTS; import static app.revanced.extension.youtube.settings.Settings.HIDE_PREVIEW_COMMENT; import static app.revanced.extension.youtube.settings.Settings.HIDE_PREVIEW_COMMENT_TYPE; @@ -119,7 +120,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { } else { Setting.privateSetValueFromString(setting, listPreference.getValue()); } - if (setting.equals(DEFAULT_PLAYBACK_SPEED)) { + if (setting.equals(DEFAULT_PLAYBACK_SPEED) || setting.equals(DEFAULT_PLAYBACK_SPEED_SHORTS)) { listPreference.setEntries(CustomPlaybackSpeedPatch.getEntries()); listPreference.setEntryValues(CustomPlaybackSpeedPatch.getEntryValues()); } @@ -310,7 +311,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { } else if (preference instanceof EditTextPreference editTextPreference) { editTextPreference.setText(setting.get().toString()); } else if (preference instanceof ListPreference listPreference) { - if (setting.equals(DEFAULT_PLAYBACK_SPEED)) { + if (setting.equals(DEFAULT_PLAYBACK_SPEED) || setting.equals(DEFAULT_PLAYBACK_SPEED_SHORTS)) { listPreference.setEntries(CustomPlaybackSpeedPatch.getEntries()); listPreference.setEntryValues(CustomPlaybackSpeedPatch.getEntryValues()); } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java index dfd02e7a7..e4cc256bf 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedSettingsPreference.java @@ -46,6 +46,7 @@ public class ReVancedSettingsPreference extends ReVancedPreferenceFragment { NavigationPreferenceLinks(); RYDPreferenceLinks(); SeekBarPreferenceLinks(); + ShortsPreferenceLinks(); SpeedOverlayPreferenceLinks(); QuickActionsPreferenceLinks(); TabletLayoutLinks(); @@ -186,6 +187,19 @@ public class ReVancedSettingsPreference extends ReVancedPreferenceFragment { ); } + /** + * Enable/Disable Preference related to Shorts settings + */ + private static void ShortsPreferenceLinks() { + if (!PatchStatus.RememberPlaybackSpeed()) { + enableDisablePreferences( + true, + Settings.SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG + ); + Settings.SHORTS_CUSTOM_ACTIONS_SPEED_DIALOG.save(false); + } + } + /** * Enable/Disable Preference related to Speed overlay settings */ diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java index 9df7bb1f6..6d8d407c4 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/VideoUtils.java @@ -202,6 +202,7 @@ public class VideoUtils extends IntentUtils { new AlertDialog.Builder(context) .setSingleChoiceItems(playbackSpeedEntries, index, (mDialog, mIndex) -> { final float selectedPlaybackSpeed = Float.parseFloat(playbackSpeedEntryValues[mIndex] + "f"); + VideoInformation.setPlaybackSpeed(selectedPlaybackSpeed); VideoInformation.overridePlaybackSpeed(selectedPlaybackSpeed); userSelectedPlaybackSpeed(selectedPlaybackSpeed); mDialog.dismiss(); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt index 52683bdd5..824364d2b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/information/VideoInformationPatch.kt @@ -5,7 +5,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction -import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableClass @@ -26,6 +25,7 @@ import app.revanced.patches.youtube.video.playerresponse.playerResponseMethodHoo import app.revanced.patches.youtube.video.videoid.hookPlayerResponseVideoId import app.revanced.patches.youtube.video.videoid.hookVideoId import app.revanced.patches.youtube.video.videoid.videoIdPatch +import app.revanced.util.addInstructionsAtControlFlowLabel import app.revanced.util.addStaticFieldToExtension import app.revanced.util.cloneMutable import app.revanced.util.findMethodOrThrow @@ -94,6 +94,8 @@ private var mdxConstructorInsertIndex = -1 private lateinit var videoTimeConstructorMethod: MutableMethod private var videoTimeConstructorInsertIndex = 2 +private lateinit var setPlaybackSpeedMethodReference: MethodReference + // Used by other patches. internal lateinit var speedSelectionInsertMethod: MutableMethod internal lateinit var videoEndMethod: MutableMethod @@ -396,12 +398,13 @@ val videoInformationPatch = bytecodePatch( Opcode.IGET_OBJECT ) val setPlaybackSpeedContainerClassFieldReference = - getInstruction(setPlaybackSpeedContainerClassFieldIndex).reference.toString() + getInstruction(setPlaybackSpeedContainerClassFieldIndex).reference val setPlaybackSpeedClassFieldReference = - getInstruction(speedSelectionValueInstructionIndex + 1).reference.toString() - val setPlaybackSpeedMethodReference = - getInstruction(speedSelectionValueInstructionIndex + 2).reference.toString() + getInstruction(speedSelectionValueInstructionIndex + 1).reference + + setPlaybackSpeedMethodReference = + getInstruction(speedSelectionValueInstructionIndex + 2).reference as MethodReference // add override playback speed method it.classDef.methods.add( @@ -450,41 +453,93 @@ val videoInformationPatch = bytecodePatch( } } - playbackSpeedClassFingerprint.matchOrThrow().let { result -> - result.method.apply { - val index = result.patternMatch!!.endIndex - val register = getInstruction(index).registerA - val playbackSpeedClass = this.returnType - - // set playback speed class - replaceInstruction( - index, - "sput-object v$register, $EXTENSION_CLASS_DESCRIPTOR->playbackSpeedClass:$playbackSpeedClass" - ) - addInstruction( - index + 1, - "return-object v$register" - ) + videoIdFingerprintShorts.matchOrThrow().let { + it.method.apply { + val shortsPlaybackSpeedClassField = it.classDef.fields.find { field -> + field.type == setPlaybackSpeedMethodReference.definingClass + } ?: throw PatchException("Failed to find hook field") val smaliInstructions = """ if-eqz v0, :ignore - invoke-virtual {v0, p0}, $playbackSpeedClass->overridePlaybackSpeed(F)V + invoke-virtual {v0, p0}, $definingClass->overridePlaybackSpeed(F)V :ignore return-void - """ + """ addStaticFieldToExtension( EXTENSION_CLASS_DESCRIPTOR, "overridePlaybackSpeed", - "playbackSpeedClass", - playbackSpeedClass, - smaliInstructions, - false + "playbackSpeedShortsClass", + definingClass, + smaliInstructions + ) + + // add override playback speed method + it.classDef.methods.add( + ImmutableMethod( + definingClass, + "overridePlaybackSpeed", + listOf(ImmutableMethodParameter("F", annotations, null)), + "V", + AccessFlags.PUBLIC or AccessFlags.PUBLIC, + annotations, + null, + ImmutableMethodImplementation( + 3, """ + # Check if the playback speed is not auto (-2.0f) + const/4 v0, 0x0 + cmpg-float v0, v2, v0 + if-lez v0, :ignore + + # Get the container class field. + iget-object v0, v1, $shortsPlaybackSpeedClassField + + # For some reason, in YouTube 19.44.39 this value is sometimes null. + if-eqz v0, :ignore + + # Invoke setPlaybackSpeed on that class. + invoke-virtual {v0, v2}, $setPlaybackSpeedMethodReference + + :ignore + return-void + """.toInstructions(), null, null + ) + ).toMutable() ) } } + playbackSpeedClassFingerprint.methodOrThrow().apply { + val index = indexOfFirstInstructionOrThrow(Opcode.RETURN_OBJECT) + val register = getInstruction(index).registerA + val playbackSpeedClass = this.returnType + + // set playback speed class + addInstructionsAtControlFlowLabel( + index, + "sput-object v$register, $EXTENSION_CLASS_DESCRIPTOR->playbackSpeedClass:$playbackSpeedClass" + ) + + val smaliInstructions = + """ + if-eqz v0, :ignore + invoke-virtual {v0, p0}, $playbackSpeedClass->overridePlaybackSpeed(F)V + return-void + :ignore + nop + """ + + addStaticFieldToExtension( + EXTENSION_CLASS_DESCRIPTOR, + "overridePlaybackSpeed", + "playbackSpeedClass", + playbackSpeedClass, + smaliInstructions, + false + ) + } + /** * Hook current video quality */ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt index 0b8282018..53abb9489 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/Fingerprints.kt @@ -20,29 +20,6 @@ internal val av1CodecFingerprint = legacyFingerprint( } ) -internal val byteBufferArrayFingerprint = legacyFingerprint( - name = "byteBufferArrayFingerprint", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - returnType = "I", - parameters = emptyList(), - opcodes = listOf( - Opcode.SHL_INT_LIT8, - Opcode.SHL_INT_LIT8, - Opcode.OR_INT_2ADDR, - Opcode.SHL_INT_LIT8, - Opcode.OR_INT_2ADDR, - Opcode.OR_INT_2ADDR, - Opcode.RETURN - ) -) - -internal val byteBufferArrayParentFingerprint = legacyFingerprint( - name = "byteBufferArrayParentFingerprint", - accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL, - returnType = "C", - parameters = listOf("Ljava/nio/charset/Charset;", "[C") -) - internal val deviceDimensionsModelToStringFingerprint = legacyFingerprint( name = "deviceDimensionsModelToStringFingerprint", returnType = "L", @@ -77,17 +54,26 @@ internal val playbackSpeedChangedFromRecyclerViewFingerprint = legacyFingerprint } ) -internal val playbackSpeedInitializeFingerprint = legacyFingerprint( - name = "playbackSpeedInitializeFingerprint", - returnType = "F", - accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC, +internal val loadVideoParamsFingerprint = legacyFingerprint( + name = "loadVideoParamsFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, parameters = listOf("L"), opcodes = listOf( - Opcode.IGET, - Opcode.RETURN + Opcode.INVOKE_INTERFACE, + Opcode.MOVE_RESULT, + Opcode.IPUT, + Opcode.INVOKE_INTERFACE, ) ) +internal val loadVideoParamsParentFingerprint = legacyFingerprint( + name = "loadVideoParamsParentFingerprint", + returnType = "Z", + parameters = listOf("J"), + strings = listOf("LoadVideoParams.playerListener = null") +) + internal val qualityChangedFromRecyclerViewFingerprint = legacyFingerprint( name = "qualityChangedFromRecyclerViewFingerprint", returnType = "L", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt index 895d7b505..41ed6bdcd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt @@ -24,8 +24,8 @@ import app.revanced.patches.youtube.utils.recyclerview.recyclerViewTreeObserverP import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference import app.revanced.patches.youtube.utils.settings.settingsPatch -import app.revanced.patches.youtube.utils.videoEndFingerprint import app.revanced.patches.youtube.video.information.hookBackgroundPlayVideoInformation +import app.revanced.patches.youtube.video.information.hookShortsVideoInformation import app.revanced.patches.youtube.video.information.hookVideoInformation import app.revanced.patches.youtube.video.information.onCreateHook import app.revanced.patches.youtube.video.information.speedSelectionInsertMethod @@ -44,6 +44,7 @@ import app.revanced.util.indexOfFirstStringInstructionOrThrow import app.revanced.util.updatePatchStatus import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference @@ -158,21 +159,30 @@ val videoPlaybackPatch = bytecodePatch( } } - playbackSpeedInitializeFingerprint.matchOrThrow(videoEndFingerprint).let { + loadVideoParamsFingerprint.matchOrThrow(loadVideoParamsParentFingerprint).let { it.method.apply { - val insertIndex = it.patternMatch!!.endIndex - val insertRegister = getInstruction(insertIndex).registerA + val targetIndex = it.patternMatch!!.endIndex + val targetReference = getInstruction(targetIndex).reference as MethodReference - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->getPlaybackSpeedInShorts(F)F - move-result v$insertRegister - """ - ) + findMethodOrThrow(definingClass) { + name == targetReference.name + }.apply { + val insertIndex = implementation!!.instructions.lastIndex + val insertRegister = getInstruction(insertIndex).registerA + + addInstructions( + insertIndex, """ + invoke-static {v$insertRegister}, $EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->getPlaybackSpeed(F)F + move-result v$insertRegister + """ + ) + } } } hookBackgroundPlayVideoInformation("$EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V") + hookShortsVideoInformation("$EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->newShortsVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V") + hookVideoInformation("$EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->newVideoStarted(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JZ)V") hookPlayerResponseVideoId("$EXTENSION_PLAYBACK_SPEED_CLASS_DESCRIPTOR->fetchMusicRequest(Ljava/lang/String;Z)V") updatePatchStatus(PATCH_STATUS_CLASS_DESCRIPTOR, "RememberPlaybackSpeed") @@ -294,25 +304,6 @@ val videoPlaybackPatch = bytecodePatch( settingArray += "SETTINGS: REPLACE_AV1_CODEC" } - // reject av1 codec response - - byteBufferArrayFingerprint.matchOrThrow(byteBufferArrayParentFingerprint).let { - it.method.apply { - val insertIndex = it.patternMatch!!.endIndex - val insertRegister = - getInstruction(insertIndex).registerA - - addInstructions( - insertIndex, """ - invoke-static {v$insertRegister}, $EXTENSION_AV1_CODEC_CLASS_DESCRIPTOR->rejectResponse(I)I - move-result v$insertRegister - """ - ) - } - } - - // endregion - // region patch for disable VP9 codec vp9CapabilityFingerprint.methodOrThrow().apply { diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 0b04f7072..783bc9185 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -1646,6 +1646,10 @@ Press and hold the More button to show the Custom actions dialog." Show open video menu Open video menu is shown. Open video menu is hidden. + Speed dialog + Show speed dialog menu + Speed dialog menu is shown. + Speed dialog menu is hidden. Repeat state Show repeat state menu Repeat state menu is shown. @@ -1763,12 +1767,45 @@ No margins on top and bottom of player." Video - Default playback speed - Default video quality on mobile network - Default video quality on Wi-Fi network + + Codec Disable HDR video HDR video is disabled. HDR video is enabled. + Disable VP9 codec + "VP9 codec is disabled. + +Info: +• Maximum resolution is 1080p. +• Video playback will use more internet data than VP9. +• VP9 codec is still used for HDR video." + VP9 codec is enabled. + Replace software AV1 codec + Replaces the software AV1 codec with the VP9 codec. + + + Playback speed + Default playback speed + Remember playback speed changes + Playback speed changes apply to all videos. + Playback speed changes only apply to the current video. + Show a toast + A toast will be shown when changing the default playback speed. + A toast will not be shown when changing the default playback speed. + + Default playback speed on Shorts + Remember playback speed changes on Shorts + "Playback speed changes apply to all Shorts. + +Info: +• The only way to change the playback speed in the Shorts player is to use the 'Speed ​​dialog' in 'Custom actions'. +• If you didn't include the 'Shorts components' patch, this wouldn't be available." + Playback speed changes only apply to the current Short. + Show a toast + A toast will be shown when changing the default playback speed on Shorts. + A toast will not be shown when changing the default playback speed on Shorts. + Changed default playback speed to: %s. + Changed default Shorts playback speed to: %s. Enable custom playback speed Custom playback speed is enabled. Custom playback speed is disabled. @@ -1777,30 +1814,34 @@ No margins on top and bottom of player." Old style flyout menu is used. Edit custom playback speeds Add or change available playback speeds. - Remember playback speed changes - Playback speed changes apply to all videos. - Playback speed changes only apply to the current video. - Show a toast - A toast will be shown when changing the default playback speed. - A toast will not be shown when changing the default playback speed. + Custom speeds must be less than %sx. + Invalid custom playback speeds. + + + Video quality + Default video quality on mobile network + Default video quality on Wi-Fi network Remember video quality changes Quality changes apply to all videos. Quality changes only apply to the current video. Show a toast A toast will be shown when changing the default video quality. A toast will not be shown when changing the default video quality. + Default Shorts quality on mobile network + Default Shorts quality on Wi-Fi network + Remember Shorts quality changes + Quality changes apply to all Shorts. + Quality changes only apply to the current Short. + Show a toast + A toast will be shown when changing the default Shorts quality. + A toast will not be shown when changing the default Shorts quality. + mobile + wifi + Changed default %1$s quality to: %2$s. + Changed Shorts %1$s quality to: %2$s. Restore old video quality menu Old video quality menu is shown. Old video quality menu is not shown. - Disable playback speed for music - Default playback speed is disabled for music. - Default playback speed is enabled for music. - Validate using categories - Default playback speed is disabled if the video category is Music. - Default playback speed is disabled for videos playable on YouTube Music. - Enable Shorts default playback speed - Default playback speed applies to Shorts. - Default playback speed does not apply to Shorts. Skipped preloaded buffer. Skip preloaded buffer "Skips the preloaded buffer at the start of videos to immediately apply the default video quality. @@ -1814,26 +1855,18 @@ Info: Toast is not shown. Spoof device dimensions "Spoofs the device dimensions to the maximum value. -High quality may be unlocked on some videos that require high device dimensions, but not all videos." - Disable VP9 codec - "VP9 codec is disabled. -• Maximum resolution is 1080p. -• Video playback will use more internet data than VP9. -• VP9 codec is still used for HDR video." - VP9 codec is enabled. - Replace software AV1 codec - Replaces the software AV1 codec with the VP9 codec. - Reject software AV1 codec response - "Forcefully rejects the software AV1 codec response. -A different codec will be applied after about 20 seconds of buffering." - Fallback process causes about 20 seconds of buffering. - Changing default speed to %s. - Changing default mobile data quality to %s. - Failed to set video quality. - Changing default Wi-Fi quality to %s. - Custom speeds must be less than %sx. - Invalid custom playback speeds. +Info: +• High quality may be unlocked on some videos that require high device dimensions, but not all videos. +• This setting is not available if 'Spoof streaming data' is turned on." + + + Disable playback speed for music + Default playback speed is disabled for music. + Default playback speed is enabled for music. + Validate using categories + Default playback speed is disabled if the video category is Music. + Default playback speed is disabled for videos playable on YouTube Music. diff --git a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml index f857250e9..3b906b092 100644 --- a/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/patches/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -639,6 +639,7 @@ + SETTINGS: SHORTS_CUSTOM_ACTIONS_SHARED --> @@ -730,32 +731,44 @@ From f0b1155d20c371654c4ce6e2160592a5e9b71bd5 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:36:39 +0900 Subject: [PATCH 46/77] fix(YouTube - Change form factor): No user dialog shown when changing settings --- .../ReVancedPreferenceFragment.java | 73 +++++++++++++------ 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index d183dbae2..af2864f36 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -65,6 +65,7 @@ import app.revanced.extension.shared.settings.EnumSetting; import app.revanced.extension.shared.settings.Setting; import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.ResourceUtils; +import app.revanced.extension.shared.utils.StringRef; import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.patches.video.CustomPlaybackSpeedPatch; import app.revanced.extension.youtube.settings.Settings; @@ -141,11 +142,8 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { if (!settingImportInProgress && !showingUserDialogMessage) { final Context context = getActivity(); - if (setting.userDialogMessage != null && - mPreference instanceof SwitchPreference switchPreference && - setting.defaultValue instanceof Boolean defaultValue && - switchPreference.isChecked() != defaultValue) { - showSettingUserDialogConfirmation(context, switchPreference, (BooleanSetting) setting); + if (setting.userDialogMessage != null && !prefIsSetToDefault(mPreference, setting)) { + showSettingUserDialogConfirmation(context, mPreference, setting); } else if (setting.rebootApp) { showRestartDialog(context); } @@ -155,25 +153,56 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { } }; - private void showSettingUserDialogConfirmation(Context context, SwitchPreference switchPreference, BooleanSetting setting) { + /** + * @return If the preference is currently set to the default value of the Setting. + */ + private boolean prefIsSetToDefault(Preference pref, Setting setting) { + Object defaultValue = setting.defaultValue; + if (pref instanceof SwitchPreference switchPref) { + return switchPref.isChecked() == (Boolean) defaultValue; + } + String defaultValueString = defaultValue.toString(); + if (pref instanceof EditTextPreference editPreference) { + return editPreference.getText().equals(defaultValueString); + } + if (pref instanceof ListPreference listPref) { + return listPref.getValue().equals(defaultValueString); + } + + throw new IllegalStateException("Must override method to handle " + + "preference type: " + pref.getClass()); + } + + private void showSettingUserDialogConfirmation(Context context, Preference pref, Setting setting) { Utils.verifyOnMainThread(); - showingUserDialogMessage = true; - assert setting.userDialogMessage != null; - new AlertDialog.Builder(context) - .setTitle(str("revanced_extended_confirm_user_dialog_title")) - .setMessage(setting.userDialogMessage.toString()) - .setPositiveButton(android.R.string.ok, (dialog, id) -> { - if (setting.rebootApp) { - showRestartDialog(context); - } - }) - .setNegativeButton(android.R.string.cancel, (dialog, id) -> { - switchPreference.setChecked(setting.defaultValue); // Recursive call that resets the Setting value. - }) - .setOnDismissListener(dialog -> showingUserDialogMessage = false) - .setCancelable(false) - .show(); + final StringRef userDialogMessage = setting.userDialogMessage; + if (context != null && userDialogMessage != null) { + showingUserDialogMessage = true; + + new AlertDialog.Builder(context) + .setTitle(str("revanced_extended_confirm_user_dialog_title")) + .setMessage(userDialogMessage.toString()) + .setPositiveButton(android.R.string.ok, (dialog, id) -> { + if (setting.rebootApp) { + showRestartDialog(context); + } + }) + .setNegativeButton(android.R.string.cancel, (dialog, id) -> { + // Restore whatever the setting was before the change. + if (setting instanceof BooleanSetting booleanSetting && + pref instanceof SwitchPreference switchPreference) { + switchPreference.setChecked(booleanSetting.defaultValue); + } else if (setting instanceof EnumSetting enumSetting && + pref instanceof ListPreference listPreference) { + listPreference.setValue(enumSetting.defaultValue.toString()); + updateListPreferenceSummary(listPreference, setting); + } + }) + .setOnDismissListener(dialog -> showingUserDialogMessage = false) + .setCancelable(false) + .show(); + } } static PreferenceManager mPreferenceManager; From 3e8c748f48c306ab8cfd836b686e68dfe12148f7 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:47:08 +0900 Subject: [PATCH 47/77] feat(YouTube): Add support version `20.03.45` https://github.com/inotia00/ReVanced_Extended/issues/2717#issuecomment-2760796211 --- .../general/toolbar/ToolBarComponentsPatch.kt | 65 +++++++++++++------ .../components/PlayerComponentsPatch.kt | 6 +- .../youtube/utils/compatibility/Constants.kt | 3 +- 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt index e701162e8..49753224d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/toolbar/ToolBarComponentsPatch.kt @@ -38,6 +38,7 @@ import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.fingerprint.mutableClassOrThrow import app.revanced.util.getReference import app.revanced.util.getWalkerMethod +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import app.revanced.util.replaceLiteralInstructionCall @@ -268,30 +269,54 @@ val toolBarComponentsPatch = bytecodePatch( createSearchSuggestionsFingerprint.methodOrThrow().apply { val iteratorIndex = indexOfIteratorInstruction(this) - val replaceIndex = indexOfFirstInstructionOrThrow(iteratorIndex) { + val replaceIndex = indexOfFirstInstruction(iteratorIndex) { opcode == Opcode.IGET_OBJECT && getReference()?.type == "Landroid/widget/ImageView;" } - val uriIndex = indexOfFirstInstructionOrThrow(replaceIndex) { - opcode == Opcode.INVOKE_STATIC && - getReference()?.toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" - } - val jumpIndex = indexOfFirstInstructionOrThrow(uriIndex, Opcode.CONST_4) - val replaceIndexInstruction = getInstruction(replaceIndex) - val freeRegister = replaceIndexInstruction.registerA - val classRegister = replaceIndexInstruction.registerB - val replaceIndexReference = - getInstruction(replaceIndex).reference + if (replaceIndex > -1) { + val uriIndex = indexOfFirstInstructionOrThrow(replaceIndex) { + opcode == Opcode.INVOKE_STATIC && + getReference()?.toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" + } + val jumpIndex = indexOfFirstInstructionOrThrow(uriIndex, Opcode.CONST_4) + val replaceIndexInstruction = getInstruction(replaceIndex) + val freeRegister = replaceIndexInstruction.registerA + val classRegister = replaceIndexInstruction.registerB + val replaceIndexReference = + getInstruction(replaceIndex).reference - addInstructionsWithLabels( - replaceIndex + 1, """ - invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail()Z - move-result v$freeRegister - if-nez v$freeRegister, :hidden - iget-object v$freeRegister, v$classRegister, $replaceIndexReference - """, ExternalLabel("hidden", getInstruction(jumpIndex)) - ) - removeInstruction(replaceIndex) + addInstructionsWithLabels( + replaceIndex + 1, """ + invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail()Z + move-result v$freeRegister + if-nez v$freeRegister, :hidden + iget-object v$freeRegister, v$classRegister, $replaceIndexReference + """, ExternalLabel("hidden", getInstruction(jumpIndex)) + ) + removeInstruction(replaceIndex) + } else { // only for YT 20.03 + val insertIndex = indexOfFirstInstructionOrThrow(iteratorIndex) { + opcode == Opcode.INVOKE_VIRTUAL && + getReference()?.toString() == "Landroid/widget/ImageView;->setVisibility(I)V" + } - 1 + if (getInstruction(insertIndex).opcode != Opcode.CONST_4) { + throw PatchException("Failed to find insert index") + } + val freeRegister = getInstruction(insertIndex).registerA + val uriIndex = indexOfFirstInstructionOrThrow(insertIndex) { + opcode == Opcode.INVOKE_STATIC && + getReference()?.toString() == "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" + } + val jumpIndex = indexOfFirstInstructionOrThrow(uriIndex, Opcode.CONST_4) + + addInstructionsWithLabels( + insertIndex, """ + invoke-static { }, $GENERAL_CLASS_DESCRIPTOR->hideSearchTermThumbnail()Z + move-result v$freeRegister + if-nez v$freeRegister, :hidden + """, ExternalLabel("hidden", getInstruction(jumpIndex)) + ) + } } if (is_19_16_or_greater) { diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt index c3c3b5b21..c6be90e33 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt @@ -634,8 +634,8 @@ val playerComponentsPatch = bytecodePatch( fingerprint.methodOrThrow(filmStripOverlayEnterParentFingerprint).hookFilmstripOverlay() } - // Removed in YouTube 20.05+ - if (!is_20_05_or_greater) { + // Removed in YouTube 20.03+ + if (!is_20_03_or_greater) { youtubeControlsOverlayFingerprint.methodOrThrow().apply { val constIndex = indexOfFirstLiteralInstructionOrThrow(fadeDurationFast) val constRegister = getInstruction(constIndex).registerA @@ -663,7 +663,7 @@ val playerComponentsPatch = bytecodePatch( ) removeInstruction(insertIndex) } - } else { + } else if (is_20_05_or_greater) { // This is a new film strip overlay added to YouTube 20.05+ // Disabling this flag is not related to the operation of the patch. filmStripOverlayConfigV2Fingerprint.injectLiteralInstructionBooleanCall( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt index f08e8b1d2..671f24067 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt @@ -13,7 +13,8 @@ internal object Constants { "19.16.39", // This is the last version where the 'Restore old seekbar thumbnails' setting works. "19.43.41", // This is the latest version where edge-to-edge display is not enforced on Android 15+. "19.44.39", // This is the only version that has experimental shortcut icons. - "19.47.53", // This is the latest version supported by the RVX patch. + "19.47.53", // This was the latest version supported by the previous RVX patch. + "20.03.45", // This is the latest version supported by the RVX patch. ) ) } \ No newline at end of file From af26cd58a88501896de884f905fa5b9813dfe82d Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:48:00 +0900 Subject: [PATCH 48/77] feat(Translations): Update translation --- .../music/translations/el-rGR/strings.xml | 1 + .../music/translations/it-rIT/strings.xml | 1 + .../music/translations/ko-rKR/strings.xml | 9 +- .../music/translations/pl-rPL/strings.xml | 1 + .../music/translations/ru-rRU/strings.xml | 1 + .../music/translations/uk-rUA/strings.xml | 1 + .../music/translations/vi-rVN/strings.xml | 1 + .../youtube/translations/ar/strings.xml | 69 +- .../youtube/translations/bg-rBG/strings.xml | 67 +- .../youtube/translations/de-rDE/strings.xml | 705 ++++++++++++++++-- .../youtube/translations/el-rGR/strings.xml | 178 ++++- .../youtube/translations/es-rES/strings.xml | 105 ++- .../youtube/translations/fr-rFR/strings.xml | 97 ++- .../youtube/translations/hu-rHU/strings.xml | 69 +- .../youtube/translations/id-rID/strings.xml | 4 + .../youtube/translations/in/strings.xml | 4 + .../youtube/translations/it-rIT/strings.xml | 145 +++- .../youtube/translations/ja-rJP/strings.xml | 111 +-- .../youtube/translations/ko-rKR/strings.xml | 132 ++-- .../youtube/translations/pl-rPL/strings.xml | 142 +++- .../youtube/translations/pt-rBR/strings.xml | 69 +- .../youtube/translations/ru-rRU/strings.xml | 245 +++--- .../youtube/translations/tr-rTR/strings.xml | 36 +- .../youtube/translations/uk-rUA/strings.xml | 138 +++- .../youtube/translations/vi-rVN/strings.xml | 271 +++++-- .../youtube/translations/zh-rCN/strings.xml | 59 +- .../youtube/translations/zh-rTW/strings.xml | 167 +++-- 27 files changed, 2037 insertions(+), 791 deletions(-) diff --git a/patches/src/main/resources/music/translations/el-rGR/strings.xml b/patches/src/main/resources/music/translations/el-rGR/strings.xml index ee606bd58..a0dfda287 100644 --- a/patches/src/main/resources/music/translations/el-rGR/strings.xml +++ b/patches/src/main/resources/music/translations/el-rGR/strings.xml @@ -194,6 +194,7 @@ Επιλέξτε την έκδοση εφαρμογής που θα χρησιμοποιηθεί. 6.42.55 - Απενεργοποίηση στίχων σε πραγματικό χρόνο 7.16.53 - Επαναφορά παλιάς γραμμής ενεργειών + 7.17.52 - Η ενότητα σχολίων δεν εμφανίζεται στην αρχική ροή Μη έγκυρη έκδοση για παραποίηση: %s. Γραμμή πλοήγησης diff --git a/patches/src/main/resources/music/translations/it-rIT/strings.xml b/patches/src/main/resources/music/translations/it-rIT/strings.xml index 083615f6a..9cb7c3a54 100644 --- a/patches/src/main/resources/music/translations/it-rIT/strings.xml +++ b/patches/src/main/resources/music/translations/it-rIT/strings.xml @@ -193,6 +193,7 @@ Questo non aggira la restrizione di età. Semplicemente la accetta automaticamen Seleziona la destinazione falsificata della versione app. 6.42.55 - Disabilita i testi in tempo reale 7.16.53 - Ripristina la vecchia barra d\'azione + 7.17.52 - La sezione commenti non viene visualizzata nel feed principale Versione dell\'app da falsificare non valida: %s. Barra di navigazione diff --git a/patches/src/main/resources/music/translations/ko-rKR/strings.xml b/patches/src/main/resources/music/translations/ko-rKR/strings.xml index b2dedc69d..7f7bbfbef 100644 --- a/patches/src/main/resources/music/translations/ko-rKR/strings.xml +++ b/patches/src/main/resources/music/translations/ko-rKR/strings.xml @@ -2,7 +2,7 @@ RVX Music 설정 - 기본값으로 초기화합니다. + 기본값으로 초기화하였습니다. 레이아웃을 정상적으로 불러오기 위해 다시 시작합니다. 새로고침 및 다시 시작 @@ -58,7 +58,7 @@ 알려진 문제점: • 간혹 홈 피드 대신 검은색 빈 화면이 표시될 수 있습니다." - 전체 화면 광고가 닫아집니다. + 전체 화면 광고가 닫아졌습니다. 일반 레이아웃 광고 제거 일반 레이아웃 광고를 숨깁니다. 미디어 광고 제거 @@ -67,7 +67,7 @@ 유료 광고 포함 라벨을 숨깁니다. Premium 프로모션 팝업 제거 Premium 프로모션 팝업을 숨깁니다. - Premium 프로모션 팝업이 닫아집니다. + Premium 프로모션 팝업이 닫아졌습니다. Premium 갱신 배너 제거 Premium 갱신 배너를 숨깁니다. Premium 프로모션 알림 배너 제거 @@ -193,6 +193,7 @@ 변경할 앱 버전을 선택하세요. 6.42.55 - 실시간 가사를 비활성화합니다. 7.16.53 - 이전 액션바로 복원합니다. + 7.17.52 - 홈 피드에서 댓글 섹션이 표시되지 않습니다. 변경할 앱 버전이 잘못되었습니다: %s 하단바 @@ -312,7 +313,7 @@ YouTube Music의 검색 및 설정과 같은 활동은 공개되지 않으므로 기본 동영상 화질 값으로 변경되었을 때, 팝업 메시지를 표시합니다. 사용자 정의 재생 속도는 %s배속보다 작아야 합니다. 잘못된 재생 속도 값입니다. - 기본 재생 속도 값을 %s 로 변경합니다. + 기본 재생 속도 값을 %s 로 변경하였습니다. 모바일 네트워크 이용 시 기본 동영상 품질 값을 %s 로 변경합니다. 동영상 품질을 설정할 수 없습니다. Wi-Fi 이용 시 기본 동영상 품질 값을 %s 로 변경합니다. diff --git a/patches/src/main/resources/music/translations/pl-rPL/strings.xml b/patches/src/main/resources/music/translations/pl-rPL/strings.xml index 9581e2a19..e847ee27a 100644 --- a/patches/src/main/resources/music/translations/pl-rPL/strings.xml +++ b/patches/src/main/resources/music/translations/pl-rPL/strings.xml @@ -194,6 +194,7 @@ Nie pomija to ograniczeń wiekowych, lecz akceptuje je automatycznie." Wybierz wersję, którą chcesz oszukiwać. 6.42.55 - Wyłącza teksty w czasie rzeczywistym 7.16.53 - Przywraca stary pasek akcji + 7.17.52 - Sekcja komentarzy nie pojawia się na stronie głównej Nieprawidłowa oszukiwana wersja aplikacji: %s. Pasek nawigacji diff --git a/patches/src/main/resources/music/translations/ru-rRU/strings.xml b/patches/src/main/resources/music/translations/ru-rRU/strings.xml index edf5695ab..2faf67d36 100644 --- a/patches/src/main/resources/music/translations/ru-rRU/strings.xml +++ b/patches/src/main/resources/music/translations/ru-rRU/strings.xml @@ -194,6 +194,7 @@ Выберите целевую версию приложения для подмены. 6.42.55 - Отключает динамических текстов 7.16.53 - Восстановить старую панель действий + 7.17.52 - Раздел комментариев не отображается на вкладке \"Главная\" Неверная версия подмены: %s. Панель навигации diff --git a/patches/src/main/resources/music/translations/uk-rUA/strings.xml b/patches/src/main/resources/music/translations/uk-rUA/strings.xml index 03ef478d6..5cabf4fc6 100644 --- a/patches/src/main/resources/music/translations/uk-rUA/strings.xml +++ b/patches/src/main/resources/music/translations/uk-rUA/strings.xml @@ -194,6 +194,7 @@ Виберіть зі списку цільову версію для підміни. 6.42.55 - Вимкнення динамічних текстів 7.16.53 - Відновлення старої панелі дій + 7.17.52 - Розділ коментарів не показується в домашній стрічці Невірна версія підміни: %s. Панель навігації diff --git a/patches/src/main/resources/music/translations/vi-rVN/strings.xml b/patches/src/main/resources/music/translations/vi-rVN/strings.xml index b410fe63d..a3cfea1ce 100644 --- a/patches/src/main/resources/music/translations/vi-rVN/strings.xml +++ b/patches/src/main/resources/music/translations/vi-rVN/strings.xml @@ -193,6 +193,7 @@ Hạn chế: Chọn phiên bản YouTube Music mà bạn muốn giả mạo. 6.42.55 - Tắt lời bài hát theo thời gian thực 7.16.53 - Khôi phục thanh thao tác kiểu cũ + 7.17.52 - Phần bình luận không xuất hiện trên thẻ Trang chủ Phiên bản ứng dụng đã chọn không hợp lệ: %s. Thanh điều hướng diff --git a/patches/src/main/resources/youtube/translations/ar/strings.xml b/patches/src/main/resources/youtube/translations/ar/strings.xml index 46a5d5620..89288d1e8 100644 --- a/patches/src/main/resources/youtube/translations/ar/strings.xml +++ b/patches/src/main/resources/youtube/translations/ar/strings.xml @@ -1550,12 +1550,27 @@ تلقائي الفيديو - سرعة التشغيل الافتراضية - جودة الفيديو الافتراضية على شبكة الجوَّال - جودة الفيديو الافتراضية على شبكة Wi-Fi + تعطيل فيديو HDR تم تعطيل فيديو HDR. تم تمكين فيديو HDR. + تعطيل ترميز VP9 + "تم تعطيل برنامج ترميز VP9. + +• الحد الأقصى للدقة هو 1080P. +• سيستهلك تشغيل الفيديو بيانات إنترنت أكثر من VP9. +• لا يزال برنامج ترميز VP9 مستخدمًا لفيديو HDR." + تم تمكين ترميز VP9. + استبدال برنامج الترميز AV1 + يستبدل برنامج الترميز AV1 ببرنامج الترميز VP9. + + سرعة التشغيل الافتراضية + تذكر التغيرات في سرعة التشغيل + تنطبق تغييرات سرعة التشغيل على جميع الفيديوهات. + تنطبق تغييرات سرعة التشغيل على الفيديو الحالي فقط. + عرض ملاحظة + سيتم عرض ملاحظة عند تغيير سرعة التشغيل الافتراضية. + لن يتم عرض ملاحظة عند تغيير سرعة التشغيل الافتراضية. تمكين سرعة التشغيل المخصصة تم تمكين سرعة التشغيل المخصصة. تم تعطيل سرعة التشغيل المخصصة. @@ -1564,12 +1579,11 @@ يتم استخدام القائمة المنبثقة بالمظهر القديم. تعديل سرعة التشغيل المخصصة إضافة أو تغيير سرعات التشغيل المتاحة. - تذكر التغيرات في سرعة التشغيل - تنطبق تغييرات سرعة التشغيل على جميع الفيديوهات. - تنطبق تغييرات سرعة التشغيل على الفيديو الحالي فقط. - عرض ملاحظة - سيتم عرض ملاحظة عند تغيير سرعة التشغيل الافتراضية. - لن يتم عرض ملاحظة عند تغيير سرعة التشغيل الافتراضية. + يجب أن تكون السرعات المخصصة أقل من %sx. + سرعات التشغيل المخصصة غير صالحة. + + جودة الفيديو الافتراضية على شبكة الجوَّال + جودة الفيديو الافتراضية على شبكة Wi-Fi تذكر تغييرات جودة الفيديو تنطبق تغييرات الجودة على جميع الفيديوهات. تنطبق تغييرات الجودة على الفيديو الحالي فقط. @@ -1579,15 +1593,6 @@ استعادة قائمة جودة الفيديو القديمة يتم عرض قائمة جودة الفيديو القديمة. لا يتم عرض قائمة جودة الفيديو القديمة. - تعطيل سرعة التشغيل للموسيقى - تم تعطيل سرعة التشغيل الافتراضية للموسيقى. - تم تمكين سرعة التشغيل الافتراضية للموسيقى. - التحقق باستخدام الفئات - سيتم تعطيل سرعة التشغيل الافتراضية إذا كانت فئة الفيديو هي موسيقى. - تم تعطيل سرعة التشغيل الافتراضية لمقاطع الفيديو القابلة للتشغيل على YouTube Music. - تمكين سرعة التشغيل الافتراضية لفيديوهات Shorts - تنطبق سرعة التشغيل الافتراضية على Shorts. - لا تنطبق سرعة التشغيل الافتراضية على Shorts. تم تخطي التخزين المؤقت الذي تم تحميله مسبقًا. تخطي التخزين المؤقت المحمل مسبقًا "لتخطي التخزين المؤقت المحمل مسبقًا في بداية الفيديوهات لتطبيق جودة الفيديو الافتراضية على الفور. @@ -1599,27 +1604,13 @@ يتم عرض الملاحظة. لا يتم عرض الملاحظة. إيهام أبعاد الجهاز - "يوهم أبعاد الجهاز من أجل فتح جودة فيديو أعلى قد لا تكون متوفرة على جهازك. -قد يتم توفير الجودة العالية في بعض الفيديوهات التي تتطلب أبعادًا عالية للجهاز، ولكن ليس كل الفيديوهات." - تعطيل ترميز VP9 - "تم تعطيل برنامج ترميز VP9. - -• الحد الأقصى للدقة هو 1080P. -• سيستهلك تشغيل الفيديو بيانات إنترنت أكثر من VP9. -• لا يزال برنامج ترميز VP9 مستخدمًا لفيديو HDR." - تم تمكين ترميز VP9. - استبدال برنامج الترميز AV1 - يستبدل برنامج الترميز AV1 ببرنامج الترميز VP9. - رفض استجابة برنامج الترميز AV1 - "يرفض قسرًا استجابة برنامج ترميز AV1. -سيتم تطبيق برنامج ترميز مختلف بعد حوالي 20 ثانية من التخزين المؤقت." - تؤدي العملية الاحتياطية إلى حوالي 20 ثانية من التخزين المؤقت. - تغيير السرعة الافتراضية إلى %s. - تغيير جودة بيانات الجوّال الافتراضية إلى %s. - فشل في تعيين جودة الفيديو. - تغيير جودة Wi-Fi الافتراضية إلى %s. - يجب أن تكون السرعات المخصصة أقل من %sx. - سرعات التشغيل المخصصة غير صالحة. + + تعطيل سرعة التشغيل للموسيقى + تم تعطيل سرعة التشغيل الافتراضية للموسيقى. + تم تمكين سرعة التشغيل الافتراضية للموسيقى. + التحقق باستخدام الفئات + سيتم تعطيل سرعة التشغيل الافتراضية إذا كانت فئة الفيديو هي موسيقى. + تم تعطيل سرعة التشغيل الافتراضية لمقاطع الفيديو القابلة للتشغيل على YouTube Music. Return YouTube Dislike تمكين Return YouTube Dislike diff --git a/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml b/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml index fe1f1c84e..7674cc0c9 100644 --- a/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml +++ b/patches/src/main/resources/youtube/translations/bg-rBG/strings.xml @@ -18,6 +18,7 @@ "%1$s не е инсталиран. Моля, изтеглете %2$s от уебсайта." %s не е инсталирано. Моля инсталирайте го. + Добави към опашката RVX език Език на приложението @@ -1378,12 +1379,26 @@ Авто Видео - Скорост на възпроизвеждане по подразбиране - Предпочитано качество при мобилни данни - Предпочитано качество при Wi-Fi + Изкл. HDR клипове HDR клиповете са изключени. HDR клиповете са включени. + Деактивирайте кодека VP9 + "Кодек VP9 е деактивиран. +• Максималната разделителна способност е 1080p. +• Възпроизвеждането на видео ще използва повече интернет данни от VP9. +• За да получите възпроизвеждане на HDR, HDR видеото все още използва кодека VP9." + VP9 кодек е включен. + Сменете софтуерния кодек AV1 + Заменя софтуерния кодек AV1 с кодека VP9. + + Скорост на възпроизвеждане по подразбиране + Запомнете промените в скоростта на възпроизвеждане + Промените в скоростта на възпроизвеждане се отнасят за всички видеоклипове. + Промените в скоростта на възпроизвеждане се отнасят само за текущия видеоклип. + Покажи съобщение + При промяна на скоростта на възпроизвеждане по подразбиране в долната част на екрана се появява съобщение. + Няма съобщение в долната част на екрана при промяна на скоростта на възпроизвеждане по подразбиране. Вкл. на скорост на видеото по избор Скоростта по избор на видеото е включена. Скоростта по избор на видеото е изключена. @@ -1392,12 +1407,11 @@ Използва се падащ панел в стар стил. Редактиране на скоростите по избор на видеото Добавяне или смяна на възможните скорости. - Запомнете промените в скоростта на възпроизвеждане - Промените в скоростта на възпроизвеждане се отнасят за всички видеоклипове. - Промените в скоростта на възпроизвеждане се отнасят само за текущия видеоклип. - Покажи съобщение - При промяна на скоростта на възпроизвеждане по подразбиране в долната част на екрана се появява съобщение. - Няма съобщение в долната част на екрана при промяна на скоростта на възпроизвеждане по подразбиране. + Скоростите по избор трябва да са по-малки от %sx. Връщане на стойностите по подразбиране. + Невалидна скорост на видеото. Връщане на стойности по подразбиране. + + Предпочитано качество при мобилни данни + Предпочитано качество при Wi-Fi Запомнете промените в качеството на видеото Промените в качеството се отнасят за всички видеоклипове. Промените в качеството се отнасят само за текущия видеоклип. @@ -1407,15 +1421,6 @@ Възстановете старото меню за качество на видеото Показва се старото меню за видео качество. Старото меню за видео качество е скрито. - Деактивирайте скоростта на възпроизвеждане за музика - Скоростта на възпроизвеждане по подразбиране е деактивирана за музика. - Скоростта на възпроизвеждане по подразбиране е активирана за музика. - Изберете скорост въз основа на категориите - Скоростта по подразбиране за категорията YouTube Music е деактивирана. - Скоростта по подразбиране за категорията YouTube Music е активирана. - Променете скоростта на възпроизвеждане на Shorts - Скоростта на възпроизвеждане по подразбиране се прилага за Shorts. - Скоростта на възпроизвеждане по подразбиране не се прилага за Shorts. Пропуснат предварително зареден буфер. Пропусни предварително зареден буфер "Пропуска предварително заредения буфер в началото на видеоклиповете, за да приложи незабавно качеството на видеото по подразбиране. @@ -1428,25 +1433,13 @@ Уведомлението се показва. Уведомлението е скрито. Лъжливи параметри на устройството - "Преоразмерява вашето устройство, за да покже видеоклипове с по-високо качество, които може да не са налични на вашето устройство." - Деактивирайте кодека VP9 - "Кодек VP9 е деактивиран. -• Максималната разделителна способност е 1080p. -• Възпроизвеждането на видео ще използва повече интернет данни от VP9. -• За да получите възпроизвеждане на HDR, HDR видеото все още използва кодека VP9." - VP9 кодек е включен. - Сменете софтуерния кодек AV1 - Заменя софтуерния кодек AV1 с кодека VP9. - Отхвърлете софтуерния кодек AV1 - "Принудително отхвърляне на софтуерния кодек AV1 -След приблизително 20 секунди буфериране ще бъде приложен друг кодек." - Буфериране поради софтуерен кодек Av1 (прибл. 20 сек.). - Смяна на скоростта на видеото на %s. - Смяна на качеството при мобилни данни на %s. - Грешка при настройка на качеството на видеото. - Смяна на качеството при Wi-Fi на%s. - Скоростите по избор трябва да са по-малки от %sx. Връщане на стойностите по подразбиране. - Невалидна скорост на видеото. Връщане на стойности по подразбиране. + + Деактивирайте скоростта на възпроизвеждане за музика + Скоростта на възпроизвеждане по подразбиране е деактивирана за музика. + Скоростта на възпроизвеждане по подразбиране е активирана за музика. + Изберете скорост въз основа на категориите + Скоростта по подразбиране за категорията YouTube Music е деактивирана. + Скоростта по подразбиране за категорията YouTube Music е активирана. Return YouTube Dislike (показва нехаресванията) Вкл. на Return YouTube Dislike diff --git a/patches/src/main/resources/youtube/translations/de-rDE/strings.xml b/patches/src/main/resources/youtube/translations/de-rDE/strings.xml index 10259962b..530305072 100644 --- a/patches/src/main/resources/youtube/translations/de-rDE/strings.xml +++ b/patches/src/main/resources/youtube/translations/de-rDE/strings.xml @@ -2,7 +2,7 @@ Bedienungshilfen für den Video-Player aktivieren? - Ihre Steuerungen wurden angepasst, da ein Barrierefreiheitsdienst aktiviert ist. + Ihre Steuerung wurde geändert, da ein Barrierefreiheitsdienst aktiv ist. RVX Suche %s @@ -19,12 +19,107 @@ "%1$s ist nicht installiert. Bitte lade %2$s von der Webseite herunter." %s ist nicht installiert. Bitte installieren. + Zur Warteschlange hinzufügen + Zur Warteschlange hinzufügen & öffnen + Zur Warteschlange hinzufügen und Video abspielen + Externer Downloader + Warteschlange öffnen + Warteschlange + Aus der Warteschlange entfernen + Aus der Warteschlange entfernen und die Warteschlange öffnen + Warteschlange löschen + Warteschlange speichern + "Öffnen Sie statt eines externen Downloaders den Warteschlangenmanager. + +Sie können den Warteschlangenmanager auch öffnen, indem Sie die Zurück-Taste in der Navigationsleiste gedrückt halten. + +Diese Funktion befindet sich noch in der Entwicklung, daher sind einige Funktionen möglicherweise nicht verfügbar. + +Bitte verwenden Sie sie nur zu Debugging-Zwecken." + Anmeldung erforderlich + Warteschlange Manager nicht verfügbar (%s). + Playlist konnte nicht identifiziert werden + Warteschlange ist leer + Video konnte nicht identifiziert werden + Video konnte nicht hinzugefügt werden. + Fehler beim Erstellen der Warteschlange. + Fehler beim Löschen der Warteschlange. + Fehler beim Entfernen des Videos. + Fehler beim Speichern der Warteschlange. + Video erfolgreich hinzugefügt. + Warteschlange erfolgreich erstellt. + Warteschlange erfolgreich gelöscht. + Video erfolgreich entfernt. + Warteschlange erfolgreich in \'%s \' gespeichert. RVX Sprache + App Sprache + "Amharic +አማርኛ" + "Arabisch +العربية" + "Azerbaijani +Azərbaycan" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" Werbung + Endbild-Banner ausblenden + Store-Banner ist ausgeblendet. + Store-Banner wird angezeigt. Vollbildwerbung verstecken Vollbildwerbung wird versteckt. Vollbildwerbung wird angezeigt. + Vollbildwerbung wurde geschlossen. Allgemeine Werbung ausblenden Allgemeine Werbung ist ausgeblendet. Allgemeine Werbung wird angezeigt. @@ -53,7 +148,7 @@ Bitte lade %2$s von der Webseite herunter." Web Suchergebnisse sind versteckt. Web Suchergebnisse werden angezeigt. YouTube Premium Werbung ausblenden - YouTube Premium Werbung wird ausgeblendet. + YouTube Premium Werbung wird versteckt. YouTube Premium Werbung wird angezeigt. Alternatives Vorschaubild @@ -103,6 +198,13 @@ Tippen Sie hier, um mehr über DeArrow zu erfahren." Schaltfläche \"Untertitel\" ist versteckt. Schaltfläche \"Untertitel\" wird angezeigt. Karussellregal ausblenden + "Versteckt folgende Abschnitte: +- Aktuelle Nachrichten +- Weiterschauen +- Entdecke mehr Kanäle +- Shopping +- Erneut anschauen" + Karussellregale werden angezeigt. Chips-Abschnitt verstecken Chips-Abschnitt wird versteckt. Chips-Abschnitt wird angezeigt @@ -165,10 +267,10 @@ Tippen Sie hier, um mehr über DeArrow zu erfahren." In den Suchergebnissen angezeigt. Kanal Profil - Komponenten im Kanalprofil ausblenden oder anzeigen. + Elemente im YouTube-Einstellungsmenü verstecken Aktivieren der Benutzerdefinierten Filter - Kanal-Tab-Filter ist aktiviert. - Kanal-Tab-Filter ist deaktiviert. + Benutzerdefinierter Filter ist aktiviert + Benutzerdefinierter Filter ist deaktiviert Kanal-Tab-Filter Liste der zu filternden Kanalnamen, getrennt durch Zeilenumbrüche. "Verkürzt @@ -182,7 +284,7 @@ Store" Links am oberen Rand des Kanalprofils werden angezeigt. Für dich ausblenden Chips-Abschnitt wird versteckt. - \'For You\' shelves are shown. + Für Sie ist Regal gezeigt. Shop-Button ausblenden Die Schaltfläche Store durchsuchen wird ausgeblendet Die Schaltfläche Store durchsuchen wird angezeigt @@ -204,6 +306,9 @@ Store" Feed Flyout Menüfilter aktivieren Feed Flyout Menüfilter ist aktiviert. Feed Flyout-Menüfilter ist deaktiviert. + Feed Flyout Menü Filtertyp + Filter, wenn vorhanden.<br><br>Um die <b>\'Nächste in der Warteschlange abspielen\'</b> Menü zu verbergen, Sie können <b>\'Wiedergabe weiter\'</b> oder <b>\'in der Warteschlange\'</b> als Schlüsselwörter verwenden. + Filtern wenn zutreffend.<br><br>Um die <b>\'Nächste in der Warteschlange abspielen\' zu verstecken</b> Menü, Sie können nur <b>\'Wiedergabe als nächstes in der Warteschlange\'</b> als Schlüsselwörter verwenden. Feed Flyout Menüfilter Liste der Filter für das Account Menü, durch Zeilenumbrüche getrennt. @@ -284,8 +389,11 @@ Wenn sich das Layout des Wiedergabebildschirms aufgrund serverseitiger Änderung Allgemein Startseite ändern Standard + Alle Abonnements Kanäle durchstöbern + Kurse / Lernen Entdecken + Mode & Schönheit Spiele Verlauf Bibliothek @@ -293,12 +401,19 @@ Wenn sich das Layout des Wiedergabebildschirms aufgrund serverseitiger Änderung Live Filme Musik + Neuigkeiten + Benachrichtigungen + Wiedergabelisten + Podcasts Suchen + Einkaufen Shorts Sport Abonnements Beliebt + Virtuelle Realität Später ansehen + Ihre Clips Startseitentyp ändern "Startseite ändert sich immer. @@ -325,6 +440,44 @@ Einschränkung: Zurück-Taste in der Symbolleiste funktioniert möglicherweise n Diskretion des Betrachters entfernen "Entfernt den Diskretionsdialog des Betrachters. Dies umgeht nicht die Altersbeschränkung. Es akzeptiert ihn nur automatisch." + Live-Ring Klick-Aktion ändern + "Der Kanal öffnet sich, wenn der Live-Ring angeklickt wird. + +Einschränkung: Wenn der Live-Stream der Shorts im regulären Player geöffnet wird, wird der Channel nicht geöffnet." + Der Live-Stream wird geöffnet, wenn der Live-Ring angeklickt wird. + Anordnungsformfactor + Standard + Telefon + Telefon (max. 480 dp) + Tablet + Tablet (min. 600 dp) + Automobil + "Änderungen umfassen: + +Tablet Layout +• Community Beiträge sind ausgeblendet. + +Automotive Layout +• Shorts werden im regulären Player geöffnet. +• Der Feed ist nach Themen und Kanälen organisiert. +• Die Videobeschreibung kann nicht geöffnet werden, wenn 'Streaming Daten fälschen' deaktiviert ist." + Layoutaktualisierungen deaktivieren + Layout wird vom Server nicht aktualisiert. + Layout wird vom Server aktualisiert. + "Das App-Layout wird auf das Layout zurückgesetzt, das bei der ersten Installation verwendet wurde. + +Einige serverseitige Layouts werden möglicherweise nicht zurückgesetzt. + +Änderungen umfassen: +• Komponenten im Player-Ausklappmenü (oder zugehörige Einstellungen) funktionieren möglicherweise nicht. +• Rollende Zahlen sind nicht animiert. +• Der Tab Mediathek wird verwendet. +• Der Musikbereich in der Videobeschreibung funktioniert möglicherweise nicht. +• Die Kontowechsel-Schaltfläche wird möglicherweise nicht im Mediathek Tab angezeigt. Verwende die Einstellung Breite Suchleiste im 'Du' Tab aktivieren." + Transparente Statusleiste deaktivieren + Statusleiste ist undurchsichtig. + Die Statusleiste ist undurchsichtig oder durchscheinend. + Bei einigen HerstellerROMs mit Android 12+ kann das Aktivieren dieser Funktion die Navigationsleiste des Systems transparent machen. Spoof App Version Version gefälscht Version nicht gefälscht @@ -342,12 +495,19 @@ Wenn später ausgeschaltet wird empfohlen, die App-Daten zu löschen, um UI-Fehl 18.33.40 - Alte Shorts Aktionsleiste wiederherstellen 18.38.45 - Altes Standard-Video-Qualitätsverhalten wiederherstellen 18.48.39 - Deaktiviert Ansichten und gefällt es, in Echtzeit aktualisiert zu werden + 19.01.34 - Videobeschreibungsinteraktion deaktivieren + 19.26.42 - Kairo-Symbol in der Navigationsleiste und der Symbolleiste deaktivieren + 19.33.37 - Alte Wiedergabegeschwindigkeits-Flyout-Anzeige wiederherstellen + Ungültige Spoof App Version: %s. Account Menü Zeige oder verstecke Element im Account Menü und mein YouTube. Account Menü verstecken "Elemente des Account Menüs und Mein YouTube. Manche Komponenten könnten nicht versteckt werden." + Kontomenü Filtertyp + Filter, wenn vorhanden.<br><br>Um die <b>\'Nächste in der Warteschlange abspielen\'</b> Menü zu verbergen, Sie können <b>\'Wiedergabe weiter\'</b> oder <b>\'in der Warteschlange\'</b> als Schlüsselwörter verwenden. + Filtern wenn zutreffend.<br><br>Um die <b>\'Nächste in der Warteschlange abspielen\' zu verstecken</b> Menü, Sie können nur <b>\'Wiedergabe als nächstes in der Warteschlange\'</b> als Schlüsselwörter verwenden. Konto-Menüfilter bearbeiten Liste der Filter für das Account Menü, durch Zeilenumbrüche getrennt. Verstecke Handle @@ -367,8 +527,18 @@ Manche Komponenten könnten nicht versteckt werden." Hook Buttons Überschreibt die Klick-Aktion von In-App-Tasten. - Download-Button + Herunterladen-Button + Herunterladen-Button der Playlist überschreiben + Der native Playlist-Download-Button wird immer angezeigt, und in öffentlichen Playlists öffnet er deinen externen Downloader. + Der native Playlist-Download-Button, falls angezeigt, öffnet den nativen In-App-Downloader. Überschreibe Video-Download-Button + Der Native Video-Download-Button öffnet Ihren externen Download. + Nativer Video-Download-Button öffnet den nativen In-App Downloader. + Warteschlangen Manager + Nativer Video-Download-Button öffnet den Warteschlangenmanager. + Der Native Video-Download-Button öffnet Ihren externen Download. + Playlist Downloader Paketname + Paketname Ihrer installierten externen Downloader-App, wie z. B. YTDLnis. YouTube Musik-Button überschreiben YouTube Music Button öffnet RVX Music. @@ -379,6 +549,7 @@ Manche Komponenten könnten nicht versteckt werden." Warnung %s ist nicht installiert. Bitte installieren. Voraussetzung + YouTube Musik wird benötigt, um die Schaltfläche zu überschreiben. Tippen Sie hier, um YouTube Musik herunterzuladen. Navigationsleiste Komponenten der Navigationsleiste ausblenden oder anzeigen. @@ -416,6 +587,9 @@ Hinweis: Durch Aktivieren dieser Option wird auch die Videowerbung zwangsweise a Auch Werbung wird nicht mehr in Shorts blockiert. Wenn diese Einstellung nicht wirksam ist, versuchen Sie in den Inkognito-Modus zu wechseln." + Transparente Navigationsleiste aktivieren + Navigationsleiste ist transparent. + Navigationsleiste ist nicht transparent. Navigationsleiste verstecken Navigationsleiste ist ausgeblendet. Navigationsleiste wird angezeigt. @@ -434,6 +608,9 @@ Wenn diese Einstellung nicht wirksam ist, versuchen Sie in den Inkognito-Modus z \"Niedrigerer Datenverbrauch\" ausblenden \"Niedrigerer Datenverbrauch\" wird ausgeblendet. \"Niedrigerer Datenverbrauch\" wird angezeigt. + Autoplay oder Wiedergabemenü ausblenden + Autoplay oder Wiedergabemenü ist ausgeblendet. + Autoplay oder Wiedergabemenü wird angezeigt. Einstellungen für Videoqualität ausblenden Einstellungen für Videoqualität wird ausgeblendet. Einstellungen für Videoqualität wird angezeigt. @@ -480,9 +657,25 @@ Wenn diese Einstellung nicht wirksam ist, versuchen Sie in den Inkognito-Modus z \"Über\" wird ausgeblendet. \"Über\" wird angezeigt. + Snackbar + Komponenten im Zusammenhang mit Snackbar ausblenden oder ändern. Snackbar verstecken Snackbar ist versteckt Snackbar wird angezeigt + Serverseitige Snackbar ausblenden + Die Snackbar auf dem Server ist ausgeblendet. + Die Snackbar auf dem Server wird angezeigt. + Snackbar Thema umkehren + Das Thema der Snackbar ist umgekehrt. + Das Thema der Snackbar ist nicht invertiert. + Hintergrund der serverseitigen Snackbar ändern + Die Hintergrundfarbe der serverseitigen Snackbar hat sich geändert. + Die Hintergrundfarbe der serverseitigen Snackbar hat sich nicht geändert. + "Einige Snackbars verwenden ein auf der Serverseite definiertes Theme und nicht das App-Theme. + +Ändern Sie die Hintergrundfarbe dieser Snackbars. + +Bei serverseitigen Änderungen kann sich die Hintergrundfarbe der Snackleiste nicht ändern." Werkzeugleiste Verstecke oder ändere Toolbar-Komponenten, wie die Suchleiste, Buttons und Header. @@ -496,6 +689,15 @@ Wenn diese Einstellung nicht wirksam ist, versuchen Sie in den Inkognito-Modus z Breite Suchleiste enthält YouTube Header Breite Suchleiste enthält nicht YouTube Header. Aktiviere breite Suchleiste in deinem Tab + "Die breite Suchleiste ist in der Registerkarte Sie aktiviert. + +Um auf die Einstellungen zuzugreifen, benutzen Sie bitte den folgenden Pfad: +Registerkarte → Kanal → Einstellungen anzeigen" + Die breite Suchleiste ist im Register You deaktiviert. + "Wenn Sie diese Einstellung aktivieren, werden die Einstellungen im Tab \"Einstellungen\" deaktiviert. + +In diesem Fall Sie müssen den folgenden Pfad verwenden, um auf die Einstellungen zuzugreifen: +Registerkarte → Kanal → Menü → Einstellungen anzeigen" Verstecke Erstellen Schaltfläche Cast Button ist versteckt. Der Cast button wird angezeigt. @@ -534,6 +736,11 @@ Tippe und halte zum Öffnen der RVX-Einstellungen." Die Transparenz der Spieler-Überlagerung muss zwischen 0-100 liegen. Zurückgesetzt auf Standardwerte. Mix-Playlists deaktivieren Mix-Playlists sind deaktiviert. + "Mix-Wiedergabelisten automatisch schalten, wenn das Autoplay eingeschaltet ist. + +Autoplay kann in den YouTube-Einstellungen geändert werden: +Einstellungen → Autoplay / Wiedergabe → Nächstes Video Autoplay" + Aktivieren dieser Funktion deaktiviert den automatischen Wechsel zu YouTube-Mix, wenn Musik abgespielt wird, während Autoplay eingeschaltet ist. Player-Popup-Panels deaktivieren Auto-Player-Popup-Panels sind deaktiviert. Auto-Player-Popup-Panels sind deaktiviert. @@ -594,6 +801,9 @@ Einstellungen → Autoplay → Nächstes Video automatisch abspielen" Zoom-Overlay ausblenden Zoom-Overlay ist ausgeblendet. Zoom-Overlay wird angezeigt. + Video-Untertitel säubern + "Phrasen wie '#', 'Fundraiser', 'Shop' und 'products' sind vor den Videountertiteln versteckt." + "Ausdrücke wie '#', 'Fundraiser', 'Shop' und 'products' werden aus den Video-Untertiteln gezeigt." Aktionsschaltflächen Aktionsschaltflächen unter Videos ausblenden oder anzeigen. @@ -631,6 +841,18 @@ Einstellungen → Autoplay → Nächstes Video automatisch abspielen" \"Danke\" Schaltfläche wird versteckt. \"Danke\" Schaltfläche wird angezeigt. + Aktionsbutton nach Index ausblenden + "Aktionstasten werden durch den Index versteckt. + +Info: +• Falsche Aktionstasten können ausgeblendet werden oder Aktionstasten können nicht ausgeblendet werden. +• Verstecke Aktionstasten lassen keinen leeren Platz." + "Aktionstasten werden durch Bezeichnerfilter ausgeblendet. + +Info: +• Knöpfe mit rechter Aktion werden ausgeblendet. +• Verstecke Aktionstasten lassen Leerzeichen." + Remix-Schaltflächenindex Ambient-Modus Ambient-Modus deaktivieren oder Einschränkungen des Ambient-Modus umgehen. @@ -670,12 +892,24 @@ Einstellungen → Autoplay → Nächstes Video automatisch abspielen" Verstecke das Erstellen der Short-Schaltfläche Erstelle Short-Schaltfläche ist ausgeblendet. Erstelle Short-Schaltfläche wird angezeigt. + Emoji und Zeitstempel ausblenden + Emoji und Zeitstempeltasten sind ausgeblendet. + Emoji und Zeitstempeltasten werden angezeigt. + Markierte Suchlinks ausblenden + Hervorgehobene Suchlinks sind versteckt. + Hervorgehobene Suchlinks werden angezeigt. Live-Chat-Nachrichten verbergen Live-Chat-Nachrichten sind ausgeblendet.\n\nDiese Einstellung gilt auch für Shorts Live-Videos. Live-Chat-Nachrichten werden angezeigt.\n\nDiese Einstellung gilt auch für Shorts Live-Videos. + Live-Chat-Zusammenfassung ausblenden + Zusammenfassung des Live-Chats ist ausgeblendet. + Zusammenfassung des Live-Chats wird angezeigt. Verstecke Vorschau-Kommentar Vorschau-Kommentar ist versteckt Vorschau-Kommentar wird angezeigt + Vorschaukommentyp ausblenden + Dies ändert nicht die Größe des Abschnitts der Kommentare, daher ist es möglich, die Live-Chat-Wiederholung im Kommentarbereich zu öffnen. + Dies ändert die Größe des Kommentarbereichs, so dass es unmöglich ist, eine Live-Chat-Wiederholung im Kommentarbereich zu öffnen. Verstecke \"Danke\" Schaltfläche \"Danke\" Schaltfläche wird versteckt. \"Danke\" Schaltfläche wird angezeigt. @@ -683,6 +917,8 @@ Einstellungen → Autoplay → Nächstes Video automatisch abspielen" Flyout Menü Komponenten des Flyout-Menüs im Feed verstecken oder anzeigen. Toggle Typ ändern + Textschalter werden verwendet. + Schalter werden verwendet. 1080p Premium ausblenden 1080p Premium wird ausgeblendet. 1080p Premium wird angezeigt. @@ -692,6 +928,7 @@ Einstellungen → Autoplay → Nächstes Video automatisch abspielen" Untertitel-Menü verstecken Untertitel-Menü ist versteckt. Untertitel-Menü wird angezeigt. + Untertitel-Menü-Fußzeile ausblenden Captions menu footer is hidden. Captions menu footer is shown. Hide lock screen menu @@ -732,16 +969,34 @@ Einstellungen → Autoplay → Nächstes Video automatisch abspielen" Hide premium controls menu Premium controls menu is hidden. Premium controls menu is shown. + Schlaf-Timer-Menü ausblenden + Schlaf-Timer-Menü ist ausgeblendet. + Schlaf-Timer-Menü wird angezeigt. Hide stable volume menu Stable volume menu is shown. Stable volume menu is hidden. Hide stats for nerds menu Stats for nerds menu is hidden. + Statistiken für Nerds werden angezeigt. + Verstecke in VR anschauen \'In VR ansehen\'-Menü wird ausgeblendet. \'In VR ansehen\'-Menü wird angezeigt. Vollbild Komponenten im Zusammenhang mit Vollbild ausblenden oder ändern. + Engagement-Panel deaktivieren + Engagement Panel ist deaktiviert. + Engagement Panel ist aktiviert. + Vollbildmodus aktivieren, wenn das Video startet + "Vollbildmodus aktivieren, wenn das Video gestartet wird. + +Einschränkung: Funktioniert nicht, wenn der Player minimiert ist, im PiP Modus oder im Hintergrund." + Vollbildmodus aktivieren, wenn das Video startet. + Vollbildmodus am Ende des Videos beenden + Deaktiviert + Hochformat + Querformat + Hoch- und Querformat Video-Titelbereich anzeigen "Zeigt den Video-Titelbereich im Vollbild. @@ -752,6 +1007,7 @@ Einschränkung: Videotitel verschwindet beim Klicken auf den Bildschirm."Live-Chat Replay-Button ausblenden Der Live-Chat-Replay-Button ist verborgen.\n\nEr erscheint im Vollbild, wenn Live-Chat geschlossen wird. Der Live-Chat-Replay-Button ist verborgen.\n\nEr erscheint im Vollbild, wenn Live-Chat geschlossen wird. + Verwandtes Video-Overlay ausblenden Im Schnellaktionscontainer werden weitere Videos sowie die zugehörige Videoüberlagerung ausgeblendet. Im Schnellaktionscontainer werden weitere Videos angezeigt sowie die zugehörige Videoüberlagerung. @@ -797,6 +1053,8 @@ Einschränkung: Videotitel verschwindet beim Klicken auf den Bildschirm."Kompaktsteuerungs-Overlay ist aktiviert Kompaktsteuerungs-Overlay ist deaktiviert Querformat behalten + Videos werden nach dem Ausschalten des Bildschirms und dem Ein- und Ausschalten im Querformat weiterhin abgespielt. + Videos werden im Hochformat abgespielt, nachdem der Bildschirm deaktiviert und eingeschaltet wurde. Timeout für den Wechsel zum Querformat Die Anzahl der Millisekunden nach dem Einschalten des Bildschirms, nachdem Querformat erzwungen wird. @@ -820,6 +1078,9 @@ Einschränkung: Videotitel verschwindet beim Klicken auf den Bildschirm." Miniplayer Ändern Sie den Stil des in App minimierten Players. + Miniplayer fortsetzen deaktivieren + <b>Weiter beobachten</b> wird beim Start der App nicht fortgesetzt. + <b>Weiter beobachten</b> wird beim Start der App fortgesetzt.<br><br>Info:<br>• <b>Weiter</b> ist die YouTube Premium-Funktion.<br>• Diese Einstellung erzwingt <b>Weiter</b> nicht zum Aktivieren. Miniplayer Typ Deaktiviert Original @@ -828,12 +1089,34 @@ Einschränkung: Videotitel verschwindet beim Klicken auf den Bildschirm."Modern 1 Modern 2 Modern 3 + Modern 4 Abgerundete Ecken aktivieren Ecken sind abgerundet. Ecken sind nicht abgerundet. Aktiviere doppeltes Tippen und Pinchen um die Größe zu ändern + "Doppeltippen und mit zwei Fingern vergrößern/verkleinern ist aktiviert + +• Doppeltippen, um die Größe des Mini-Players zu vergrößern +• Nochmals doppeltippen, um die ursprüngliche Größe wiederherzustellen." + Doppel-Tipp-Aktion und Pinch um die Größe zu verändern, ist deaktiviert. Drag and Drop aktivieren + "Drag-and-Drop ist aktiviert + +Der Mini-Player kann in jede Ecke des Bildschirms gezogen werden." Drag and Drop ist deaktiviert. + Horizontales Ziehen aktivieren. + "Horizontale Ziehgeste aktiviert + +Der Mini-Player kann mit einer Wischgeste vom Bildschirm nach links oder rechts gezogen werden." + Horizontale Drag Geste deaktiviert. + Overlay-Tasten verbergen + Overlay-Tasten sind ausgeblendet. + Overlay-Schaltflächen werden angezeigt. + Ausklappen und Schließen der Tasten ausblenden + "Tasten sind ausgeblendet. + +Wischen zum erweitern oder schließen." + Erweitern und Schließen Schaltflächen werden angezeigt. Vorwärts- und Rückwärts-Buttons ausblenden Vorwärts springen und zurück sind versteckt. Vor- und zurückspringen wird angezeigt. @@ -885,6 +1168,8 @@ Tap and hold to copy video timestamp." Tippen um Lautstärke des aktuellen Videos stumm zu schalten. Zum laut schalten erneut tippen. Show external download button Tap to launch external downloader. + Warteschlangen Manager + Statt einen externen Downloader zu starten, öffnen Sie den Warteschlangen-Manager. Zeige Geschwindigkeitsdialog Taste "Tippen um den Geschwindigkeitsdialog zu öffnen. Tippen und halten um die Wiedergabegeschwindigkeit auf 1.0x zurückzusetzen. Halten Sie erneut gedrückt, um die Standardgeschwindigkeit wiederherzustellen." @@ -892,6 +1177,26 @@ Tippen und halten um die Wiedergabegeschwindigkeit auf 1.0x zurückzusetzen. Hal \"Tippen, um den Whitelist-Dialog zu öffnen. Tippen und halten Sie, um den Einstellungsdialog für die Whitelist anzuzeigen. \"Alle abspielen\"-Button anzeigen + "Tippen, um eine Wiedergabeliste aller Videos aus dem Kanal zu generieren. +Tippen und halten um rückgängig zu machen. + +Info: +• Funktioniert möglicherweise nicht auf Live-Streams." + Wiedergabelistenmodus erzeugen + Alle Inhalte (Sortieren nach Uhrzeit, aufsteigend) + Alle Inhalte (sortieren nach Zeit) + Alle Inhalte (nach Beliebt) + Nur Videos (Nach Zeit sortieren) + Nur Videos (nach Beliebt) + Nur Shorts (sortieren nach Zeit) + Nur Shorts (nach Beliebt) + Nur gestreamte Videos (sortieren nach Zeit) + Nur gestreamte Videos (nach Beliebt) + Alle Mitglieder nur Inhalte + Nur Mitglieder Videos + Nur Mitglieder Shorts + Nur Mitglieder Live-Streams + Wiedergabeliste kann aufgrund von Kanal-Id nicht generiert werden. Kanal Whitelist Überprüfen oder die Liste der Kanäle entfernen, die zur Whitelist hinzugefügt wurden. Der Kanal \'%1$s\' wurde auf die Whitelist für %2$s gesetzt. @@ -922,12 +1227,23 @@ Tippen und halten Sie, um den Einstellungsdialog für die Whitelist anzuzeigen.< Replace time stamp action Tap to open playback speed or video quality flyout menu. Tap to show the remaining time. + Suchleisten-Kapitel deaktivieren + Kapitel sind in der Suchleiste deaktiviert. + Kapitel sind in der Suchleiste aktiviert. Eigene Suchleistenfarbe aktivieren Die benutzerdefinierte Farbe der Suchleiste ist aktiviert Die benutzerdefinierte Farbe der Suchleiste ist deaktiviert + Benutzerdefinierte Suchleisten-Primärfarbe + Geben Sie den Hex-Code der Suchbar-Primärfarbe ein. + Farbliche Anpassung des Fortschrittsanzeige-Akzents + Geben Sie den Hex-Code der Suchleisten-Akzentfarbe ein. + Ungültige Suchleistenfarbe. Aktiviere Suchleisten-Tippen (Video Fortschrittsbalken) Tippen der Suchleiste ist aktiviert Tippen der Suchleiste ist deaktiviert + Suchleisten-Kapitelbezeichnungen ausblenden + Kapitelbezeichnungen neben der Suchleiste werden ausgeblendet. + Die Kapitelbezeichnungen neben der Suchleiste werden angezeigt. Verstecke Video-Player-Suchleiste Suchleiste für Video-Player wird versteckt Suchleiste für Video-Player wird angezeigt @@ -940,18 +1256,32 @@ Tippen und halten Sie, um den Einstellungsdialog für die Whitelist anzuzeigen.< Alte Suchleiste Thumbnails wiederherstellen Suchleiste Miniaturansichten werden über der Suchleiste angezeigt. Thumbnails der Suchleiste werden im Vollbild angezeigt. + Aktiviere hochwertige Vorschaubilder + Thumbnails der Suchleiste sind hohe Qualität. + Thumbnails der Suchleiste sind mittlere Qualität. + "Damit werden Thumbnails auf Live-Streams wiederhergestellt, die keine Suchleisten-Thumbnails haben. + +Internet-Datennutzung kann höher sein, und Suchleisten-Thumbnails werden eine leichte Verzögerung haben, bevor sie angezeigt werden. + +Diese Funktion funktioniert am besten mit einer sehr schnellen Internetverbindung." Videobeschreibung Komponenten der Videobeschreibung ausblenden oder anzeigen. Disable rolling number animations Rolling numbers are not animated. Rolling numbers are animated. + AI-generierte Video-Zusammenfassung ausblenden + AI generierte Video-Zusammenfassung-Abschnitt ist versteckt. + AI generierte Video-Zusammenfassung-Abschnitt wird angezeigt. Attributbereich ausblenden Ausgewählte Orte, Spiele und Musiksektionen sind versteckt. Vorgestellte Orte, Spiele und Musikbereiche werden angezeigt. Hide chapters sections Chapters sections are hidden. Chapters sections are shown. + Inhaltsbereich ausblenden + Wie dieser Inhalt erstellt wurde, wird ausgeblendet. + Wie dieser Inhalt erstellt wurde Abschnitt angezeigt. Podcast-Abschnitte ausblenden Podcast-Abschnitte sind ausgeblendet. Podcast-Abschnitte werden angezeigt. @@ -961,6 +1291,11 @@ Tippen und halten Sie, um den Einstellungsdialog für die Whitelist anzuzeigen.< Schlüsselkonzeptsektion ausblenden Schlüsselkonzepte sind ausgeblendet. Schlüsselkonzepte werden angezeigt. + Shopping-Links ausblenden + Einkaufslinks sind ausgeblendet. + Einkaufslinks werden angezeigt. + Transkript-Abschnitt ausblenden + Transkript-Abschnitt ist ausgeblendet. Transkriptabschnitte werden angezeigt Videobeschreibungsinteraktion deaktivieren @@ -973,14 +1308,27 @@ Tippen und halten Sie, um den Einstellungsdialog für die Whitelist anzuzeigen.< Videobeschreibungen werden nicht automatisch erweitert. Shorts + Shorts-Hintergrundwiedergabe deaktivieren + Shorts-Hintergrundwiedergabe ist deaktiviert. + Shorts-Hintergrundwiedergabe ist aktiviert. Shorts-Player beim App-Start ausblenden Shorts-Player aktiv beim Start der Anwendung. Shorts-Player aktiv beim Start der Anwendung + Schwebende Taste ausblenden + "Schwebende Schaltflächen wie 'Diesen Ton verwenden' werden im Tab Kurzkanal ausgeblendet." + "Schwebende Schaltflächen wie 'Diesen Ton verwenden' werden im Tab 'Kurzkanal' angezeigt." + Shorts Regale Verstecke Ausschnitte aus Shorts in Kanälen "Verstecke Shorts Regale. Nebeneffekt: Offizielle Kopfzeilen in Suchergebnissen werden ausgeblendet." + Verstecke im Kanal + "Versteckt im Kanal. + +Info: +• Nur Regale mit der Kopfzeile auf der Startseite werden versteckt." + Im Kanal anzeigen. Verstecke im Home Feed und verwandten Videos Versteckt in Home Feed und verwandten Videos. Im Home Feed und verwandte Videos anzeigen. @@ -991,12 +1339,20 @@ Nebeneffekt: Offizielle Kopfzeilen in Suchergebnissen werden ausgeblendet."Community-Beiträge im Abonnement-Feed sind versteckt. Community-Beiträge im Abonnement-Feed werden angezeigt. Verstecke im Beobachtungsverlauf + Versteckt im Verlauf. + Im Verlauf angezeigt. + Shorts-Hintergrundwiederholungsstatus ändern + Shorts Wiederholungsstatus ändern Autoplay Standard Pause Wiederholen + Öffne Shorts im regulären Spieler + Öffne Shorts im regulären Spieler. + Öffne keine Shorts im regulären Spieler. + Shorts Player Elemente im YouTube-Einstellungsmenü verstecken Kanalleiste ausblenden Kanalleiste ist ausgeblendet. @@ -1008,13 +1364,20 @@ Nebeneffekt: Offizielle Kopfzeilen in Suchergebnissen werden ausgeblendet."Infokarten werden ausgeblendet. Infokarten werden angezeigt. Teilnehmen-Schaltfläche verstecken + Teilnehmen Button ist versteckt. + Teilnehmen Button wird angezeigt. Live-Chat-Kopfzeile ausblenden Live-Chat-Kopfzeile wird ausgeblendet.\n\nZurück Button wird nicht ausgeblendet. Live-Chat-Kopfzeile wird angezeigt.\n\nZurück Button wird nicht ausgeblendet. Verstecke Label für bezahlte Promotion Label für bezahlte Promotion wird versteckt. Label für bezahlte Promotion wird angezeigt. + Pausierter Header ausblenden + Pausierter Header ist ausgeblendet. + Pausierter Header wird angezeigt. Pausierte Overlay-Tasten ausblenden + Pausierte Overlay-Tasten sind ausgeblendet. + Angehaltene Overlay-Schaltflächen werden angezeigt. Shop-Schaltfläche verstecken Shop-Schaltfläche wird versteckt. Shop-Schaltfläche wird angezeigt. @@ -1025,6 +1388,8 @@ Nebeneffekt: Offizielle Kopfzeilen in Suchergebnissen werden ausgeblendet."Sticker sind versteckt. Sticker werden angezeigt. Abonnement-Button ausblenden + Abonnieren Button ist versteckt. + Abonnieren Button wird angezeigt. Verstecke \"Trends\" Schaltfläche \"Trends\" Schaltfläche wird versteckt. \"Trends\" Schaltfläche wird angezeigt. @@ -1032,25 +1397,59 @@ Nebeneffekt: Offizielle Kopfzeilen in Suchergebnissen werden ausgeblendet."Titel ist ausgeblendet. Titel wird angezeigt. + Vorgeschlagene Maßnahmen + Green-Screen-Button ausblenden + Green-Screen-Button ist ausgeblendet. + Green-Screen-Button wird angezeigt. + Standortschaltfläche ausblenden + Standortbutton ist ausgeblendet. + Standortbutton wird angezeigt. + \'Musik speichern\'-Button ausblenden + Musik-Button speichern ist ausgeblendet. + Musikspeicher Button wird angezeigt. + Suchvorschläge ausblenden + Suchvorschläge Button ist ausgeblendet. + Suchvorschläge Button wird angezeigt. Shop-Schaltfläche verstecken + Shop-Schaltfläche wird versteckt. + Shop-Schaltfläche wird angezeigt. Super Dankeschön ausblenden \"Super Thanks\" Button wird ausgeblendet. \"Super Thanks\" Button wird angezeigt. Markierte Produkte ausblenden Markierte Produkte sind ausgeblendet. Markierte Produkte werden angezeigt. + \'Vorlage verwenden\'-Button ausblenden + Template-Schaltfläche verwenden ist ausgeblendet. + Template-Schaltfläche verwenden. + Diese Tonschaltfläche ausblenden + Verwenden Sie diese Sound-Taste ist ausgeblendet. + Verwenden Sie diesen Sound-Button wird angezeigt. Aktionsschaltflächen Verstecke \"Gefällt mir\" Button + \"Gefällt mir\" Schaltfläche ist versteckt. + Schaltfläche \"Gefällt mir\" wird angezeigt. Verstecke den Dislike-Button Dislike-Button ist versteckt. Dislike-Button wird angezeigt. Verstecke Kommentar Button + Kommentar Button wird versteckt. + Kommentar Button wird angezeigt. Verstecke Remix Button + Remix button is hidden. + Remix-Schaltfläche wird angezeigt. Verstecke \"Teilen\" Schaltfläche - Sound button is hidden. + Teilen-Schaltfläche ist versteckt. + Teilen-Schaltfläche wird angezeigt. + Tonschaltfläche ausblenden + Sound-Taste ist ausgeblendet. + Tonschaltfläche wird angezeigt. Animation / Feedback + Fontänenanimation \"Gefällt mir\" deaktivieren + Fountain Animation über der Schaltfläche \"Gefällt mir\" ist deaktiviert. + Fountain Animation über der Schaltfläche \"Gefällt mir\" ist aktiviert. Doppeltipp-Animation Original Mag ich @@ -1064,9 +1463,41 @@ Nebeneffekt: Offizielle Kopfzeilen in Suchergebnissen werden ausgeblendet." Benutzerdefinierte Aktionen Benutzerdefinierte Aktionen im Flyout-Menü aktivieren + "Benutzerdefinierte Aktionen sind im Flyout-Menü aktiviert. + +Einschränkungen: +• Funktioniert nicht mit Live-Stream." + Benutzerdefinierte Aktionen sind im Flyout-Menü deaktiviert. + Eigene Aktionen in der Symbolleiste aktivieren + "Benutzerdefinierte Aktionen sind in der Werkzeugleiste aktiviert. + +Drücken und halten Sie die Schaltfläche Mehr, um den Dialog benutzerdefinierte Aktionen anzuzeigen." + Benutzerdefinierte Aktionen sind in der Symbolleiste deaktiviert. Benutzerdefinierte Aktionen + Kopiere Zeitstempel URL + Kopierzeitstempel URL-Menü anzeigen + Kopiere Zeitstempel-URL-Menü wird angezeigt. + Kopiere Zeitstempel-URL-Menü ist ausgeblendet. Video-URL kopieren + Kopiere Video-URL-Menü anzeigen + Video-URL-Menü kopieren. + Video-URL-Menü kopieren ist ausgeblendet. + Externer Downloader + Externes Downloadmenü anzeigen + Externes Download-Menü wird angezeigt. + Externes Download-Menü ist ausgeblendet. Video öffnen + Zeige geöffnetes Video-Menü + Video-Menü wird angezeigt. + Video-Menü öffnen ist ausgeblendet. + Status wiederholen + Zeige Wiederholungsstatus Menü + Das Statusmenü wird angezeigt. + Statusmenü wiederholen ist ausgeblendet. + Über Eigene Aktionen + "Diese Funktion ist noch experimentell, so dass es keine Garantie dafür gibt, dass es perfekt funktioniert. + +Die meisten Fehler können aufgrund von Client-seitigen Einschränkungen nicht behoben werden. Verwenden Sie sie daher nur für Testzwecke." Zeitstempel aktivieren "Zeitstempel ist aktiviert. @@ -1081,12 +1512,19 @@ Bekannte Probleme: Da dies eine Funktion in der Entwicklungsphase von Google ist Navigationsleiste verstecken Navigationsleiste ist versteckt. Navigation bar is shown. + Prozentsatz des leeren Speichers + Konfigurieren Sie den Prozentsatz der Höhe des leeren Leerraums, wenn die Navigationsleiste ausgeblendet ist, zwischen 0 und 100 (%). + Die Höhe muss zwischen 0-100 (%) liegen. Toolbar verstecken Symbolleiste ist versteckt. Symbolleiste wird angezeigt. Kanalhandle ersetzen Kanalname wird verwendet. Kanalhandle wird verwendet. + Altes Player-Layout wiederherstellen + "Altes Spielerlayout wird verwendet. +Keine Ränder oben und unten des Spielers." + Altes Player-Layout wird nicht verwendet. Wischgesten Aktiviere Auto-Helligkeit durch Wischen @@ -1098,15 +1536,32 @@ Bekannte Probleme: Da dies eine Funktion in der Entwicklungsphase von Google ist Aktiviere Lautstärkegesten "Lautstärkegeste ist aktiviert" Lautstärkegeste ist deaktiviert + Helligkeit speichern und wiederherstellen aktivieren + Speichern und die Helligkeit wiederherstellen, wenn Sie den Vollbild verlassen oder betreten. + Helligkeit beim Beenden oder Vollbild nicht speichern und wiederherstellen. Aktiviere Drücken-zu-Wischgeste Berühren und halten, um die Wischgeste zu aktivieren. Berühren, um die Wischgeste zu aktivieren. Haptisches Feedback aktivieren Haptisches Feedback ist aktiviert. Haptisches Feedback ist deaktiviert. + Wischgesten im Sperrbildschirm-Modus + Wischgesten sind im Sperrbildschirm-Modus aktiviert. Wischgesten sind im Sperrbildschirmmodus deaktiviert. Wischgrößen-Schwellenwert Der Schwellenwert für das Wischen + Alternative UI Wischen überlagern + Alternatives UI wird verwendet. + Legacy-UI wird verwendet. + Aktivieren Sie den minimalistischen Stil + Minimaler Overlay-Stil ist aktiviert. + Minimaler Overlay-Stil ist deaktiviert. + Kreisförmige Überlagerung anzeigen + Kreisförmige Überlagerung wird angezeigt. + Horizontales Overlay wird angezeigt. + Wische Overlay-Hintergrund Deckkraft + Deckkraft Wert zwischen 0-100. + Wischtransparenz muss zwischen 0-100 liegen. Wischüberlagerung Textgröße Die Textgröße für Wischüberlagerung Wischüberlagerungsgröße @@ -1114,53 +1569,34 @@ Bekannte Probleme: Da dies eine Funktion in der Entwicklungsphase von Google ist Die Größe des Wischbereichs darf nicht mehr als 50 betragen. Zurückgesetzt auf Standardwert. Swipe Overlay-Zeitüberschreitung Die Anzahl der Millisekunden, die das Overlay sichtbar ist + Helligkeit wischen Empfindlichkeit + Konfiguriere den Mindestabstand für Helligkeitswischen zwischen 1 und 1000 (%).\nJe kürzer der Mindestabstand, desto schneller ändert sich die Helligkeitsstufe. + Die Helligkeitswischempfindlichkeit muss zwischen 1-1000 liegen (%). + Lautstärke-Wischen Empfindlichkeit + Konfigurieren Sie den Mindestabstand für das Wischen von Lautstärke zwischen 1 und 1000 (%).\n\nJe kürzer der Mindestabstand, desto schneller ändert sich die Lautstärke.\n\nEmpfohlene Lautstärke-Wischempfindlichkeit beträgt 100% bei 15-Volumen-Schritten und 10% bei 150-Volumen-Schritten. + Lautstärke-Wischempfindlichkeit muss zwischen 1-1000 (%) liegen. Deaktiviere automatische HDR-Helligkeit Automatische HDR-Helligkeit ist deaktiviert Automatische HDR-Helligkeit ist aktiviert Geste zum Wechseln des Videos deaktiviern Wischen nach oben / nach unten wird nicht das nächste / vorherige Video abspielen. Wischen nach oben / unten wird das nächste / vorherige Video abspielen. + Wischen deaktivieren, um in den Vollbildmodus zu gelangen (unter dem Spieler) + Unten unter dem Spieler wischen wird der Vollbildmodus nicht betreten. + Wenn du unter dem Spieler wischst, wird der Vollbildmodus geöffnet. + Wischen deaktivieren, um in den Vollbildmodus zu gelangen (im Player) + Beim Hochwischen im Player wird der Vollbildmodus nicht betreten. + Beim Hochwischen im Player wird der Vollbildmodus gewechselt. + Wischen zum Beenden des Vollbildmodus deaktivieren + Beim Wischen nach unten im Vollbildmodus wird der Vollbildmodus nicht beendet. + Beim Wischen nach unten im Vollbildmodus wird der Vollbildmodus beendet. Auto Video - Standard Wiedergabegeschwindigkeit - Standard Videoqualität im Mobilfunk - Standard-Videoqualität im Wlan + HDR-Video deaktivieren HDR-Video ist deaktiviert HDR-Video ist aktiviert - Benutzerdefinierte Wiedergabegeschwindigkeit aktivieren - Benutzerdefinierte Wiedergabegeschwindigkeit ist aktiviert - Benutzerdefinierte Wiedergabegeschwindigkeit ist deaktiviert - Menü-Typ für benutzerdefinierte Wiedergabegeschwindigkeiten - Benutzerdefinierter Dialog wird verwendet. - Altes Flyout Menü wird verwendet. - Benutzerdefinierte Wiedergabegeschwindigkeiten bearbeiten - Verfügbare Wiedergabegeschwindigkeiten hinzufügen oder ändern - Remember playback speed changes - Playback speed changes apply to all videos. - Playback speed changes only apply to the current video. - Qualitätseinstellungen merken - Qualitätseinstellungen werden für alle Videos angewendet - Qualitätseinstellungen werden nur für das aktuelle Video angewendet - Altes Qualitätsmenü wiederherstellen - Altes Qualitätsmenü wird angezeigt - Altes Qualitätsmenü wird nicht angezeigt - Standard Wiedergabegeschwindigkeit für Shorts aktivieren - Die Standard-Wiedergabegeschwindigkeit gilt für Shorts. - Die Standard-Wiedergabegeschwindigkeit gilt nicht für Shorts. - Skipped preloaded buffer. - Skip preloaded buffer - "Skips the preloaded buffer at the start of videos to immediately apply the default video quality. - -Info: -• When the video starts, there is a delay of approximately 0.3 seconds. -• Does not apply to HDR videos, live stream videos, or videos shorter than 15 seconds." - Zeige eine Benachrichtigung beim Überspringen an - Benachrichtigung wird angezeigt. - Benachrichtigung wird nicht angezeigt. - Spoof device dimensions - "Spoofs the device dimensions in order to unlock higher video qualities that may not be available on your device." VP9 Codec deaktivieren "VP9-Codec ist deaktiviert. @@ -1170,16 +1606,55 @@ Info: VP9-Codec ist aktiviert. Replace software AV1 codec Replaces the software AV1 codec with the VP9 codec. - Reject software AV1 codec response - "Forcefully rejects the software AV1 codec response. -A different codec will be applied after about 20 seconds of buffering." - Das Fallback-Verfahren führt zu etwa 20 Sekunden Pufferung. - %s ändert Standardgeschwindigkeit. - Changing default mobile data quality to %s. - Failed to set video quality. - Changing default Wi-Fi quality to %s. + + Standard Wiedergabegeschwindigkeit + Remember playback speed changes + Playback speed changes apply to all videos. + Playback speed changes only apply to the current video. + Toast anzeigen + Beim Ändern der Standard-Wiedergabegeschwindigkeit wird ein Toast angezeigt. + Beim Ändern der Standard-Wiedergabegeschwindigkeit wird kein Toast angezeigt. + Benutzerdefinierte Wiedergabegeschwindigkeit aktivieren + Benutzerdefinierte Wiedergabegeschwindigkeit ist aktiviert + Benutzerdefinierte Wiedergabegeschwindigkeit ist deaktiviert + Menü-Typ für benutzerdefinierte Wiedergabegeschwindigkeiten + Benutzerdefinierter Dialog wird verwendet. + Altes Flyout Menü wird verwendet. + Benutzerdefinierte Wiedergabegeschwindigkeiten bearbeiten + Verfügbare Wiedergabegeschwindigkeiten hinzufügen oder ändern Ungültige benutzerdefinierte Wiedergabegeschwindigkeiten. Auf Standardwerte zurücksetzen. Ungültige benutzerdefinierte Wiedergabegeschwindigkeiten. Auf Standardwerte zurücksetzen. + + Standard Videoqualität im Mobilfunk + Standard-Videoqualität im Wlan + Qualitätseinstellungen merken + Qualitätseinstellungen werden für alle Videos angewendet + Qualitätseinstellungen werden nur für das aktuelle Video angewendet + Toast anzeigen + Beim Ändern der Standard-Videoqualität wird ein Toast angezeigt. + Beim Ändern der Standard-Videoqualität wird kein Toast angezeigt. + Altes Qualitätsmenü wiederherstellen + Altes Qualitätsmenü wird angezeigt + Altes Qualitätsmenü wird nicht angezeigt + Skipped preloaded buffer. + Skip preloaded buffer + "Skips the preloaded buffer at the start of videos to immediately apply the default video quality. + +Info: +• When the video starts, there is a delay of approximately 0.3 seconds. +• Does not apply to HDR videos, live stream videos, or videos shorter than 15 seconds." + Das Einschalten dieser Einstellung kann zu Videowiedergabeproblemen führen. + Zeige eine Benachrichtigung beim Überspringen an + Benachrichtigung wird angezeigt. + Benachrichtigung wird nicht angezeigt. + Gerätemaße fälschen + + Wiedergabegeschwindigkeit für Musik deaktivieren + Die Standardgeschwindigkeit der Wiedergabe ist für Musik deaktiviert. + Die Standardgeschwindigkeit der Wiedergabe ist für Musik aktiviert. + Mit Kategorien validieren + Standardmäßig ist die Wiedergabegeschwindigkeit deaktiviert, wenn die Videokategorie Musik ist. + Die Standardgeschwindigkeit der Wiedergabe ist für Videos deaktiviert, die auf YouTube Musik abgespielt werden können. Return YouTube Dislike Return YouTube Dislike aktivieren @@ -1214,6 +1689,24 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Video neu laden, um mit Return YouTube Dislike abzustimmen Versteckt + YouTube-Benutzername zurückgeben + Retour-YouTube-Benutzername aktivieren + Benutzername wird verwendet. + Handle wird verwendet. + Stil anzeigen + Benutzername + Benutzername (@handle) + \@handle (Benutzername) + YouTube Data API Schlüssel + Der Entwicklerschlüssel für die Verwendung der YouTube Data API v3. + Über YouTube Data API Schlüssel + "Ein YouTube Data API v3 Developer Key wird benötigt, um Handles durch Benutzernamen zu ersetzen. + +Das tägliche Kontingent für API-Schlüssel auf dem kostenlosen Paket ist 10.000, und 1 Quota wird verwendet, um ein Handle durch einen Benutzernamen für 1 Kommentar zu ersetzen. + +Klicken Sie hier, um zu sehen, wie Sie einen API-Schlüssel ausgeben." + YouTube Data API v3 Entwicklerschlüssel ausgeben + 1. Gehen Sie zu <a href=%1$s>Erstellen Sie ein neues Projekt</a>.<br>. Klicken Sie auf die <b>Erstelle</b> Schaltfläche.<br>3. Gehen Sie zu <a href=%2$s>YouTube Data API v3</a>.<br>4. Klicken Sie auf <b></b> Knopf.<br>5. Klicken Sie auf <b>CREDENTIALS</b> Schaltfläche.<br>6. Wählen Sie die Option <b>Öffentliche Daten</b> aus.<br>7. Klicken Sie auf die <b>NEXT</b> Schaltfläche.<br>8. API-Schlüssel kopieren.<br><br> ※ API-Schlüssel sollte niemals mit anderen geteilt werden, daher ist er nicht in den Einstellungen Import / Export enthalten. SponsorBlock SponsorBlock aktivieren @@ -1291,6 +1784,7 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Überspringen Schaltfläche anzeigen In der Suchleiste anzeigen Deaktivieren + Deckfähigkeit: Farbe: Farbe geändert Farben zurücksetzen @@ -1303,6 +1797,8 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Button für neues Segment anzeigen Button für neues Segment wird angezeigt Button für neues Segment wird nicht angezeigt + Neuen Segmentschritt anpassen + Anzahl der Millisekunden, die sich die Zeitanpassungsschaltflächen beim Erstellen neuer Segmente bewegen. Wert muss eine positive Zahl sein Richtlinien anzeigen Richtlinien enthalten Tipps und Regeln zum Einreichen von Segmenten @@ -1315,12 +1811,16 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Zeige eine Benachrichtigung an, wenn die API nicht verfügbar ist Benachrichtigung wird angezeigt, wenn „SponsorBlock“ nicht verfügbar ist. Benachrichtigung wird nicht angezeigt, wenn „SponsorBlock“ nicht verfügbar ist. + Aktiviere Sprungzähler-Tracking + Lassen Sie die SponsorBlock Rangliste wissen, wie viel Zeit gespeichert wird. Jedes Mal, wenn ein Segment übersprungen wird, wird eine Nachricht an die Rangliste gesendet. Skip count tracking is not enabled. Minimale Segment-Dauer Segment kürzer als dieser Werte (in Sekunden) werden nicht angezeigt oder übersprungen. + Ungültige Zeitdauer. Ihre private Benutzer-ID Dies sollte privat gehalten werden. Es ist wie ein Passwort und sollte nicht an andere weitergegeben werden. Wenn jemand es hat, kann er sich für Sie ausgeben Benutzer-ID darf nicht leer sein + API URL ändern Die Addresse zum API-Server von SponsorBlock API-URL zurücksetzen. API-URL ist ungültig @@ -1332,6 +1832,7 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Einstellungen erfolgreich importiert. Importieren fehlgeschlagen: %s. Export fehlgeschlagen: %s. + Ihre Einstellungen enthalten eine private SponsorBlock Benutzeride.\n\nIhre Benutzer-Id ist wie ein Passwort und sollte nie geteilt werden.\n Do not show again SponsorBlock temporarily unavailable. SponsorBlock temporarily unavailable (status %d). @@ -1351,9 +1852,11 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Kategorie ändern Es gibt keine Segmente zur Abstimmung + %1$s bis %2$s Wähle eine Segmentkategorie aus Category is disabled in settings. Enable category to submit. Neues SponsorBlock Segment + %s als Start oder Ende eines neuen Segments festlegen? Start Ende Jetzt @@ -1378,6 +1881,7 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Benutzername wurde erfolgreich geändert Your reputation is <b>%.2f</b> You\'ve created <b>%s</b> segments + Tippen Sie hier, um Ihre Segmente anzuzeigen. SponsorBlock Rangliste You\'ve saved people from <b>%s</b> segments Hier tippen, um die globalen Statistiken und Top-Mitwirkende zu sehen @@ -1393,7 +1897,10 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." sponsor.ajay.app Die Daten werden von der SponsorBlock API bereitgestellt. Tippen Sie hier, um mehr zu erfahren und Downloads für andere Plattformen zu sehen - Sonstiges + PreferenceScreen: Sonstiges + URL-Weiterleitungen umgehen + URL-Weiterleitungen werden umgangen. + URL-Umleitungen werden nicht umgangen. QUIC-Protokoll deaktivieren "CronetEngine's QUIC-Protokoll deaktivieren" Debug-Protokollierung aktivieren @@ -1402,11 +1909,17 @@ Einschränkung: Dislikes werden im Inkognito Modus nicht angezeigt." Debug-Pufferprotokollierung aktivieren Debug-Protokolle enthalten Puffer. Debug-Protokolle enthalten keinen Puffer. + Öffne Links extern + Öffnet Links im externen Browser. + Öffnet Links im In-App-Browser. + Freigabe-Links säubern + Entfernt das Teilen von Links durch das Entfernen von Tracking-Abfrageparametern. Standard-App-Einstellungen öffnen Um RVX in einem externen Browser zu öffnen, aktivieren Sie \'Unterstützte Links öffnen\' und aktivieren Sie die unterstützen Web-Adressen GmsCore öffnen Cloud-Nachrichteneinstellungen aktivieren, um Benachrichtigungen zu erhalten GmsCore ist nicht installiert. Bitte installiere es. + Aktion erforderlich "GmsCore hat keine Berechtigung um im Hintergrund zu laufen. Folge der 'Don't kill my app!' Anleitung für dein Gerät and wende die Anweisungen auf deine GmsCore Installation an. @@ -1417,6 +1930,9 @@ Dies wird zum Funktionieren der App benötigt." Drücke Weiter und deaktiviere Akku-Optimierungen." Fortsetzen + Freigabeblatt ändern + System Share Sheet wird verwendet. + App-Freigabeblatt wird verwendet. OPUS Codec aktivieren Aktiviere den OPUS-Codec, wenn die Antwort des Players den OPUS-Codec enthält. @@ -1440,21 +1956,106 @@ Drücke Weiter und deaktiviere Akku-Optimierungen." Einstellungen zurücksetzen Einstellungen wurden erfolgreich importiert. Zurücksetzen + Einstellungen in Zwischenablage kopiert. + Spoof Streamingdaten + Spoof die Streaming-Daten, um Wiedergabeprobleme zu vermeiden. + Spoof Streamingdaten + Streaming-Daten sind gefälscht. + "Streaming-Daten sind nicht gefälscht. Videowiedergabe funktioniert möglicherweise nicht." + Das Deaktivieren dieser Einstellung kann zu Videowiedergabeproblemen führen. + Standard-Client + "Android TV +(Anmeldung erforderlich)" + Android VR + "Android VR +(Keine Authentizität)" + "iOS +(veraltet)" + "iOS TV +(Login erforderlich)" + Nebenwirkungen des Spoofings + "• Audiospurmenü fehlt. +• Stabile Lautstärke ist nicht verfügbar. +• Erzwungene automatische Audiospuren deaktivieren ist nicht verfügbar. +• Kindervideos dürfen nicht abgespielt werden, wenn sie ausgeloggt oder im Inkognito-Modus sind." + • Ganze ASNs/IP-Bereiche können vom Server blockiert werden. + "• Stabile Lautstärke ist nicht verfügbar. +• Filme oder bezahlte Videos können nicht abgespielt werden. +• Kindervideos können nicht abgespielt werden, wenn sie ausgeloggt oder im Inkognito-Modus sind." + Verwende iOS-Client + "iOS-Client zu verfügbaren Clients hinzugefügt. + +WARNUNG: iOS-Client ist veraltet. Alle Probleme, die während der Nutzung auftreten, gehen auf Ihr eigenes Risiko." + iOS-Client wurde nicht zu verfügbaren Clients hinzugefügt. + "Wenn Sie YouTube-API-Endpunkte mit iOS anfordern, benötigen Sie die Auth Token des iOS-Geräts und die von iOSGuard herausgegebenen PoToken. + +Das bedeutet, dass Streaming-Anfragen über iOS sowohl die Auth Token als auch die PoTokens fehlen und der Server kann den Benutzer als Bot betrachten und den gesamten ASN/IP-Bereich blockieren. + +BENUTZEN AUF IHREM EIGENEN RISK!" + iOS AVC (H.264) erzwingen + Video Codec ist zum AVC (H.264) gezwungen. + Video Codec wird automatisch ermittelt. + "Aktivieren Sie dies, um die Akkulaufzeit zu verbessern und Ruckeln bei der Wiedergabe zu beheben. + +AVC hat eine maximale Auflösung von 1080p, Opus-Audiocodec ist nicht verfügbar und die Videowiedergabe verbraucht mehr Internetdaten als VP9 oder AV1." + Onesie-Antwort-Verschlüsselung überspringen + "Onesie Antwortverschlüsselung überspringen. + +• Behebt einen neuen Typ von Wiedergabefehler, mit dem einige Benutzer konfrontiert sind. +• AV1 Codec ist möglicherweise nicht verfügbar." + "Onesie Antwortverschlüsselung nicht überspringen. + +• Einige Benutzer können ein neues Wiedergabeproblem erleben." + Zeigt Statistiken für Nerds + Der Client zum Abrufen von Streaming-Daten wird in Statistiken für Nerds angezeigt. + Client zum Abrufen von Streaming-Daten wird in Statistiken für Nerds versteckt. + Standard-Audiostreamsprache für VR + PoToken / VisitorData + PoToken zu verwenden + PoToken von BotGuard in einem vertrauenswürdigen Browser herausgegeben. + Zu verwendende Besucherdaten + Besucherdaten, die von BotGuard in einem vertrauenswürdigen Browser ausgegeben werden. + Über PoToken / Besucherdaten + "Einige Clients benötigen PoToken und Besucherdaten, um eine gültige Antwort auf Streaming-Daten zu erhalten. + +Wenn Sie versuchen, iOS als Standard-Client zu verwenden, benötigen Sie diese Werte. + +Klicken Sie hier, um weitere Informationen zu sehen." + Historie ansehen + Einstellungen im Zusammenhang mit dem Beobachtungsverlauf ändern. + Alle Chronik verwalten + Klicken Sie hier, um die Verwaltung der YouTube Beobachtungsverlauf zu öffnen. + Überwachungsverlaufstyp + Original + Domain ersetzen + Blocküberwachungsverlauf + Status des Überwachungsverlaufs + • Überwachungsverlauf blockiert. + • Folgen Sie den Einstellungen für den Verlauf von Google-Konto. + "• Folgt den Einstellungen des Beobachtungsverlaufs von Google-Konto. +• Überwachungsverlauf kann aufgrund von DNS oder VPN nicht funktionieren." Patch-Informationen Patch-Informationen Informationen über angewandte Patches + Werkzeug verwendet + Andere + Benutzerdefiniert Stock Afn Blau Afn Rot MMT + Revancify Blau + Revancify Rot YouTube Stock + ausgeschlossen + Enthalten Stock diff --git a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml index e7d129fcc..12a04b89a 100644 --- a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml +++ b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml @@ -19,6 +19,38 @@ "Το %1$s δεν είναι εγκατεστημένο. Παρακαλούμε εγκαταστήστε το %2$s από την ιστοσελίδα." %s δεν έχει εγκατασταθεί. Παρακαλούμε εγκαταστήστε το. + Προσθήκη στην ουρά + Προσθήκη στην ουρά και άνοιγμα ουράς + Προσθήκη στην ουρά και αναπαραγωγή βίντεο + Εξωτερικό πρόγραμμα λήψης + Άνοιγμα ουράς + Ουρά + Αφαίρεση από την ουρά + Αφαίρεση από την ουρά και άνοιγμα ουράς + Κατάργηση ουράς + Αποθήκευση ουράς + "Αντί να ανοίξετε ένα εξωτερικό πρόγραμμα λήψης, ανοίξτε το παράθυρο διαχείρισης ουράς. + +Μπορείτε επίσης να ανοίξετε τον διαχειριστή ουράς πατώντας παρατεταμένα το κουμπί επιστροφής στη γραμμή πλοήγησης. + +Αυτή η λειτουργία είναι ακόμη υπό ανάπτυξη, οπότε οι περισσότερες λειτουργίες μπορεί να μη λειτουργούν. + +Παρακαλούμε χρησιμοποιήστε την για σκοπούς εντοπισμού σφαλμάτων μόνο." + Απαιτείται σύνδεση + Διαχειριστής ουράς μη διαθέσιμος (%s). + Αδυναμία αναγνώρισης λίστας αναπαραγωγής + Η ουρά είναι κενή + Αδυναμία αναγνώρισης βίντεο + Αποτυχία προσθήκης βίντεο. + Αποτυχία δημιουργίας ουράς. + Αποτυχία διαγραφής ουράς. + Αποτυχία αφαίρεσης βίντεο. + Αποτυχία αποθήκευσης της ουράς. + Το βίντεο προστέθηκε επιτυχώς. + Η ουρά δημιουργήθηκε επιτυχώς. + Η ουρά διαγράφηκε επιτυχώς. + Το βίντεο αφαιρέθηκε επιτυχώς. + Η ουρά αποθηκεύτηκε επιτυχώς στο \'%s\'. Γλώσσα ρυθμίσεων RVX Γλώσσα εφαρμογής "Αμχαρικά @@ -497,6 +529,7 @@ Playlists Απενεργοποίηση διαφανούς γραμμής κατάστασης Η γραμμή κατάστασης δεν είναι διαφανής. Η διαφάνεια της γραμμής κατάστασης ορίζεται αυτόματα. + Σε ορισμένες εργοστασιακές ROM που τρέχουν Android 12+, η ενεργοποίηση αυτής της λειτουργίας μπορεί να κάνει τη γραμμή πλοήγησης του συστήματος διαφανή. Παραποίηση έκδοσης εφαρμογής Η έκδοση παραποιείται. Η έκδοση δεν παραποιείται. @@ -553,6 +586,9 @@ Playlists Μετατροπή κουμπιού λήψης βίντεο Το κουμπί λήψης του YouTube ανοίγει το εξωτερικό πρόγραμμα λήψης σας. Το κουμπί λήψης του YouTube ανοίγει το εγγενές πρόγραμμα λήψης της εφαρμογής. + Διαχειριστής ουράς + Το κουμπί λήψης βίντεο του YouTube ανοίγει τον διαχειριστή ουράς. + Το κουμπί λήψης βίντεο του YouTube ανοίγει το εξωτερικό πρόγραμμα λήψης σας. Όνομα πακέτου προγράμματος λήψης λίστας αναπαραγωγής Όνομα πακέτου της εγκατεστημένης σας εξωτερικής εφαρμογής λήψης (π.χ YTLDnis). @@ -1190,6 +1226,8 @@ Playlists Εξωτερική λήψη του βίντεο Κουμπί εξωτερικής λήψης του βίντεο. Πατήστε για εκκίνηση του προεπιλεγμένου σας εξωτερικού προγράμματος λήψης. + Διαχειριστής ουράς + Αντί να ανοίξετε ένα εξωτερικό πρόγραμμα λήψης, ανοίξτε τον διαχειριστή ουράς. Αλλαγή ταχύτητας αναπαραγωγής "Κουμπί ρύθμισης ταχύτητας αναπαραγωγής. Πατήστε για να ανοίξετε το παράθυρο αλλαγής ταχύτητας αναπαραγωγής. @@ -1524,6 +1562,10 @@ Playlists Εμφάνιση μενού ανοίγματος του βίντεο Το μενού ανοίγματος του βίντεο εμφανίζεται. Το μενού ανοίγματος του βίντεο δεν εμφανίζεται. + Παράθυρο αλλαγής ταχύτητας + Εμφάνιση μενού αλλαγής ταχύτητας + Εμφανίζεται. + Δεν εμφανίζεται. Κατάσταση επανάληψης Εμφάνιση μενού κατάστασης επανάληψης Το μενού κατάστασης επανάληψης εμφανίζεται. @@ -1567,10 +1609,14 @@ Playlists Η χαμηλότερη τιμή της χειρονομίας φωτεινότητας ενεργοποιεί την αυτόματη φωτεινότητα. Η χαμηλότερη τιμή της χειρονομίας φωτεινότητας δεν ενεργοποιεί την αυτόματη φωτεινότητα. Έλεγχος σάρωσης για Φωτεινότητα - "Η αλλαγή φωτεινότητας με χειρονομία σάρωσης στην αριστερή πλευρά της οθόνης είναι ενεργοποιημένη." + "Η χειρονομία σάρωσης για αλλαγή φωτεινότητας στην πλήρη οθόνη είναι ενεργοποιημένη. + +Προσαρμόστε τη φωτεινότητα σαρώνοντας κάθετα στην αριστερή πλευρά της οθόνης." Η αλλαγή φωτεινότητας με χειρονομία σάρωσης στην αριστερή πλευρά της οθόνης είναι απενεργοποιημένη. Έλεγχος σάρωσης για Ένταση Ήχου - "Η αλλαγή έντασης ήχου με χειρονομία σάρωσης στη δεξιά πλευρά της οθόνης είναι ενεργοποιημένη." + "Η χειρονομία σάρωσης για αλλαγή έντασης ήχου στην πλήρη οθόνη είναι ενεργοποιημένη. + +Προσαρμόστε την ένταση ήχου σαρώνοντας κάθετα στη δεξιά πλευρά της οθόνης." Η αλλαγή έντασης ήχου με χειρονομία σάρωσης στη δεξιά πλευρά της οθόνης είναι απενεργοποιημένη. Αποθήκευση και επαναφορά φωτεινότητας Η φωτεινότητα αποθηκεύεται και επαναφέρεται κατά την έξοδο ή την είσοδο σε πλήρη οθόνη. @@ -1586,6 +1632,18 @@ Playlists Οι χειρονομίες σάρωσης είναι απενεργοποιημένες στη λειτουργία «Οθόνη κλειδώματος». Κατώτατο όριο μεγέθους σάρωσης Ελάχιστο πλάτος κίνησης αναγνωρίσιμο ως χειρονομία σάρωσης. + Εναλλακτική διεπαφή χρήστη για σάρωση + Χρησιμοποιείται η εναλλακτική διεπαφή χρήστη. + Χρησιμοποιείται η παλιά διεπαφή χρήστη. + Διάταξη μινιμαλιστικού στυλ + Το μινιμαλιστικό στυλ διάταξης των ελέγχων σάρωσης είναι ενεργοποιημένο. + Το μινιμαλιστικό στυλ διάταξης των ελέγχων σάρωσης είναι απενεργοποιημένο. + Εμφάνιση κυκλικής διάταξης + Η διάταξη των ελέγχων σάρωσης είναι κυκλική. + Η διάταξη των ελέγχων σάρωσης είναι οριζόντια. + Αδιαφάνεια φόντου σάρωσης + Τιμή αδιαφάνειας μεταξύ 0-100. + Η αδιαφάνεια σάρωσης πρέπει να είναι μεταξύ 0-100. Μέγεθος κειμένου φόντου σάρωσης Το μέγεθος κειμένου στοιχείων ελέγχου του φόντου σάρωσης. Μέγεθος περιοχής οθόνης σάρωσης @@ -1617,12 +1675,41 @@ Playlists Αυτόματη Βίντεο - Προεπιλεγμένη ταχύτητα αναπαραγωγής - Προεπιλεγμένη ποιότητα βίντεο με δεδομένα κινητής τηλεφωνίας - Προεπιλεγμένη ποιότητα βίντεο με Wi-Fi + + Κωδικοποιητής Απενεργοποίηση βίντεο HDR Τα βίντεο που υποστηρίζουν HDR δεν αναπαράγονται σε HDR ποιότητα. Τα βίντεο που υποστηρίζουν HDR αναπαράγονται σε HDR ποιότητα. + Απενεργοποίηση κωδικοποιητή VP9 + "Ο κωδικοποιητής VP9 είναι απενεργοποιημένος. + +• Η μέγιστη ανάλυση είναι 1080p. +• Η αναπαραγωγή βίντεο θα χρησιμοποιεί περισσότερα δεδομένα Internet από τον VP9. +• Για την αναπαραγωγή βίντεο τύπου HDR, ο κωδικοποιητής VP9 εξακολουθεί να χρησιμοποιείται." + Ο κωδικοποιητής VP9 είναι ενεργοποιημένος. + Αντικατάσταση κωδικοποιητή AV1 + Αντικατάσταση του κωδικοποιητή λογισμικού AV1 με τον κωδικοποιητή VP9. + + Ταχύτητα αναπαραγωγής + Προεπιλεγμένη ταχύτητα αναπαραγωγής + Απομνημόνευση αλλαγών ταχύτητας αναπαραγωγής + Οι αλλαγές ταχύτητας αναπαραγωγής ισχύουν για όλα τα βίντεο. + Οι αλλαγές ταχύτητας αναπαραγωγής ισχύουν μόνο για το τρέχον βίντεο. + Εμφάνιση μηνύματος + Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή προεπιλεγμένης ταχύτητας αναπαραγωγής. + Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή προεπιλεγμένης ταχύτητας αναπαραγωγής. + Προεπιλεγμένη ταχύτητα αναπαραγωγής στα Shorts + Απομνημόνευση αλλαγών ταχύτητας αναπαραγωγής στα Shorts + "Οι αλλαγές ταχύτητας αναπαραγωγής ισχύουν για όλα τα Shorts. + +Πληροφορίες: +Ο μόνος τρόπος για αλλαγή της ταχύτητας αναπαραγωγής στα Shorts είναι η χρήση της λειτουργίας «Παράθυρο αλλαγής ταχύτητας» στις «Προσαρμοσμένες ενέργειες». Αν δεν συμπεριλάβατε την τροποποίηση «Shorts components», δε θα είναι διαθέσιμα." + Οι αλλαγές ταχύτητας αναπαραγωγής ισχύουν μόνο για το τρέχον Short. + Εμφάνιση μηνύματος + Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή της προεπιλεγμένης ταχύτητας αναπαραγωγής στα Shorts. + Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή της προεπιλεγμένης ταχύτητας αναπαραγωγής στα Shorts. + Η προεπιλεγμένη ταχύτητα άλλαξε σε: %s. + Η προεπιλεγμένη ταχύτητα Shorts άλλαξε σε: %s. Προσαρμοσμένη ταχύτητα αναπαραγωγής Η προσαρμοσμένη ταχύτητα αναπαραγωγής είναι ενεργοποιημένη. Η προσαρμοσμένη ταχύτητα αναπαραγωγής είναι απενεργοποιημένη. @@ -1631,30 +1718,33 @@ Playlists Εμφανίζεται το αναδυόμενο μενού παλιού στυλ. Επεξεργασία ταχυτήτων αναπαραγωγής Προσθέστε ή αλλάξτε τις διαθέσιμες ταχύτητες αναπαραγωγής. - Απομνημόνευση αλλαγών ταχύτητας αναπαραγωγής - Οι αλλαγές ταχύτητας αναπαραγωγής ισχύουν για όλα τα βίντεο. - Οι αλλαγές ταχύτητας αναπαραγωγής ισχύουν μόνο για το τρέχον βίντεο. - Εμφάνιση μηνύματος - Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή προεπιλεγμένης ταχύτητας αναπαραγωγής. - Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή προεπιλεγμένης ταχύτητας αναπαραγωγής. + Οι ταχύτητες πρέπει να είναι μικρότερες από %sx. + Μη έγκυρες ταχύτητες αναπαραγωγής. + + Ποιότητα βίντεο + Προεπιλεγμένη ποιότητα βίντεο σε δίκτυο κινητής τηλεφωνίας + Προεπιλεγμένη ποιότητα βίντεο σε δίκτυο Wi-Fi Απομνημόνευση αλλαγών ποιότητας βίντεο Οι αλλαγές ποιότητας ισχύουν για όλα τα βίντεο. Οι αλλαγές ποιότητας ισχύουν μόνο για το τρέχον βίντεο. Εμφάνιση μηνύματος Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή προεπιλεγμένης ποιότητας βίντεο. Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή προεπιλεγμένης ποιότητας βίντεο. + Προεπιλεγμένη ποιότητα Shorts σε δίκτυο κινητής τηλεφωνίας + Προεπιλεγμένη ποιότητα Shorts σε δίκτυο Wi-Fi + Απομνημόνευση αλλαγών ποιότητας στα Shorts + Οι αλλαγές ποιότητας ισχύουν για όλα τα Shorts. + Οι αλλαγές ποιότητας ισχύουν μόνο για το τρέχον Short. + Εμφάνιση μηνύματος + Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή της προεπιλεγμένης ποιότητας στα Shorts. + Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης κατά την αλλαγή της προεπιλεγμένης ποιότητας στα Shorts. + δεδομένων + Wi-Fi + Η προεπιλεγμένη ποιότητα %1$s άλλαξε σε: %2$s. + Η προεπιλεγμένη ποιότητα Shorts με %1$s άλλαξε σε %2$s. Μενού ποιότητας βίντεο παλιού στυλ Εμφανίζεται το μενού αλλαγής ποιότητας βίντεο παλιού στυλ. Εμφανίζεται το μενού αλλαγής ποιότητας βίντεο νέου στυλ. - Απενεργοποίηση αλλαγής ταχύτητας σε βίντεο μουσικής - Η προεπιλεγμένη ταχύτητα δεν εφαρμόζεται σε βίντεο μουσικής. - Η προεπιλεγμένη ταχύτητα εφαρμόζεται σε βίντεο μουσικής. - Επικύρωση με βάση τις κατηγορίες - Η προεπιλεγμένη ταχύτητα αναπαραγωγής είναι απενεργοποιημένη αν η κατηγορία βίντεο είναι μουσική. - Η προεπιλεγμένη ταχύτητα αναπαραγωγής είναι απενεργοποιημένη για βίντεο που μπορούν να αναπαραχθούν στο YouTube Music. - Αλλαγή προεπιλεγμένης ταχύτητας Shorts - Η προεπιλεγμένη ταχύτητα αναπαραγωγής εφαρμόζεται στα Shorts. - Η προεπιλεγμένη ταχύτητα αναπαραγωγής δεν εφαρμόζεται στα Shorts. Η προφόρτωση βίντεο παραλείφθηκε. Παράλειψη προφόρτωσης βίντεο "Παράλειψη προφόρτωσης στην αρχή του βίντεο, ώστε να γίνει άμεση εφαρμογή της προεπιλεγμένης ποιότητας. @@ -1666,27 +1756,18 @@ Playlists Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης. Δεν εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης. Παραποίηση διαστάσεων συσκευής - "Παραποίηση διαστάσεων συσκευής στη μέγιστη τιμή. -Ενδέχεται να ξεκλειδωθούν υψηλότερες ποιότητες σε κάποια βίντεο που απαιτούν υψηλές διαστάσεις συσκευής, αλλά όχι σε όλα τα βίντεο." - Απενεργοποίηση κωδικοποιητή VP9 - "Ο κωδικοποιητής VP9 είναι απενεργοποιημένος. + "Παραποίηση των διαστάσεων συσκευής στη μέγιστη τιμή. -• Η μέγιστη ανάλυση είναι 1080p. -• Η αναπαραγωγή βίντεο θα χρησιμοποιεί περισσότερα δεδομένα Internet από τον VP9. -• Για την αναπαραγωγή βίντεο τύπου HDR, ο κωδικοποιητής VP9 εξακολουθεί να χρησιμοποιείται." - Ο κωδικοποιητής VP9 είναι ενεργοποιημένος. - Αντικατάσταση κωδικοποιητή AV1 - Αντικατάσταση του κωδικοποιητή λογισμικού AV1 με τον κωδικοποιητή VP9. - Απόρριψη απόκρισης κωδικοποιητή AV1 - "Εξαναγκαστική απόρριψη της απόκρισης του κωδικοποιητή λογισμικού AV1. -Μετά από περίπου 20 δευτερόλεπτα φόρτωσης, θα γίνεται αλλαγή σε διαφορετικό κωδικοποιητή." - Η διαδικασία προκαλεί περίπου 20 δευτερόλεπτα φόρτωσης. - Η προεπιλεγμένη ταχύτητα άλλαξε σε %s. - Η προεπιλεγμένη ποιότητα δεδομένων άλλαξε σε %s. - Αποτυχία ορισμού ποιότητας βίντεο. - Η προεπιλεγμένη ποιότητα με Wi-Fi άλλαξε σε %s. - Οι ταχύτητες πρέπει να είναι μικρότερες από %sx. - Μη έγκυρες ταχύτητες αναπαραγωγής. +Πληροφορίες: +• Ενδέχεται να ξεκλειδωθούν υψηλότερες ποιότητες βίντεο σε ορισμένα βίντεο που απαιτούν μεγάλες διαστάσεις συσκευής, αλλά όχι σε όλα. +• Αυτή η λειτουργία δεν είναι διαθέσιμη αν η λειτουργία «Παραποίηση ροών βίντεο» είναι ενεργοποιημένη." + + Απενεργοποίηση αλλαγής ταχύτητας σε βίντεο μουσικής + Η προεπιλεγμένη ταχύτητα δεν εφαρμόζεται σε βίντεο μουσικής. + Η προεπιλεγμένη ταχύτητα εφαρμόζεται σε βίντεο μουσικής. + Επικύρωση με βάση τις κατηγορίες + Η προεπιλεγμένη ταχύτητα αναπαραγωγής είναι απενεργοποιημένη αν η κατηγορία βίντεο είναι μουσική. + Η προεπιλεγμένη ταχύτητα αναπαραγωγής είναι απενεργοποιημένη για βίντεο που μπορούν να αναπαραχθούν στο YouTube Music. Return YouΤube Dislike Επιστροφή του «Δεν μου αρέσει» στο YouTube @@ -1816,6 +1897,7 @@ Playlists Εμφάνιση κουμπιού παράλειψης Εμφάνιση στη γραμμή προόδου Απενεργοποίηση + Αδιαφάνεια: Χρώμα: Το χρώμα άλλαξε. Το χρώμα επαναφέρθηκε. @@ -1883,6 +1965,7 @@ Playlists Αλλαγή κατηγορίας Δεν υπάρχουν τμήματα προς ψήφιση. + %1$s έως %2$s Επιλέξτε την κατηγορία τμήματος Η κατηγορία είναι απενεργοποιημένη στις ρυθμίσεις. Ενεργοποιήστε την κατηγορία για υποβολή. Νέο τμήμα SponsorBlock @@ -2004,6 +2087,8 @@ Playlists Android VR "Android VR (χωρίς auth)" + "iOS +(Ξεπερασμένο)" "iOS TV (Απαιτείται σύνδεση)" Παρενέργειες παραποίησης @@ -2011,9 +2096,20 @@ Playlists • Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη. • Η λειτουργία «Απενεργοποίηση υποχρεωτικών κομματιών ήχου» δεν είναι διαθέσιμη. • Τα βίντεο για παιδιά ενδέχεται να μην αναπαράγονται αν είστε αποσυνδεμένοι ή σε λειτουργία ανώνυμης περιήγησης." + • Ολόκληρα αυτόνομα συστήματα (ASN) ή εύρη διευθύνσεων IP ενδέχεται να αποκλειστούν από τον διακομιστή. "• Η λειτουργία «Σταθερή ένταση» δεν είναι διαθέσιμη. • Οι ταινίες ή τα επί πληρωμή βίντεο ενδέχεται να μην αναπαράγονται. • Τα βίντεο για παιδιά ενδέχεται να μην αναπαράγονται αν είστε αποσυνδεμένοι ή σε λειτουργία ανώνυμης περιήγησης." + Χρήση του προγράμματος πελάτη iOS + "Το iOS προστέθηκε στα διαθέσιμα προγράμματα πελάτη. + +ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το πρόγραμμα πελάτη iOS είναι ξεπερασμένο. Οποιοδήποτε θέμα προκύψει κατά τη χρήση του είναι με δική σας ευθύνη." + Το iOS δεν προστέθηκε στα διαθέσιμα προγράμματα πελάτη. + "Κατά την αποστολή αιτημάτων προς το YouTube API endpoint μέσω iOS, απαιτούνται τα Auth token που εκδίδονται από τη συσκευή iOS και τα PoToken που εκδίδονται από το iOSGuard. + +Αυτό σημαίνει ότι τα αιτήματα ροής μέσω iOS δεν θα περιλαμβάνουν ούτε τα Auth token ούτε τα PoToken, γεγονός που μπορεί να οδηγήσει τον διακομιστή στο να θεωρήσει τον χρήστη ως bot και να αποκλείσει ολόκληρο το ASN ή τα εύρη διευθύνσεων IP. + +ΧΡΗΣΙΜΟΠΟΙΗΣΤΕ ΤΟ ΜΕ ΔΙΚΗ ΣΑΣ ΕΥΘΥΝΗ!" Εξαναγκασμός iOS AVC (H.264) Ο κωδικοποιητής βίντεο έχει οριστεί υποχρεωτικά σε AVC (H.264). Ο κωδικοποιητής βίντεο ορίζεται αυτόματα. @@ -2032,6 +2128,8 @@ Playlists Το πρόγραμμα πελάτη που χρησιμοποιείται για τη λήψη δεδομένων ροής εμφανίζεται στο μενού «Στατιστικά για σπασίκλες». Το πρόγραμμα πελάτη που χρησιμοποιείται για τη λήψη δεδομένων ροής δεν εμφανίζεται στο μενού «Στατιστικά για σπασίκλες». Προεπιλεγμένη γλώσσα ροής ήχου VR + Αδυναμία λήψης ροής του προγράμματος πελάτη. + Μπορεί να μην έχετε συνδεθεί. PoToken / VisitorData PoToken προς χρήση diff --git a/patches/src/main/resources/youtube/translations/es-rES/strings.xml b/patches/src/main/resources/youtube/translations/es-rES/strings.xml index 478023eeb..6ccc07135 100644 --- a/patches/src/main/resources/youtube/translations/es-rES/strings.xml +++ b/patches/src/main/resources/youtube/translations/es-rES/strings.xml @@ -1543,6 +1543,10 @@ Mantén pulsado el botón Más para mostrar el cuadro de diálogo Acciones perso Mostrar menú de abrir vídeo El menú de abrir vídeo está visible. El menú de abrir vídeo está oculto. + Diálogo de velocidad + Mostrar menú de diálogo de velocidad + El menú de diálogo de velocidad está visible. + El menú de diálogo de velocidad está oculto. Estado de repetición Mostrar menú de estado de repetición El menú del estado de repetición está visible. @@ -1646,12 +1650,42 @@ No hay márgenes en la parte superior e inferior del reproductor." Automático Vídeo - Velocidad predeterminada de reproducción - Calidad predeterminada de vídeo en red móvil - Calidad predeterminada de vídeo en red Wi-Fi + + Códec Desactivar vídeo HDR El vídeo HDR está desactivado. El vídeo HDR está activado. + Desactivar códec VP9 + "El códec VP9 está desactivado. + +• La resolución máxima es 1080p. +• La reproducción de vídeo utilizará más datos de Internet que VP9. +• Para obtener reproducción HDR, el vídeo HDR sigue utilizando el códec VP9." + El códec VP9 está activado. + Reemplazar códec AV1 del software + Reemplaza el códec AV1 del software con el códec VP9. + + Velocidad de reproducción + Velocidad predeterminada de reproducción + Recordar cambios de velocidad de reproducción + Los cambios de velocidad de reproducción se aplican a todos los vídeos. + Los cambios de velocidad de reproducción solo se aplican al vídeo actual. + Mostrar un mensaje + Se mostrará un mensaje al cambiar la velocidad de reproducción predeterminada. + No se mostrará un mensaje al cambiar la velocidad de reproducción predeterminada. + Velocidad predeterminada de reproducción en Shorts + Recordar cambios de velocidad de reproducción en Shorts + "Los cambios en la velocidad de reproducción se aplican a todos los Shorts. + +Información: +• La única forma de cambiar la velocidad de reproducción en el reproductor de Shorts es usar el 'Diálogo de velocidad' en 'Acciones personalizadas'. +• Si no incluyó el parche 'Componentes de Shorts', esto no estaría disponible." + Los cambios de velocidad de reproducción solo se aplican al Short actual. + Mostrar un mensaje + Se mostrará un mensaje al cambiar la velocidad predeterminada de reproducción en los Shorts. + No se mostrará un mensaje al cambiar la velocidad predeterminada de reproducción en los Shorts. + Se ha cambiado la velocidad predeterminada de reproducción a: %s. + Se ha cambiado la velocidad predeterminada de reproducción de Shorts a: %s. Activar velocidad personalizada de reproducción La velocidad personalizada de reproducción está activada. La velocidad personalizada de reproducción está desactivada. @@ -1660,30 +1694,33 @@ No hay márgenes en la parte superior e inferior del reproductor." Se utiliza el antiguo estilo del panel desplegable. Editar velocidades personalizadas de reproducción Añadir o cambiar las velocidades de reproducción disponibles. - Recordar cambios de velocidad de reproducción - Los cambios de velocidad de reproducción se aplican a todos los vídeos. - Los cambios de velocidad de reproducción solo se aplican al vídeo actual. - Mostrar un mensaje - Se mostrará un mensaje al cambiar la velocidad de reproducción predeterminada. - No se mostrará un mensaje al cambiar la velocidad de reproducción predeterminada. + Las velocidades personalizadas deben ser inferiores a %sx. Utilizando valores predeterminados. + Velocidades personalizadas de reproducción no válidas. Utilizando valores predeterminados. + + Calidad de vídeo + Calidad predeterminada de vídeo en red móvil + Calidad predeterminada de vídeo en red Wi-Fi Recordar cambios de calidad de vídeo Los cambios de calidad se aplican a todos los vídeos. Los cambios de calidad solo se aplican al vídeo actual. Mostrar un mensaje Se mostrará un mensaje al cambiar la calidad de vídeo predeterminada. No se mostrará un mensaje al cambiar la calidad de vídeo predeterminada. + Calidad predeterminada de Shorts en red móvil + Calidad predeterminada de Shorts en red Wi-Fi + Recordar cambios de calidad de Shorts + Los cambios de calidad se aplican a todos los Shorts. + Los cambios de calidad solo se aplican al Short actual. + Mostrar un mensaje + Se mostrará un mensaje al cambiar la calidad predeterminada de los Shorts. + No se mostrará un mensaje al cambiar la calidad predeterminada de los Shorts. + móvil + Wi-Fi + Se ha cambiado la calidad %1$s predeterminada a: %2$s. + Se ha cambiado la calidad %1$s de los Shorts a: %2$s. Restaurar antiguo menú de calidad de vídeo El antiguo menú de calidad de vídeo está visible. El antiguo menú de calidad de vídeo está oculto. - Desactivar velocidad de reproducción para música - La velocidad predeterminada de reproducción está desactivada para la música. - La velocidad predeterminada de reproducción está activada para la música. - Validar mediante categorías - La velocidad predeterminada de reproducción se desactiva si la categoría de vídeo es Música. - La velocidad predeterminada de reproducción está desactivada para los vídeos reproducibles en YouTube Music. - Activar velocidad predeterminada de reproducción de Shorts - La velocidad predeterminada de reproducción se aplica a los Shorts. - La velocidad predeterminada de reproducción no se aplica a los Shorts. Búfer precargado omitido. Omitir búfer precargado "Omite el búfer precargado al iniciar el vídeo para evitar la demora en la aplicación de la calidad predeterminada del video. @@ -1695,26 +1732,18 @@ No hay márgenes en la parte superior e inferior del reproductor." El mensaje está visible. El mensaje está oculto. Falsificar dimensiones del dispositivo - "Falsifica las dimensiones del dispositivo para desbloquear calidades de vídeo superiores que pueden no estar disponibles en tu dispositivo." - Desactivar códec VP9 - "El códec VP9 está desactivado. + "Falsifica las dimensiones del dispositivo al valor máximo. -• La resolución máxima es 1080p. -• La reproducción de vídeo utilizará más datos de Internet que VP9. -• Para obtener reproducción HDR, el vídeo HDR sigue utilizando el códec VP9." - El códec VP9 está activado. - Reemplazar códec AV1 del software - Reemplaza el códec AV1 del software con el códec VP9. - Rechazar respuesta del códec AV1 del software - "Rechaza fuertemente la respuesta del códec AV1 del software. -Después de unos 20 segundos de búfer, cambia a un códec diferente." - El proceso de Fallback causa unos 20 segundos de búfer. - Cambiando la velocidad predeterminada a %s. - Cambiando la calidad predeterminada con datos móviles a %s. - Error al establecer la calidad de vídeo. - Cambiando la calidad predeterminada con Wi-Fi a %s. - Las velocidades personalizadas deben ser inferiores a %sx. Utilizando valores predeterminados. - Velocidades personalizadas de reproducción no válidas. Utilizando valores predeterminados. +Información: +• La alta calidad puede ser desbloqueada en algunos vídeos que requieren altas dimensiones del dispositivo, pero no en todos los vídeos. +• Este ajuste no está disponible si está activada la opción 'Falsificar datos de streaming'." + + Desactivar velocidad de reproducción para música + La velocidad predeterminada de reproducción está desactivada para la música. + La velocidad predeterminada de reproducción está activada para la música. + Validar mediante categorías + La velocidad predeterminada de reproducción se desactiva si la categoría de vídeo es Música. + La velocidad predeterminada de reproducción está desactivada para los vídeos reproducibles en YouTube Music. Return YouTube Dislike Activar Return YouTube Dislike @@ -2071,6 +2100,8 @@ AVC tiene una resolución máxima de 1080p, el códec de audio Opus no está dis El cliente utilizado para obtener datos de transmisión se muestra en estadísticas para nerds. El cliente utilizado para obtener datos de transmisión no se muestra en estadísticas para nerds. Idioma de transmisión de audio por defecto VR + No se han podido obtener las transmisiones de ningún cliente. + Puede que no hayas iniciado sesión. PoToken / VisitorData PoToken a utilizar diff --git a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml index 8f75ed08f..0e769ed8d 100644 --- a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml +++ b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml @@ -534,6 +534,7 @@ Les modifications incluent : Désactiver la barre de notification translucide La barre de notification est opaque. La barre de notification est opaque ou translucide. + Pour certaines ROMs de fabricants fonctionnant sous Android 12 ou supérieur, l\'activation de cette fonctionnalité peut rendre la barre de navigation du système transparente. Falsifier la version de l\'app Version falsifiée Version non falsifiée @@ -1612,6 +1613,18 @@ Pas de marges en haut et en bas du lecteur." Les contrôles par gestes sont désactivés en mode \'Écran verrouillé\'. Intensité des gestes Seuil de déclenchement pour que le geste de balayage se produise. + Interface alternative à l\'overlay par geste + L\'interface alternative est utilisée. + L\'ancienne interface est utilisée. + Activer le style minimaliste + Le style minimaliste d\'overlay est activé. + Le style minimaliste d\'overlay est désactivé. + Afficher l\'overlay circulaire + L\'overlay circulaire est affiché. + L\'overlay horizontal est affiché. + Opacité de l\'arrière-plan de l\'overlay par geste + Valeur d\'opacité entre 0-100. + L\'opacité doit être comprise entre 0 et 100 pour les gestes. Taille du texte superposé La taille du texte pendant le voile lors du geste. Taille de la zone de gestes @@ -1643,12 +1656,27 @@ Pas de marges en haut et en bas du lecteur." Auto Vitesses et qualités vidéo - Vitesse de lecture par défaut - Qualité vidéo par défaut sur les données mobiles - Qualité vidéo par défaut sur le réseau Wi-Fi + Déaactiver les vidéos HDR Les vidéos en HDR sont désactivés. Les vidéos en HDR sont activés. + Désactiver le codec VP9 + "Le codec VP9 est désactivé. + +• La résolution maximale est en 1080p. +• La lecture vidéo utilisera plus de données internet que le VP9. +• Le codec VP9 est également utilisé pour les vidéos HDR." + Le codec VP9 est activé. + Remplacer le codec AV1 + Remplacer le codec AV1 par le codec VP9. + + Vitesse de lecture par défaut + Enreg. modif. de la vitesse de lecture + La modification de vitesse de lecture est appliqué pour toutes les vidéos. + La modification de la vitesse de lecture est appliqué pour la vidéo en cours. + Afficher un message + Un message sera affiché lorsque vous modifiez la vitesse de lecture par défaut. + Un message ne sera pas affiché lorsque vous modifiez la vitesse de lecture par défaut. Activer vitesses de lecture perso. Les vitesses de lecture personnalisées sont activées. Les vitesses de lecture personnalisées sont désactivées. @@ -1657,12 +1685,11 @@ Pas de marges en haut et en bas du lecteur." L\'ancien style du menu déroulant est utilisé. Saisir des vitesses de lecture personnalisées Ajouter ou modifier les vitesses de lecture disponibles. - Enreg. modif. de la vitesse de lecture - La modification de vitesse de lecture est appliqué pour toutes les vidéos. - La modification de la vitesse de lecture est appliqué pour la vidéo en cours. - Afficher un message - Un message sera affiché lorsque vous modifiez la vitesse de lecture par défaut. - Un message ne sera pas affiché lorsque vous modifiez la vitesse de lecture par défaut. + Les vitesses personnalisées doivent être inférieures à %sx. + Valeur des vitesses de lecture invalide. + + Qualité vidéo par défaut sur les données mobiles + Qualité vidéo par défaut sur le réseau Wi-Fi Enreg. modification de la qualité La modification de la résolution est appliqué pour toutes les vidéos. La modification de la résolution est appliqué pour la vidéo en cours. @@ -1672,15 +1699,6 @@ Pas de marges en haut et en bas du lecteur." Restaur. ancien. interface de qualité vidéo Affiche l\'ancienne interface de qualité vidéo. Masque la nouvelle interface de qualité vidéo. - Désactiver la vitesse de lecture pour la musique - La vitesse de lecture par défaut est activée pour la musique. - La vitesse de lecture par défaut est activée pour la musique. - Valider en utilisant les catégories - La vitesse de lecture par défaut est désactivée si la catégorie de la vidéo est Musique. - La vitesse de lecture par défaut est désactivée pour les vidéos lues sur YouTube Music. - Activ. vitesses de lecture shorts par défaut - La vitesse de lecture par défaut s\'applique aux Shorts. - La vitesse de lecture par défaut ne s\'applique pas aux Shorts. Tampon préchargé passé. Tampon préchargé "Passe le tampon préchargé au début de la vidéo pour appliquer immédiatement la qualité vidéo. @@ -1693,27 +1711,13 @@ Info : Le message est affiché. Le message est masqué. Falsifier les dimensions de l\'appareil - "Falsifie les dimensions de l'appareil a la valeur maximale. -Les hautes qualités peuvent être débloquées sur certaines vidéos qui requièrent des appareils ayant des dimensions élevées, mais pas sur toutes les vidéos." - Désactiver le codec VP9 - "Le codec VP9 est désactivé. - -• La résolution maximale est en 1080p. -• La lecture vidéo utilisera plus de données internet que le VP9. -• Le codec VP9 est également utilisé pour les vidéos HDR." - Le codec VP9 est activé. - Remplacer le codec AV1 - Remplacer le codec AV1 par le codec VP9. - Rejeter la réponse du codec AV1 - "Force le rejet de la réponse du codec AV1. -Un codec différent sera appliqué après environ 20 secondes de mise en mémoire tampon." - Le processus de rejet entraîne une mise en mémoire tampon d\'environ 20 secondes. - Vitesse de lecture modifiée par %s. - La résolution sur les données mobiles a été modifiée par %s. - Impossible de définir la qualité vidéo. - La résolution sur le Wi-Fi a été modifiée par %s. - Les vitesses personnalisées doivent être inférieures à %sx. - Valeur des vitesses de lecture invalide. + + Désactiver la vitesse de lecture pour la musique + La vitesse de lecture par défaut est activée pour la musique. + La vitesse de lecture par défaut est activée pour la musique. + Valider en utilisant les catégories + La vitesse de lecture par défaut est désactivée si la catégorie de la vidéo est Musique. + La vitesse de lecture par défaut est désactivée pour les vidéos lues sur YouTube Music. Return YouTube Dislike Activer Return YouTube Dislike @@ -1843,6 +1847,7 @@ Cliquez ici pour découvrir comment créer une clé API." Afficher un bouton \'Passer\' Afficher dans la barre de progression Désactiver + Opacité : Couleur : Couleur modifiée. Couleur réinitialisée. @@ -1910,6 +1915,7 @@ Cliquez ici pour découvrir comment créer une clé API." Changer de catégorie Il n\'y a aucun segments pour lesquels voter. + %1$s vers %2$s Choisissez la catégorie du segment La catégorie est désactivée dans les paramètres. Activez la catégorie pour soumettre. Nouveau segment SponsorBlock @@ -2029,6 +2035,8 @@ Cliquez sur le bouton Continuer et autorisez les modifications d'optimisations." Android VR "Android VR (sans authentification)" + "iOS +(Obsolète)" "iOS TV (Connexion requise)" Effets inconnus de la falsification @@ -2036,8 +2044,19 @@ Cliquez sur le bouton Continuer et autorisez les modifications d'optimisations." • Le volume stable n'est pas disponible. • La désactivation forcée des pistes audio automatiques n'est pas disponible. • Les vidéos pour enfants peuvent ne pas être lues en cas de déconnexion ou en mode incognito." + • Des plages entières d\'ASN/adresses IP peuvent être bloquées par le serveur. "• Les films ou vidéos payantes peut ne pas être lus. • Les vidéos pour enfants peuvent ne pas être lues en cas de déconnexion ou en mode incognito." + Utiliser le client iOS + "Le client iOS a été ajouté aux clients disponibles. + +AVERTISSEMENT : Le client iOS est obsolète. Tout problème survenant lors de son utilisation est à vos propres risques." + Le client iOS n\'a pas été ajouté aux clients disponibles. + "Lors de la requête des points de terminaison de l'API YouTube en utilisant iOS, vous aurez besoin des jetons d'authentification (Auth tokens) émis par l'appareil iOS et des PoTokens émis par iOSGuard. + +Cela signifie que les requêtes de streaming via iOS manqueront à la fois des jetons d'authentification (Auth tokens) et des PoTokens, et le serveur pourrait considérer l'utilisateur comme un bot et bloquer l'ensemble de la plage ASN/IP. + +UTILISEZ À VOS PROPRES RISQUES !" Forcer le codec AVC de iOS (H.264) Le codec vidéo est forcé sur AVC (H.264). Le codec vidéo est déterminé automatiquement. diff --git a/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml b/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml index 73a578469..61f16bae5 100644 --- a/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml +++ b/patches/src/main/resources/youtube/translations/hu-rHU/strings.xml @@ -1478,12 +1478,27 @@ Megjegyzés: Ezzel a képernyőterület méretét is megváltoztatja, ahol érz Automatikus Videó - Alapértelmezett lejátszási sebesség - Alapértelmezett videó minőség mobilhálózaton - Alapértelmezett videó minőség Wi-Fi hálózaton + HDR videó letiltása A HDR videó le van tiltva. A HDR videó engedélyezett. + VP9 kodek letiltása + "A VP9 kodek le van tiltva. + +• A maximális felbontás 1080p. +• A videolejátszás több internetes adatot használ, mint a VP9. +• A HDR lejátszáshoz a HDR videó továbbra is a VP9 kodeket használja." + VP9 kodek engedélyezve van. + Szoftver AV1 kodek cseréje + A szoftver AV1 kodeket a VP9 kodekkel helyettesíti. + + Alapértelmezett lejátszási sebesség + Lejátszási sebesség módosításainak megjegyzése + A lejátszási sebesség módosítása minden videóra érvényes. + A lejátszási sebesség módosítása csak a jelenlegi videóra érvényes. + Mutass egy felugró értesítést + Egy felugró értesítés fog látszani, amikor megváltozik az alapértelmezett lejátszási sebesség. + Nem fog felugró értesítés látszani, amikor megváltozik az alapértelmezett lejátszási sebesség. Egyéni lejátszási sebesség engedélyezése Az egyéni lejátszási sebesség engedélyezett. Az egyéni lejátszási sebesség le van tiltva. @@ -1492,12 +1507,11 @@ Megjegyzés: Ezzel a képernyőterület méretét is megváltoztatja, ahol érz A régi stílusú előugró menüt használja. Egyéni lejátszási sebességek szerkesztése Az elérhető lejátszási sebességek hozzáadás vagy módosítása. - Lejátszási sebesség módosításainak megjegyzése - A lejátszási sebesség módosítása minden videóra érvényes. - A lejátszási sebesség módosítása csak a jelenlegi videóra érvényes. - Mutass egy felugró értesítést - Egy felugró értesítés fog látszani, amikor megváltozik az alapértelmezett lejátszási sebesség. - Nem fog felugró értesítés látszani, amikor megváltozik az alapértelmezett lejátszási sebesség. + Az egyéni sebességnek kisebbnek kell lennie, mint %sx. + Érvénytelen egyéni lejátszási sebesség. + + Alapértelmezett videó minőség mobilhálózaton + Alapértelmezett videó minőség Wi-Fi hálózaton Videó minőség módosításainak megjegyzése A minőség változások alkalmazása az összes videóra. A minőség változások alkalmazása csak a jelenlegi videóra. @@ -1507,15 +1521,6 @@ Megjegyzés: Ezzel a képernyőterület méretét is megváltoztatja, ahol érz Régi videóminőség menü visszaállítása A régi videóminőség menü látható. A régi videóminőség menü nem látható. - Lejátszási sebesség zenéhez kiválasztás elrejtése - Az alapértelmezett lejátszási sebesség le van tiltva zene lejátszásnál. - Az alapértelmezett lejátszási sebesség engedélyezett zene lejátszásnál. - Érvényesítés kategóriák használatával - Az alapértelmezett lejátszási sebesség le van tiltva, ha a videó kategóriája zene. - Az alapértelmezett lejátszási sebesség le van tiltva a YouTube Music szolgáltatásban lejátszható videóknál. - Shortok alapértelmezett lejátszási sebességének engedélyezése - Az alapértelmezett lejátszási sebesség vonatkozik a Shortokra. - Az alapértelmezett lejátszási sebesség nem vonatkozik a Shortokra. Kihagyott előtöltött puffer. Előtöltött puffer kihagyása "Átugorja a videók kezdetén az előzetesen betöltött puffert, hogy azonnal alkalmazza az alapértelmezett videóminőséget. @@ -1528,27 +1533,13 @@ Info: A felugró üzenet látható. A felugró üzenet nem látható. Eszközméret hamisítása - "A maximális értékre hamisítja az eszköz méreteit. -Előfordulhat, hogy a jó minőség feloldódik bizonyos videóknál, amelyek nagy eszközméretet igényelnek, de nem minden videónál." - VP9 kodek letiltása - "A VP9 kodek le van tiltva. - -• A maximális felbontás 1080p. -• A videolejátszás több internetes adatot használ, mint a VP9. -• A HDR lejátszáshoz a HDR videó továbbra is a VP9 kodeket használja." - VP9 kodek engedélyezve van. - Szoftver AV1 kodek cseréje - A szoftver AV1 kodeket a VP9 kodekkel helyettesíti. - Elutasítja a szoftver AV1 kodek választ - "Erőteljesen elutasítja a szoftveres AV1 codec válaszát. -Egy másik kodek kerül alkalmazásra kb. 20 másodperc pufferezés után." - Az alapfolyamat kb. 20 másodpercig pufferez. - Az alapértelmezett sebesség módosítva: %s. - Az alapértelmezett videó minőség mobil hálózaton: %s. - Nem sikerült beállítani a videóminőséget. - Az alapértelmezett videó minőség Wi-Fi hálózaton: %s. - Az egyéni sebességnek kisebbnek kell lennie, mint %sx. - Érvénytelen egyéni lejátszási sebesség. + + Lejátszási sebesség zenéhez kiválasztás elrejtése + Az alapértelmezett lejátszási sebesség le van tiltva zene lejátszásnál. + Az alapértelmezett lejátszási sebesség engedélyezett zene lejátszásnál. + Érvényesítés kategóriák használatával + Az alapértelmezett lejátszási sebesség le van tiltva, ha a videó kategóriája zene. + Az alapértelmezett lejátszási sebesség le van tiltva a YouTube Music szolgáltatásban lejátszható videóknál. YouTube nem tetszések visszaállítása YouTube nem tetszések visszaállításának engedélyezése diff --git a/patches/src/main/resources/youtube/translations/id-rID/strings.xml b/patches/src/main/resources/youtube/translations/id-rID/strings.xml index cffad2782..8c9ecd0d9 100644 --- a/patches/src/main/resources/youtube/translations/id-rID/strings.xml +++ b/patches/src/main/resources/youtube/translations/id-rID/strings.xml @@ -376,6 +376,10 @@ Keterbatasan: Tombol Kembali pada bilah alat mungkin tidak berfungsi." + + + + diff --git a/patches/src/main/resources/youtube/translations/in/strings.xml b/patches/src/main/resources/youtube/translations/in/strings.xml index cffad2782..8c9ecd0d9 100644 --- a/patches/src/main/resources/youtube/translations/in/strings.xml +++ b/patches/src/main/resources/youtube/translations/in/strings.xml @@ -376,6 +376,10 @@ Keterbatasan: Tombol Kembali pada bilah alat mungkin tidak berfungsi." + + + + diff --git a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml index 13f33e4c6..bfbe32566 100644 --- a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml +++ b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml @@ -530,6 +530,7 @@ Le modifiche includono: Disattiva la barra di stato traslucida La barra di stato è opaca. La barra di stato è opaca o traslucida. + Per alcune ROM con Android 12+, l\'attivazione di questa impostazione potrebbe rendere trasparente la barra di navigazione del sistema. Attiva il camuffamento della versione dell\'app Il camuffamento della versione dell\'app è attivato. Il camuffamento della versione dell\'app è disattivato. @@ -805,7 +806,7 @@ Note: • La disattivazione della sovrapposizione della velocità ripristinerà il gesto Scorri la Barra di Avanzamento della vecchia interfaccia. • La disattivazione di questa impostazione non attiva forzatamente la sovrapposizione della velocità." Valore di sovrapposizione della velocità di riproduzione - Valore di sovrapposizione della velocità di riproduzione tra 0 e 8. + Il valore di sovrapposizione della velocità di riproduzione tra 0 e 8. Il valore di sovrapposizione della velocità di riproduzione deve essere tra 0 e 8 Nascondi il watermark nei video Il watermark nei video è nascosto. @@ -1543,6 +1544,10 @@ Tocca e tieni premuto il pulsante Altro per visualizzare la finestra delle azion Mostra il menù Apri il Video Il menù Apri il Video è visibile. Il menù Apri il Video è nascosto. + Finestra della velocità + Mostra la finestra della velocità + La finestra della velocità è visibile. + La finestra della velocità è nascosta. Stato di ripetizione Mostra il menù Stato di Ripetizione Il menù Stato di Ripetizione è visibile. @@ -1586,10 +1591,14 @@ Note: Il valore più basso del gesto della luminosità attiva la luminosità automatica. Il valore più basso del gesto della luminosità non attiva la luminosità automatica. Attiva il gesto della luminosità - "Il gesto della luminosità è attivato." + "Il gesto della luminosità è attivato. + +Regola la luminosità scorrendo verticalmente sul lato sinistro dello schermo." Il gesto della luminosità è disattivato. Attiva il gesto del volume - "Il gesto del volume è attivato." + "Il gesto del volume è attivato. + +Regola il volume scorrendo verticalmente sul lato destro dello schermo." Il gesto del volume è disattivato. Attiva il salvataggio e il ripristino della luminosità Salva e ripristina la luminosità uscendo ed entrando a schermo intero. @@ -1605,6 +1614,18 @@ Note: I gesti di trascinamento in modalità Blocca Schermo sono disattivati. Il limite di ampiezza del trascinamento Il limite di ampiezza entro cui deve avvenire il trascinamento. + Interfaccia alternativa con sovrapposizione di scorrimento + È in uso l\'interfaccia alternativa. + È in uso l\'interfaccia originale. + Attiva lo stile di sovrapposizione minimale + Lo stile di sovrapposizione minimale è attivato. + Lo stile di sovrapposizione minimale è disattivato. + Mostra la sovrapposizione circolare + È mostrata la sovrapposizione circolare. + È mostrata la sovrapposizione orizzontale. + Opacità dello sfondo della sovrapposizione di scorrimento + Il valore dell\'opacità tra 0 e 100. + L\'opacità dello scorrimento deve essere tra 0 e 100 La dimensione del testo del trascinamento La dimensione del testo in sovrapposizione durante il trascinamento. La dimensione dello schermo in sovrapposizione del trascinamento @@ -1636,12 +1657,43 @@ Note: Automatico Video - Velocità di riproduzione predefinita - Qualità predefinita con connessione dati - Qualità predefinita con Wi-Fi + + Codec Disattiva l\'HDR dei video L\'HDR dei video è disattivato. L\'HDR dei video è attivato. + Disattiva il codec VP9 + "Il codec VP9 è disattivato. + +Note: +• La risoluzione massima è 1080p. +• La riproduzione userà più dati internet di VP9. +• VP9 è comunque usato per la riproduzione in HDR." + Il codec VP9 è attivato. + Sostituisci il codec AV1 + Sostituisce il codec AV1 con il codec VP9. + + Velocità di riproduzione + Velocità di riproduzione predefinita + Ricorda i cambiamenti della velocità di riproduzione + I cambiamenti alla velocità di riproduzione si applicano a tutti i video. + I cambiamenti alla velocità di riproduzione si applicano solo al video corrente. + Mostra una notifica toast al cambio della velocità di riproduzione + Una notifica toast verrà mostrata al cambio della velocità di riproduzione predefinita. + Una notifica toast non verrà mostrata al cambio della velocità di riproduzione predefinita. + Velocità di riproduzione predefinita degli Shorts + Ricorda i cambiamenti della velocità di riproduzione degli Shorts + "I cambiamenti alla velocità di riproduzione si applicano a tutti gli Shorts. + +Note: +• L'unico modo per modificare la velocità di riproduzione nel riproduttore degli Shorts è usare la \"finestra della velocità\" in \"Azioni personalizzate\". +• Se non hai incluso la patch \"Componenti Shorts\", questa impostazione non sarà disponibile." + I cambiamenti alla velocità di riproduzione si applicano solo allo Short corrente. + Mostra una notifica toast + Una notifica toast verrà mostrata al cambio della velocità di riproduzione predefinita degli Shorts. + Una notifica toast non verrà mostrata al cambio della velocità di riproduzione predefinita degli Shorts. + La velocità di riproduzione predefinita è stata cambiata a %s + La velocità di riproduzione predefinita degli Shorts è stata cambiata a %s Attiva la velocità di riproduzione personalizzata La velocità di riproduzione personalizzata è attivata. La velocità di riproduzione personalizzata è disattivata. @@ -1650,30 +1702,33 @@ Note: Vecchio menù a comparsa Modifica le velocità di riproduzione personalizzate Aggiungi, rimuovi o modifica le velocità di riproduzione. - Ricorda i cambiamenti della velocità di riproduzione - I cambiamenti alla velocità di riproduzione si applicano a tutti i video. - I cambiamenti alla velocità di riproduzione si applicano solo al video corrente. - Mostra una notifica toast al cambio della velocità di riproduzione - Una notifica toast verrà mostrata al cambio della velocità di riproduzione predefinita. - Una notifica toast non verrà mostrata al cambio della velocità di riproduzione predefinita. + Le velocità personalizzate devono essere inferiori a %sx + Velocità di riproduzione personalizzate non valide + + Qualità video + Qualità predefinita con connessione dati + Qualità predefinita con Wi-Fi Ricorda i cambiamenti della qualità I cambiamenti alla qualità si applicano a tutti i video. I cambiamenti alla qualità si applicano solo al video corrente. Mostra una notifica toast al cambio della qualità Una notifica toast verrà mostrata quando al cambio della qualità predefinita. Una notifica toast non verrà mostrata quando al cambio della qualità predefinita. + Qualità predefinita degli Shorts con connessione dati + Qualità predefinita degli Shorts con Wi-Fi + Ricorda i cambiamenti della qualità degli Shorts + I cambiamenti alla qualità si applicano a tutti gli Shorts. + I cambiamenti alla qualità si applicano solo allo Short corrente. + Mostra una notifica toast + Una notifica toast verrà mostrata quando al cambio della qualità predefinita degli Shorts. + Una notifica toast non verrà mostrata quando al cambio della qualità predefinita degli Shorts. + Cellulare + Wi-Fi + La qualità predefinita è stata cambiata da %1$s a %2$s + La qualità predefinita degli Shorts è stata cambiata da %1$s a %2$s Attiva il vecchio menù Qualità Il vecchio menù Qualità è attivato. Il vecchio menù Qualità è disattivato. - Disattiva la velocità di riproduzione predefinita per la musica - La velocità di riproduzione predefinita per la musica è disattivata. - La velocità di riproduzione predefinita per la musica è attivata. - Convalida usando le categorie - La velocità di riproduzione predefinita è disattivata se la categoria video è Musica. - La velocità di riproduzione predefinita è attivata se la categoria video è Musica. - Attiva la velocità di riproduzione predefinita negli Shorts - La velocità di riproduzione predefinita negli Shorts è attivata. - La velocità di riproduzione predefinita negli Shorts è disattivata. Buffer precaricato saltato Salta il buffer precaricato "Salta il buffer precaricato all'avvio dei video per bypassare il ritardo della qualità video predefinita forzata. @@ -1686,27 +1741,18 @@ Note: Una notifica toast verrà mostrata quando un segmento è saltato. Una notifica toast non verrà mostrata quando un segmento è saltato. Camuffa le dimensioni del dispositivo - "Camuffa le dimensioni del dispositivo portandole al valore massimo. -Nota: la qualità alta potrebbe essere sbloccata per alcuni video, ma non per tutti, che richiedono dimensioni del dispositivo elevate." - Disattiva il codec VP9 - "Il codec VP9 è disattivato. + "Camuffa le dimensioni del dispositivo al valore massimo. -• La risoluzione massima è 1080p. -• La riproduzione userà più dati internet di VP9. -• VP9 è usato per la riproduzione HDR." - Il codec VP9 è attivato. - Sostituisci il codec AV1 - Sostituisce il codec AV1 con il codec VP9. - Rifiuta la risposta del codec AV1 - "Rifiuta forzatamente la risposta del codec AV1. -Verrà applicato un codec diverso dopo circa 20 secondi di buffering." - Il processo di fallback provoca circa 20 secondi di buffering - Cambiando la velocità di riproduzione predefinita a %s - Cambiando la qualità video predefinita con connessione dati a %s - Impossibile impostare la qualità video - Cambiando la qualità video predefinita con Wi-Fi a %s - Le velocità personalizzate devono essere inferiori a %sx - Velocità di riproduzione personalizzate non valide +Note: +• L'alta qualità potrebbe essere sbloccata su alcuni video che richiedono dimensioni di dispositivo elevate, ma non su tutti i video. +• Questa impostazione non è disponibile se è stato attivato \"Camuffa i dati in streaming\"." + + Disattiva la velocità di riproduzione predefinita per la musica + La velocità di riproduzione predefinita per la musica è disattivata. + La velocità di riproduzione predefinita per la musica è attivata. + Convalida usando le categorie + La velocità di riproduzione predefinita è disattivata se la categoria video è Musica. + La velocità di riproduzione predefinita è attivata se la categoria video è Musica. Return YouTube Dislike Attiva Return YouTube Dislike @@ -1836,6 +1882,7 @@ Tocca qui per vedere come emettere una chiave API." Mostra un pulsante salta Mostra nella barra di avanzamento Disabilita + Opacità: Colore: Colore cambiato Colore ripristinato @@ -1903,6 +1950,7 @@ Tocca qui per vedere come emettere una chiave API." Cambia la categoria Non ci sono segmenti per cui votare. + %1$s a %2$s Scegli la categoria del segmento La categoria è disattivata nelle impostazioni. Attiva la categoria da inviare. Nuovo segmento SponsorBlock @@ -2020,6 +2068,8 @@ Tocca il pulsante Continua e consenti le modifiche di ottimizzazione." Android VR "Android VR (Nessun accesso richiesto)" + "iOS +(Obsoleto)" "iOS TV (Accesso richiesto)" Effetti collaterali del camuffamento @@ -2027,9 +2077,20 @@ Tocca il pulsante Continua e consenti le modifiche di ottimizzazione." • Il volume stabile non funziona. • La disattivazione delle tracce audio automatiche forzate non funziona. • I video per bambini potrebbero non essere riprodotti se si è disconnessi o navigando in incognito." + • Interi intervalli di ASN/IP potrebbero essere bloccati dal server. "• Il volume stabile non funziona. • I film o i video a pagamento potrebbero non essere riproducibili. • I video per bambini potrebbero non essere riprodotti se si è disconnessi o navigando in incognito." + Usa il client iOS + "Il client iOS è stato aggiunto ai client disponibili. + +Nota: il client iOS è obsoleto, pertanto eventuali problemi riscontrati durante l'uso sono a tuo rischio." + Il client iOS non è stato aggiunto ai client disponibili. + "Quando richiedi gli endpoint API di YouTube tramite iOS, avrai bisogno dei token Auth emessi dal dispositivo iOS e dei PoToken emessi da iOSGuard. + +Ciò significa che alle richieste di streaming tramite iOS mancheranno sia i token Auth che i PoToken, e il server potrebbe considerare l'utente come un bot e bloccare l'intero intervallo ASN/IP. + +Usalo a tuo rischio!" Forza iOS AVC (H.264) Il codec video è forzato ad AVC (H.264). Il codec video è determinato automaticamente. @@ -2047,6 +2108,8 @@ Note: Il client usato per recuperare i dati in streaming è visibile nelle statistiche per nerd. Il client usato per recuperare i dati in streaming è nascosto nelle statistiche per nerd. Lingua predefinita dello stream audio VR + Non è stato possibile recuperare alcun flusso client + Potresti non essere connesso PoToken / VisitorData PoToken da usare diff --git a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml index 53217d1c1..e0860efb2 100644 --- a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml +++ b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml @@ -483,6 +483,7 @@ DeArrow の詳細については、ここをタップしてください。"半透明なステータスバーを無効化 ステータスバーを不透明にします。 ステータスバーを不透明にします。 + Android 12 以降を実行している一部のメーカーの ROM では、この機能を有効にすると、システムナビゲーションバーが透明になる可能性があります。 アプリのバージョンを偽装 アプリのバージョンを偽装できます。 アプリのバージョンを偽装できます。 @@ -1536,10 +1537,14 @@ DeArrow の詳細については、ここをタップしてください。"スワイプして明るさを 0 にして、明るさの自動調節を有効化します。 スワイプして明るさを 0 にして、明るさの自動調節を有効化します。 明るさのジェスチャーを有効化 - "明るさのスワイプコントロールを有効化します。" + "明るさのスワイプコントロールを有効化します。 + +画面左側を垂直にスワイプして明るさを調整できます。" 明るさのスワイプコントロールを有効化します。 音量ジェスチャーを有効化 - "音量のスワイプコントロールを有効化します。" + "音量のスワイプコントロールを有効化します。 + +画面左側を垂直にスワイプして音量を調整できます。" 音量のスワイプコントロールを有効化します。 明るさの保存と復元を有効化 全画面表示を終了 / 開始した際に明るさを保存/復元します。 @@ -1555,6 +1560,18 @@ DeArrow の詳細については、ここをタップしてください。"スワイプジェスチャーを「画面のロック」モードで有効化します。 スワイプ可能な領域のしきい値 スワイプとして検出する量のしきい値です。 + 代替の UI でスワイプオーバーレイを表示 + スワイプオーバーレイを代替の UI で表示します。 + スワイプオーバーレイを代替の UI で表示します。 + オーバーレイを最小化 + オーバーレイのスタイルを最小化します。 + オーバーレイのスタイルを最小化します。 + 円形のオーバーレイを表示 + 円形のオーバーレイを表示します。 + 円形のオーバーレイを表示します。 + スワイプオーバーレイの背景の透明度 + 不透明度は 0~100 の間の値です。 + 透明度の値は 0~100 の間でなければなりません。 スワイプオーバーレイのテキストサイズ スワイプオーバーレイのテキストサイズです。 スワイプオーバーレイの画面サイズ @@ -1586,12 +1603,28 @@ DeArrow の詳細については、ここをタップしてください。"自動 動画 - デフォルトの再生速度 - モバイルネットワーク使用時のデフォルト画質 - Wi-Fi 使用時のデフォルト画質 + HDR 動画を無効化 HDR 動画を無効化します。 HDR 動画を無効化します。 + VP9 コーデックを無効化 + "VP9 コーデックを無効化します。 + +注意: +・最大解像度は 1080p です。 +・動画を再生する際には VP9 コーデックよりも多くの通信量を消費します。 +・HDR 再生を可能にするために、HDR 動画では引き続き VP9 コーデックが使用されます。" + VP9 コーデックを無効化します。\n\n注意: \n・最大解像度は 1080p です。\n・動画を再生する際には VP9 コーデックよりも多くの通信量を消費します。\n・HDR 再生を可能にするために、HDR 動画では引き続き VP9 コーデックが使用されます。 + AV1 コーデックを置換 + AV1 コーデックを VP9 コーデックに置き換えます。 + + デフォルトの再生速度 + 再生速度の変更を保存 + 現在の設定: 再生速度の変更はすべての動画に適用されます。 + 現在の設定: 再生速度の変更は現在の動画にのみ適用されます。 + トーストを表示 + デフォルトの再生速度を変更した際にトーストが表示されるようにします。 + デフォルトの再生速度を変更した際にトーストが表示されるようにします。 カスタム再生速度を有効化 再生速度のカスタムを有効化します。 再生速度のカスタムを有効化します。 @@ -1600,12 +1633,11 @@ DeArrow の詳細については、ここをタップしてください。"現在の設定: 古いスタイルのフライアウトパネルが使用されます。 カスタム再生速度の編集 利用可能な再生速度を追加または変更します。 - 再生速度の変更を保存 - 現在の設定: 再生速度の変更はすべての動画に適用されます。 - 現在の設定: 再生速度の変更は現在の動画にのみ適用されます。 - トーストを表示 - デフォルトの再生速度を変更した際にトーストが表示されるようにします。 - デフォルトの再生速度を変更した際にトーストが表示されるようにします。 + カスタム再生速度は %s 倍速未満である必要があります。デフォルト値にリセットします。 + 無効なカスタム再生速度です。デフォルトの値を使用します。 + + モバイルネットワーク使用時のデフォルト画質 + Wi-Fi 使用時のデフォルト画質 画質の変更を保存 現在の設定: 画質の変更はすべての動画に適用されます。 現在の設定: 画質の変更は現在の動画にのみ適用されます。 @@ -1615,15 +1647,6 @@ DeArrow の詳細については、ここをタップしてください。"古いスタイルの画質メニューを復元 古いスタイルの画質設定メニューを復活させます。 古いスタイルの画質設定メニューを復活させます。 - 音楽再生時にデフォルトの再生速度を無効化 - 音楽を再生する際に「デフォルトの再生速度」で設定した再生速度を無効化します。 - 音楽を再生する際に、「デフォルトの再生速度」で設定した再生速度を無効化します。\n\n注意: この設定は、「YouTube Music で聴く」バナーが表示されている動画にのみ適用されます。 - 自動的にデフォルトの再生速度を無効化 - 動画のカテゴリが「音楽」の場合、デフォルトの再生速度を無効にします。 - 動画のカテゴリが「音楽」の場合、デフォルトの再生速度を無効にします。 - ショートのデフォルト再生速度を有効化 - デフォルトの再生速度をショートに適用します。 - デフォルトの再生速度をショートに適用します。 事前に読み込まれたバッファをスキップしました。 事前に読み込まれたバッファをスキップ "動画開始時に予め読み込まれたバッファをスキップして、デフォルトの画質を即座に適用します。 @@ -1636,28 +1659,13 @@ DeArrow の詳細については、ここをタップしてください。"スキップ時にトーストを表示します。 スキップ時にトーストを表示します。 デバイスの解像度を偽装 - "デバイスの解像度を最大値に偽装します。 -高画質は、高いデバイスの解像度を必要とする一部の動画でアンロックされる可能性がありますが、すべての動画でアンロックされるわけではありません。" - VP9 コーデックを無効化 - "VP9 コーデックを無効化します。 - -注意: -・最大解像度は 1080p です。 -・動画を再生する際には VP9 コーデックよりも多くの通信量を消費します。 -・HDR 再生を可能にするために、HDR 動画では引き続き VP9 コーデックが使用されます。" - VP9 コーデックを無効化します。\n\n注意: \n・最大解像度は 1080p です。\n・動画を再生する際には VP9 コーデックよりも多くの通信量を消費します。\n・HDR 再生を可能にするために、HDR 動画では引き続き VP9 コーデックが使用されます。 - AV1 コーデックを置換 - AV1 コーデックを VP9 コーデックに置き換えます。 - AV1 コーデックの応答を拒否 - "AV1 コーデック応答を強制的に拒否します。 -約 20 秒間のバッファリングの後、異なるコーデックに切り替わります。" - フォールバック処理で約20秒のバッファリングが発生します。 - デフォルトの再生速度を %s に変更しました。 - モバイルネットワーク使用時のデフォルト画質を %s に変更しました。 - 画質を設定できませんでした。 - Wi-Fi 使用時のデフォルト画質を %s に変更しました。 - カスタム再生速度は %s 倍速未満である必要があります。デフォルト値にリセットします。 - 無効なカスタム再生速度です。デフォルトの値を使用します。 + + 音楽再生時にデフォルトの再生速度を無効化 + 音楽を再生する際に「デフォルトの再生速度」で設定した再生速度を無効化します。 + 音楽を再生する際に、「デフォルトの再生速度」で設定した再生速度を無効化します。\n\n注意: この設定は、「YouTube Music で聴く」バナーが表示されている動画にのみ適用されます。 + 自動的にデフォルトの再生速度を無効化 + 動画のカテゴリが「音楽」の場合、デフォルトの再生速度を無効にします。 + 動画のカテゴリが「音楽」の場合、デフォルトの再生速度を無効にします。 Return YouTube Dislike Return YouTube Dislike を有効化 @@ -1787,6 +1795,7 @@ API キーの発行方法については、ここをタップしてください スキップボタンを表示 シークバーに表示 無効 + 不透明度: 色: 色を変更しました。 色をリセットしました。 @@ -1828,7 +1837,7 @@ API キーの発行方法については、ここをタップしてください API の URl が無効です。 API の URL を変更しました。 コピー - 設定のインポート/エクスポート + 設定のインポート / エクスポート SponsorBlock 設定の JSON は、ReVanced Extended やその他の SponsorBlock プラットフォームにインポート/エクスポートできます。 ReVanced Extended や他のプラットフォームの SponsorBlock にインポート/エクスポート可能な SponsorBlock 設定の JSON です。これにはプライベートユーザー ID が含まれています。共有する際は十分注意してください。 設定は正常にインポートされました。 @@ -1854,6 +1863,7 @@ API キーの発行方法については、ここをタップしてください カテゴリーを変更 評価できるセグメントがありません + %1$s から %2$s セグメントのカテゴリを選択してください カテゴリーは設定で無効になっています。送信するにはカテゴリーを有効にしてください。 新しい SponsorBlock セグメント @@ -1967,12 +1977,14 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に ストリーミングデータを偽装していない場合、動画の再生ができない可能性があります。 "ストリーミングデータを偽装していない場合、動画の再生ができない可能性があります。" この設定をオフにした場合、動画が再生できない問題が発生する可能性があります。 - 偽装するクライアントの種類 + 偽装するクライアントを選択 "Android TV (Google アカウントへのログインが必要)" Android VR "Android VR (認証なし)" + "iOS +(非推奨)" "iOS TV (Google アカウントへのログインが必要)" ストリーミングデータを偽装することによる副作用 @@ -1980,9 +1992,20 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に ・「一定音量」は利用できません。 ・「音声トラックの強制を無効化」は利用できません。 ・ログインをしていない場合やシークレットモードでは、子供向け動画は再生できない可能性があります。" + ・ASN/IP 範囲全体がサーバーによってブロックされる可能性があります。 "・「一定音量」は利用できません。 ・映画や有料動画は再生できない可能性があります。 ・ログインをしていない場合やシークレットモードでは、子供向け動画は再生できない可能性があります。" + iOS クライアントを使用 + "偽装するクライアントの一覧に iOS クライアントを追加します。 + +警告: iOS クライアントは非推奨です。使用中に問題が発生した場合は、自己責任で対処してください。" + 偽装するクライアントの一覧に iOS クライアントを追加します。\n\n警告: iOS クライアントは非推奨です。使用中に問題が発生した場合は、自己責任で対処してください。 + "iOS を使用して YouTube API エンドポイントをリクエストする場合、iOS デバイスによって発行された Auth トークンと iOSGuard によって発行された PoToken が必要になります。 + +つまり、iOS 経由のストリーミングリクエストでは Auth トークンと PoToken の両方が欠落し、サーバーがユーザーをボットと見なして ASN/IP 範囲全体をブロックする可能性があります。 + +自己責任で使用してください。" iOS クライアントで AVC (H.264) を強制 iOS クライアントで AVC (H.264) を強制します。 iOS クライアントで AVC (H.264) を強制します。 diff --git a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml index 4350d1e5d..590672df5 100644 --- a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml +++ b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml @@ -6,7 +6,7 @@ RVX 설정 %s 검색 - 기본값으로 초기화합니다. + 기본값으로 초기화하였습니다. 실험 기능 계속하시겠습니까? 레이아웃을 정상적으로 불러오기 위해 다시 시작합니다. @@ -169,7 +169,7 @@ 전체 화면 광고 숨기기 전체 화면 광고가 숨겨집니다. 전체 화면 광고가 표시됩니다. - 전체 화면 광고가 닫아집니다. + 전체 화면 광고가 닫아졌습니다. 일반 레이아웃 광고 숨기기 일반 레이아웃 광고가 숨겨집니다. 일반 레이아웃 광고가 표시됩니다. @@ -397,10 +397,10 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 전체 단어 일치시키기 필터링할 키워드 및 구문을 큰따옴표로 묶으면 동영상 제목과 채널 이름이 부분적으로 일치하지 않도록 방지할 수 있습니다.<br><br>• 예를 들어, <b>\"ai\"</b>라는 키워드로 <b>AI 커리어 완벽 가이드</b>라는 동영상을 숨길 수 있지만, <b>생성형AI가 바꿔놓은 세계</b> 또는 <b>What does fair use mean?</b>라는 동영상은 숨길 수 없습니다.<br>• 그리고 구두점을 단어의 경계로 간주하기 때문에 <b>인공지능(AI)의 원리</b>라는 동영상은 숨길 수 있습니다. 큰따옴표는 다른 단어 내부의 하위 문자열만 무시합니다 (예: <b>fair</b>는 숨길 수 없지만, <b>f(ai)r</b>는 숨김). 키워드를 사용할 수 없습니다: %s - 따옴표를 추가하여 키워드를 사용합니다: %s + 키워드를 사용하려면 따옴표를 추가하세요: %s 키워드에 충돌하는 선언이 있습니다: %s 키워드가 너무 짧아서 따옴표가 필요합니다: %s - 키워드가 모든 동영상을 숨깁니다: %s + 키워드가 모든 동영상을 숨길 것입니다: %s 추천 동영상 조회수가 낮은 추천 동영상 숨기기 @@ -535,7 +535,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 반투명 상태바 비활성화하기 상태바가 불투명합니다. 상태바가 불투명하거나 반투명합니다. - Android 12+가 설치되어 있는 일부 제조사 ROM의 경우에는 이 기능을 활성화하면 시스템 네비게이션 바가 투명해질 수 있습니다. + Android 12+로 실행되는 일부 제조사 ROM의 경우에는 이 기능을 활성화하면 시스템 네비게이션 바가 투명해질 수 있습니다. 앱 버전 변경하기 앱 버전을 변경합니다. 앱 버전을 변경하지 않습니다. @@ -1554,6 +1554,10 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 일반 플레이어에서 재생 메뉴 표시하기 일반 플레이어에서 재생 메뉴가 표시됩니다. 일반 플레이어에서 재생 메뉴가 숨겨집니다. + 재생 속도 + 재생 속도 메뉴 표시하기 + 재생 속도 메뉴가 표시됩니다. + 재생 속도 메뉴가 숨겨집니다. 반복 상태 변경 반복 상태 변경 메뉴 표시하기 반복 상태 변경 메뉴가 표시됩니다. @@ -1622,9 +1626,9 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 최소화된 스타일 활성화하기 최소화된 오버레이 스타일을 활성화합니다. 최소화된 오버레이 스타일을 비활성화합니다. - 원형 조절 오버레이 표시하기 - 원형 조절 오버레이를 표시합니다. - 바형 조절 오버레이를 표시합니다. + 원형 오버레이 표시하기 + 원형 오버레이를 표시합니다. + 바형 오버레이를 표시합니다. 스와이프 오버레이 배경 불투명도 스와이프 불투명도 값은 0-100 사이여야 합니다. 스와이프 불투명도 값은 0-100 사이여야 합니다. @@ -1659,12 +1663,41 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 자동 동영상 - 기본 동영상 재생 속도 - 모바일 네트워크 이용 시 기본 동영상 화질 - Wi-Fi 이용 시 기본 동영상 화질 + + 코덱 HDR 동영상 비활성화하기 HDR 동영상을 비활성화합니다. HDR 동영상을 활성화합니다. + VP9 코덱 비활성화하기 + "VP9 코덱을 비활성화합니다. +• 재생 문제가 없는 계정이거나 VR 또는 iOS 클라이언트는 AV1 코덱까지 지원되기 때문에 2160p까지 재생될 수 있고, 나머지 클라이언트는 VP9 코덱까지만 지원되기 때문에 1080p까지 재생될 수 있습니다. +• AVC 코덱 동영상을 재생했을 경우에는 VP9보다 더 많은 데이터가 사용되오니 주의하세요. +• HDR 동영상을 재생하기 위해 HDR 동영상에서는 VP9 또는 AV1 코덱이 사용됩니다." + VP9 코덱을 활성화합니다.\n• 예전에 업로드된 동영상에서 일부 화질 값들이 제거되어 360p와 1080p(Premium 기능)만 선택할 수 있거나 화질 메뉴를 선택할 수 없을 수 있습니다. + AV1 코덱 변경하기 + AV1 코덱을 VP9 코덱으로 변경합니다. + + 재생 속도 + 기본 동영상 재생 속도 + 동영상 재생 속도 저장 활성화하기 + 동영상 재생 속도 값을 변경할 때마다 기본 동영상 재생 속도로 저장합니다. + 동영상 재생 속도 값을 변경할 때마다 기본 동영상 재생 속도로 저장하지 않습니다. + 팝업 메시지 표시하기 + 기본 동영상 재생 속도 값을 변경하였을 때, 팝업 메시지를 표시합니다. + 기본 동영상 재생 속도 값을 변경하였을 때, 팝업 메시지를 표시하지 않습니다. + 기본 Shorts 재생 속도 + Shorts 재생 속도 저장 활성화하기 + "Shorts 재생 속도 값을 변경할 때마다 기본 Shorts 재생 속도로 저장합니다. + +알림: +• Shorts 플레이어에서 재생 속도를 변경하는 유일한 방법은 '사용자 정의 동작'에서 '재생 속도' 메뉴를 사용하는 것입니다. +• ‘Shorts components’ 패치를 포함되지 않은 앱일 경우에는 이 기능을 사용할 수 없습니다." + Shorts 재생 속도 값을 변경할 때마다 기본 Shorts 재생 속도로 저장하지 않습니다. + 팝업 메시지 표시하기 + 기본 Shorts 재생 속도를 변경하였을 때, 팝업 메시지를 표시합니다. + 기본 Shorts 재생 속도를 변경하였을 때, 팝업 메시지를 표시하지 않습니다. + 기본 동영상 재생 속도 값을 %s 로 변경하였습니다. + 기본 Shorts 재생 속도 값을 %s 로 변경하였습니다. 사용자 정의 동영상 재생 속도 활성화하기 사용자 정의 동영상 재생 속도를 활성화합니다. 사용자 정의 동영상 재생 속도를 비활성화합니다. @@ -1673,30 +1706,33 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 이전 메뉴 구성요소를 활성화합니다. 사용자 정의 동영상 재생 속도 편집하기 사용하고 싶은 동영상 재생 속도 값을 추가 또는 변경할 수 있습니다. - 동영상 재생 속도 저장 활성화하기 - 동영상 재생 속도 값을 변경할 때마다 기본 동영상 재생 속도로 저장합니다. - 동영상 재생 속도 값을 변경할 때마다 기본 동영상 재생 속도로 저장하지 않습니다. - 팝업 메시지 표시하기 - 기본 동영상 재생 속도 값을 변경하였을 때, 팝업 메시지를 표시합니다. - 기본 동영상 재생 속도 값을 변경하였을 때, 팝업 메시지를 표시하지 않습니다. + 사용자 정의 재생 속도는 %s 배속보다 작아야 합니다. + 잘못된 재생 속도 값입니다. + + 동영상 화질 + 모바일 네트워크 이용 시 기본 동영상 화질 + Wi-Fi 이용 시 기본 동영상 화질 동영상 화질 저장 활성화하기 동영상 화질 값을 변경할 때마다 기본 동영상 화질으로 저장합니다. 동영상 화질 값을 변경할 때마다 기본 동영상 화질으로 저장하지 않습니다. 팝업 메시지 표시하기 기본 동영상 화질 값을 변경하였을 때, 팝업 메시지를 표시합니다. 기본 동영상 화질 값을 변경하였을 때, 팝업 메시지를 표시하지 않습니다. + 모바일 네트워크 이용 시 기본 Shorts 화질 + Wi-Fi 이용 시 기본 Shorts 화질 + Shorts 화질 저장 활성화하기 + Shorts 화질 값을 변경할 때마다 기본 Shorts 화질으로 저장합니다. + Shorts 화질 값을 변경할 때마다 기본 Shorts 화질으로 저장하지 않습니다. + 팝업 메시지 표시하기 + 기본 Shorts 화질을 변경하였을 때, 팝업 메시지를 표시합니다. + 기본 Shorts 화질을 변경하였을 때, 팝업 메시지를 표시하지 않습니다. + 모바일 네트워크 + Wi-Fi + %1$s 이용 시 기본 동영상 화질 값을 %2$s 로 변경하였습니다. + %1$s 이용 시 기본 Shorts 화질 값을 %2$s 로 변경하였습니다. 이전 동영상 화질 설정 메뉴 활성화하기 이전 동영상 화질 설정 메뉴를 활성화합니다. 이전 동영상 화질 설정을 비활성화합니다. - 음악에서 기본 동영상 재생 속도 비활성화하기 - 음악 동영상에서 기본 동영상 재생 속도를 비활성화합니다. - 음악 동영상에서 기본 동영상 재생 속도를 활성화합니다. - 카테고리를 사용하여 유효성 검사하기 - 동영상 카테고리가 음악인 경우에는 기본 동영상 재생 속도를 비활성화합니다. - YouTube Music에서 재생할 수 있는 동영상인 경우에는 기본 동영상 재생 속도를 비활성화합니다. - Shorts에서 기본 동영상 재생 속도 활성화하기 - Shorts에서 기본 동영상 재생 속도를 활성화합니다. - Shorts에서 기본 동영상 재생 속도를 비활성화합니다. 미리 로드된 버퍼를 건너뛰었습니다. 미리 로드된 버퍼 건너뛰기 "동영상을 시작할 때, 미리 로드된 버퍼를 건너뛰어 기본 동영상 화질 적용 지연을 우회합니다. @@ -1707,27 +1743,18 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 팝업 메시지를 표시합니다. 팝업 메시지를 표시하지 않습니다. 기기 크기 정보 변경하기 - "기기 크기 정보를 최대값으로 변경합니다. -• 높은 기기 크기 정보가 필요한 일부 동영상에서는 고화질 동영상 값이 잠금 해제될 수 있지만 모든 동영상에는 적용되지 않습니다. -• 일부 스마트폰에서 이 설정을 활성화하면, 동영상 재생이 끊기거나 배터리 수명이 단축될 수 있으며, 알려지지 않은 문제점도 발생할 수 있습니다." - VP9 코덱 비활성화하기 - "VP9 코덱을 비활성화합니다. -• 재생 문제가 없는 계정이거나 iOS 클라이언트는 AV1 코덱까지 지원되기 때문에 2160p까지 재생될 수 있고, 나머지 클라이언트는 VP9 코덱까지만 지원되기 때문에 1080p까지 재생될 수 있습니다. -• AVC 코덱 동영상을 재생했을 경우에는 VP9보다 더 많은 데이터가 사용되오니 주의하세요. -• HDR 동영상을 재생하기 위해 HDR 동영상에서는 VP9 또는 AV1 코덱이 사용됩니다." - VP9 코덱을 활성화합니다.\n• 예전에 업로드된 동영상에서 일부 화질 값들이 제거되어 360p와 1080p(Premium 기능)만 선택할 수 있거나 화질 메뉴를 선택할 수 없을 수 있습니다. - AV1 코덱 변경하기 - AV1 코덱을 VP9 코덱으로 변경합니다. - AV1 코덱 응답 거부하기 - "AV1 코덱 응답을 강제로 거부합니다. -• 약 20초정도의 버퍼링 후에 다른 코덱으로 전환됩니다." - Fallback 프로세스로 인하여 약 20초정도의 버퍼링이 발생합니다. - 기본 동영상 재생 속도 값을 %s 로 변경합니다. - 모바일 네트워크 이용 시 기본 동영상 화질 값을 %s 로 변경합니다. - 동영상 화질을 설정할 수 없습니다. - Wi-Fi 이용 시 기본 동영상 화질 값을 %s 로 변경합니다. - 사용자 정의 재생 속도는 %s 배속보다 작아야 합니다. - 잘못된 재생 속도 값입니다. + "기기 크기 정보를 최대 값으로 변경합니다. + +알림: +• 높은 기기 크기 정보가 필요한 동영상에서는 고화질 동영상 값이 해제될 수 있지만 모든 동영상에는 적용되지 않습니다. +• '스트리밍 데이터 변경하기'가 활성화되어 있으면, 이 설정을 사용할 수 없습니다." + + 음악에서 기본 동영상 재생 속도 비활성화하기 + 음악 동영상에서 기본 동영상 재생 속도를 비활성화합니다. + 음악 동영상에서 기본 동영상 재생 속도를 활성화합니다. + 카테고리를 사용하여 유효성 검사하기 + 동영상 카테고리가 음악인 경우에는 기본 동영상 재생 속도를 비활성화합니다. + YouTube Music에서 재생할 수 있는 동영상인 경우에는 기본 동영상 재생 속도를 비활성화합니다. Return YouTube Dislike Return YouTube Dislike 활성화하기 @@ -2058,17 +2085,18 @@ GmsCore 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 • VR은 Kids // TV는 재생목록과 음악 동영상에서 다른 클라이언트가 사용될 수 있습니다. • TV는 AV1 코덱이 지원되지 않습니다. • 인증 없음: 사용자 로그인 정보를 사용하지 않음" - • 서버에서 전체 ASNs/IP 범위를 차단할 수 있습니다. + • 서버에서 전체 ASNs/IP 범위가 차단될 수 있습니다. "• 안정적인 볼륨을 사용할 수 없습니다. • 영화 또는 유료 동영상이 재생되지 않을 수 있습니다. • 사용자가 로그인을 하지 않았거나 시크릿 모드에서는 Kids 동영상이 재생되지 않을 수 있습니다. • 음악 동영상에서 다른 클라이언트가 사용될 수 있습니다. • AV1 코덱이 지원되지 않습니다." iOS 클라이언트 사용하기 - "사용 가능한 기본 클라이언트에 iOS 클라이언트가 추가되었습니다. + "사용 가능한 클라이언트에 iOS 클라이언트가 추가되었습니다. -경고: iOS 클라이언트는 폐기될 예정입니다. 사용 중 발생하는 모든 문제는 사용자의 책임입니다." - 사용 가능한 기본 클라이언트에 iOS 클라이언트가 추가되지 않습니다. +경고: +• iOS 클라이언트는 폐기될 예정입니다. 사용 중 발생하는 모든 문제는 사용자의 책임입니다." + 사용 가능한 클라이언트에 iOS 클라이언트가 추가되지 않습니다. "iOS를 사용하여 YouTube API 엔드포인트를 요청할 때는 iOS 기기에서 발급된 Auth Token과 iOSGuard에 의해 발급된 PoTokens가 필요합니다. 즉, iOS를 통한 스트리밍 요청에는 Auth Token과 PoTokens가 모두 누락되며, 서버는 사용자를 봇으로 간주하여 전체 ASN/IP 범위를 차단할 수 있습니다. @@ -2092,6 +2120,8 @@ AVC의 최대 화질 값은 1080p이고, OPUS 코덱을 사용불가 및 HDR 동 스트리밍 데이터를 가져오는 데 사용되는 클라이언트가 전문 통계에서 표시됩니다.\n\n• 만약 선택한 기본 클라이언트가 재생할 수 없는 동영상을 재생하려하거나 클라이언트 재생 문제가 발생하면, 그 문제를 해결하기 위해 다른 클라이언트가 사용되는 경우도 있기 때문에 전문 통계에서 다르게 표시될 수 있습니다. 스트리밍 데이터를 가져오는 데 사용되는 클라이언트가 전문 통계에서 숨겨집니다.\n\n• 만약 선택한 기본 클라이언트가 재생할 수 없는 동영상을 재생하려하거나 클라이언트 재생 문제가 발생하면, 그 문제를 해결하기 위해 다른 클라이언트가 사용되는 경우도 있기 때문에 전문 통계에서 다르게 표시될 수 있습니다. VR 기본 오디오 스트림 언어 + 클라이언트 스트림을 가져올 수 없습니다. + 로그인하지 않은 것 같습니다. PoToken & VisitorData PoToken 등록하기 diff --git a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml index 4cb59d164..de3b68df1 100644 --- a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml +++ b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml @@ -534,6 +534,7 @@ Zmiany zawierają: Półprzezroczystość paska statusu Wyłączona Włączona + Dla większości producentów ROM-ów bazujących na Androidzie 12 i wzwyż, włączenie tej opcji spowoduje stanie się systemowego paska nawigacji przezroczystym. Oszukiwanie wersji aplikacji Włączone Wyłączone @@ -1551,6 +1552,10 @@ Kliknij i przytrzymaj przycisk 'Więcej', by wyświetlić okno z własnymi akcja Menu od otwierania filmu Widoczne Ukryte + Prędkość odtwarzania + Menu od prędkości odtwarzania + Widoczne + Ukryte Stan powtarzania Shortsów Menu od stanu powtarzania Shortsów Widoczne @@ -1593,10 +1598,14 @@ Ograniczenia: Najniższa wartość jasności aktywowana przesuwaniem włącza automatyczną jasność Najniższa wartość jasności aktywowana przesuwaniem nie włącza automatycznej jasności Zmienianie jasności przesuwaniem - "Włączone" + "Włączone + +Dostosuj jasność, przesuwając pionowo po lewej stronie ekranu." Wyłączone Zmienianie głośności przesuwaniem - "Włączone" + "Włączone + +Dostosuj głośność, przesuwając pionowo po prawej stronie ekranu." Wyłączone Zapisuj i przywracaj jasność podczas zamykania lub wchodzenia w tryb pełnoekranowy Tak @@ -1612,6 +1621,18 @@ Ograniczenia: Wyłączone Minimalna długość przesunięcia Minimalna długość przesunięcia + Wygląd nakładki przesuwania + Alternatywny + Starszy + Minimalistyczny styl nakładki przesuwania + Włączony + Wyłączony + Okrągła nakładka + Włączona + Wyłączona + Przezroczystość tła nakładki przesuwania + Wartość musi być pomiędzy 0 a 100 + Wartość musi być pomiędzy 0 a 100. Rozmiar tekstu nakładki przesuwania Rozmiar tekstu nakładki przesuwania Rozmiar obszaru przesuwania @@ -1643,12 +1664,42 @@ Ograniczenia: Automatyczna Filmy - Domyślna prędkość odtwarzania - Domyślna jakość filmu podczas używania sieci mobilnej - Domyślna jakość filmu podczas używania Wi-Fi + + Kodek Filmy z HDR Wyłączone Włączone + Wyłącz kodek VP9 + "Wyłączone + +• Maksymalną rozdzielczością filmów jest 1080p +• Odtwarzanie filmów wykorzystuje więcej danych internetowych niż VP9 +• Kodek VP9 jest używany do filmów z HDR" + Włączone + Zmień kodek AV1 programu + Zastąp kodek AV1 programu kodekiem VP9 + + Prędkość odtwarzania + Domyślna prędkość odtwarzania + Zapamiętuj zmiany prędkości odtwarzania + Zmiany prędkości odtwarzania dotyczą wszystkich filmów + Zmiany prędkości odtwarzania dotyczą tylko bieżącego filmu + Komunikaty o zmianie domyślnej prędkości odtwarzania + Włączone + Wyłączone + Domyślna prędkość odtwarzania w Shortsach + Zapamiętuj zmiany prędkości odtwarzania w Shortsach + "Dla wszystkich Shortsów + +Informacje: +• jedyną drogą zmiany prędkości odtwarzania w odtwarzaczu Shortsów jest użycie 'Prędkość odtwarzania' w 'Własne akcje' +• jeśli nie zawarłeś łatki związanej z komponentami Shortsów, nie będzie to możliwe" + Dla bieżącego Shortsa + Komunikat o zmianie domyślnej prędkości odtwarzania dla Shortsów + Włączony + Wyłączony + Zmieniono domyślną prędkość odtwarzania na: %s. + Zmieniono domyślną prędkość odtwarzania w Shortsach na: %s. Niestandardowa prędkość odtwarzania Włączona Wyłączona @@ -1657,30 +1708,33 @@ Ograniczenia: Stary Edytuj niestandardowe prędkości odtwarzania Dodaj lub zmień dostępne prędkości odtwarzania - Zapamiętuj zmiany prędkości odtwarzania - Zmiany prędkości odtwarzania dotyczą wszystkich filmów - Zmiany prędkości odtwarzania dotyczą tylko bieżącego filmu - Komunikaty o zmianie domyślnej prędkości odtwarzania - Włączone - Wyłączone + Niestandardowe prędkości muszą by mniejsze niż %sx. + Nieprawidłowe niestandardowe prędkości odtwarzania. + + Jakość filmu + Domyślna jakość filmu podczas używania sieci mobilnej + Domyślna jakość filmu podczas używania Wi-Fi Zapamiętuj zmiany jakości filmu Zmiany jakości dotyczą wszystkich filmów Zmiany jakości dotyczą tylko bieżącego filmu Komunikaty o zmianie domyślnej jakości filmów Włączone Wyłączone + Domyślna jakość Shortsów podczas używania sieci mobilnej + Domyślna jakość Shortsów podczas używania Wi-Fi + Zapamiętuj zmiany jakości Shortsów + Dla wszystkich Shortsów + Dla bieżącego Shortsa + Komunikat o zmianie domyślnej jakości Shortsa + Włączony + Wyłączony + Sieć mobilna + Wi-Fi + Zmieniono domyślną jakość filmu z %1$s na: %2$s. + Zmieniono domyślną jakość Shortsa z %1$s na: %2$s. Stare menu od jakości filmu Widoczne Niewidoczne - Domyślna prędkość odtwarzania dla muzyki - Wyłączona - Włączona - Sprawdzaj przy użyciu kategorii - Wyłączone dla filmów z kategorią muzyki - Wyłączone dla filmów odtwarzalnych w YouTube Music - Domyślna prędkość odtwarzania w Shortsach - Włączona - Wyłączona Pominięto wstępnie załadowany bufor. Wstępnie załadowany bufor "Pomija wstępnie załadowany bufor na początku filmu, aby natychmiastowo ustawić domyślną jakość filmu. @@ -1694,26 +1748,17 @@ Informacje: Ukryte Oszukaj rozdzielczość urządzenia "Oszukuje rozdzielczość urządzenia do maksymalnej wartości. -Wysoka jakość może być odblokowana na niektórych filmach, które wymagają wysokiej rozdzielczości urządzenia, lecz nie na wszystkich." - Wyłącz kodek VP9 - "Wyłączone -• Maksymalną rozdzielczością filmów jest 1080p -• Odtwarzanie filmów wykorzystuje więcej danych internetowych niż VP9 -• Kodek VP9 jest używany do filmów z HDR" - Włączone - Zmień kodek AV1 programu - Zastąp kodek AV1 programu kodekiem VP9 - Odrzucaj kodek AV1 programu - "Odrzucaj kodek AV1 programu. -Po około 20 sekundach ładowania kodek zostanie zmieniony." - Ten sposób powoduje około 20 sekund ładowania. - Zmieniono domyślną prędkość odtwarzania na %s. - Zmieniono domyślną jakość podczas używania sieci mobilnej na %s. - Nie udało się zmienić jakości obrazu. - Zmieniono domyślną jakość podczas używania Wi-Fi na %s. - Niestandardowe prędkości muszą by mniejsze niż %sx. - Nieprawidłowe niestandardowe prędkości odtwarzania. +Informacje: +• wysoka jakość może być odblokowana na niektórych filmach, które wymagają wysokiej rozdzielczości urządzenia, lecz nie na wszystkich +• ustawienie nie będzie dostępne, jeśli opcja 'Oszukuj strumień danych' jest włączona" + + Domyślna prędkość odtwarzania dla muzyki + Wyłączona + Włączona + Sprawdzaj przy użyciu kategorii + Wyłączone dla filmów z kategorią muzyki + Wyłączone dla filmów odtwarzalnych w YouTube Music Return YouTube Dislike Return YouTube Dislike @@ -1843,6 +1888,7 @@ Kliknij, by zobaczyć, jak zgłosić klucz API." Pokaż przycisk od pomijania Pokazuj w pasku postępu filmu Wyłącz + Przezroczystość: Kolor: Kolor został zmieniony. Kolor został zresetowany. @@ -1910,6 +1956,7 @@ Kliknij, by zobaczyć, jak zgłosić klucz API." Zmień kategorię Brak segmentów, na które można zagłosować. + %1$s do %2$s Wybierz kategorię segmentu Ta kategoria jest wyłączona w ustawieniach. Włącz kategorię, aby móc wysłać ten segment. Nowy segment SponsorBlock @@ -2029,6 +2076,8 @@ Stuknij przycisk kontynuacji i zezwól na zmiany w optymalizacji." Android VR "Android VR (Bez autoryzacji)" + "iOS +(Porzucone)" "iOS TV (Wymagane zalogowanie)" Efekty uboczne oszukiwania @@ -2036,9 +2085,22 @@ Stuknij przycisk kontynuacji i zezwól na zmiany w optymalizacji." • Stabilna głośność nie jest dostępna • Automatyczne wymuszenie ścieżki dźwiękowej nie jest dostępne • Filmy dla dzieci mogą się nie odtwarzać będąc zalogowanym lub w trybie incognito" + • Cały zakres ASNów/IP może być zablokowany przez serwer "• Stabilna głośność nie jest dostępna • Filmy kinowe lub płatne mogą się nie odtwarzać • Filmy dla dzieci mogą się nie odtwarzać będąc zalogowanym lub w trybie incognito" + Włącz klienta iOS + "Tak + +OSTRZEŻENIE: Klient iOS jest porzucony. Wszelkie problemy pojawiające się podczas korzystania, są na własne ryzyko." + Nie + "Podczas żądania punktów końcowych interfejsu API YouTube za pomocą systemu iOS potrzebne będą tokeny Auth wydane przez urządzenie z systemem iOS oraz PoTokeny wydane przez iOSGuard. + +Oznacza to, że żądania przesyłania strumieniowego za pośrednictwem systemu iOS będą pozbawione zarówno tokenów Auth, jak i PoTokenów, a serwer może uznać użytkownika za bota i zablokować cały zakres ASN/IP. + +UŻYWAJ NA WŁASNE RYZYKO! + +Przetłumaczono z DeepL.com (wersja darmowa)" Wymuś kodek iOS AVC (H.264) Wymuszony Określany automatycznie @@ -2057,6 +2119,8 @@ AVC obsługuje maksymalnie rozdzielczość 1080p, kodek audio OPUS nie jest dost Widoczna Ukryta Domyślny język dla transmisji na żywo dla VR + Nie można przechwycić żadnego ze strumieni klienta. + Możesz nie być zalogowany. PoToken / VisitorData PoToken do użycia diff --git a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml index 7da22d7dc..80d098a01 100644 --- a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml +++ b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml @@ -1466,12 +1466,27 @@ Sem margens na parte superior e inferior do reprodutor." Automático Vídeo - Velocidade de reprodução padrão - Qualidade de vídeo padrão nos dados móveis - Qualidade de vídeo padrão no Wi-Fi + Desativar vídeo HDR O vídeo HDR está desativado. O vídeo HDR está ativado. + Desativar codec VP9 + "O codec VP9 está desativado. + +• A resolução máxima é 1080p. +• A reprodução de vídeos usará mais dados na internet do que VP9. +• Para fazer com que o HDR reproduza, o vídeo HDR ainda usa o codec VP9." + O codec VP9 está ativado. + Substituir codec AV1 do software + Substitua o codec AV1 do software com o codec VP9. + + Velocidade de reprodução padrão + Lembrar alterações na velocidade de reprodução + As alterações de velocidade de reprodução aplicam-se a todos os vídeos. + As alterações de velocidade de reprodução só se aplicam ao vídeo atual. + Mostrar uma notificação flutuante + Uma notificação flutuante será exibida quando mudar a velocidade padrão de reprodução. + Uma notificação flutuante não será exibida quando mudar a velocidade padrão de reprodução. Ativar velocidade de reprodução personalizada A velocidade de reprodução personalizada está ativada. A velocidade de reprodução personalizada está desativada. @@ -1480,12 +1495,11 @@ Sem margens na parte superior e inferior do reprodutor." O menu flutuante antigo é usado. Editar velocidades de reprodução personalizadas Adicionar ou alterar as velocidades de reprodução disponíveis - Lembrar alterações na velocidade de reprodução - As alterações de velocidade de reprodução aplicam-se a todos os vídeos. - As alterações de velocidade de reprodução só se aplicam ao vídeo atual. - Mostrar uma notificação flutuante - Uma notificação flutuante será exibida quando mudar a velocidade padrão de reprodução. - Uma notificação flutuante não será exibida quando mudar a velocidade padrão de reprodução. + As velocidades personalizadas devem ser inferiores a %sx. Usando valores padrão. + Velocidade personalizada de reprodução inválida. Usando valores padrão. + + Qualidade de vídeo padrão nos dados móveis + Qualidade de vídeo padrão no Wi-Fi Lembrar alterações na qualidade do vídeo As alterações de qualidade aplicam-se a todos os vídeos. As alterações de qualidade só se aplicam ao vídeo atual. @@ -1495,15 +1509,6 @@ Sem margens na parte superior e inferior do reprodutor." Restaurar menu antigo de qualidade de vídeo O menu antigo de qualidade de vídeo está sendo exibido. O menu antigo de qualidade de vídeo não está sendo exibido. - Desativar a velocidade de reprodução para música - A velocidade de reprodução padrão está desativada para música. - A velocidade de reprodução padrão está ativada para música. - Validar usando categorias - A velocidade de reprodução padrão está desativada se a categoria de vídeo for Música. - A velocidade padrão de reprodução está desativada para vídeos reproduzíveis no YouTube. - Ativar velocidade de reprodução padrão no Shorts - A velocidade de reprodução padrão se aplica ao Shorts. - A velocidade de reprodução padrão não se aplica ao Shorts. O buffer pré-carregado é ignorado. Ignorar buffer pré-carregado "Ignore o buffer pré-carregado no início do vídeo para ignorar o atraso padrão na aplicação da qualidade do vídeo. @@ -1515,27 +1520,13 @@ Sem margens na parte superior e inferior do reprodutor." Uma notificação flutuante será exibida. Uma notificação flutuante não será exibida. Falsificar dimensões do dispositivo - "Falsifica as dimensões do dispositivo para o valor máximo. -A alta qualidade pode ser desbloqueada em alguns vídeos que exigem dimensões elevadas do dispositivo, mas não em todos os vídeos." - Desativar codec VP9 - "O codec VP9 está desativado. - -• A resolução máxima é 1080p. -• A reprodução de vídeos usará mais dados na internet do que VP9. -• Para fazer com que o HDR reproduza, o vídeo HDR ainda usa o codec VP9." - O codec VP9 está ativado. - Substituir codec AV1 do software - Substitua o codec AV1 do software com o codec VP9. - Rejeitar resposta do codec AV1 do software - "Rejeita à força a resposta do codec AV1 do software. -Após cerca de 20 segundos de buffer, muda para um codec diferente." - O processo de fallback causa cerca de 20 segundos de buffer. - Alterando a velocidade padrão para %s. - Alterando a qualidade padrão de dados móveis para %s. - Falha ao definir a qualidade de vídeo. - Alterando a qualidade padrão do Wi-Fi para %s. - As velocidades personalizadas devem ser inferiores a %sx. Usando valores padrão. - Velocidade personalizada de reprodução inválida. Usando valores padrão. + + Desativar a velocidade de reprodução para música + A velocidade de reprodução padrão está desativada para música. + A velocidade de reprodução padrão está ativada para música. + Validar usando categorias + A velocidade de reprodução padrão está desativada se a categoria de vídeo for Música. + A velocidade padrão de reprodução está desativada para vídeos reproduzíveis no YouTube. Return YouTube Dislike Ativar Return YouTube Dislike diff --git a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml index 30bfe5d92..1783fb89f 100644 --- a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml +++ b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml @@ -21,7 +21,7 @@ %s не установлен. Установите его. Добавить в очередь Добавить в очередь и открыть очередь - Добавить в очередь и воспроизвести видео + Добавить в очередь и посмотреть Внешний загрузчик Открыть очередь Очередь @@ -38,7 +38,7 @@ Пожалуйста, используйте её только для отладки." Требуется авторизация Управление очередью недоступно (%s). - Не удалось идентифицировать список воспроизведения + Не определился список просмотра Очередь пустая Не удалось идентифицировать видео Не удалось добавить видео. @@ -362,8 +362,8 @@ Shorts Фильтр всплывающего меню ленты включен. Фильтр всплывающего меню ленты отключен. Тип фильтра выдвижного меню в ленте - Фильтруется, если содержат.<br><br>Чтобы скрыть меню <b>\'Воспроизвести следующим в очереди\'</b>, можете использовать <b>\'Воспроизвести следующим\'</b> или <b>\'в очереди\'</b> как ключевые слова. - Фильтруется, если совпадают.<br><br>Чтобы скрыть меню <b>\'Воспроизвести следующим в очереди\'</b>, можете использовать только <b>\'Воспроизвести следующим в очереди\'</b> как ключевые слова. + Фильтр, если содержат.<br><br> Чтобы скрыть меню <b>\'Просмотр следующим в очереди\'</b>, можете использовать <b>\'Просмотр следующим\'</b> или <b>\'в очереди\'</b> как ключевые слова. + Фильтр, если совпадают.<br><br> Чтобы скрыть меню <b>\'Просмотр следующим в очереди\'</b>, можете использовать только <b>\'Просмотр следующим в очереди\'</b> как ключевые слова. Фильтр всплывающего меню ленты Список имен всплывающего меню ленты для скрытия.\nРазделять новой строкой. @@ -374,9 +374,9 @@ Shorts Фильтр комментариев Фильтр комментариев включен. Фильтр комментариев отключен. - Фильтр видео в \"Главная\" - Фильтр видео в \"Главная\" включен. - Фильтр видео в \"Главная\" отключен. + Фильтр видео на главной + Фильтр видео на главной включен. + Фильтр видео на главной отключен. Фильтр результатов поиска Фильтр результатов поиска включен. Фильтр результатов поиска отключен. @@ -414,9 +414,9 @@ Shorts • С каналов, на которые вы не подписаны (менее 1000 просмотров)." Фильтр по количеству просмотров - Фильтр видео в \"Главная\" по просмотрам - Фильтр видео в \"Главная\", по просмотрам, включен. - Фильтр видео в \"Главная\", по просмотрам, отключен. + Фильтр видео на главной по просмотрам + Фильтр видео на главной, по просмотрам, включен. + Фильтр видео на главной, по просмотрам, отключен. Фильтр результатов поиска по просмотрам Фильтр результатов поиска, по просмотрам, включен. Фильтр результатов поиска, по просмотрам, отключен. @@ -541,6 +541,7 @@ Shorts Полупрозрачность строки состояния Полупрозрачность включена. Полупрозрачность отключена. + Для прошивок некоторых разработчиков Android 12+, включение этой функции может сделать панель навигации системы прозрачной. Подмена версии приложения Версия приложения подменена Версия приложения не подменена @@ -672,7 +673,7 @@ Shorts Экономия трафика Экономия трафика скрыта. Экономия трафика отображена. - Меню автовоспроизведения или воспроизведения + Меню авто просмотра или просмотра Скрыто. Отображено. Качество видео @@ -800,11 +801,11 @@ Shorts Значение должно быть в диапазоне от 0 до 100. Сброс по умолчанию. Переключатель списков \"Джем\" Авто-переключатель списков \"Джем\" отключен. - "Авто-переключение списков \"Джем\", при активном автовоспроизведении, включено. + "Авто переключение списков \"Джем\", при активном авто просмотре, включено. -Автовоспроизведение настраивается в: -Настройки YouTube → Автовоспроизведение → Автовоспроизведение следующего видео" - Авто-переключение списков \"Джем\", при активном автовоспроизведении, отключено. +Авто просмотр настраивается в: +Настройки YouTube → Авто просмотр → Авто просмотр следующего видео" + Авто переключение списков \"Джем\", при активном авто просмотре, отключено. Всплывающие панели плеера Всплывающие панели плеера отключены. Всплывающие панели плеера включены. @@ -856,7 +857,7 @@ Shorts Автовоспроизведение можно изменить в настройках YouTube: Настройки -> Автовоспроизведение -> Автовоспроизведение следующего видео" Рекомендуемое видео в конце воспроизведения отображено. - Задержка автовоспроизведения + Задержка авто просмотра Задержка автовоспроизведения следующего видео отключена. Задержка автовоспроизведения следующего видео включена. Реакции по времени @@ -1001,9 +1002,9 @@ Shorts Меню \"Дополнительная информация\" Меню \"Дополнительная информация\" скрыто. Меню \"Дополнительная информация\" отображено. - Меню \"Скорость воспроизведения\" - Меню \"Скорость воспроизведения\" скрыто. - Меню \"Скорость воспроизведения\" отображено. + Меню \"Скорость просмотра\" + Меню \"Скорость просмотра\" скрыто. + Меню \"Скорость просмотра\" отображено. Заголовок меню выбора качества Заголовок меню выбора качества скрыт. Заголовок меню выбора качества отображен. @@ -1068,9 +1069,9 @@ Shorts "Показывает секцию заголовка видео в полноэкранном режиме. Ограничение: заголовок видео исчезает при нажатии." - Превью автовоспроизведения - Превью автовоспроизведения скрыто. - Превью автовоспроизведения отображено. + Превью авто просмотра + Превью авто просмотра скрыто. + Превью авто просмотра отображено. Кнопка \"Повтор\" в чате трансляции Кнопка \"Повтор\" в онлайн чате скрыта.\n\nПоявляется в полноэкранном режиме при закрытии онлайн чата. Кнопка \"Повтор\" в онлайн чате отображена.\n\nПоявляется в полноэкранном режиме при закрытии онлайн чата. @@ -1199,9 +1200,9 @@ Shorts Кнопки плеера Скрыть или показать кнопки в видео. - Кнопка \"Автовоспроизведение\" - Кнопка \"Автовоспроизведение\" скрыта. - Кнопка \"Автовоспроизведение\" отображена. + Кнопка \"Авто просмотр\" + Кнопка \"Авто просмотр\" скрыта. + Кнопка \"Авто просмотр\" отображена. Кнопка \"Субтитры\" Кнопка \"Субтитры\" скрыта. Кнопка \"Субтитры\" отображена. @@ -1237,14 +1238,14 @@ Shorts Запустить внешний загрузчик. Управление очередью Вместо запуска внешнего загрузчика открывается управление очередью. - Кнопка скорости воспроизведения + Кнопка Скорость просмотра "Нажать - открытие окна скорости. -Нажать и удерживать - скорость воспроизведения в 1.0x." +Нажать и удерживать - скорость просмотра в 1.0x." Кнопка \"Белый список\" Нажать - Открыть \"Белый список\". Нажать и удерживать - Открыть настройки \"Белый список\". Кнопка воспроизвести все - "Коснитесь, чтобы создать список воспроизведения всех видео из канала. + "Коснитесь, чтобы создать список просмотра всех видео из канала. Коснитесь и удерживайте, для отмены. Инфо: @@ -1274,7 +1275,7 @@ Shorts Каналы в белом списке отсутствуют. Не добавлен в белый список. Добавлен в белый список. - Скорость воспроизведения + Скорость просмотра SponsorBlock Ошибка загрузки данных канала. Скорость сброшена на: %sx. @@ -1290,9 +1291,9 @@ Shorts Информация метки времени отключена. Добавить тип информации Добавить качество видео. - Показывать скорость воспроизведения. + Показывать скорость просмотра. Заменить действие метки времени - Нажмите, чтобы открыть меню скорости воспроизведения или качества видео. + Открыть меню скорости просмотра или качества видео. Нажмите, чтобы показать оставшееся время. Главы в прогрессе Главы в прогрессе скрыты. @@ -1375,9 +1376,9 @@ Shorts Описание видео разворачивается вручную. Shorts - Фоновое воспроизведение Shorts - Фоновое воспроизведение Shorts отключено. - Фоновое воспроизведение Shorts включено. + Фоновый просмотр Shorts + Фоновый просмотр Shorts отключен. + Фоновый просмотр Shorts включен. Возобновление Shorts при запуске приложения Возобновление Shorts отключено. Возобновление Shorts включено. @@ -1529,7 +1530,7 @@ Shorts Сердечко Сердце (Оттенок) Скрыта - Фон кнопки \"Воспроизведение\" - \"Пауза\" + Фон кнопки \"Просмотр\" - \"Пауза\" Фон скрыт. Фон отображен. @@ -1563,6 +1564,10 @@ Shorts Меню открыть видео Меню открыть видео отображено. Меню открыть видео скрыто. + Выбор скорости + Окно выбора скорости + Отображено. + Скрыто. Режим повтора Меню режима повтора Меню режима повтора отображено. @@ -1626,6 +1631,18 @@ Shorts Жесты в режиме \"Блокировка экрана\" отключены. Порог величины жеста Амплитуда движения распознаваемая как жест. + Альтернативный интерфейс жеста + Используется альтернативный интерфейс. + Используется старый интерфейс. + Включить минималистичный стиль + Минималистичный стиль включен. + Минималистичный стиль отключен. + Показать круговой индикатор + Отображается круговой индикатор. + Отображается линейный индикатор. + Затемнение фона панели во время жеста + Значение затемнения в пределах 0-100. + Затемнение при жесте должно быть в пределах 0-100. Размер текста при жесте Размер текста для наложения жестов. Размер области экрана для жестов @@ -1659,12 +1676,42 @@ Shorts Авто Видео - Скорость по умолчанию - Качество видео для мобильной сети - Качество видео для Wi-Fi сети + + Кодек HDR видео HDR видео отключены. HDR видео включены. + VP9 кодек + "VP9 кодек отключен. + +• Максимальное разрешение 1080p. +• Просмотр будет использовать больше трафика, чем с VP9. +• HDR просмотр недоступен, HDR видео все еще использует VP9 кодек." + VP9 кодек включен. + Заменить программный кодек AV1 + Замена программного кодека AV1 на VP9. + + Скорость просмотра + Скорость по умолчанию + Запомнить скорость воспроизведения + Изменяется скорость воспроизведения у всех видео. + Изменяется скорость воспроизведения у текущего видео. + Уведомление о выбранной скорости + Всплывающее уведомление отображено. + Всплывающее уведомление скрыто. + Скорость просмотра в Shorts по умолчанию + Запомнить скорость просмотра в Shorts + "Скорость просмотра применяется ко всем Shorts. + +Информация: +• Изменить скорость просмотра в плеере Shorts - можно, только, через диалог «Скорость» в разделе «Пользовательские действия». +• При отключенном патче «компоненты Shorts», изменения недоступны." + Скорость просмотра применяются, только, к текущему Short. + Уведомление о выбранной скорости + Уведомление включено. + Уведомление отключено. + Скорость просмотра: %s. + Скорость просмотра Shorts: %s. Пользовательская скорость воспроизведения Пользовательская скорость воспроизведения включена. Пользовательская скорость воспроизведения отключена. @@ -1673,30 +1720,33 @@ Shorts Старый стиль всплывающего меню скорости воспроизведения. Пользовательская скорость воспроизведения Добавить или изменить скорости воспроизведения. - Запомнить скорость воспроизведения - Изменяется скорость воспроизведения у всех видео. - Изменяется скорость воспроизведения у текущего видео. - Уведомление о выбранной скорости - Всплывающее уведомление отображено. - Всплывающее уведомление скрыто. + Значения пользовательской скорости не должны превышать %sx. Сброс к значениям по умолчанию. + Недопустимые значения скорости. Сброс к значениям по умолчанию. + + Качество видео + Качество видео для мобильной сети + Качество видео для Wi-Fi сети Запомнить изменения качества видео Изменяется качество у всех видео. Изменяется качество у текущего видео. Уведомление о выбранном качестве Всплывающее уведомление отображено. Всплывающее уведомление скрыто. + Качество Shorts, мобильной сети + Качество Shorts, Wi-Fi сети + Запомнить изменения качества Shorts + Изменяется качество у всех Shorts. + Изменяется качество у текущего Shorts. + Уведомление о выбранном качестве + Уведомление включено. + Уведомление отключено. + Мобильный + WiFi + Качество %1$s изменено на: %2$s. + Качество Shorts %1$s изменено на: %2$s. Старое меню качества Старое меню качества отображено. Старое меню качества скрыто. - Скорость воспроизведения для музыки - Скорость по умолчанию для категории YouTube Музыка включена. - Скорость воспроизведения по умолчанию для музыки включена. - Выбирать скорость ориентируясь на категории - Скорость по умолчанию для категории YouTube Музыка отключена. - Скорость по умолчанию для категории YouTube Музыка включена. - Скорость воспроизведения по умолчанию в Shorts - Скорость воспроизведения по умолчанию в Shorts включена. - Скорость воспроизведения по умолчанию в Shorts отключена. Пропущен предварительно загруженный буфер. Пропустить предварительно загруженный буфер "Пропустить предварительно загруженный буфер при запуске видео, чтобы избежать задержек обеспечения качества видео. @@ -1710,26 +1760,18 @@ Shorts Уведомление включено. Уведомление отключено. Подмена размеров устройства - "Подменяет размеры устройства, для разблокировки более высокого качества видео, которое может быть недоступно на вашем устройстве." - VP9 кодек - "VP9 кодек отключен. + "Подменяет размеры устройства до максимального значения. -• Максимальное разрешение 1080p. -• Воспроизведение видео будет использовать больше сетевых данных, чем с VP9. -• HDR воспроизведения нет, HDR видео все еще использует VP9 кодек." - VP9 кодек включен. - Заменить программный кодек AV1 - Замена программного кодека AV1 на VP9. - Отказ от программного кодека AV1 - "Принудительный отказ от программного кодека AV1. -После примерно 20 секунд буферизации будет применён другой кодек." - Буферизация из-за программного кодека AV1 (примерно 20 сек.) - Скорость воспроизведения по умолчанию изменена на %s. - Качество видео в моб. сети изменено на %s. - Ошибка установки качества видео. - Качество видео в Wi-Fi сети изменено на %s. - Значения пользовательской скорости не должны превышать %sx. Сброс к значениям по умолчанию. - Недопустимые значения скорости. Сброс к значениям по умолчанию. +Информация: +• Высокое качество может быть разблокировано на некоторых видео, которые это требуют, не все видео. +• Недоступно, если включена опция 'Подмена потоковых данных'." + + Скорость воспроизведения для музыки + Скорость по умолчанию для категории YouTube Музыка включена. + Скорость воспроизведения по умолчанию для музыки включена. + Выбирать скорость ориентируясь на категории + Скорость по умолчанию для категории YouTube Музыка отключена. + Скорость по умолчанию для категории YouTube Музыка включена. Вернуть YouTube Dislike Включить Return YouTube Dislike @@ -1860,6 +1902,7 @@ Shorts Показывать кнопку \"Пропуск\" Показывать в шкале воспроизведения Ничего не делать + Непрозрачность: Цвет: Цвет изменен. Цвет сброшен. @@ -1927,6 +1970,7 @@ Shorts Изменить категорию Нет сегментов для голосования. + %1$s до %2$s Выберите категорию сегмента Эта категория отключена в настройках. Включите ее для отправки сегмента. Новый сегмент SponsorBlock @@ -1988,7 +2032,7 @@ Shorts Открывает ссылки в браузере приложения. Очистить ссылки при отправке Убирает параметры отслеживания запросов из URL при отправке ссылки. - Использование по умолчанию + Открыть настройки Чтобы открывать ссылки YouTube с помощью RVX, настройте \"Открытие поддерживаемых ссылок\" и включите нужные поддерживаемые веб-адреса. Открыть GmsCore Включите \"Облачные уведомления\" для получения уведомлений. @@ -2004,9 +2048,9 @@ Shorts Нажмите кнопку \"Продолжить\" и отключите оптимизацию батареи." Продолжить - Список приложений общего доступа - Список приложений общего доступа - системный. - Список приложений общего доступа - встроенный. + Изменить диалог \"Поделиться\" + Используется системный диалог. + Используется встроенный диалог. Включить кодек OPUS Включить кодек OPUS, если содержимое в плеере подходит для кодека. @@ -2033,47 +2077,62 @@ Shorts Настройки скопированы в буфер обмена. Подмена потоковых данных - Подменяет потоковые данные при проблемах с воспроизведением видео. + Подменяет потоковые данные при проблемах с просмотром видео. Подмена потоковых данных Подмена потоковых данных включена. "Подмена потоковых данных отключена. -Воспроизведение видео может не работать." - Отключение этой настройки вызовет проблемы с воспроизведением видео. +Просмотр может быть не доступен." + Отключение этой настройки вызовет проблемы с просмотром. Клиент по умолчанию "Android TV (Требуется вход)" Android VR "Android VR (Без автора)" + "iOS +(Устаревшая)" "iOS (Необходим вход)" Эффекты от подмены "• Меню аудио дорожки отсутствует. • Стабильная громкость недоступна. • Отключить принудительные авто звуковые дорожки недоступна. -• Детские видео не могут воспроизводиться в режиме инкогнито или выхода." - "• Фильмы или платные видео могут не воспроизводиться. -• Детские видео могут не воспроизводиться при выходе из системы или в режиме инкогнито." +• Детские видео могут не работать в режиме инкогнито или выхода." + • Целые диапазоны ASN/IP могут блокироваться сервером. + "• Фильмы или платные видео могут не работать. +• Детские видео могут не работать при выходе из системы или в режиме инкогнито." + Использовать клиент iOS + "Клиент iOS добавлен к доступным клиентам. + +ВНИМАНИЕ: Клиент iOS устаревший. Любые проблемы, возникающие при его использовании, на свой страх и риск." + Клиент iOS не добавлен к доступным клиентам. + "При запросе конечных точек YouTube API с помощью iOS требуются токены Auth, выданные устройством iOS, и токены PoToken, выданные iOSGuard. + +Это означает, что в запросах трансляции через iOS не будет ни токенов Auth, ни токенов PoToken, и сервер может считать пользователя ботом и заблокировать целый диапазон ASN/IP. + +ИСПОЛЬЗУЙТЕ НА СВОЙ СТРАХ И РИСК!" Принудительно iOS, AVC (H.264) - Принудительное использование AVC (H.264) включено. - Принудительное использование AVC (H.264) отключено. + Принудительно AVC (H.264) включено. + Принудительно AVC (H.264) отключено. "Включение может: - улучшить время автономной работы - устранить прерывания при воспроизведении. -Максимальное разрешение видео AVC составляет 1080p. Кодек Opus недоступен. Потребление интернет трафика будет больше, чем при VP9 или AV1." - Пропустить шифрование ответа Onesie - "Шифрование ответа Onesie пропускается. +Максимальное разрешение AVC - 1080p. Кодек Opus недоступен. Потребление трафика больше, чем при VP9 или AV1." + Пропуск ответа для шифрования оболочки + "Пропуск включен. -• Исправлен новый тип воспроизведения, с которыми сталкиваются некоторые пользователи. +• Устраняет проблемы просмотра, у некоторых пользователей. • Кодек AV1 может быть недоступен." - "Шифрование ответа Onesie не пропускается. + "Пропуск отключен. -• Некоторые пользователи могут сталкиваться с новым типом проблемы воспроизведения." +• Могут быть проблемы просмотра, у некоторых пользователей." Статистике для сисадминов Клиент потоковых данных отображается в Статистике для сисадминов. Клиент потоковых данных скрыт в Статистике для сисадминов. Язык аудио потока по умолчанию VR + Не получены клиентские потоки. + Возможно, Вы не вошли в систему. PoToken / VisitorData PoToken @@ -2081,11 +2140,11 @@ Shorts VisitorData VisitorData выданный с BotGuard в надежном браузере. О PoToken / VisitorData - "Некоторые клиенты требуют PoToken и VisitorData для получения правильного потокового ответа данных. + "Некоторые клиенты требуют PoToken и VisitorData для получения правильного ответа потоковых данных. -При использовании iOS клиента по умолчанию, эти значения могут потребоваться. +Для iOS клиента по умолчанию, эти значения могут потребоваться. -Нажмите, чтобы увидеть дополнительную информацию." +Нажмите, для дополнительной информации." История просмотра Изменить настройки истории просмотра. diff --git a/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml b/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml index 707f6fb05..2ca246e47 100644 --- a/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml +++ b/patches/src/main/resources/youtube/translations/tr-rTR/strings.xml @@ -1217,12 +1217,17 @@ Bilinen sorunlar: Otomatik Video - Varsayılan oynatma hızı - Mobil ağda varsayılan video kalitesi - Wi̇-Fi ağında varsayılan video kalitesi + HDR\'lı videolarda, HDR\'ı devre dışı bırak HDR devre dışı HDR etkin + AV1 codec yazılımı bileşenini değiştirin + AV1 codec yazılımı bileşenini VP9 kodeği ile değiştirin. + + Varsayılan oynatma hızı + Oynatma hızı değişimlerini hatırla + Oynatma hızı değişimleri bütün videolara uygulanıyor. + Oynatma hızı değişimleri sadece oynatılan videoya uygulanıyor Özel oynatma hızlarını etkinleştir Özel oynatma hızları etkin Özel oynatma hızları kapalı @@ -1231,18 +1236,17 @@ Bilinen sorunlar: Eski stil açılır menü kullanıldı. Özel oynatma hızlarını düzenle Mevcut oynatma hızlarını değiştirin. - Oynatma hızı değişimlerini hatırla - Oynatma hızı değişimleri bütün videolara uygulanıyor. - Oynatma hızı değişimleri sadece oynatılan videoya uygulanıyor + Geçersiz özel oynatma hızları. Hızlar varsayılana sıfırlandı. + Geçersiz özel oynatma hızları. Varsayılanlar seçildi. + + Mobil ağda varsayılan video kalitesi + Wi̇-Fi ağında varsayılan video kalitesi Video kalitesi değişimlerini hatırla Kalite değişimleri bütün videolara uygulanıyor Kalite değişimleri sadece oynatılan videoya uygulanıyor Eski video kalite menüsünü geri getir Eski video kalite menüsü gösteriliyor. Eski video kalite menüsü gösterilmiyor. - Shorts videolarında varsayılan oynatma hızını etkinleştir - Varsayılan oynatma hızı Shorts videolara uygulanır. - Varsayılan oynatma hızı Shorts videolara uygulanmaz. Önceden yüklenmiş arabellek atlandı. Önceden yüklenmiş arabelleği atla "Varsayılan video kalitesi uygulama gecikmesini atlamak için video başlangıcında önceden yüklenmiş arabelleği atlayın. @@ -1254,19 +1258,7 @@ Bilinen sorunlar: Gizlenmiyor Gizleniyor Farklı cihaz boyutlarını taklit et - "Cihaz boyutlarını maksimum değere kadar taklit eder. Yüksek cihaz boyutları gerektiren bazı videolarda yüksek kalitenin kilidi açılabilir ancak tüm videolarda bu durum geçerli olmayabilir." - AV1 codec yazılımı bileşenini değiştirin - AV1 codec yazılımı bileşenini VP9 kodeği ile değiştirin. - AV1 codec yazılımı yanıtını reddet - "AV1 codec yazılımı yanıtı zorla reddeder. -Yaklaşık 20 saniyelik ara belleğe alma işleminin ardından farklı codec bileşenine geçiş yapılır." - Geri çekilme işlemi yaklaşık 20 saniyelik ara belleğe alma işlemine neden olur. - Varsayılan hız %s olarak değiştiriliyor. - Mobil ağda varsayılan video kalitesi %s olarak değiştiriliyor. - Video kalitesi ayarlanamadı. - Wi-Fi\'da varsayılan video kalitesi %s olarak değiştiriliyor. - Geçersiz özel oynatma hızları. Hızlar varsayılana sıfırlandı. - Geçersiz özel oynatma hızları. Varsayılanlar seçildi. + Return YouTube Dislike Return YouTube Dislike\'ı etkinleştir diff --git a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml index 410053cd2..0c11595e6 100644 --- a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml +++ b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml @@ -534,6 +534,7 @@ Вимкнути напівпрозорість рядка стану Рядок стану непрозорий. Рядок стану непрозорий чи напівпрозорий. + Для прошивок деяких розробників Android 12+, увімкнення цієї функції може зробити панель навігації системи прозорою. Підробити версію програми Версію підроблено Версію не підроблено @@ -1549,6 +1550,10 @@ Показувати меню Відкрити відео Меню Відкрити відео показується. Меню Відкрити відео приховано. + Діалог швидкості + Показувати меню Діалог швидкості + Меню Діалог швидкості показується. + Меню Діалог швидкості приховано. Стан повторення Показувати меню Стан повторення Меню Стан повторення показується. @@ -1592,10 +1597,14 @@ Нижнє значення жесту яскравості активує автояскравість. Нижнє значення жесту яскравості не активує автояскравість. Увімкнути зміну яскравості жестом - "Зміну яскравості жестом увімкнено." + "Зміну яскравості жестом увімкнено. + +Регулюйте яскравість вертикальним проведенням по лівій стороні екрана." Зміну яскравості жестом вимкнено. Увімкнути зміну гучності жестом - "Зміну гучності жестом увімкнено." + "Зміну гучності жестом увімкнено. + +Регулюйте гучність вертикальним проведенням по правій стороні екрана." Зміну гучності жестом вимкнено. Увімкнути збереження та відновлення яскравості Зберігається та відновлюється яскравість при переході з/до повноекранного режиму. @@ -1614,6 +1623,15 @@ Альтернативний інтерфейс жесту Використовується альтернативний інтерфейс. Використовується старий інтерфейс. + Увімкнути мінімалістичний стиль + Мінімалістичний стиль увімкнено. + Мінімалістичний стиль вимкнено. + Показувати круговий індикатор + Показується круговий індикатор. + Показується лінійний індикатор. + Затемнення фону панелі під час жесту + Значення затемнення в межах 0-100. + Затемнення при жесті повинно бути в межах 0-100. Розмір шрифту панелі Розмір шрифту в панелі при жесті Розмір екрана накладки проведення @@ -1645,12 +1663,43 @@ Авто Відео - Типова швидкість відтворення - Типова якість відео в мобільній мережі - Типова якість відео в Wi-Fi мережі + + Кодек Вимкнути HDR відео HDR відео вимкнено. HDR відео увімкнено. + Вимкнути кодек VP9 + "Кодек VP9 вимкнено. + +Інформація: +• Максимальна роздільна здатність - 1080p. +• Відтворення відео використовуватиме більше інтернет даних ніж VP9. +• Кодек VP9 все ще використовується для HDR відео." + Кодек VP9 увімкнено. + Замінити програмний кодек AV1 + Замінити програмний кодек AV1 кодеком VP9. + + Швидкість відтворення + Типова швидкість відтворення + Запам\'ятовувати зміни швидкості відтворення + Зміни швидкості відтворення застосовуються до всіх відео. + Зміни швидкості відтворення застосовуються лише до поточного відео. + Показувати тост + Тост показуватиметься при зміні типової швидкості відтворення. + Тост не показуватиметься при зміні типової швидкості відтворення. + Типова швидкість відтворення Shorts + Запам\'ятовувати зміни швидкості відтворення Shorts + "Зміни швидкості відтворення застосовуються до всіх Shorts. + +Інформація: +• Єдиним спосіб змінити швидкість відтворення у плеєрі Shorts є використання 'Діалог швидкості' у 'Спеціальні дії'. +• Якщо не включити патч 'Shorts components', це буде недоступно." + Зміни швидкості відтворення застосовуються лише до поточного Shorts. + Показувати тост + Тост показуватиметься при зміні типової швидкості відтворення Shorts. + Тост не показуватиметься при зміні типової швидкості відтворення Shorts. + Типову швидкість відтворення змінено на: %s. + Типову швидкість відтворення Shorts змінено на: %s. Увімкнути користувацьку швидкість відтворення Користувацьку швидкість відтворення увімкнено. Користувацьку швидкість відтворення вимкнено. @@ -1659,30 +1708,33 @@ Використовується висувне меню старого стилю. Редагувати користувацькі швидкості відтворення Додати або змінити доступні швидкості відтворення - Запам\'ятовувати зміни швидкості відтворення - Зміни швидкості відтворення застосовуються до всіх відео. - Зміни швидкості відтворення застосовуються лише до поточного відео. - Показувати тост - Тост показуватиметься при зміні типової швидкості відтворення. - Тост не показуватиметься при зміні типової швидкості відтворення. + Користувацькі швидкості повинні бути менше ніж %sx. + Неправильні користувацькі швидкості відтворення. + + Якість відео + Типова якість відео в мобільній мережі + Типова якість відео в Wi-Fi мережі Запам\'ятовувати зміни якості відео Зміни якості застосовуються до всіх відео. Зміни якості застосовуються лише до поточного відео. Показувати тост Тост показуватиметься при зміні типової якості відео. Тост не показуватиметься при зміні типової якості відео. + Типова якість Shorts в мобільній мережі + Типова якість Shorts в Wi-Fi мережі + Запам\'ятовувати зміни якості Shorts + Зміни якості застосовуються до всіх Shorts. + Зміни якості застосовуються лише до поточного Shorts. + Показувати тост + Тост показуватиметься при зміні типової якості Shorts. + Тост не показуватиметься при зміні типової якості Shorts. + мобільна + wifi + Зміна типової якості %1$s на: %2$s. + Зміна якості Shorts %1$s на: %2$s. Відновити старе меню якості відео Старе меню якості відео показується. Старе меню якості відео не показується. - Вимкнути швидкість відтворення для музики - Типову швидкість відтворення вимкнено для музики. - Типову швидкість відтворення увімкнено для музики. - Перевіряти за допомогою категорій - Типову швидкість відтворення вимкнено якщо категорія відео Музика. - Типову швидкість відтворення вимкнено для відтворення відео на YouTube Music. - Увімкнути типову швидкість відтворення Shorts - Типову швидкість відтворення застосовується для Shorts. - Типову швидкість відтворення не застосовується для Shorts. Пропущено перед вантажений буфер Пропустити перед вантажений буфер "Пропуск перед вантаженого буфера під час запуску відео для обходу затримки примусового застосування типової якості відео. @@ -1695,26 +1747,17 @@ Тост не показується. Підробити розміри пристрою "Підробка розмірів пристрою до максимального значення. -Високу якість може бути розблоковано для деяких відео, які вимагають великих розмірів пристрою, але не для всіх відео." - Вимкнути кодек VP9 - "Кодек VP9 вимкнено. -• Максимальна роздільна здатність - 1080p. -• Відтворення відео використовуватиме більше інтернет даних ніж VP9. -• Кодек VP9 все ще використовується для HDR відео." - Кодек VP9 увімкнено. - Замінити програмний кодек AV1 - Замінити програмний кодек AV1 кодеком VP9. - Відкинути відповідь програмного кодека AV1 - "Примусово відкидається відповідь програмного кодека AV1. -Приблизно через 20 секунд буферизації перемикається на інший кодек." - Процес спричиняє приблизно 20 секунд буферизації. - Зміна типової швидкості на %s. - Зміна типової якості при мобільному з\'єднанні на %s. - Не вдалося встановити якість відео. - Зміна типової якості при Wi-Fi на %s. - Користувацькі швидкості повинні бути менше ніж %sx. - Неправильні користувацькі швидкості відтворення. +Інформація: +• Високі якості можуть розблокуватися на деяких відео, які потребують великих розмірів пристрою, але не на всіх відео. +• Це налаштування недоступне якщо увімкнене 'Підробити дані трансляції'." + + Вимкнути швидкість відтворення для музики + Типову швидкість відтворення вимкнено для музики. + Типову швидкість відтворення увімкнено для музики. + Перевіряти за допомогою категорій + Типову швидкість відтворення вимкнено якщо категорія відео Музика. + Типову швидкість відтворення вимкнено для відтворення відео на YouTube Music. Повернення Дизлайків Ввімкнути повернення дизлайків YouTube @@ -1844,6 +1887,7 @@ Показувати кнопку пропуску Показувати в панелі прогресу Вимкнути + Непрозорість: Колір: Колір змінено Колір скинуто @@ -1911,6 +1955,7 @@ Змінити категорію Немає сегментів для голосування + %1$s до %2$s Вибрати категорію сегмента Категорія вимкнена у налаштуваннях. Увімкніть категорію, щоб надіслати. Новий сегмент Спонсорблок @@ -2026,6 +2071,8 @@ Android VR "Android VR (Без авторизації)" + "iOS +(Застаріла)" "iOS TV (Потрібна авторизація)" Побічні ефекти імітування @@ -2033,9 +2080,20 @@ • Стабілізація гучності недоступна. • Вимкнення примусових авто звукових доріжок недоступне. • Відео для дітей можуть не відтворюватися коли вийшли з системи або в анонімному режимі." + • Цілі діапазони ASN/IP можуть блокуватися сервером. "• Стабілізація гучності недоступна. • Фільми та платні відео можуть не відтворюватися. • Відео для дітей можуть не відтворюватися коли вийшли з системи або в анонімному режимі." + Використовувати клієнт iOS + "Клієнт iOS доданий до доступних клієнтів. + +ЗАУВАЖЕННЯ: Клієнт iOS застарілий. Будь-які проблеми, які виникають під час його використання, на власний ризик." + Клієнт iOS не доданий до доступних клієнтів. + "Під час запиту кінцевих точок YouTube API за допомогою iOS потрібні токени Auth, видані пристроєм iOS, і токени PoToken, видані iOSGuard. + +Це означає, що в запитах трансляції через iOS не буде ані токенів Auth, ані токенів PoToken, і сервер може вважати користувача ботом і заблокувати цілий діапазон ASN/IP. + +ВИКОРИСТОВУЙТЕ НА ВЛАСНИЙ РИЗИК!" Примусово AVC (H.264) iOS Примусово увімкнено відеокодек AVC (H.264). Відеокодек визначається автоматично. @@ -2054,6 +2112,8 @@ AVC має максимальну роздільну здатність 1080p, Клієнт, що використовується для отримання даних трансляції показується у Статистика для сисадмінів. Клієнт, що використовується для отримання даних трансляції приховано у Статистика для сисадмінів. Мова звукової доріжки для VR + Не вдалося отримати якісь трансляції клієнта. + Не можливо авторизуватися. PoToken / VisitorData PoToken для використання diff --git a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml index 1a89faa6b..c616b7f87 100644 --- a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml +++ b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml @@ -31,7 +31,7 @@ Lưu hàng chờ "Thay vì mở trình tải xuống bên ngoài, khi tương tác sẽ mở hộp thoại quản lý hàng chờ. -Ngoài ra, bạn cũng có thể mở quản lý hàng chờ bằng cách nhấn và giữ nút quay lại trên thanh điều hướng. +Ngoài ra, bạn cũng có thể mở hộp thoại quản lý hàng chờ bằng cách nhấn và giữ nút quay lại trên thanh điều hướng. Nhưng tính năng này vẫn còn đang trong quá trình phát triển, vì vậy phần lớn các tính năng có thể chưa hoạt động. @@ -53,6 +53,116 @@ Vui lòng chỉ sử dụng cho mục đích gỡ lỗi." Lưu hàng chờ thành công thành \"%s\". Ngôn ngữ trong cài đặt RVX Theo ứng dụng + "Amharic +አማርኛ" + "Arabic +العربية" + "Azerbaijani +Azərbaycan" + "Belarusian +беларуская" + "Bulgarian +Български" + "Bengali +বাংলা" + "Catalan +Català" + "Czech +Čeština" + "Danish +Dansk" + "German +Deutsch" + "Greek +Ελληνικά" + "English +English" + "Spanish +Español" + "Estonian +Eesti" + "Persian +فارسی" + "Finnish +Suomi" + "French +Français" + "Gujarati +ગુજરાતી" + "Hebrew +עברי" + "Hindi +हिन्दी" + "Croatian +Hrvatski" + "Hungarian +Magyar" + "Indonesian +Indonesia" + "Italian +Italiano" + "Japanese +日本語" + "Kazakh +Қазақ тілі" + "Korean +한국어" + "Lithuanian +Lietuvių" + "Latvian +Latviešu" + "Macedonian +Македонски" + "Mongolian +Монгол" + "Marathi +मराठी" + "Malay +Melayu" + "Burmese +ဗမာ" + "Dutch +Nederlands" + "Odia +ଓଡ଼ିଆ" + "Punjabi +ਪੰਜਾਬੀ" + "Polish +Polski" + "Portuguese +Português" + "Romanian +Română" + "Russian +Русский" + "Slovak +Slovenčina" + "Albanian +Shqip" + "Slovene +Slovenščina" + "Serbian +Српски" + "Swedish +Svenska" + "Swahili +Kiswahili" + "Tamil +தமிழ்" + "Telugu +తెలుగు" + "Thai +ไทย" + "Turkish +Türkçe" + "Ukrainian +Українська" + "Urdu +اردو" + "Vietnamese +Tiếng Việt" + "Chinese +中文" Quảng cáo Ẩn dải quảng cáo cửa hàng ở cuối video @@ -407,7 +517,7 @@ Bố cục máy tính bảng Bố cục màn hình ô tô • Video ngắn sẽ được mở trong trình phát thông thường. • Bảng tin được sắp xếp theo chủ đề và kênh. -• Không thể mở mô tả video khi cài đặt \"Giả mạo luồng dữ liệu trực tuyến\" đang tắt." +• Không thể mở mô tả video khi cài đặt \"Giả mạo dữ liệu phát trực tuyến\" đang tắt." Tắt cập nhật bố cục Bố cục sẽ không được máy chủ cập nhật. Bố cục sẽ được máy chủ cập nhật. @@ -424,6 +534,7 @@ Các thay đổi bao gồm: Vô hiệu hoá thanh trạng thái trong suốt Thanh trạng thái không còn trong suốt. Thanh trạng thái có thể trong suốt hoặc không. + Trên một số ROM tùy chỉnh chạy Android 12+, bật tính năng này có thể làm cho thanh điều hướng hệ thống trở nên trong suốt. Giả mạo phiên bản ứng dụng Phiên bản được giả mạo Phiên bản không được giả mạo @@ -1435,6 +1546,10 @@ Nhấn và giữ nút Thêm (⋮) để hiển thị hộp thoại Tác vụ tu Mục mở video Mục mở video được hiển thị. Mục mở video đã ẩn. + Hộp thoại tốc độ phát + Mục hộp thoại tốc độ phát + Mục hộp thoại tốc độ phát được hiển thị. + Mục hộp thoại tốc độ phát đã ẩn. Trạng thái lặp lại Mục trạng thái lặp lại Mục trạng thái lặp lại được hiển thị. @@ -1478,10 +1593,14 @@ Không còn lề trên và dưới trong trình phát." Chế độ độ sáng tự động sẽ được bật khi vuốt độ sáng về mức tổi thiểu. Chế độ độ sáng tự động sẽ không được bật khi vuốt độ sáng về mức tổi thiểu. Vuốt điều chỉnh độ sáng - "Cử chỉ vuốt điều chỉnh độ sáng đã bật." + "Cử chỉ vuốt điều chỉnh độ sáng ở chế độ Toàn màn hình đã bật. + + Điều chỉnh độ sáng bằng cách vuốt dọc bên cạnh trái màn hình." Cử chỉ vuốt điều chỉnh độ sáng đã tắt. Vuốt điều chỉnh âm lượng - "Cử chỉ vuốt điều chỉnh âm lượng đã bật." + "Cử chỉ vuốt điều chỉnh âm lượng ở chế độ Toàn màn hình đã bật. + + Điều chỉnh âm lượng bằng cách vuốt dọc bên cạnh phải màn hình." Cử chỉ vuốt điều chỉnh âm lượng đã tắt. Lưu độ sáng Lưu độ sáng khi thoát ra hoặc vào chế độ toàn màn hình. @@ -1497,6 +1616,18 @@ Không còn lề trên và dưới trong trình phát." Vuốt ở chế độ Khoá màn hình đã tắt. Độ rộng ngưỡng vuốt Độ rộng của ngưỡng vuốt để thực hiện cử chỉ vuốt. + Giao diện thay thế lớp phủ vuốt + Đang sử dụng giao diện thay thế. + Đang sử dụng giao diện cũ. + Chế độ tối giản + Lớp phủ tối giản đã bật. + Lớp phủ tối giản đã tắt. + Lớp phủ hình tròn + Lớp phủ hình tròn được hiển thị. + Lớp ngủ ngang được hiển thị. + Độ mờ nền của lớp phủ vuốt + Độ mờ có thể điều chỉnh từ 0 đến 100. + Giá trị của độ mờ khi vuốt phải từ 0 đến 100. Kích thước văn bản trên lớp phủ Độ lớn của văn bản được hiển thị trên lớp phủ khi vuốt. Kích thước màn hình lớp phủ @@ -1528,12 +1659,43 @@ Không còn lề trên và dưới trong trình phát." Tự động Video - Tốc độ phát mặc định - Chất lượng video mặc định trên mạng di động - Chất lượng video mặc định trên mạng Wi-Fi + + Codec Tắt video HDR Video HDR đã tắt. Video HDR đã bật. + Vô hiệu hoá codec VP9 + "Codec VP9 đã bị vô hiệu hoá. + +Chi tiết: +• Độ phân giải tối đa lúc này là 1080p. +• Phát video sẽ sử dụng nhiều dữ liệu di động hơn so với VP9. +• Codec VP9 vẫn được sử dụng cho video HDR." + Codec VP9 được kích hoạt. + Thay thế codec AV1 phần mềm + Thay thế codec AV1 phần mềm bằng codec VP9. + + Tốc độ phát + Tốc độ phát mặc định + Lưu lựa chọn tốc độ phát + Lựa chọn tốc độ phát đã chọn sẽ áp dụng cho tất cả video. + Lựa chọn tốc độ phát đã chọn chỉ áp dụng cho video hiện tại. + Thông báo ngắn + Hiển thị một thông báo ngắn khi thay đổi tốc độ phát mặc định. + Không hiện một thông báo ngắn khi thay đổi tốc độ phát mặc định. + Tốc độ phát mặc định trên Shorts + Lưu lựa chọn tốc độ phát trên Shorts + "Lựa chọn tốc độ phát đã chọn sẽ áp dụng cho tất cả video Shorts. + +Chi tiết: +• Cách duy nhất để thay đổi tốc độ phát trong trình phát Shorts là dùng \"Hộp thoại tốc độ phát\" trong \"Tác vụ tùy chỉnh\". +• Nếu bạn không bao gồm bản vá \"Shorts components\", tùy chọn này sẽ không khả dụng." + Lựa chọn tốc độ phát đã chọn chỉ áp dụng cho video Shorts hiện tại. + Thông báo ngắn + Hiển thị một thông báo ngắn khi thay đổi tốc độ phát mặc định trên Shorts. + Không hiện một thông báo ngắn khi thay đổi tốc độ phát mặc định trên Shorts. + Đã thay đổi tốc độ phát mặc định thành: %s. + Đã thay đổi tốc độ phát mặc định trên Shorts thành: %s. Tốc độ phát tuỳ chỉnh Đang áp dụng các giá trị tốc độ phát video tuỳ chỉnh. Đang áp dụng các giá trị tốc độ phát video mặc định. @@ -1542,30 +1704,33 @@ Không còn lề trên và dưới trong trình phát." Mục tốc độ phát kiểu cũ được sử dụng. Chỉnh sửa tốc độ phát Thêm hoặc thay đổi tốc độ phát lại có sẵn. - Lưu lựa chọn tốc độ phát - Lựa chọn tốc độ phát đã chọn sẽ áp dụng cho tất cả video. - Lựa chọn tốc độ phát đã chọn chỉ áp dụng cho video hiện tại. - Thông báo ngắn - Hiển thị một thông báo ngắn khi thay đổi tốc độ phát mặc định. - Không hiện một thông báo ngắn khi thay đổi tốc độ phát mặc định. + Tốc độ tùy chỉnh phải nhỏ hơn %sx. + Tốc độ phát tùy chỉnh không hợp lệ. + + Chất lượng video + Chất lượng video mặc định trên mạng di động + Chất lượng video mặc định trên mạng Wi-Fi Lưu lựa chọn chất lượng video Lựa chọn chất lượng video đã chọn sẽ áp dụng cho tất cả video. Lựa chọn chất lượng video đã chọn chỉ áp dụng cho video hiện tại. Thông báo ngắn Hiển thị một thông báo ngắn khi thay đổi chất lượng video mặc định. Không hiện một thông báo ngắn khi thay đổi chất lượng video mặc định. + Chất lượng video Shorts mặc định trên mạng di động + Chất lượng video Shorts mặc định trên mạng Wi-Fi + Lưu lựa chọn chất lượng video Shorts + Lựa chọn chất lượng video đã chọn sẽ áp dụng cho tất cả video Shorts. + Lựa chọn chất lượng video đã chọn chỉ áp dụng cho video Shorts hiện tại. + Thông báo ngắn + Hiển thị một thông báo ngắn khi thay đổi chất lượng video Shorts mặc định. + Không hiện một thông báo ngắn khi thay đổi chất lượng video Shorts mặc định. + mạng di động + wi-fi + Đã thay đổi chất lượng mặc định %1$s thành: %2$s. + Đã thay đổi chất lượng Shorts mặc định %1$s thành: %2$s. Khôi phục mục chất lượng video kiểu cũ Mục chất lượng video kiểu cũ được hiển thị. Mục chất lượng video kiểu cũ không được hiển thị. - Tắt tùy chọn tốc độ phát khi phát nhạc - Tốc độ phát mặc định đã tắt khi phát nhạc. - Tốc độ phát mặc định được kích hoạt khi phát nhạc. - Dựa vào danh mục - Tốc độ phát mặc định đã tắt nếu video thuộc danh mục Âm nhạc. - Tốc độ phát mặc định đã tắt đối với các video chơi game trên Youtube Music. - Tốc độ phát mặc định cho video ngắn - Tốc độ phát mặc định đã đặt đang được áp dụng khi xem Shorts. - Tốc độ phát mặc định đã đặt không áp dụng cho Shorts. Đã bỏ qua bộ đệm tải trước. Bỏ qua bộ đệm tải trước "Bỏ qua bộ đệm tải trước ở đầu video để áp dụng ngay chất lượng video mặc định. @@ -1578,27 +1743,18 @@ Chi tiết: Thông báo ngắn được hiển thị. Thông báo ngắn đã ẩn. Giả mạo kích thước thiết bị - "Giả lập kích thước thiết bị đến giá trị tối đa. -Chất lượng cao có thể được mở khóa trên một số video yêu cầu kích thước thiết bị lớn, nhưng không phải tất cả các video." - Vô hiệu hoá codec VP9 - "Codec VP9 đã vô hiệu hoá. + "Giả mạo kích thước thiết bị đến giá trị tối đa. -• Độ phân giải tối đa lúc này là 1080p. -• Phát video sẽ sử dụng nhiều dữ liệu di động hơn so với VP9. -• Codec VP9 vẫn được sử dụng cho video HDR." - Codec VP9 được kích hoạt. - Thay thế codec AV1 phần mềm - Thay thế codec AV1 phần mềm bằng codec VP9. - Từ chối phản hồi codec AV1 phần mềm - "Buộc từ chối phản hồi codec AV1 phần mềm. -Một codec khác sẽ được áp dụng sau khoảng 20 giây tải bộ đệm." - Quá trình dự phòng khiến việc tải bộ đệm mất khoảng 20 giây trước khi bắt đầu. - Đã lưu lựa chọn tốc độ phát mặc định thành %s. - Đã lưu lựa chọn chất lượng video mặc định khi sử dụng dữ liệu di động thành %s. - Thay đổi lựa chọn chất lượng video thất bại. - Đã lưu lựa chọn chất lượng video mặc định khi sử dụng Wi-Fi thành %s. - Tốc độ tùy chỉnh phải nhỏ hơn %sx. - Tốc độ phát tùy chỉnh không hợp lệ. +Chi tiết: +• Có thể mở khóa chất lượng cao cho một số video yêu cầu thiết bị có màn hình lớn, nhưng không phải tất cả. +• Cài đặt này sẽ không khả dụng nếu \"Giả mạo dữ liệu phát trực tuyến\" đang được bật." + + Tắt tùy chọn tốc độ phát khi phát nhạc + Tốc độ phát mặc định đã tắt khi phát nhạc. + Tốc độ phát mặc định được kích hoạt khi phát nhạc. + Dựa vào danh mục + Tốc độ phát mặc định đã tắt nếu video thuộc danh mục Âm nhạc. + Tốc độ phát mặc định đã tắt đối với các video chơi game trên Youtube Music. Return YouTube Dislike Hiện số lượt không thích @@ -1728,6 +1884,7 @@ Nhấp vào đây để xem các bước phát hành khóa API." Hiển thị nút Bỏ qua Hiển thị trong thanh tiến trình Tắt + Độ mờ: Màu: Đã thay đổi màu. Đặt lại màu @@ -1795,6 +1952,7 @@ Nhấp vào đây để xem các bước phát hành khóa API." Đổi danh mục Không có phân đoạn nào để bình chọn. + %1$s đến %2$s Chọn danh mục phân đoạn Danh mục đã tắt trong cài đặt. Bật danh mục để gửi. Đoạn SponsorBlock mới @@ -1902,11 +2060,11 @@ Nhấn vào Tiếp tục và cho phép thay đổi lựa chọn tối ưu hoá p Đặt lại Đã sao chép cài đặt sang bảng nhớ tạm. - Giả mạo luồng dữ liệu trực tuyến - Giả mạo luồng dữ liệu trực tuyến để khắc phục sự cố phát video. - Giả mạo luồng dữ liệu trực tuyến - Luồng dữ liệu trực tuyến được giả mạo. - "Luồng dữ liệu trực tuyến chưa được giả mạo. Khi phát video có thể gặp sự cố đứng hình." + Giả mạo dữ liệu phát trực tuyến + Giả mạo dữ liệu phát trực tuyến để khắc phục sự cố phát video. + Giả mạo dữ liệu phát trực tuyến + Dữ liệu phát trực tuyến được giả mạo. + "Dữ liệu phát trực tuyến chưa được giả mạo. Khi phát video có thể gặp sự cố đứng hình." Tắt cài đặt này có thể gây ra sự cố phát video. Ứng dụng khách mặc định "Android TV @@ -1914,6 +2072,8 @@ Nhấn vào Tiếp tục và cho phép thay đổi lựa chọn tối ưu hoá p Android VR "Android VR (Không xác thực)" + "iOS +(Không khuyến khích)" "iOS TV (Yêu cầu Đăng nhập)" Hạn chế @@ -1921,9 +2081,20 @@ Nhấn vào Tiếp tục và cho phép thay đổi lựa chọn tối ưu hoá p • Âm lượng ổn định không khả dụng. • Tắt Bản âm thanh tự động không khả dụng. • Video dành cho trẻ em có thể không phát được khi bạn đã đăng xuất hoặc bật chế độ ẩn danh." + • Máy chủ có thể chặn toàn bộ dải ASN/IP. "• Âm lượng ổn định không khả dụng. • Phim hoặc video trả phí có thể không phát được. • Video dành cho trẻ em có thể không phát được khi bạn đã đăng xuất hoặc bật chế độ ẩn danh." + Ứng dụng khách iOS + "Ứng dụng khách iOS được thêm vào danh sách ứng dụng khách có sẵn. + +CẢNH BÁO: Ứng dụng khách iOS đã không còn được hỗ trợ. Mọi sự cố phát sinh khi sử dụng đều do bạn tự chịu trách nhiệm." + Ứng dụng khách iOS không được thêm vào danh sách ứng dụng khách có sẵn. + "Khi yêu cầu các điểm cuối YouTube API bằng iOS, bạn sẽ cần các mã xác thực do thiết bị iOS và PoTokens do iOSGuard cung cấp. + +Điều này có nghĩa là các yêu cầu phát trực tuyến qua iOS sẽ bị thiếu cả mã xác thực và PoTokens, khiến máy chủ có thể coi người dùng là bot cũng như chặn toàn bộ dải ASN/IP. + +HÃY CÂN NHẮC RỦI RO TRƯỚC KHI SỬ DỤNG!" Bắt buộc iOS sử dụng AVC (H.264) Codec video luôn là AVC (H.264). Codec video được xác định tự động. @@ -1942,9 +2113,11 @@ Hạn chế: • Một số người dùng có thể gặp phải sự cố phát mới." Hiển thị trong Thống kê chi tiết - Ứng dụng khách sử dụng để nạp luồng dữ liệu trực tuyến được hiển thị trong Thống kê chi tiết. - Ứng dụng khách sử dụng để nạp luồng dữ liệu trực tuyến đã ẩn trong Thống kê chi tiết. + Ứng dụng khách sử dụng để nạp dữ liệu phát trực tuyến được hiển thị trong Thống kê chi tiết. + Ứng dụng khách sử dụng để nạp dữ liệu phát trực tuyến đã ẩn trong Thống kê chi tiết. Ngôn ngữ luồng âm thanh mặc định cho ứng dụng khách VR + Không thể nạp dữ liệu luồng từ ứng dụng khách. + Có thể bạn chưa đăng nhập. PoToken/VisitorData PoToken diff --git a/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml b/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml index 4b4e753dc..a77aecfd8 100644 --- a/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rCN/strings.xml @@ -1246,12 +1246,27 @@ 自动 视频 - 默认播放速度 - 移动网络的默认视频画质 - WiFi 网络的默认视频画质 + HDR 视频 HDR 视频已禁用 HDR 视频已启用 + 禁用 VP9 编解码器 + "VP9 编解码器已禁用 + +• 最大分辨率是 1080p +• 视频播放将使用比 VP9 更多的网络数据 +要获取 HDR 播放,HDR 视频仍使用VP9 编解码器" + VP9 编解码器已启用 + 替换软件 AV1 编解码器 + 使用 VP9 编解码器替换软件 AV1 编解码器 + + 默认播放速度 + 记住播放速度更改 + 播放速度更改适用于所有视频 + 播放速度更改仅适用于当前视频 + 显示 Toast + 更改默认播放速度时,显示 Toast + 更改默认播放速度时,不显示 Toast 启用自定义播放速度 自定义播放速度已启用 自定义播放速度已禁用 @@ -1260,12 +1275,11 @@ 使用旧版弹出菜单 编辑自定义播放速度 添加或更改播放速度 - 记住播放速度更改 - 播放速度更改适用于所有视频 - 播放速度更改仅适用于当前视频 - 显示 Toast - 更改默认播放速度时,显示 Toast - 更改默认播放速度时,不显示 Toast + 自定义播放速度必须小于 %sx,已重置为默认值 + 无效的自定义播放速度将使用默认值 + + 移动网络的默认视频画质 + WiFi 网络的默认视频画质 记住视频画质更改 画质更改适用于所有视频 画质更改仅适用于当前视频 @@ -1275,11 +1289,6 @@ 恢复旧的视频画质菜单 显示旧的视频画质菜单 不显示旧的视频画质菜单 - 禁用音乐播放速度 - 音乐默认播放速度已启用 - 启用 Shorts 默认播放速度 - 默认播放速度适用于 Shorts - 默认播放速度不适用于 Shorts 跳过预加载缓冲 跳过预加载缓冲 "视频播放开始时,跳过预加载缓冲的默认视频画质 @@ -1291,25 +1300,9 @@ 提示信息已显示 提示信息已隐藏 伪装设备尺寸 - "伪装设备尺寸,以解锁设备可能无法提供的更高视频质量" - 禁用 VP9 编解码器 - "VP9 编解码器已禁用 - -• 最大分辨率是 1080p -• 视频播放将使用比 VP9 更多的网络数据 -要获取 HDR 播放,HDR 视频仍使用VP9 编解码器" - VP9 编解码器已启用 - 替换软件 AV1 编解码器 - 使用 VP9 编解码器替换软件 AV1 编解码器 - 拒绝软件 AV1 编解码器切换 - "强制拒绝软件 AV1 编解码器响应约 20 秒缓冲后,切换到其他编解码器" - 切换过程会导致约 20 秒缓冲 - 将默认速度更改为 %s - 将默认移动数据画质更改为 %s - 无法设置视频画质 - 将默认 WiFi 画质更改为 %s - 自定义播放速度必须小于 %sx,已重置为默认值 - 无效的自定义播放速度将使用默认值 + + 禁用音乐播放速度 + 音乐默认播放速度已启用 恢复 YouTube 点踩 恢复 YouTube 点踩 diff --git a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml index 1e51233a0..c63ed3679 100644 --- a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml @@ -1,7 +1,7 @@ - 是否啟用影片播放器的無障礙控制? + 啟用影片播放器的無障礙控制功能? 由於已啟用無障礙服務,因此你的控制選項已被修改。 RVX @@ -426,11 +426,11 @@ 指定你的語言模板來修飾使用者。中每個影片下顯示的播放量。每個關鍵字(在你的語言中的一個字/詞) -> 值(關鍵字的含義)必須單獨一行。在「->」符號之前是關鍵字。如果更改應用程序或系統語言,則需要重置此設定。\n\n示範:\n英語:10K 觀看數 = K -> 1000,觀看數 -> 觀看數\n西班牙文:10 K 觀看數 = K -> 1000,觀看數 -> 觀看數 千 -> 1 000\n百萬 -> 1 000 000\n十億 -> 1 000 000 000\n觀看數 -> 觀看數 關於觀看次數篩選 - "主頁/訂閱/搜尋結果將被過濾以隱藏觀看次數小於或大於指定數量的影片。 + "主頁/訂閱/搜尋結果將被篩選以隱藏觀看次數小於或大於指定數量的影片。 限制: -• 短影片無法隱藏。 -• 觀看次數為0的影片不會被曬選。" +• 短影音無法隱藏。 +• 觀看次數為零的影片不會被篩選。" 隱藏相關影片 相關影片已隱藏。 相關影片已顯示。 @@ -509,9 +509,9 @@ • 社群貼文被隱藏。 車用佈局 -• 常規播放器中的短影片開啟。 +• 常規播放器中的短影音開啟。 • 資訊流依主題和頻道進行組織。 -• 關閉「偽裝串流資料」時無法開啟影片說明。" +• 關閉「偽裝串流數據」時無法開啟影片說明。" 禁用佈局更新 伺服器不會更新佈局。 佈局將由伺服器更新。 @@ -528,6 +528,7 @@ 停用半透明狀態列 狀態列不透明。 狀態列是不透明或半透明的。 + 對於一些運行 Android 12 以上版本的製造商 ROM,啟用此功能可能會使系統導覽列變得透明。 偽裝應用程式版本 已偽裝版本 未偽裝版本 @@ -1166,7 +1167,7 @@ "按鈕被隱藏。 滑動即可展開或關閉。" - 顯示展開和關閉按鈕。 + 顯示擴展和關閉按鈕。 隱藏快轉和倒轉按鈕 快轉和倒轉按鈕已隱藏 快轉和倒轉按鈕已顯示 @@ -1238,13 +1239,13 @@ 所有內容 (按熱門排序) 僅限影片 (按時間排序) 僅限影片 (按熱門排序) - 僅限短影片 (按時間排序) - 僅限短影片 (按流行排序) + 僅限短影音 (按時間排序) + 僅限短影音 (按流行排序) 僅限串流媒體影片 (按時間排序) 僅限串流媒體影片 (按熱門排序) 所有會員專屬內容 會員專屬影片 - 會員專屬短影片 + 會員專屬短影音 會員專屬直播 由於頻道ID不匹配 因此無法產生播放清單。 頻道白名單 @@ -1358,9 +1359,9 @@ 手動展開影片描述 短片 - 停用 短影片 後台播放 - 短影片 後台播放已停用。 - 短影片 後台播放已啟用。 + 停用 短影音 後台播放 + 短影音 後台播放已停用。 + 短影音 後台播放已啟用。 停用恢復短片播放器 短片播放器在應用程式啟動時不會恢復播放。 短片播放器在應用程式啟動時會恢復播放。 @@ -1382,9 +1383,9 @@ 在首頁和相關影片中隱藏 在首頁和相關影片中隱藏 在首頁和相關影片中顯示 - 隱藏搜尋結果中的短片 - 搜尋結果中的短片已隱藏 - 搜尋結果中的短片已顯示 + 在搜尋結果中隱藏 + 隱藏在搜尋結果中。 + 顯示在搜尋結果中。 隱藏訂閱中的短片 訂閱中的短片已隱藏 訂閱中的短片已顯示 @@ -1540,6 +1541,10 @@ 顯示開啟影片選單 開啟影片選單已顯示。 開啟影片選單已隱藏。 + 快速對話 + 顯示快速對話選單 + 快速對話選單已顯示。 + 快速對話選單已隱藏。 重複狀態 顯示重複狀態選單 重複狀態選單已顯示。 @@ -1598,6 +1603,18 @@ 在「鎖定螢幕」模式下停用滑動手勢 滑動幅度閾值 防誤觸的滑動幅度閾值 + 滑動覆蓋替代用戶介面 + 使用替代的使用者介面。 + 使用舊版使用者介面。 + 啟用極簡風格 + 已啟用最小覆蓋樣式。 + 最小覆蓋樣式已停用。 + 顯示圓形覆蓋層 + 圓形覆蓋層已顯示。 + 水平覆蓋層已顯示。 + 滑動調節覆蓋層背景不透明度 + 不透明度值介於 0 到 100 之間。 + 滑動透明度必須介於 0 到 100 之間。 滑動疊加層上的檔案大小 滑動疊加層上的檔案大小 滑動覆蓋螢幕尺寸 @@ -1629,12 +1646,42 @@ 自動 影片 - 預設播放速度 - 行動數據的預設影片畫質 - Wi-Fi 預設的影片畫質 + + 編解碼器 HDR 影片 HDR 影片已啟用 HDR 影片已停用 + 停用 VP9 編解碼器 + "VP9 編解碼器已停用。 + +• 最高解析度為 1080p。 +• 影片播放將使用比 VP9 更多的網路數據。 +• 若要獲得 HDR 播放,HDR 影片仍會使用 VP9 編解碼器。" + VP9 編解碼器已啟用。 + 替換軟體 AV1 編解碼器 + 將軟體 AV1 編解碼器替換為 VP9 編解碼器。 + + 播放速度 + 預設播放速度 + 記住播放速度更改 + 播放速度更改適用於所有影片 + 播放速度更改僅適用於當前影片 + 顯示提示訊息 + 變更預設播放速度時會顯示提示訊息。 + 變更預設播放速度時不會顯示提示訊息。 + 短影音的預設播放速度 + 記住短影音的播放速度變更 + "播放速度變更適用於所有短影音。 + +資訊: +• 在短影音播放器中變更播放速度的唯一方法是使用「自訂動作」中的「速度對話框」。 +• 如果您未包含「短影音元件」補丁,則此功能將無法使用。" + 播放速度變更僅適用於目前的短影音。 + 顯示提示訊息 + 變更短影音上的預設播放速度時,會顯示提示訊息。 + 變更短影音上的預設播放速度時,不會顯示提示訊息。 + 將預設播放速度變更為:%s。 + 將預設短影音播放速度變更為:%s。 啟用自定義播放速度 自定義播放速度已啟用 自定義播放速度已停用 @@ -1643,30 +1690,34 @@ 使用舊版彈出選單 編輯自定義播放速度 添加或更改播放速度 - 記住播放速度更改 - 播放速度更改適用於所有影片 - 播放速度更改僅適用於當前影片 - 顯示提示訊息 - 變更預設播放速度時會顯示提示訊息。 - 變更預設播放速度時不會顯示提示訊息。 + 自訂速度必須小於 %sx +使用預設值 + 無效的自定播放速度將使用預設值 + + 影片畫質 + 行動數據的預設影片畫質 + Wi-Fi 預設的影片畫質 記住影片畫質更改 畫質更改適用於所有影片 畫質更改僅適用於當前影片 顯示提示訊息 更改預設影片畫質時將顯示提示訊息。 更改預設影片畫質時不會顯示提示訊息。 + 行動網路上的預設短影音畫質 + 無線網路上的預設短影音畫質 + 記住短影音的畫質變化 + 畫質變更適用於所有短影音。 + 畫質變化僅適用於目前的短影音。 + 顯示提示訊息 + 變更預設短影音畫質時將顯示提示。 + 變更預設短影音畫質時不會顯示提示。 + 行動網路 + 無線上網 + 將預設 %1$s 畫質變更為: %2$s。 + 將短影音 %1$s 的畫質變更為: %2$s。 恢復舊的影片畫質選單 顯示舊的影片畫質選單 不顯示舊的影片畫質選單 - 停用音樂的播放速度 - 音樂的預設播放速度被禁用。 - 音樂的預設播放速度已啟用。 - 使用類別進行驗證 - 如果影片類別為音樂,則預設播放速度將被停用。 - YouTube 音樂上可播放的影片的預設播放速度為停用。 - 啟用短片預設播放速度 - 預設播放速度適用於短片 - 預設播放速度不適用於短片 跳過預載入 跳過預載入 "跳過影片開頭的預先載入緩衝區以立即套用預設影片品質 @@ -1679,27 +1730,18 @@ 提示訊息已顯示 提示訊息已隱藏 偽裝裝置尺寸 - "變更裝置尺寸設定,以便解鎖在您目前的裝置上原本不支援的較高影片品質。" - 停用 VP9 編解碼器 - "VP9 編解碼器已停用。 + "將設備尺寸偽裝為最大值。 -• 最高解析度為 1080p。 -• 影片播放將使用比 VP9 更多的網路數據。 -• 若要獲得 HDR 播放,HDR 影片仍會使用 VP9 編解碼器。" - VP9 編解碼器已啟用。 - 替換軟體 AV1 編解碼器 - 將軟體 AV1 編解碼器替換為 VP9 編解碼器。 - 拒絕軟體 AV1 編解碼器回應 - "強制拒絕軟體 AV1 編解碼器回應。 -約 20 秒的緩衝後會應用不同的編解碼器。" - 切換過程會導致約 20 秒載入 - 將預設速度更改為 %s - 將預設移動數據畫質更改為 %s - 無法設定影片畫質 - 將預設 WiFi 畫質更改為 %s - 自訂速度必須小於 %sx -使用預設值 - 無效的自定播放速度將使用預設值 +資訊: +• 某些需要較高設備尺寸的影片可能會解鎖高畫質,但並非所有影片都適用。 +• 如果開啟“偽裝串流數據”,則此設定不可用。" + + 停用音樂的播放速度 + 音樂的預設播放速度被禁用。 + 音樂的預設播放速度已啟用。 + 使用類別進行驗證 + 如果影片類別為音樂,則預設播放速度將被停用。 + YouTube 音樂上可播放的影片的預設播放速度為停用。 恢復 YouTube 倒讚 啟用恢復 YouTube 倒讚 @@ -1831,6 +1873,7 @@ 顯示跳過按鈕 僅在進度條中顯示 停用 + 不透明度: 顏色: 顏色已更改 顏色已重置 @@ -1901,6 +1944,7 @@ 更改類別 沒有可供投票的片段 + %1$s 到 %2$s 選擇片段類別 類別在設定中被停用請啟用類別以提交 新的 SponsorBlock 片段 @@ -2019,6 +2063,8 @@ Android VR "Android VR (無授權)" + "iOS +(已棄用)" "iOS TV (需要登入)" 偽裝副作用 @@ -2026,8 +2072,19 @@ • 無法獲得穩定的音量。 • 停用強制自動音軌無法使用。 • 登出或處於隱身模式時可能無法播放兒童影片。" + • 整個 ASN/IP 範圍可能會被伺服器封鎖。 "• 電影或付費影片可能無法播放。 • 登出或處於隱身模式時可能無法播放兒童影片。" + 使用 iOS 用戶端 + " iOS 用戶端已新增到可用用戶端列表中。 + +警告:iOS 用戶端已被棄用。使用過程中出現的任何問題 風險自負。" + iOS 用戶端未新增至可用用戶端列表中。 + "當使用 iOS 請求 YouTube API 端點時,您將需要 iOS 裝置頒發的 Auth 令牌和 iOSGuard 頒發的 PoTokens。 + +這意味著透過 iOS 的串流請求將缺少 Auth 令牌和 PoTokens,而伺服器可能會將使用者視為機器人並阻止整個 ASN/IP 範圍。 + +請自行承擔風險!" 強制 iOS AVC (H.264) 影片編解碼器強制為 AVC (H.264)。 影片編解碼器是自動決定的。 @@ -2046,6 +2103,8 @@ AVC 的最大解析度為 1080p,Opus 音訊編解碼器不可用,影片播 用於取得串流資料的用戶端顯示在統計資料中。 用於獲取串流資料的用戶端隱藏在統計資料中。 VR預設音訊串流語言 + 無法獲取任何客戶端串流。 + 您可能尚未登入。 Potoken / 訪客數據 使用PoToken From 6818df45079a99f245d8c48055495e6775e98a88 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 19:48:38 +0900 Subject: [PATCH 49/77] bump 5.6.1-dev.3 --- README.md | 249 ++++++++++++++++---------------- gradle.properties | 2 +- patches.json | 309 ++++++++++++++++++++++++---------------- patches/api/patches.api | 6 +- 4 files changed, 317 insertions(+), 249 deletions(-) diff --git a/README.md b/README.md index 0e4c0c0d6..c5c347884 100644 --- a/README.md +++ b/README.md @@ -11,73 +11,73 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `Alternative thumbnails` | Adds options to replace video thumbnails using the DeArrow API or image captures from the video. | 19.05.36 ~ 19.47.53 | -| `Ambient mode control` | Adds options to disable Ambient mode and to bypass Ambient mode restrictions. | 19.05.36 ~ 19.47.53 | -| `Bypass URL redirects` | Adds an option to bypass URL redirects and open the original URL directly. | 19.05.36 ~ 19.47.53 | -| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 19.05.36 ~ 19.47.53 | -| `Change form factor` | Adds an option to change the UI appearance to a phone, tablet, or automotive device. | 19.05.36 ~ 19.47.53 | -| `Change live ring click action` | Adds an option to open the channel instead of the live stream when clicking on the live ring. | 19.05.36 ~ 19.47.53 | -| `Change player flyout menu toggles` | Adds an option to use text toggles instead of switch toggles within the additional settings menu. | 19.05.36 ~ 19.47.53 | -| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 19.05.36 ~ 19.47.53 | -| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 19.05.36 ~ 19.47.53 | -| `Custom Shorts action buttons` | Changes, at compile time, the icon of the action buttons of the Shorts player. | 19.05.36 ~ 19.47.53 | -| `Custom branding icon for YouTube` | Changes the YouTube app icon to the icon specified in patch options. | 19.05.36 ~ 19.47.53 | -| `Custom branding name for YouTube` | Changes the YouTube app name to the name specified in patch options. | 19.05.36 ~ 19.47.53 | -| `Custom double tap length` | Adds Double-tap to seek values that are specified in patch options. | 19.05.36 ~ 19.47.53 | -| `Custom header for YouTube` | Applies a custom header in the top left corner within the app. | 19.05.36 ~ 19.47.53 | -| `Description components` | Adds options to hide and disable description components. | 19.05.36 ~ 19.47.53 | -| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 19.05.36 ~ 19.47.53 | -| `Disable forced auto audio tracks` | Adds an option to disable audio tracks from being automatically enabled. | 19.05.36 ~ 19.47.53 | -| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 19.05.36 ~ 19.47.53 | -| `Disable haptic feedback` | Adds options to disable haptic feedback when swiping in the video player. | 19.05.36 ~ 19.47.53 | -| `Disable layout updates` | Adds an option to disable layout updates by server. | 19.05.36 ~ 19.47.53 | -| `Disable resuming Miniplayer on startup` | Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup. | 19.05.36 ~ 19.47.53 | -| `Disable resuming Shorts on startup` | Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched. | 19.05.36 ~ 19.47.53 | -| `Disable splash animation` | Adds an option to disable the splash animation on app startup. | 19.05.36 ~ 19.47.53 | -| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 19.05.36 ~ 19.47.53 | -| `Enable debug logging` | Adds an option to enable debug logging. | 19.05.36 ~ 19.47.53 | -| `Enable gradient loading screen` | Adds an option to enable the gradient loading screen. | 19.05.36 ~ 19.47.53 | -| `Force hide player buttons background` | Removes, at compile time, the dark background surrounding the video player controls. | 19.05.36 ~ 19.47.53 | -| `Fullscreen components` | Adds options to hide or change components related to fullscreen. | 19.05.36 ~ 19.47.53 | -| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 19.05.36 ~ 19.47.53 | -| `Hide Shorts dimming` | Removes, at compile time, the dimming effect at the top and bottom of Shorts videos. | 19.05.36 ~ 19.47.53 | -| `Hide accessibility controls dialog` | Removes, at compile time, accessibility controls dialog 'Turn on accessibility controls for the video player?'. | 19.05.36 ~ 19.47.53 | -| `Hide action buttons` | Adds options to hide action buttons under videos. | 19.05.36 ~ 19.47.53 | -| `Hide ads` | Adds options to hide ads. | 19.05.36 ~ 19.47.53 | -| `Hide comments components` | Adds options to hide components related to comments. | 19.05.36 ~ 19.47.53 | -| `Hide feed components` | Adds options to hide components related to feeds. | 19.05.36 ~ 19.47.53 | -| `Hide feed flyout menu` | Adds the ability to hide feed flyout menu components using a custom filter. | 19.05.36 ~ 19.47.53 | -| `Hide layout components` | Adds options to hide general layout components. | 19.05.36 ~ 19.47.53 | -| `Hide player buttons` | Adds options to hide buttons in the video player. | 19.05.36 ~ 19.47.53 | -| `Hide player flyout menu` | Adds options to hide player flyout menu components. | 19.05.36 ~ 19.47.53 | -| `Hide shortcuts` | Remove, at compile time, the app shortcuts that appears when the app icon is long pressed. | 19.05.36 ~ 19.47.53 | -| `Hook YouTube Music actions` | Adds support for opening music in RVX Music using the in-app YouTube Music button. | 19.05.36 ~ 19.47.53 | -| `Hook download actions` | Adds support to download videos with an external downloader app using the in-app download button. | 19.05.36 ~ 19.47.53 | -| `MaterialYou` | Applies the MaterialYou theme for Android 12+ devices. | 19.05.36 ~ 19.47.53 | -| `Miniplayer` | Adds options to change the in-app minimized player, and if patching target 19.16+ adds options to use modern miniplayers. | 19.05.36 ~ 19.47.53 | -| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 19.05.36 ~ 19.47.53 | -| `Open links externally` | Adds an option to always open links in your browser instead of the in-app browser. | 19.05.36 ~ 19.47.53 | -| `Overlay buttons` | Adds options to display useful overlay buttons in the video player. | 19.05.36 ~ 19.47.53 | -| `Player components` | Adds options to hide or change components related to the video player. | 19.05.36 ~ 19.47.53 | -| `Remove background playback restrictions` | Removes restrictions on background playback, including for music and kids videos. | 19.05.36 ~ 19.47.53 | -| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 19.05.36 ~ 19.47.53 | -| `Return YouTube Dislike` | Adds an option to show the dislike count of videos using the Return YouTube Dislike API. | 19.05.36 ~ 19.47.53 | -| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 19.05.36 ~ 19.47.53 | -| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 19.05.36 ~ 19.47.53 | -| `Seekbar components` | Adds options to hide or change components related to the seekbar. | 19.05.36 ~ 19.47.53 | -| `Settings for YouTube` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 19.05.36 ~ 19.47.53 | -| `Shorts components` | Adds options to hide or change components related to YouTube Shorts. | 19.05.36 ~ 19.47.53 | -| `Snack bar components` | Adds options to hide or change components related to the snack bar. | 19.05.36 ~ 19.47.53 | -| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content. | 19.05.36 ~ 19.47.53 | -| `Spoof app version` | Adds options to spoof the YouTube client version. This can be used to restore old UI elements and features. | 19.05.36 ~ 19.47.53 | -| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 19.05.36 ~ 19.47.53 | -| `Swipe controls` | Adds options for controlling volume and brightness with swiping, and whether to enter fullscreen when swiping down below the player. | 19.05.36 ~ 19.47.53 | -| `Theme` | Changes the app's themes to the values specified in patch options. | 19.05.36 ~ 19.47.53 | -| `Toolbar components` | Adds options to hide or change components located on the toolbar, such as the search bar, header, and toolbar buttons. | 19.05.36 ~ 19.47.53 | -| `Translations for YouTube` | Add translations or remove string resources. | 19.05.36 ~ 19.47.53 | -| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 19.05.36 ~ 19.47.53 | -| `Visual preferences icons for YouTube` | Adds icons to specific preferences in the settings. | 19.05.36 ~ 19.47.53 | -| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 19.05.36 ~ 19.47.53 | +| `Alternative thumbnails` | Adds options to replace video thumbnails using the DeArrow API or image captures from the video. | 19.05.36 ~ 20.03.45 | +| `Ambient mode control` | Adds options to disable Ambient mode and to bypass Ambient mode restrictions. | 19.05.36 ~ 20.03.45 | +| `Bypass URL redirects` | Adds an option to bypass URL redirects and open the original URL directly. | 19.05.36 ~ 20.03.45 | +| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 19.05.36 ~ 20.03.45 | +| `Change form factor` | Adds an option to change the UI appearance to a phone, tablet, or automotive device. | 19.05.36 ~ 20.03.45 | +| `Change live ring click action` | Adds an option to open the channel instead of the live stream when clicking on the live ring. | 19.05.36 ~ 20.03.45 | +| `Change player flyout menu toggles` | Adds an option to use text toggles instead of switch toggles within the additional settings menu. | 19.05.36 ~ 20.03.45 | +| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 19.05.36 ~ 20.03.45 | +| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 19.05.36 ~ 20.03.45 | +| `Custom Shorts action buttons` | Changes, at compile time, the icon of the action buttons of the Shorts player. | 19.05.36 ~ 20.03.45 | +| `Custom branding icon for YouTube` | Changes the YouTube app icon to the icon specified in patch options. | 19.05.36 ~ 20.03.45 | +| `Custom branding name for YouTube` | Changes the YouTube app name to the name specified in patch options. | 19.05.36 ~ 20.03.45 | +| `Custom double tap length` | Adds Double-tap to seek values that are specified in patch options. | 19.05.36 ~ 20.03.45 | +| `Custom header for YouTube` | Applies a custom header in the top left corner within the app. | 19.05.36 ~ 20.03.45 | +| `Description components` | Adds options to hide and disable description components. | 19.05.36 ~ 20.03.45 | +| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 19.05.36 ~ 20.03.45 | +| `Disable forced auto audio tracks` | Adds an option to disable audio tracks from being automatically enabled. | 19.05.36 ~ 20.03.45 | +| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 19.05.36 ~ 20.03.45 | +| `Disable haptic feedback` | Adds options to disable haptic feedback when swiping in the video player. | 19.05.36 ~ 20.03.45 | +| `Disable layout updates` | Adds an option to disable layout updates by server. | 19.05.36 ~ 20.03.45 | +| `Disable resuming Miniplayer on startup` | Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup. | 19.05.36 ~ 20.03.45 | +| `Disable resuming Shorts on startup` | Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched. | 19.05.36 ~ 20.03.45 | +| `Disable splash animation` | Adds an option to disable the splash animation on app startup. | 19.05.36 ~ 20.03.45 | +| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 19.05.36 ~ 20.03.45 | +| `Enable debug logging` | Adds an option to enable debug logging. | 19.05.36 ~ 20.03.45 | +| `Enable gradient loading screen` | Adds an option to enable the gradient loading screen. | 19.05.36 ~ 20.03.45 | +| `Force hide player buttons background` | Removes, at compile time, the dark background surrounding the video player controls. | 19.05.36 ~ 20.03.45 | +| `Fullscreen components` | Adds options to hide or change components related to fullscreen. | 19.05.36 ~ 20.03.45 | +| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 19.05.36 ~ 20.03.45 | +| `Hide Shorts dimming` | Removes, at compile time, the dimming effect at the top and bottom of Shorts videos. | 19.05.36 ~ 20.03.45 | +| `Hide accessibility controls dialog` | Removes, at compile time, accessibility controls dialog 'Turn on accessibility controls for the video player?'. | 19.05.36 ~ 20.03.45 | +| `Hide action buttons` | Adds options to hide action buttons under videos. | 19.05.36 ~ 20.03.45 | +| `Hide ads` | Adds options to hide ads. | 19.05.36 ~ 20.03.45 | +| `Hide comments components` | Adds options to hide components related to comments. | 19.05.36 ~ 20.03.45 | +| `Hide feed components` | Adds options to hide components related to feeds. | 19.05.36 ~ 20.03.45 | +| `Hide feed flyout menu` | Adds the ability to hide feed flyout menu components using a custom filter. | 19.05.36 ~ 20.03.45 | +| `Hide layout components` | Adds options to hide general layout components. | 19.05.36 ~ 20.03.45 | +| `Hide player buttons` | Adds options to hide buttons in the video player. | 19.05.36 ~ 20.03.45 | +| `Hide player flyout menu` | Adds options to hide player flyout menu components. | 19.05.36 ~ 20.03.45 | +| `Hide shortcuts` | Remove, at compile time, the app shortcuts that appears when the app icon is long pressed. | 19.05.36 ~ 20.03.45 | +| `Hook YouTube Music actions` | Adds support for opening music in RVX Music using the in-app YouTube Music button. | 19.05.36 ~ 20.03.45 | +| `Hook download actions` | Adds support to download videos with an external downloader app using the in-app download button. | 19.05.36 ~ 20.03.45 | +| `MaterialYou` | Applies the MaterialYou theme for Android 12+ devices. | 19.05.36 ~ 20.03.45 | +| `Miniplayer` | Adds options to change the in-app minimized player, and if patching target 19.16+ adds options to use modern miniplayers. | 19.05.36 ~ 20.03.45 | +| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 19.05.36 ~ 20.03.45 | +| `Open links externally` | Adds an option to always open links in your browser instead of the in-app browser. | 19.05.36 ~ 20.03.45 | +| `Overlay buttons` | Adds options to display useful overlay buttons in the video player. | 19.05.36 ~ 20.03.45 | +| `Player components` | Adds options to hide or change components related to the video player. | 19.05.36 ~ 20.03.45 | +| `Remove background playback restrictions` | Removes restrictions on background playback, including for music and kids videos. | 19.05.36 ~ 20.03.45 | +| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 19.05.36 ~ 20.03.45 | +| `Return YouTube Dislike` | Adds an option to show the dislike count of videos using the Return YouTube Dislike API. | 19.05.36 ~ 20.03.45 | +| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 19.05.36 ~ 20.03.45 | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 19.05.36 ~ 20.03.45 | +| `Seekbar components` | Adds options to hide or change components related to the seekbar. | 19.05.36 ~ 20.03.45 | +| `Settings for YouTube` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 19.05.36 ~ 20.03.45 | +| `Shorts components` | Adds options to hide or change components related to YouTube Shorts. | 19.05.36 ~ 20.03.45 | +| `Snack bar components` | Adds options to hide or change components related to the snack bar. | 19.05.36 ~ 20.03.45 | +| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content. | 19.05.36 ~ 20.03.45 | +| `Spoof app version` | Adds options to spoof the YouTube client version. This can be used to restore old UI elements and features. | 19.05.36 ~ 20.03.45 | +| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 19.05.36 ~ 20.03.45 | +| `Swipe controls` | Adds options for controlling volume and brightness with swiping, and whether to enter fullscreen when swiping down below the player. | 19.05.36 ~ 20.03.45 | +| `Theme` | Changes the app's themes to the values specified in patch options. | 19.05.36 ~ 20.03.45 | +| `Toolbar components` | Adds options to hide or change components located on the toolbar, such as the search bar, header, and toolbar buttons. | 19.05.36 ~ 20.03.45 | +| `Translations for YouTube` | Add translations or remove string resources. | 19.05.36 ~ 20.03.45 | +| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 19.05.36 ~ 20.03.45 | +| `Visual preferences icons for YouTube` | Adds icons to specific preferences in the settings. | 19.05.36 ~ 20.03.45 | +| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 19.05.36 ~ 20.03.45 | ### [📦 `com.google.android.apps.youtube.music`](https://play.google.com/store/apps/details?id=com.google.android.apps.youtube.music) @@ -85,48 +85,48 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `Bitrate default value` | Sets the audio quality to 'Always High' when you first install the app. | 6.20.51 ~ 8.10.52 | -| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 6.20.51 ~ 8.10.52 | -| `Certificate spoof` | Enables YouTube Music to work with Android Auto by spoofing the YouTube Music certificate. | 6.20.51 ~ 8.10.52 | -| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 6.20.51 ~ 8.10.52 | -| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 6.20.51 ~ 8.10.52 | -| `Custom branding icon for YouTube Music` | Changes the YouTube Music app icon to the icon specified in patch options. | 6.20.51 ~ 8.10.52 | -| `Custom branding name for YouTube Music` | Changes the YouTube Music app name to the name specified in patch options. | 6.20.51 ~ 8.10.52 | -| `Custom header for YouTube Music` | Applies a custom header in the top left corner within the app. | 6.20.51 ~ 8.10.52 | -| `Dark theme` | Changes the app's dark theme to the values specified in patch options. | 6.20.51 ~ 8.10.52 | -| `Disable Cairo splash animation` | Adds an option to disable Cairo splash animation. | 7.06.54 ~ 8.10.52 | -| `Disable DRC audio` | Adds an option to disable DRC (Dynamic Range Compression) audio. | 6.20.51 ~ 8.10.52 | -| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 6.20.51 ~ 8.10.52 | -| `Disable dislike redirection` | Adds an option to disable redirection to the next track when clicking the Dislike button. | 6.20.51 ~ 8.10.52 | -| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 6.20.51 ~ 8.10.52 | -| `Disable music video in album` | Adds option to redirect music videos from albums for non-premium users. | 6.20.51 ~ 8.10.52 | -| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 6.20.51 ~ 8.10.52 | -| `Enable debug logging` | Adds an option to enable debug logging. | 6.20.51 ~ 8.10.52 | -| `Enable landscape mode` | Adds an option to enable landscape mode when rotating the screen on phones. | 6.20.51 ~ 8.10.52 | -| `Flyout menu components` | Adds options to hide or change flyout menu components. | 6.20.51 ~ 8.10.52 | -| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 6.20.51 ~ 8.10.52 | -| `Hide account components` | Adds options to hide components related to the account menu. | 6.20.51 ~ 8.10.52 | -| `Hide action bar components` | Adds options to hide action bar components and replace the offline download button with an external download button. | 6.20.51 ~ 8.10.52 | -| `Hide ads` | Adds options to hide ads. | 6.20.51 ~ 8.10.52 | -| `Hide layout components` | Adds options to hide general layout components. | 6.20.51 ~ 8.10.52 | -| `Hide overlay filter` | Removes, at compile time, the dark overlay that appears when player flyout menus are open. | 6.20.51 ~ 8.10.52 | -| `Hide player overlay filter` | Removes, at compile time, the dark overlay that appears when single-tapping in the player. | 6.20.51 ~ 8.10.52 | -| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 6.20.51 ~ 8.10.52 | -| `Player components` | Adds options to hide or change components related to the player. | 6.20.51 ~ 8.10.52 | -| `Remove background playback restrictions` | Removes restrictions on background playback, including for kids videos. | 6.20.51 ~ 8.10.52 | -| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 6.20.51 ~ 8.10.52 | -| `Restore old style library shelf` | Adds an option to return the Library tab to the old style. | 6.20.51 ~ 8.10.52 | -| `Return YouTube Dislike` | Adds an option to show the dislike count of songs using the Return YouTube Dislike API. | 6.20.51 ~ 8.10.52 | -| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 6.20.51 ~ 8.10.52 | -| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 6.20.51 ~ 8.10.52 | -| `Settings for YouTube Music` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 6.20.51 ~ 8.10.52 | -| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as non-music sections. | 6.20.51 ~ 8.10.52 | +| `Bitrate default value` | Sets the audio quality to 'Always High' when you first install the app. | 6.20.51 ~ 8.12.53 | +| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 6.20.51 ~ 8.12.53 | +| `Certificate spoof` | Enables YouTube Music to work with Android Auto by spoofing the YouTube Music certificate. | 6.20.51 ~ 8.12.53 | +| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 6.20.51 ~ 8.12.53 | +| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 6.20.51 ~ 8.12.53 | +| `Custom branding icon for YouTube Music` | Changes the YouTube Music app icon to the icon specified in patch options. | 6.20.51 ~ 8.12.53 | +| `Custom branding name for YouTube Music` | Changes the YouTube Music app name to the name specified in patch options. | 6.20.51 ~ 8.12.53 | +| `Custom header for YouTube Music` | Applies a custom header in the top left corner within the app. | 6.20.51 ~ 8.12.53 | +| `Dark theme` | Changes the app's dark theme to the values specified in patch options. | 6.20.51 ~ 8.12.53 | +| `Disable Cairo splash animation` | Adds an option to disable Cairo splash animation. | 7.06.54 ~ 8.12.53 | +| `Disable DRC audio` | Adds an option to disable DRC (Dynamic Range Compression) audio. | 6.20.51 ~ 8.12.53 | +| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 6.20.51 ~ 8.12.53 | +| `Disable dislike redirection` | Adds an option to disable redirection to the next track when clicking the Dislike button. | 6.20.51 ~ 8.12.53 | +| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 6.20.51 ~ 8.12.53 | +| `Disable music video in album` | Adds option to redirect music videos from albums for non-premium users. | 6.20.51 ~ 8.12.53 | +| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 6.20.51 ~ 8.12.53 | +| `Enable debug logging` | Adds an option to enable debug logging. | 6.20.51 ~ 8.12.53 | +| `Enable landscape mode` | Adds an option to enable landscape mode when rotating the screen on phones. | 6.20.51 ~ 8.12.53 | +| `Flyout menu components` | Adds options to hide or change flyout menu components. | 6.20.51 ~ 8.12.53 | +| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 6.20.51 ~ 8.12.53 | +| `Hide account components` | Adds options to hide components related to the account menu. | 6.20.51 ~ 8.12.53 | +| `Hide action bar components` | Adds options to hide action bar components and replace the offline download button with an external download button. | 6.20.51 ~ 8.12.53 | +| `Hide ads` | Adds options to hide ads. | 6.20.51 ~ 8.12.53 | +| `Hide layout components` | Adds options to hide general layout components. | 6.20.51 ~ 8.12.53 | +| `Hide overlay filter` | Removes, at compile time, the dark overlay that appears when player flyout menus are open. | 6.20.51 ~ 8.12.53 | +| `Hide player overlay filter` | Removes, at compile time, the dark overlay that appears when single-tapping in the player. | 6.20.51 ~ 8.12.53 | +| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 6.20.51 ~ 8.12.53 | +| `Player components` | Adds options to hide or change components related to the player. | 6.20.51 ~ 8.12.53 | +| `Remove background playback restrictions` | Removes restrictions on background playback, including for kids videos. | 6.20.51 ~ 8.12.53 | +| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 6.20.51 ~ 8.12.53 | +| `Restore old style library shelf` | Adds an option to return the Library tab to the old style. | 6.20.51 ~ 8.12.53 | +| `Return YouTube Dislike` | Adds an option to show the dislike count of songs using the Return YouTube Dislike API. | 6.20.51 ~ 8.12.53 | +| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 6.20.51 ~ 8.12.53 | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 6.20.51 ~ 8.12.53 | +| `Settings for YouTube Music` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 6.20.51 ~ 8.12.53 | +| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as non-music sections. | 6.20.51 ~ 8.12.53 | | `Spoof app version` | Adds options to spoof the YouTube Music client version. This can be used to restore old UI elements and features. | 6.51.53 ~ 8.10.52 | -| `Spoof player parameter` | Adds options to spoof player parameter to allow playback. | 6.20.51 ~ 8.10.52 | -| `Translations for YouTube Music` | Add translations or remove string resources. | 6.20.51 ~ 8.10.52 | -| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 6.20.51 ~ 8.10.52 | -| `Visual preferences icons for YouTube Music` | Adds icons to specific preferences in the settings. | 6.20.51 ~ 8.10.52 | -| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 6.20.51 ~ 8.10.52 | +| `Spoof player parameter` | Adds options to spoof player parameter to allow playback. | 6.20.51 ~ 8.12.53 | +| `Translations for YouTube Music` | Add translations or remove string resources. | 6.20.51 ~ 8.12.53 | +| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 6.20.51 ~ 8.12.53 | +| `Visual preferences icons for YouTube Music` | Adds icons to specific preferences in the settings. | 6.20.51 ~ 8.12.53 | +| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 6.20.51 ~ 8.12.53 | ### [📦 `com.reddit.frontpage`](https://play.google.com/store/apps/details?id=com.reddit.frontpage) @@ -134,19 +134,19 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `Change package name` | Changes the package name for Reddit to the name specified in patch options. | 2024.17.0 ~ 2025.05.1 | -| `Custom branding name for Reddit` | Changes the Reddit app name to the name specified in patch options. | 2024.17.0 ~ 2025.05.1 | -| `Disable screenshot popup` | Adds an option to disable the popup that appears when taking a screenshot. | 2024.17.0 ~ 2025.05.1 | -| `Hide Recently Visited shelf` | Adds an option to hide the Recently Visited shelf in the sidebar. | 2024.17.0 ~ 2025.05.1 | -| `Hide ads` | Adds options to hide ads. | 2024.17.0 ~ 2025.05.1 | -| `Hide navigation buttons` | Adds options to hide buttons in the navigation bar. | 2024.17.0 ~ 2025.05.1 | -| `Hide recommended communities shelf` | Adds an option to hide the recommended communities shelves in subreddits. | 2024.17.0 ~ 2025.05.1 | -| `Open links directly` | Adds an option to skip over redirection URLs in external links. | 2024.17.0 ~ 2025.05.1 | -| `Open links externally` | Adds an option to always open links in your browser instead of in the in-app-browser. | 2024.17.0 ~ 2025.05.1 | -| `Premium icon` | Unlocks premium app icons. | 2024.17.0 ~ 2025.05.1 | -| `Remove subreddit dialog` | Adds options to remove the NSFW community warning and notifications suggestion dialogs by dismissing them automatically. | 2024.17.0 ~ 2025.05.1 | -| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 2024.17.0 ~ 2025.05.1 | -| `Settings for Reddit` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 2024.17.0 ~ 2025.05.1 | +| `Change package name` | Changes the package name for Reddit to the name specified in patch options. | 2024.17.0 ~ 2025.12.0 | +| `Custom branding name for Reddit` | Changes the Reddit app name to the name specified in patch options. | 2024.17.0 ~ 2025.12.0 | +| `Disable screenshot popup` | Adds an option to disable the popup that appears when taking a screenshot. | 2024.17.0 ~ 2025.12.0 | +| `Hide Recently Visited shelf` | Adds an option to hide the Recently Visited shelf in the sidebar. | 2024.17.0 ~ 2025.12.0 | +| `Hide ads` | Adds options to hide ads. | 2024.17.0 ~ 2025.12.0 | +| `Hide navigation buttons` | Adds options to hide buttons in the navigation bar. | 2024.17.0 ~ 2025.12.0 | +| `Hide recommended communities shelf` | Adds an option to hide the recommended communities shelves in subreddits. | 2024.17.0 ~ 2025.12.0 | +| `Open links directly` | Adds an option to skip over redirection URLs in external links. | 2024.17.0 ~ 2025.12.0 | +| `Open links externally` | Adds an option to always open links in your browser instead of in the in-app-browser. | 2024.17.0 ~ 2025.12.0 | +| `Premium icon` | Unlocks premium app icons. | 2024.17.0 ~ 2025.12.0 | +| `Remove subreddit dialog` | Adds options to remove the NSFW community warning and notifications suggestion dialogs by dismissing them automatically. | 2024.17.0 ~ 2025.12.0 | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 2024.17.0 ~ 2025.12.0 | +| `Settings for Reddit` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 2024.17.0 ~ 2025.12.0 | @@ -169,7 +169,8 @@ Example: "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -187,7 +188,7 @@ Example: "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -199,7 +200,7 @@ Example: "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] diff --git a/gradle.properties b/gradle.properties index 2f5dfd87a..1d8ab2764 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official kotlin.jvm.target.validation.mode = IGNORE -version = 5.6.1-dev.2 +version = 5.6.1-dev.3 diff --git a/patches.json b/patches.json index e37037588..fbef79d0c 100644 --- a/patches.json +++ b/patches.json @@ -15,7 +15,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -34,7 +35,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -55,7 +57,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -73,7 +75,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -95,7 +98,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -114,7 +117,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -133,7 +137,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -153,7 +157,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -174,7 +179,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -187,7 +193,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [ @@ -219,7 +225,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -242,7 +249,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -262,7 +269,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -284,7 +292,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -302,7 +310,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -342,7 +351,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -378,7 +388,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -435,7 +446,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [ @@ -483,7 +494,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [ @@ -514,7 +525,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -550,7 +562,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [ @@ -597,7 +609,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -625,7 +638,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -659,7 +673,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [ @@ -692,7 +706,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [ @@ -744,7 +758,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -764,7 +779,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -786,7 +801,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -808,7 +823,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -827,7 +842,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -849,7 +865,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -875,7 +891,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -897,7 +914,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -916,7 +933,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -934,7 +952,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -952,7 +971,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -975,7 +995,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -993,7 +1013,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1012,7 +1033,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1028,7 +1050,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -1047,7 +1069,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1069,7 +1092,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1088,7 +1111,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1109,7 +1133,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1127,7 +1151,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1145,7 +1170,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1167,7 +1193,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1195,7 +1221,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1213,7 +1239,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1238,7 +1265,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1260,7 +1288,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [ @@ -1324,7 +1352,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -1384,7 +1413,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -1402,7 +1431,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1420,7 +1450,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1442,7 +1473,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1468,7 +1499,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1489,7 +1520,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1517,7 +1549,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1532,7 +1564,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -1555,7 +1587,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1576,7 +1609,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1601,7 +1635,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1620,7 +1655,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1645,7 +1681,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1668,7 +1704,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1683,7 +1720,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -1705,7 +1742,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1727,7 +1764,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1749,7 +1787,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1768,7 +1807,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1783,7 +1822,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -1802,7 +1841,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -1857,7 +1897,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1878,7 +1919,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1897,7 +1939,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1917,7 +1960,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1942,7 +1986,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -1964,7 +2008,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -1980,7 +2025,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -1996,7 +2041,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -2015,7 +2060,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2039,7 +2085,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -2110,7 +2157,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -2138,7 +2185,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2151,7 +2199,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -2172,7 +2220,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -2192,7 +2240,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2207,7 +2256,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -2229,7 +2278,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -2248,7 +2297,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2269,7 +2319,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -2291,7 +2341,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -2313,7 +2363,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2336,7 +2387,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -2355,7 +2406,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2377,7 +2429,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -2392,7 +2444,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [] @@ -2411,7 +2463,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2435,7 +2488,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2451,7 +2505,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", - "2025.05.1" + "2025.12.0" ] }, "options": [ @@ -2486,7 +2540,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -2552,7 +2607,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [ @@ -2597,7 +2652,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2616,7 +2672,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -2708,7 +2765,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -2728,7 +2785,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -2789,7 +2847,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2812,7 +2871,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -2834,7 +2893,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -2867,7 +2927,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2886,7 +2947,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -2946,7 +3008,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -2964,7 +3027,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -3013,7 +3077,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [ @@ -3064,7 +3128,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -3091,7 +3155,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] @@ -3109,7 +3174,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [ @@ -3156,7 +3222,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [ @@ -3194,7 +3260,7 @@ "7.16.53", "7.25.53", "8.05.51", - "8.10.52" + "8.12.53" ] }, "options": [] @@ -3213,7 +3279,8 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53" + "19.47.53", + "20.03.45" ] }, "options": [] diff --git a/patches/api/patches.api b/patches/api/patches.api index 3208bf21c..40b6e9036 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -257,6 +257,7 @@ public final class app/revanced/patches/music/utils/resourceid/SharedResourceIdP public static final fun getBottomSheetRecyclerView ()J public static final fun getButtonContainer ()J public static final fun getButtonIconPaddingMedium ()J + public static final fun getChannelHandle ()J public static final fun getChipCloud ()J public static final fun getColorGrey ()J public static final fun getDarkBackground ()J @@ -555,10 +556,9 @@ public final class app/revanced/patches/shared/mapping/ResourceElement { } public final class app/revanced/patches/shared/mapping/ResourceMappingPatchKt { - public static final fun get (Ljava/util/List;Lapp/revanced/patches/shared/mapping/ResourceType;Ljava/lang/String;)J - public static final fun get (Ljava/util/List;Ljava/lang/String;Ljava/lang/String;)J + public static final fun getResourceId (Lapp/revanced/patches/shared/mapping/ResourceType;Ljava/lang/String;)J + public static final fun getResourceId (Ljava/lang/String;Ljava/lang/String;)J public static final fun getResourceMappingPatch ()Lapp/revanced/patcher/patch/ResourcePatch; - public static final fun getResourceMappings ()Ljava/util/List; } public final class app/revanced/patches/shared/mapping/ResourceType : java/lang/Enum { From 481a310d068a4a34c7dcf5c5e11e04286ea97c04 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 20:25:24 +0900 Subject: [PATCH 50/77] fix typo --- .../extension/youtube/patches/video/PlaybackSpeedPatch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java index 7ad27b152..b426e3d5a 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java @@ -69,7 +69,7 @@ public class PlaybackSpeedPatch { videoIdShorts = newlyLoadedVideoId; isLiveStreamShorts = newlyLoadedLiveStreamValue; - Logger.printInfo(() -> "newShortsVideoStarted: " + newlyLoadedVideoId); + Logger.printDebug(() -> "newShortsVideoStarted: " + newlyLoadedVideoId); } /** From 34e482b03e7516ce0f96990c96df9519258ea57a Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 20:26:12 +0900 Subject: [PATCH 51/77] fix(YouTube - Video playback): Update descriptions --- .../main/resources/youtube/settings/host/values/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 783bc9185..49ea2b6e2 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -1848,7 +1848,8 @@ Info: Info: • When the video starts, there is a delay of approximately 0.3 seconds. -• Does not apply to HDR videos, live stream videos, or videos shorter than 15 seconds." +• Does not apply to Shorts, HDR videos, live stream videos, or videos shorter than 15 seconds. +• The 'Spoof streaming data' removes preloaded buffers in other ways, so this setting is not needed if you use that setting." Turning on this setting may cause video playback issues. Show a toast when skipping Toast is shown. From b8b61fdf517f32cbe8b3cc6b0b637b8654cdbccb Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 20:28:07 +0900 Subject: [PATCH 52/77] fix typo --- .../src/main/resources/youtube/settings/host/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 49ea2b6e2..92d66c0d2 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -1849,7 +1849,7 @@ Info: Info: • When the video starts, there is a delay of approximately 0.3 seconds. • Does not apply to Shorts, HDR videos, live stream videos, or videos shorter than 15 seconds. -• The 'Spoof streaming data' removes preloaded buffers in other ways, so this setting is not needed if you use that setting." +• The 'Spoof streaming data' setting removes preloaded buffers in other ways, so this setting is not needed if you use that setting." Turning on this setting may cause video playback issues. Show a toast when skipping Toast is shown. From 758e8ac568925ae9d1e6ec5301c448b9a65fa28f Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Fri, 28 Mar 2025 20:29:24 +0900 Subject: [PATCH 53/77] fix(YouTube - Video playback): Update descriptions --- .../src/main/resources/youtube/settings/host/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 92d66c0d2..4a6cd861c 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -1849,7 +1849,7 @@ Info: Info: • When the video starts, there is a delay of approximately 0.3 seconds. • Does not apply to Shorts, HDR videos, live stream videos, or videos shorter than 15 seconds. -• The 'Spoof streaming data' setting removes preloaded buffers in other ways, so this setting is not needed if you use that setting." +• The 'Spoof streaming data' setting also removes preloaded buffers, so this setting is not needed if you use that setting." Turning on this setting may cause video playback issues. Show a toast when skipping Toast is shown. From b8f3917b55ea63c8f8e1f24e97ee6b6ce8debe2c Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:46:28 +0900 Subject: [PATCH 54/77] chore(YouTube): Integrate methods related to Shorts state into RootView --- .../youtube/patches/player/PlayerPatch.java | 3 +-- .../youtube/patches/shorts/CustomActionsPatch.java | 10 +++++----- .../youtube/patches/video/PlaybackSpeedPatch.java | 12 ++++-------- .../youtube/patches/video/VideoQualityPatch.java | 11 +++-------- .../revanced/extension/youtube/shared/RootView.java | 4 ++++ .../extension/youtube/shared/ShortsPlayerState.kt | 8 ++++++++ 6 files changed, 25 insertions(+), 23 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java index 992bebdf9..6ee95843d 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/player/PlayerPatch.java @@ -33,7 +33,6 @@ import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.shared.EngagementPanel; import app.revanced.extension.youtube.shared.PlayerType; import app.revanced.extension.youtube.shared.RootView; -import app.revanced.extension.youtube.shared.ShortsPlayerState; import app.revanced.extension.youtube.shared.VideoInformation; import app.revanced.extension.youtube.utils.VideoUtils; @@ -440,7 +439,7 @@ public class PlayerPatch { if (isLiveChatOrPlaylistPanel) { return true; } - return isAutoPopupPanel && ShortsPlayerState.getCurrent().isClosed(); + return isAutoPopupPanel && !RootView.isShortsActive(); } /** diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java index 7dfdf27e8..bb288a116 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java @@ -2,6 +2,7 @@ package app.revanced.extension.youtube.patches.shorts; import static app.revanced.extension.shared.utils.ResourceUtils.getString; import static app.revanced.extension.youtube.patches.components.ShortsCustomActionsFilter.isShortsFlyoutMenuVisible; +import static app.revanced.extension.youtube.shared.RootView.isShortsActive; import static app.revanced.extension.youtube.utils.ExtendedUtils.isSpoofingToLessThan; import android.content.Context; @@ -30,7 +31,6 @@ import app.revanced.extension.shared.utils.ResourceUtils; import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.patches.components.ShortsCustomActionsFilter; import app.revanced.extension.youtube.settings.Settings; -import app.revanced.extension.youtube.shared.ShortsPlayerState; import app.revanced.extension.youtube.utils.ExtendedUtils; import app.revanced.extension.youtube.utils.VideoUtils; @@ -55,7 +55,7 @@ public final class CustomActionsPatch { if (!SHORTS_CUSTOM_ACTIONS_TOOLBAR_ENABLED) { return; } - if (ShortsPlayerState.getCurrent().isClosed()) { + if (!isShortsActive()) { return; } if (!isMoreButton(enumString)) { @@ -118,7 +118,7 @@ public final class CustomActionsPatch { if (!SHORTS_CUSTOM_ACTIONS_FLYOUT_MENU_ENABLED) { return; } - if (ShortsPlayerState.getCurrent().isClosed()) { + if (!isShortsActive()) { return; } if (bottomSheetMenuObject == null) { @@ -136,7 +136,7 @@ public final class CustomActionsPatch { if (!SHORTS_CUSTOM_ACTIONS_FLYOUT_MENU_ENABLED) { return; } - if (ShortsPlayerState.getCurrent().isClosed()) { + if (!isShortsActive()) { return; } for (CustomAction customAction : CustomAction.values()) { @@ -164,7 +164,7 @@ public final class CustomActionsPatch { } recyclerView.getViewTreeObserver().addOnDrawListener(() -> { try { - if (ShortsPlayerState.getCurrent().isClosed()) { + if (!isShortsActive()) { return; } contextRef = new WeakReference<>(recyclerView.getContext()); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java index b426e3d5a..e731c0b75 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java @@ -1,6 +1,7 @@ package app.revanced.extension.youtube.patches.video; import static app.revanced.extension.shared.utils.StringRef.str; +import static app.revanced.extension.youtube.shared.RootView.isShortsActive; import androidx.annotation.NonNull; @@ -13,7 +14,6 @@ import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.patches.utils.PatchStatus; import app.revanced.extension.youtube.patches.video.requests.MusicRequest; import app.revanced.extension.youtube.settings.Settings; -import app.revanced.extension.youtube.shared.ShortsPlayerState; import app.revanced.extension.youtube.shared.VideoInformation; import app.revanced.extension.youtube.whitelist.Whitelist; @@ -44,7 +44,7 @@ public class PlaybackSpeedPatch { public static void newVideoStarted(@NonNull String newlyLoadedChannelId, @NonNull String newlyLoadedChannelName, @NonNull String newlyLoadedVideoId, @NonNull String newlyLoadedVideoTitle, final long newlyLoadedVideoLength, boolean newlyLoadedLiveStreamValue) { - if (isShorts()) { + if (isShortsActive()) { channelIdShorts = newlyLoadedChannelId; videoIdShorts = newlyLoadedVideoId; isLiveStreamShorts = newlyLoadedLiveStreamValue; @@ -100,7 +100,7 @@ public class PlaybackSpeedPatch { * Injection point. */ public static float getPlaybackSpeed(float playbackSpeed) { - boolean isShorts = isShorts(); + boolean isShorts = isShortsActive(); String currentChannelId = isShorts ? channelIdShorts : channelId; String currentVideoId = isShorts ? videoIdShorts : videoId; boolean currentVideoIsLiveStream = isShorts ? isLiveStreamShorts : isLiveStream; @@ -137,7 +137,7 @@ public class PlaybackSpeedPatch { */ public static void userSelectedPlaybackSpeed(float playbackSpeed) { try { - boolean isShorts = isShorts(); + boolean isShorts = isShortsActive(); if (PatchStatus.RememberPlaybackSpeed()) { BooleanSetting rememberPlaybackSpeedLastSelectedSetting = isShorts ? Settings.REMEMBER_PLAYBACK_SPEED_SHORTS_LAST_SELECTED @@ -186,10 +186,6 @@ public class PlaybackSpeedPatch { } } - private static boolean isShorts() { - return !ShortsPlayerState.getCurrent().isClosed(); - } - private static boolean isMusic() { if (DISABLE_DEFAULT_PLAYBACK_SPEED_MUSIC && !videoId.isEmpty()) { try { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java index d4769d084..0ce60f14e 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/VideoQualityPatch.java @@ -1,6 +1,7 @@ package app.revanced.extension.youtube.patches.video; import static app.revanced.extension.shared.utils.StringRef.str; +import static app.revanced.extension.youtube.shared.RootView.isShortsActive; import androidx.annotation.NonNull; @@ -9,7 +10,6 @@ import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Utils; import app.revanced.extension.youtube.settings.Settings; import app.revanced.extension.youtube.shared.PlayerType; -import app.revanced.extension.youtube.shared.ShortsPlayerState; import app.revanced.extension.youtube.shared.VideoInformation; @SuppressWarnings("unused") @@ -56,7 +56,7 @@ public class VideoQualityPatch { } private static void setVideoQuality(long delayMillis) { - boolean isShorts = isShorts(); + boolean isShorts = isShortsActive(); IntegerSetting defaultQualitySetting = Utils.getNetworkType() == Utils.NetworkType.MOBILE ? isShorts ? shortsQualityMobile : videoQualityMobile : isShorts ? shortsQualityWifi : videoQualityWifi; @@ -75,13 +75,12 @@ public class VideoQualityPatch { private static void userSelectedVideoQuality(final int defaultQuality) { if (defaultQuality != DEFAULT_YOUTUBE_VIDEO_QUALITY) { - boolean isShorts = isShorts(); final Utils.NetworkType networkType = Utils.getNetworkType(); String networkTypeMessage = networkType == Utils.NetworkType.MOBILE ? str("revanced_remember_video_quality_mobile") : str("revanced_remember_video_quality_wifi"); - if (isShorts) { + if (isShortsActive()) { if (Settings.REMEMBER_VIDEO_QUALITY_SHORTS_LAST_SELECTED.get()) { IntegerSetting defaultQualitySetting = networkType == Utils.NetworkType.MOBILE ? shortsQualityMobile @@ -114,8 +113,4 @@ public class VideoQualityPatch { } } } - - private static boolean isShorts() { - return !ShortsPlayerState.getCurrent().isClosed(); - } } \ No newline at end of file diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/RootView.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/RootView.java index 3d18b32b2..cad23ab5f 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/RootView.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/RootView.java @@ -58,6 +58,10 @@ public final class RootView { return PlayerType.getCurrent().isMaximizedOrFullscreen() || isActionBarVisible.get(); } + public static boolean isShortsActive() { + return ShortsPlayerState.getCurrent().isOpen(); + } + /** * Get current BrowseId. * Rest of the implementation added by patch. diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/ShortsPlayerState.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/ShortsPlayerState.kt index e3e56c58e..76f201265 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/ShortsPlayerState.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/ShortsPlayerState.kt @@ -48,4 +48,12 @@ enum class ShortsPlayerState { fun isClosed(): Boolean { return this == CLOSED } + + /** + * Check if the shorts player is [OPEN]. + * Useful for checking if a shorts player is open. + */ + fun isOpen(): Boolean { + return this == OPEN + } } \ No newline at end of file From 79f933dad42b3d587f308907720fde333b4e44aa Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:51:35 +0900 Subject: [PATCH 55/77] fix(YouTube - Remove background playback restrictions): Media controls appear in the status bar when playing Shorts from the feed --- .../patches/misc/BackgroundPlaybackPatch.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/BackgroundPlaybackPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/BackgroundPlaybackPatch.java index 4223b6a26..0541d4f1b 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/BackgroundPlaybackPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/misc/BackgroundPlaybackPatch.java @@ -2,6 +2,7 @@ package app.revanced.extension.youtube.patches.misc; import app.revanced.extension.shared.settings.BooleanSetting; import app.revanced.extension.youtube.settings.Settings; +import app.revanced.extension.youtube.shared.PlayerType; import app.revanced.extension.youtube.shared.ShortsPlayerState; @SuppressWarnings("unused") @@ -14,7 +15,16 @@ public class BackgroundPlaybackPatch { */ public static boolean isBackgroundPlaybackAllowed(boolean original) { if (original) return true; - return ShortsPlayerState.getCurrent().isClosed(); + return ShortsPlayerState.getCurrent().isClosed() && + // 1. Shorts background playback is enabled. + // 2. Autoplay in feed is turned on. + // 3. Play Shorts from feed. + // 4. Media controls appear in status bar. + // (For unpatched YouTube with Premium accounts, media controls do not appear in the status bar) + // + // This is just a visual bug and does not affect Shorts background play in any way. + // To fix this, just check PlayerType. + PlayerType.getCurrent() != PlayerType.INLINE_MINIMAL; } /** From e157e9447d38044c12c3ba22b2cf9cce04ce5859 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:52:45 +0900 Subject: [PATCH 56/77] fix(YouTube): Playback speed sometimes changes to 1.0x in Shorts (Unpatched YouTube bug) --- .../utils/PlaybackSpeedWhilePlayingPatch.java | 16 ++++++++++------ .../PlaybackSpeedWhilePlayingPatch.kt | 2 ++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaybackSpeedWhilePlayingPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaybackSpeedWhilePlayingPatch.java index 67e65bd5c..00990e95c 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaybackSpeedWhilePlayingPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaybackSpeedWhilePlayingPatch.java @@ -1,20 +1,24 @@ package app.revanced.extension.youtube.patches.utils; import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.youtube.shared.EngagementPanel; import app.revanced.extension.youtube.shared.PlayerType; +import app.revanced.extension.youtube.shared.ShortsPlayerState; @SuppressWarnings("unused") public class PlaybackSpeedWhilePlayingPatch { private static final float DEFAULT_YOUTUBE_PLAYBACK_SPEED = 1.0f; public static boolean playbackSpeedChanged(float playbackSpeed) { - PlayerType playerType = PlayerType.getCurrent(); - if (playbackSpeed == DEFAULT_YOUTUBE_PLAYBACK_SPEED && - playerType.isMaximizedOrFullscreenOrPiP()) { + if (playbackSpeed == DEFAULT_YOUTUBE_PLAYBACK_SPEED) { + if (PlayerType.getCurrent().isMaximizedOrFullscreenOrPiP() + // Since RVX has a default playback speed setting for Shorts, + // Playback speed reset should also be prevented in Shorts. + || ShortsPlayerState.getCurrent().isOpen() && EngagementPanel.isOpen()) { + Logger.printDebug(() -> "Ignore changing playback speed, as it is invalid request"); - Logger.printDebug(() -> "Ignore changing playback speed, as it is invalid request: " + playerType.name()); - - return true; + return true; + } } return false; diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/playbackspeed/PlaybackSpeedWhilePlayingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/playbackspeed/PlaybackSpeedWhilePlayingPatch.kt index 26e4b110e..ee5ab2ead 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/playbackspeed/PlaybackSpeedWhilePlayingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/playbackspeed/PlaybackSpeedWhilePlayingPatch.kt @@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.youtube.utils.engagement.engagementPanelHookPatch import app.revanced.patches.youtube.utils.extension.Constants.UTILS_PATH import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch import app.revanced.patches.youtube.utils.playertype.playerTypeHookPatch @@ -22,6 +23,7 @@ val playbackSpeedWhilePlayingPatch = bytecodePatch( ) { dependsOn( sharedExtensionPatch, + engagementPanelHookPatch, playerTypeHookPatch, versionCheckPatch, ) From fbf19ee78b7214b52bdb83dacce0316ac7c97781 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:54:24 +0900 Subject: [PATCH 57/77] feat(YouTube): Change the latest supported version from `20.03.45` to `20.03.43` https://github.com/inotia00/ReVanced_Extended/issues/2885#issuecomment-2763077766 --- .../revanced/patches/youtube/utils/compatibility/Constants.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt index 671f24067..a28a5ca7a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/compatibility/Constants.kt @@ -14,7 +14,7 @@ internal object Constants { "19.43.41", // This is the latest version where edge-to-edge display is not enforced on Android 15+. "19.44.39", // This is the only version that has experimental shortcut icons. "19.47.53", // This was the latest version supported by the previous RVX patch. - "20.03.45", // This is the latest version supported by the RVX patch. + "20.03.43", // This is the latest version supported by the RVX patch. ) ) } \ No newline at end of file From 4feff6b150c50b1a4f4e6d1e19c6c8fbe15b14ba Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:55:41 +0900 Subject: [PATCH 58/77] feat(Reddit): Restore support version `2025.05.1` --- .../app/revanced/patches/reddit/utils/compatibility/Constants.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt index 52276f40b..acb655efa 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/compatibility/Constants.kt @@ -10,6 +10,7 @@ internal object Constants { REDDIT_PACKAGE_NAME, setOf( "2024.17.0", // This is the last version that can be patched without anti-split. + "2025.05.1", // This was the latest version supported by the previous RVX patch. "2025.12.0", // This is the latest version supported by the RVX patch. ) ) From 4330b7f6df3a1d9830b459833766393996432561 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:56:21 +0900 Subject: [PATCH 59/77] fix(Reddit - Hide ads): `Hide comment ads` does not work https://github.com/inotia00/ReVanced_Extended/issues/2884 --- .../revanced/patches/reddit/ad/AdsPatch.kt | 19 ++++++++++--------- .../patches/reddit/ad/Fingerprints.kt | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/AdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/AdsPatch.kt index 51c8c7e54..74a75cc5e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/AdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/AdsPatch.kt @@ -27,14 +27,6 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference private const val EXTENSION_CLASS_DESCRIPTOR = "$PATCHES_PATH/GeneralAdsPatch;" -private val isCommentAdsMethod: Method.() -> Boolean = { - parameterTypes.size == 1 && - parameterTypes.first().startsWith("Lcom/reddit/ads/conversation/") && - accessFlags == AccessFlags.PUBLIC or AccessFlags.FINAL && - returnType == "V" && - indexOfFirstStringInstruction("ad") >= 0 -} - @Suppress("unused") val adsPatch = bytecodePatch( HIDE_ADS.title, @@ -94,11 +86,20 @@ val adsPatch = bytecodePatch( if (is_2025_06_or_greater) { listOf( commentAdCommentScreenAdViewFingerprint, - commentAdDetailListHeaderViewFingerprint + commentAdDetailListHeaderViewFingerprint, + commentsViewModelFingerprint ).forEach { fingerprint -> fingerprint.methodOrThrow().hook() } } else { + val isCommentAdsMethod: Method.() -> Boolean = { + parameterTypes.size == 1 && + parameterTypes.first().startsWith("Lcom/reddit/ads/conversation/") && + accessFlags == AccessFlags.PUBLIC or AccessFlags.FINAL && + returnType == "V" && + indexOfFirstStringInstruction("ad") >= 0 + } + classes.forEach { classDef -> classDef.methods.forEach { method -> if (method.isCommentAdsMethod()) { diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/Fingerprints.kt index 70df18225..9d434fbd5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/ad/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/ad/Fingerprints.kt @@ -8,6 +8,7 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.iface.reference.TypeReference internal val adPostFingerprint = legacyFingerprint( name = "adPostFingerprint", @@ -49,6 +50,20 @@ internal val commentAdDetailListHeaderViewFingerprint = legacyFingerprint( }, ) +internal val commentsViewModelFingerprint = legacyFingerprint( + name = "commentsViewModelFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "Z", "L", "I"), + customFingerprint = { method, classDef -> + classDef.superclass == "Lcom/reddit/screen/presentation/CompositionViewModel;" && + method.indexOfFirstInstruction { + opcode == Opcode.NEW_INSTANCE && + getReference()?.type?.startsWith("Lcom/reddit/postdetail/comment/refactor/CommentsViewModel\$LoadAdsSeparately\$") == true + } >= 0 + }, +) + internal val newAdPostFingerprint = legacyFingerprint( name = "newAdPostFingerprint", returnType = "L", From 274e10aabc10d7e38446e94c29418becc8b3a9b1 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:57:21 +0900 Subject: [PATCH 60/77] fix: add missing dependency --- .../youtube/utils/engagement/EngagementPanelHookPatch.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/EngagementPanelHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/EngagementPanelHookPatch.kt index 6af2931bc..bd58204fe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/EngagementPanelHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/engagement/EngagementPanelHookPatch.kt @@ -6,6 +6,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patches.youtube.utils.extension.Constants.SHARED_PATH +import app.revanced.patches.youtube.utils.extension.sharedExtensionPatch import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.methodOrThrow @@ -29,7 +30,10 @@ internal var engagementPanelIdRegister = 0 val engagementPanelHookPatch = bytecodePatch( description = "engagementPanelHookPatch" ) { - dependsOn(sharedResourceIdPatch) + dependsOn( + sharedExtensionPatch, + sharedResourceIdPatch, + ) execute { fun Method.setFreeIndex(startIndex: Int) { From aca0591575bb800b2af9d2145a79f6b33cfe371a Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:58:04 +0900 Subject: [PATCH 61/77] feat(Translations): Update translation --- .../music/translations/ja-rJP/strings.xml | 1 + .../music/translations/pt-rBR/strings.xml | 4 + .../youtube/translations/ar/strings.xml | 45 +++++- .../youtube/translations/fr-rFR/strings.xml | 41 +++++ .../youtube/translations/it-rIT/strings.xml | 43 ++--- .../youtube/translations/ja-rJP/strings.xml | 50 +++++- .../youtube/translations/ko-rKR/strings.xml | 21 +-- .../youtube/translations/pl-rPL/strings.xml | 5 +- .../youtube/translations/pt-rBR/strings.xml | 59 +++++++ .../youtube/translations/uk-rUA/strings.xml | 8 +- .../youtube/translations/vi-rVN/strings.xml | 3 +- .../youtube/translations/zh-rTW/strings.xml | 149 +++++++++--------- 12 files changed, 312 insertions(+), 117 deletions(-) diff --git a/patches/src/main/resources/music/translations/ja-rJP/strings.xml b/patches/src/main/resources/music/translations/ja-rJP/strings.xml index 4089a8a93..fbe5ecfdf 100644 --- a/patches/src/main/resources/music/translations/ja-rJP/strings.xml +++ b/patches/src/main/resources/music/translations/ja-rJP/strings.xml @@ -194,6 +194,7 @@ 偽装するバージョンを選択してください。 6.42.55 - リアルタイムの歌詞を無効化 7.16.53 - 古いアクションバーを復元 + 7.17.52 - コメントセクションがホームフィードに表示されません 無効な偽装アプリバージョンです: %s ナビゲーションバー diff --git a/patches/src/main/resources/music/translations/pt-rBR/strings.xml b/patches/src/main/resources/music/translations/pt-rBR/strings.xml index 64f93b21a..b9501f56a 100644 --- a/patches/src/main/resources/music/translations/pt-rBR/strings.xml +++ b/patches/src/main/resources/music/translations/pt-rBR/strings.xml @@ -172,6 +172,8 @@ Limitações: Oculta o painel de cartão de lista de reprodução no feed. Ocultar painel Descobertas Oculta o painel Descobertas no feed. + Ocultar botão de pesquisa + Oculta o botão de pesquisa na barra de ferramentas. Ocultar botão de pesquisa de som Oculta o botão de pesquisa de som na barra de pesquisa. Ocultar botão Toque para atualizar @@ -192,6 +194,8 @@ Isso não ignora a restrição de idade, apenas aceita isso automaticamente."Selecione a versão do app para falsificação. 6.42.55 - Desativar letras em tempo real 7.16.53 - Restaurar barra de ação antiga + 7.17.52 - A seção de comentários não aparece no feed inicial + Versão da falsificação do app inválida: %s. Barra de Navegação Ativar cor personalizada da barra de navegação diff --git a/patches/src/main/resources/youtube/translations/ar/strings.xml b/patches/src/main/resources/youtube/translations/ar/strings.xml index 89288d1e8..bca339310 100644 --- a/patches/src/main/resources/youtube/translations/ar/strings.xml +++ b/patches/src/main/resources/youtube/translations/ar/strings.xml @@ -1439,6 +1439,10 @@ عرض قائمة فتح الفيديو يتم عرض قائمة فتح الفيديو. تم إخفاء قائمة فتح الفيديو. + مربع حوار السرعة + عرض قائمة مربع حوار السرعة + يتم عرض قائمة حوار السرعة. + تم إخفاء قائمة حوار السرعة. حالة التكرار عرض قائمة حالة التكرار يتم عرض قائمة حالة التكرار. @@ -1551,12 +1555,14 @@ الفيديو + الترميز تعطيل فيديو HDR تم تعطيل فيديو HDR. تم تمكين فيديو HDR. تعطيل ترميز VP9 "تم تعطيل برنامج ترميز VP9. +معلومات: • الحد الأقصى للدقة هو 1080P. • سيستهلك تشغيل الفيديو بيانات إنترنت أكثر من VP9. • لا يزال برنامج ترميز VP9 مستخدمًا لفيديو HDR." @@ -1564,6 +1570,7 @@ استبدال برنامج الترميز AV1 يستبدل برنامج الترميز AV1 ببرنامج الترميز VP9. + سرعة التشغيل سرعة التشغيل الافتراضية تذكر التغيرات في سرعة التشغيل تنطبق تغييرات سرعة التشغيل على جميع الفيديوهات. @@ -1571,6 +1578,19 @@ عرض ملاحظة سيتم عرض ملاحظة عند تغيير سرعة التشغيل الافتراضية. لن يتم عرض ملاحظة عند تغيير سرعة التشغيل الافتراضية. + سرعة التشغيل الافتراضية على فيديوهات Shorts + تذكر التغيرات في سرعة التشغيل على فيديوهات Shorts + "تنطبق تغييرات سرعة التشغيل على جميع فيديوهات Shorts. + +معلومات: +• الطريقة الوحيدة لتغيير سرعة التشغيل في مشغل فيديوهات Shorts هي استخدام \"مربع حوار السرعة\" ضمن \"الإجراءات المخصصة\". +• إذا لم تُضمّن تعديل 'Shorts components'، فلن يكون هذا متاحًا." + تنطبق تغييرات سرعة التشغيل على فيديو Shorts الحالي فقط. + عرض ملاحظة + سيتم عرض ملاحظة عند تغيير سرعة التشغيل الافتراضية في فيديوهات Shorts. + لن يتم عرض ملاحظة عند تغيير سرعة التشغيل الافتراضية في فيديوهات Shorts. + تغيير سرعة التشغيل الافتراضية إلى: %s. + تغيير سرعة تشغيل Shorts الافتراضية إلى: %s. تمكين سرعة التشغيل المخصصة تم تمكين سرعة التشغيل المخصصة. تم تعطيل سرعة التشغيل المخصصة. @@ -1582,6 +1602,7 @@ يجب أن تكون السرعات المخصصة أقل من %sx. سرعات التشغيل المخصصة غير صالحة. + جودة الفيديو جودة الفيديو الافتراضية على شبكة الجوَّال جودة الفيديو الافتراضية على شبكة Wi-Fi تذكر تغييرات جودة الفيديو @@ -1590,6 +1611,18 @@ عرض ملاحظة سيتم عرض ملاحظة عند تغيير جودة الفيديو الافتراضية. لن يتم عرض ملاحظة عند تغيير جودة الفيديو الافتراضية. + جودة فيديوهات Shorts الافتراضية على شبكة الجوَّال + جودة فيديوهات Shorts الافتراضية على شبكة Wi-Fi + تذكر تغييرات جودة فيديوهات Shorts + تنطبق تغييرات الجودة على جميع فيديوهات Shorts. + تنطبق تغييرات الجودة على فيديو Shorts الحالي فقط. + عرض ملاحظة + سيتم عرض ملاحظة عند تغيير جودة فيديوهات Shorts الافتراضية. + لن يتم عرض ملاحظة عند تغيير جودة فيديوهات Shorts الافتراضية. + الجوّال + Wi-Fi + تم تغيير جودة %1$s الافتراضية إلى: %2$s. + تم تغيير جودة Shorts %1$s الافتراضية إلى: %2$s. استعادة قائمة جودة الفيديو القديمة يتم عرض قائمة جودة الفيديو القديمة. لا يتم عرض قائمة جودة الفيديو القديمة. @@ -1597,13 +1630,21 @@ تخطي التخزين المؤقت المحمل مسبقًا "لتخطي التخزين المؤقت المحمل مسبقًا في بداية الفيديوهات لتطبيق جودة الفيديو الافتراضية على الفور. +معلومات: • عند بَدْء تشغيل الفيديو، يكون هناك تأخير قدره 0.3 ثانية تقريبًا. -• لا ينطبق على فيديوهات HDR, فيديوهات البث المباشر, الفيديوهات التي تقل مدتها عن 15 ثوانٍ." +• لا ينطبق على فيديوهات Shorts, فيديوهات HDR, فيديوهات البث المباشر, الفيديوهات التي تقل مدتها عن 15 ثوانٍ. +• يؤدي إعداد 'Spoof Streaming Data' أيضًا إلى إزالة المخازن المؤقتة المحملة مسبقًا، وبالتالي لا تكون هناك حاجة إلى هذا الإعداد إذا كنت تستخدم هذا الإعداد." تشغيل هذا الإعداد قد يسبب مشاكل في تشغيل الفيديو. عرض ملاحظة عند التخطي يتم عرض الملاحظة. لا يتم عرض الملاحظة. إيهام أبعاد الجهاز + "يُغيّر أبعاد الجهاز إلى أقصى قيمة. + +معلومات: +• قد تكون الجودة العالية متاحة لبعض الفيديوهات التي تتطلب أبعاد جهاز عالية، ولكن ليس لجميعها. + +• لا يتوفر هذا الإعداد عند تمكين 'Spoof Streaming Data'." تعطيل سرعة التشغيل للموسيقى تم تعطيل سرعة التشغيل الافتراضية للموسيقى. @@ -1970,6 +2011,8 @@ AVC لديه حد أقصى للدقة 1080p، لا يتوفر ترميز الص يتم عرض العميل المستخدم لجلب بيانات البث في إحصاءات تقنية. تم إخفاء العميل المستخدم لجلب بيانات البث في إحصاءات تقنية. لغة البث الصوتي الافتراضية للواقع الافتراضي VR + لم يتمكن من جلب أي تدفقات عميل. + ربما لم تتمكن من تسجيل الدخول. PoToken / VisitorData استخدام PoToken diff --git a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml index 0e769ed8d..8873c2d86 100644 --- a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml +++ b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml @@ -1551,6 +1551,10 @@ Appuyez longuement sur le bouton \"Plus\" pour afficher les actions personnalis Afficher le menu \'Ouvrir la vidéo\' Le menu \'Ouvrir la vidéo\' est affiché. Le menu \'Ouvrir la vidéo\' est masqué. + Dialogue de vitesse + Afficher menu \'Vitesse de lecture\' + Le menu \'Vitesse de lecture\' est affiché. + Le menu \'Vitesse de lecture\' est masqué. État de répétition Afficher le menu \'État de répétition\' Le menu \'État de répétition\' est affiché. @@ -1657,6 +1661,7 @@ Pas de marges en haut et en bas du lecteur." Vitesses et qualités vidéo + Codec Déaactiver les vidéos HDR Les vidéos en HDR sont désactivés. Les vidéos en HDR sont activés. @@ -1670,6 +1675,7 @@ Pas de marges en haut et en bas du lecteur." Remplacer le codec AV1 Remplacer le codec AV1 par le codec VP9. + Vitesse de lecture Vitesse de lecture par défaut Enreg. modif. de la vitesse de lecture La modification de vitesse de lecture est appliqué pour toutes les vidéos. @@ -1677,6 +1683,20 @@ Pas de marges en haut et en bas du lecteur." Afficher un message Un message sera affiché lorsque vous modifiez la vitesse de lecture par défaut. Un message ne sera pas affiché lorsque vous modifiez la vitesse de lecture par défaut. + Vitesse de lecture par défaut sur les Shorts + Enreg. modif. de la vitesse de lecture sur les Shorts + "Les changements de vitesse de lecture s'appliquent à tous les Shorts. + +Info : +• La seule façon de modifier la vitesse de lecture dans le lecteur de Shorts est d'utiliser le 'Dialogue de vitesse' dans 'Actions personnalisées'. + +• Si vous n'avez pas inclus le patch 'Composants pour Shorts' , cette option ne serait pas disponible." + La modification de vitesse de lecture est appliqué pour ce Short. + Afficher un message + Un message sera affiché lorsque vous modifiez la vitesse de lecture par défaut sur les Shorts. + Un message ne sera pas affiché lorsque vous modifiez la vitesse de lecture par défaut sur les Shorts. + Vitesse de lecture par défaut modifiée en : %s. + Vitesse de lecture par défaut des Shorts modifiée en : %s. Activer vitesses de lecture perso. Les vitesses de lecture personnalisées sont activées. Les vitesses de lecture personnalisées sont désactivées. @@ -1688,6 +1708,7 @@ Pas de marges en haut et en bas du lecteur." Les vitesses personnalisées doivent être inférieures à %sx. Valeur des vitesses de lecture invalide. + Qualité vidéo Qualité vidéo par défaut sur les données mobiles Qualité vidéo par défaut sur le réseau Wi-Fi Enreg. modification de la qualité @@ -1696,6 +1717,18 @@ Pas de marges en haut et en bas du lecteur." Afficher un message Un message sera affiché lorsque vous modifiez la qualité vidéo par défaut. Un message ne sera pas affiché lorsque vous modifiez la qualité vidéo par défaut. + Qualité par défaut des Shorts sur le réseau mobile + Qualité par défaut des Shorts sur le réseau Wi-Fi + Enreg. modification du changement de qualité des Shorts + La modification de la résolution est appliqué pour tous les Shorts. + La modification de la résolution est appliqué pour ce Short. + Afficher un message + Un message sera affiché lorsque vous modifiez la qualité vidéo des Shorts par défaut. + Un message ne sera pas affiché lorsque vous modifiez la qualité vidéo des Shorts par défaut. + Mobiles + Wi-Fi + Qualité par défaut %1$s modifiée en : %2$s. + Qualité des Shorts %1$s modifiée en : %2$s. Restaur. ancien. interface de qualité vidéo Affiche l\'ancienne interface de qualité vidéo. Masque la nouvelle interface de qualité vidéo. @@ -1711,6 +1744,12 @@ Info : Le message est affiché. Le message est masqué. Falsifier les dimensions de l\'appareil + "Falsifie les dimensions de l'appareil à la valeur maximale. + +Info : +• Une qualité élevée peut être déverrouillée sur certaines vidéos qui nécessitent des dimensions d'appareil élevées, mais pas toutes les vidéos. + +• Ce paramètre n'est pas disponible si l'option 'Falsifier les données de lecture en direct' est activée." Désactiver la vitesse de lecture pour la musique La vitesse de lecture par défaut est activée pour la musique. @@ -2075,6 +2114,8 @@ AVC a une résolution maximale de 1080p, le codec audio Opus n'est pas disponibl Le client utilisé pour récupérer les données de lecture en direct est affiché dans \'Statistiques pour les nerds\'. Le client utilisé pour récupérer les données de lecture en direct est masqué dans \'Statistiques pour les nerds\'. Langue de la piste audio par défaut pour VR + Ne peut pas récupérer les flux des clients. + Vous n\'êtes peut-être pas connecté. PoToken / VisitorData PoToken à utiliser diff --git a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml index bfbe32566..3c5133350 100644 --- a/patches/src/main/resources/youtube/translations/it-rIT/strings.xml +++ b/patches/src/main/resources/youtube/translations/it-rIT/strings.xml @@ -1668,19 +1668,19 @@ Regola il volume scorrendo verticalmente sul lato destro dello schermo." +• VP9 è comunque usato per la riproduzione HDR." Il codec VP9 è attivato. Sostituisci il codec AV1 Sostituisce il codec AV1 con il codec VP9. Velocità di riproduzione - Velocità di riproduzione predefinita - Ricorda i cambiamenti della velocità di riproduzione + Velocità di riproduzione predefinita dei video + Ricorda i cambiamenti della velocità di riproduzione dei video I cambiamenti alla velocità di riproduzione si applicano a tutti i video. I cambiamenti alla velocità di riproduzione si applicano solo al video corrente. - Mostra una notifica toast al cambio della velocità di riproduzione - Una notifica toast verrà mostrata al cambio della velocità di riproduzione predefinita. - Una notifica toast non verrà mostrata al cambio della velocità di riproduzione predefinita. + Mostra una notifica toast al cambio della velocità di riproduzione predefinita dei video + Una notifica toast verrà mostrata al cambio della velocità di riproduzione predefinita dei video. + Una notifica toast non verrà mostrata al cambio della velocità di riproduzione predefinita dei video. Velocità di riproduzione predefinita degli Shorts Ricorda i cambiamenti della velocità di riproduzione degli Shorts "I cambiamenti alla velocità di riproduzione si applicano a tutti gli Shorts. @@ -1689,10 +1689,10 @@ Note: • L'unico modo per modificare la velocità di riproduzione nel riproduttore degli Shorts è usare la \"finestra della velocità\" in \"Azioni personalizzate\". • Se non hai incluso la patch \"Componenti Shorts\", questa impostazione non sarà disponibile." I cambiamenti alla velocità di riproduzione si applicano solo allo Short corrente. - Mostra una notifica toast + Mostra una notifica toast al cambio della velocità di riproduzione predefinita degli Shorts Una notifica toast verrà mostrata al cambio della velocità di riproduzione predefinita degli Shorts. Una notifica toast non verrà mostrata al cambio della velocità di riproduzione predefinita degli Shorts. - La velocità di riproduzione predefinita è stata cambiata a %s + La velocità di riproduzione predefinita dei video è stata cambiata a %s La velocità di riproduzione predefinita degli Shorts è stata cambiata a %s Attiva la velocità di riproduzione personalizzata La velocità di riproduzione personalizzata è attivata. @@ -1706,36 +1706,37 @@ Note: Velocità di riproduzione personalizzate non valide Qualità video - Qualità predefinita con connessione dati - Qualità predefinita con Wi-Fi - Ricorda i cambiamenti della qualità + Qualità predefinita dei video con connessione dati + Qualità predefinita dei video con Wi-Fi + Ricorda i cambiamenti della qualità dei video I cambiamenti alla qualità si applicano a tutti i video. I cambiamenti alla qualità si applicano solo al video corrente. - Mostra una notifica toast al cambio della qualità - Una notifica toast verrà mostrata quando al cambio della qualità predefinita. - Una notifica toast non verrà mostrata quando al cambio della qualità predefinita. + Mostra una notifica toast al cambio della qualità predefinita dei video + Una notifica toast verrà mostrata al cambio della qualità predefinita dei video. + Una notifica toast non verrà mostrata al cambio della qualità predefinita dei video. Qualità predefinita degli Shorts con connessione dati Qualità predefinita degli Shorts con Wi-Fi Ricorda i cambiamenti della qualità degli Shorts I cambiamenti alla qualità si applicano a tutti gli Shorts. I cambiamenti alla qualità si applicano solo allo Short corrente. - Mostra una notifica toast - Una notifica toast verrà mostrata quando al cambio della qualità predefinita degli Shorts. - Una notifica toast non verrà mostrata quando al cambio della qualità predefinita degli Shorts. + Mostra una notifica toast al cambio della qualità predefinita degli Shorts + Una notifica toast verrà mostrata al cambio della qualità predefinita degli Shorts. + Una notifica toast non verrà mostrata al cambio della qualità predefinita degli Shorts. Cellulare Wi-Fi - La qualità predefinita è stata cambiata da %1$s a %2$s + La qualità predefinita dei video è stata cambiata da %1$s a %2$s La qualità predefinita degli Shorts è stata cambiata da %1$s a %2$s Attiva il vecchio menù Qualità Il vecchio menù Qualità è attivato. Il vecchio menù Qualità è disattivato. Buffer precaricato saltato Salta il buffer precaricato - "Salta il buffer precaricato all'avvio dei video per bypassare il ritardo della qualità video predefinita forzata. + "Salta il buffer precaricato all'avvio dei video per applicare immediatamente la qualità video predefinita. Note: -• Quando il video inizia, c'è un ritardo di circa 0.7 secondi, ma la qualità video predefinita viene applicata immediatamente. -• Non si applica ai video HDR, live e più brevi di 10 secondi." +• Quando il video inizia, c'è un ritardo di circa 0.3 secondi. +• Non si applica agli Shorts, ai video HDR, live e più brevi di 15 secondi. +• L'impostazione \"Camuffa i dati in streaming\" rimuove anche i buffer precaricati, pertanto questa impostazione non è necessaria se si usa tale impostazione." L\'attivazione di questa impostazione potrebbe causare problemi di riproduzione. Mostra una notifica toast quando un segmento è saltato Una notifica toast verrà mostrata quando un segmento è saltato. diff --git a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml index e0860efb2..0084f6416 100644 --- a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml +++ b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml @@ -1493,6 +1493,10 @@ DeArrow の詳細については、ここをタップしてください。"動画を開くメニューを表示 動画を開くメニューを表示します。 動画を開くメニューを表示します。 + 再生速度ダイアログ + 再生速度のダイアログメニューを表示 + 再生速度のダイアログメニューを表示します。 + 再生速度のダイアログメニューを表示します。 リピート状態 リピート状態のメニューを表示 リピート状態のメニューを表示します。 @@ -1604,6 +1608,7 @@ DeArrow の詳細については、ここをタップしてください。" 動画 + コー​​デック HDR 動画を無効化 HDR 動画を無効化します。 HDR 動画を無効化します。 @@ -1613,11 +1618,12 @@ DeArrow の詳細については、ここをタップしてください。" +・HDR 動画では引き続き VP9 コーデックが使用されます。" VP9 コーデックを無効化します。\n\n注意: \n・最大解像度は 1080p です。\n・動画を再生する際には VP9 コーデックよりも多くの通信量を消費します。\n・HDR 再生を可能にするために、HDR 動画では引き続き VP9 コーデックが使用されます。 AV1 コーデックを置換 AV1 コーデックを VP9 コーデックに置き換えます。 + 再生速度 デフォルトの再生速度 再生速度の変更を保存 現在の設定: 再生速度の変更はすべての動画に適用されます。 @@ -1625,6 +1631,19 @@ DeArrow の詳細については、ここをタップしてください。"トーストを表示 デフォルトの再生速度を変更した際にトーストが表示されるようにします。 デフォルトの再生速度を変更した際にトーストが表示されるようにします。 + ショートのデフォルトの再生速度 + ショートの再生速度の変更を記憶 + "現在の設定: 再生速度の変更はすべてのショートに適用されます。 + +注意: +・ショートのプレーヤーで再生速度を変更する唯一の方法は、「カスタムアクション」の「再生速度ダイアログ」を使用することです。 +・「Shorts components」パッチを含めていない場合、この機能は利用できません。" + 現在の設定: 再生速度の変更は現在のショートにのみ適用されます。 + トーストを表示 + ショートでデフォルトの再生速度を変更した際にトーストを表示します。 + ショートでデフォルトの再生速度を変更した際にトーストを表示します。 + デフォルトの再生速度を %s に変更しました。 + デフォルトのショートの再生速度を %s に変更しました。 カスタム再生速度を有効化 再生速度のカスタムを有効化します。 再生速度のカスタムを有効化します。 @@ -1633,10 +1652,11 @@ DeArrow の詳細については、ここをタップしてください。"現在の設定: 古いスタイルのフライアウトパネルが使用されます。 カスタム再生速度の編集 利用可能な再生速度を追加または変更します。 - カスタム再生速度は %s 倍速未満である必要があります。デフォルト値にリセットします。 + カスタム再生速度は %s 倍速未満である必要があります。 無効なカスタム再生速度です。デフォルトの値を使用します。 - モバイルネットワーク使用時のデフォルト画質 + 画質 + モバイルデータ通信使用時のデフォルト画質 Wi-Fi 使用時のデフォルト画質 画質の変更を保存 現在の設定: 画質の変更はすべての動画に適用されます。 @@ -1644,6 +1664,18 @@ DeArrow の詳細については、ここをタップしてください。"トーストを表示 デフォルトの画質を変更した際にトーストが表示されるようにします。 デフォルトの画質を変更した際にトーストが表示されるようにします。 + モバイルデータ通信使用時のデフォルト画質 + Wi-Fi 使用時のデフォルト画質 + ショートの画質変更を保存 + 現在の設定: 画質の変更はすべてのショートに適用されます。 + 現在の設定: 画質の変更は現在のショートにのみ適用されます。 + トーストを表示 + ショートの画質を変更した際にトーストを表示します。 + ショートの画質を変更した際にトーストを表示します。 + モバイルデータ通信 + Wi-Fi + デフォルトの画質 (%1$s) を %2$s に変更しました。 + ショートの画質 (%1$s) を %2$s に変更しました。 古いスタイルの画質メニューを復元 古いスタイルの画質設定メニューを復活させます。 古いスタイルの画質設定メニューを復活させます。 @@ -1653,12 +1685,18 @@ DeArrow の詳細については、ここをタップしてください。" +・ショート、HDR 動画、ライブ配信、15 秒未満の動画には適用されません。 +・「ストリーミングデータを偽装」設定を既に有効化している場合、予め読み込まれたバッファはスキップされるため、この設定は必要ありません。" この設定をオンにした場合、動画が再生できない問題が発生する可能性があります。 スキップ時にトーストを表示 スキップ時にトーストを表示します。 スキップ時にトーストを表示します。 デバイスの解像度を偽装 + "デバイスの解像度を最大値に偽装します。 + +注意: +・高いデバイス解像度を必要とする一部の動画では高画質が利用可能になる可能性がありますが、すべての動画で利用可能になるわけではありません。 +・「ストリーミングデータを偽装」が有効化されている場合、この機能は利用できません。" 音楽再生時にデフォルトの再生速度を無効化 音楽を再生する際に「デフォルトの再生速度」で設定した再生速度を無効化します。 @@ -1857,7 +1895,7 @@ API キーの発行方法については、ここをタップしてください セグメントは正常に送信されました セグメントの評価を送信できませんでした (API がタイムアウトしました) セグメントの評価を送信できませんでした (ステータス: %1$d %2$s) - セグメントの評価を送信できませんでした: %s + セグメントに投票できません: %s 賛成 反対 カテゴリーを変更 @@ -2024,6 +2062,8 @@ GmsCore の電池の最適化を無効にしても、バッテリーの使用に 統計情報に偽装したクライアントを表示します。 統計情報に偽装したクライアントを表示します。 偽装するクライアントを Android VR に設定した際にデフォルトで使用する音声トラックの言語 + クライアントストリームを取得できませんでした。 + ログインをしていない可能性があります。 PoToken / VisitorData 使用する PoToken を入力 diff --git a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml index 590672df5..24c5abefe 100644 --- a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml +++ b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml @@ -1735,9 +1735,12 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." 이전 동영상 화질 설정을 비활성화합니다. 미리 로드된 버퍼를 건너뛰었습니다. 미리 로드된 버퍼 건너뛰기 - "동영상을 시작할 때, 미리 로드된 버퍼를 건너뛰어 기본 동영상 화질 적용 지연을 우회합니다. -• 동영상이 시작되면 약 0.3초정도의 지연이 발생하지만 기본 동영상 화질이 즉시 적용됩니다. -• HDR 동영상, 실시간 스트림, 15초 미만의 동영상에는 적용되지 않습니다." + "동영상 시작 시 미리 로드된 버퍼를 건너뛰고 기본 동영상 화질을 즉시 적용합니다. + +알림: +• 동영상이 시작되면 약 0.3초의 지연이 발생합니다. +• Shorts 동영상, HDR 동영상, 실시간 스트리밍 동영상 또는 15초 미만의 동영상에는 적용되지 않습니다. +• ‘스트리밍 데이터 변경하기’ 기능은 미리 로드된 버퍼도 제거하므로 사용하는 경우에는 이 기능이 필요하지 않습니다." 이 설정을 활성화하면 동영상 재생 문제가 발생할 수 있습니다. 건너뛸 때, 팝업 메시지 표시하기 팝업 메시지를 표시합니다. @@ -2081,15 +2084,15 @@ GmsCore 앱 배터리 최적화를 비활성화(제한 없음)하더라도, 배 "• 오디오 트랙 메뉴가 표시되지 않습니다. • 안정적인 볼륨을 사용할 수 없습니다. • 자동 오디오 트랙을 비활성화할 수 없습니다. -• 사용자가 로그인을 하지 않았거나 시크릿 모드에서는 Kids 동영상이 재생되지 않을 수 있습니다. -• VR은 Kids // TV는 재생목록과 음악 동영상에서 다른 클라이언트가 사용될 수 있습니다. +• 로그인을 하지 않았거나 시크릿 모드에서는 Kids 동영상이 재생되지 않을 수 있습니다. (로그인 정보가 필요함) +• VR은 Kids // TV는 재생목록, 음악 동영상 또는 로그인 정보가 없을 경우에는 다른 클라이언트가 사용될 수 있습니다. • TV는 AV1 코덱이 지원되지 않습니다. -• 인증 없음: 사용자 로그인 정보를 사용하지 않음" +• 인증 없음: 로그인 정보를 사용하지 않음" • 서버에서 전체 ASNs/IP 범위가 차단될 수 있습니다. "• 안정적인 볼륨을 사용할 수 없습니다. • 영화 또는 유료 동영상이 재생되지 않을 수 있습니다. -• 사용자가 로그인을 하지 않았거나 시크릿 모드에서는 Kids 동영상이 재생되지 않을 수 있습니다. -• 음악 동영상에서 다른 클라이언트가 사용될 수 있습니다. +• 로그인을 하지 않았거나 시크릿 모드에서는 Kids 동영상이 재생되지 않을 수 있습니다. (로그인 정보가 필요함) +• 음악 동영상 또는 로그인 정보가 없을 경우에는 다른 클라이언트가 사용될 수 있습니다. • AV1 코덱이 지원되지 않습니다." iOS 클라이언트 사용하기 "사용 가능한 클라이언트에 iOS 클라이언트가 추가되었습니다. @@ -2121,7 +2124,7 @@ AVC의 최대 화질 값은 1080p이고, OPUS 코덱을 사용불가 및 HDR 동 스트리밍 데이터를 가져오는 데 사용되는 클라이언트가 전문 통계에서 숨겨집니다.\n\n• 만약 선택한 기본 클라이언트가 재생할 수 없는 동영상을 재생하려하거나 클라이언트 재생 문제가 발생하면, 그 문제를 해결하기 위해 다른 클라이언트가 사용되는 경우도 있기 때문에 전문 통계에서 다르게 표시될 수 있습니다. VR 기본 오디오 스트림 언어 클라이언트 스트림을 가져올 수 없습니다. - 로그인하지 않은 것 같습니다. + 로그인하지 않았을 수 있습니다. PoToken & VisitorData PoToken 등록하기 diff --git a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml index de3b68df1..43310e109 100644 --- a/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml +++ b/patches/src/main/resources/youtube/translations/pl-rPL/strings.xml @@ -1740,8 +1740,9 @@ Informacje: "Pomija wstępnie załadowany bufor na początku filmu, aby natychmiastowo ustawić domyślną jakość filmu. Informacje: -• Po uruchomieniu filmu występuje opóźnienie około 0.3 sekundy -• Nie działa w przypadku filmów z HDR, transmisji na żywo i filmów krótszych niż 15 sekund." +• po uruchomieniu filmu występuje opóźnienie około 0.3 sekundy +• nie działa w przypadku filmów z HDR, transmisji na żywo i filmów krótszych niż 15 sekund. +• opcja 'Oszukuj strumień danych' również pomija wstępnie załadowany bufor, więc ta opcja nie jest potrzebna, jeśli używasz tego ustawienia" Włączenie tej opcji może spowodować problemy z odtwarzaniem filmów. Komunikaty o pominięciu Widoczne diff --git a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml index 80d098a01..08b66fcf1 100644 --- a/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml +++ b/patches/src/main/resources/youtube/translations/pt-rBR/strings.xml @@ -19,8 +19,48 @@ "%1$s não está instalado. Por favor, baixe %2$s do site." %s não está instalado. Por favor, instale-o. + Adicionar à fila + Adicionar à fila e abrir a fila + Adicionar à fila e reproduzir o vídeo + Download externo + Abrir fila + Fila + Remover da lista + Remover da fila e abrir a fila + Remover fila + Salvar fila + "Em vez de abrir um aplicativo de download externo, abra a caixa de diálogo do gerenciador de filas. + +Você também pode abrir o gerenciador de filas pressionando e segurando o botão Voltar na barra de navegação. + +Este recurso ainda está em andamento, então a maioria dos recursos pode não funcionar. + +Use-o apenas para fins de depuração." + Login obrigatório + Gerenciador de filas indisponível (%s). + Não foi possível identificar a playlist + A fila está vazia + Não foi possível identificar vídeo + Falha ao adicionar vídeo. + Falha ao criar fila. + Falha ao excluir fila. + Falha ao remover o vídeo. + Falha ao salvar fila. + Vídeo adicionado com sucesso. + Fila criada com sucesso. + Fila excluída com sucesso. + Vídeo removido com sucesso. + Fila salva com sucesso em \'%s\'. Idioma do RVX Idioma do app + "Francês +Français" + "Português +Português" + "Romeno +Română" + "Russo +Русский" Anúncios Ocultar banner da loja na tela final @@ -369,6 +409,9 @@ Automotivo layout • Shorts abertos no reprodutor regular. • O feed é organizado por tópicos e canais. • A descrição do vídeo não pode ser aberta quando o 'Falsificar dados de reprodução' está desligado." + Desativar atualizações de layout + O layout não será atualizado pelo servidor. + O layout será atualizado pelo servidor. Desativar barra de status transparente A barra de status está opaca. A barra de status está opaca ou transparente. @@ -389,8 +432,10 @@ Se for desativado posteriormente, é recomendável limpar os dados do aplicativo 18.33.40 - Restaurar barra de ação antiga do shorts 18.38.45 - Restaurar antigo comportamento padrão de qualidade de vídeo 18.48.39 - Desativa a atualização em tempo real de \'visualizações\' e \'curtidas\' + 19.01.34 - Desativar interação com descrição do vídeo 19.26.42 - Desativar ícone do Cairo na barra de navegação e de ferramentas 19.33.37 - Restaurar painel flutuante antigo de velocidade de reprodução + Versão da falsificação do app inválida: %s. Menu da Conta Ocultar ou mostrar elementos no menu de contas e na aba Você. @@ -424,6 +469,9 @@ Alguns componentes podem não ser ocultos" Substituir o botão de download de vídeo O botão de download de vídeo nativo abre seu aplicativo de download externo. O botão de download de vídeo nativo abre o download nativo do aplicativo. + Gerenciador de Filas + O botão nativo de download de vídeo abre o gerenciador de filas. + O botão de download de vídeo nativo abre seu aplicativo de download externo. Nome do pacote do aplicativo de download de playlist Nome do pacote do seu aplicativo de download externo instalado, como YTDLnis. @@ -1435,6 +1483,8 @@ Sem margens na parte superior e inferior do reprodutor." Os gestos de deslize estão desativados no modo \'Tela de bloqueio\'. Limite de magnitude de deslize A quantidade de limite para que o deslize ocorra. + Interface alternativa é utilizada. + Interface antiga é utilizada. Tamanho do texto da sobreposição de gestos O tamanho do texto para a sobreposição de gestos Tamanho da área deslizável da tela de sobreposição @@ -1467,6 +1517,7 @@ Sem margens na parte superior e inferior do reprodutor." Vídeo + Codec Desativar vídeo HDR O vídeo HDR está desativado. O vídeo HDR está ativado. @@ -1480,6 +1531,7 @@ Sem margens na parte superior e inferior do reprodutor." Substituir codec AV1 do software Substitua o codec AV1 do software com o codec VP9. + Velocidade de reprodução Velocidade de reprodução padrão Lembrar alterações na velocidade de reprodução As alterações de velocidade de reprodução aplicam-se a todos os vídeos. @@ -1498,6 +1550,7 @@ Sem margens na parte superior e inferior do reprodutor." As velocidades personalizadas devem ser inferiores a %sx. Usando valores padrão. Velocidade personalizada de reprodução inválida. Usando valores padrão. + Qualidade do vídeo Qualidade de vídeo padrão nos dados móveis Qualidade de vídeo padrão no Wi-Fi Lembrar alterações na qualidade do vídeo @@ -1506,6 +1559,7 @@ Sem margens na parte superior e inferior do reprodutor." Mostrar uma notificação flutuante Uma notificação flutuante será exibida quando mudar a qualidade padrão de vídeo. Uma notificação flutuante não será exibida quando mudar a qualidade padrão de vídeo. + móvel Restaurar menu antigo de qualidade de vídeo O menu antigo de qualidade de vídeo está sendo exibido. O menu antigo de qualidade de vídeo não está sendo exibido. @@ -1849,6 +1903,11 @@ Toque no botão continuar e desative as otimizações da bateria." • Os vídeos para crianças podem não reproduzir quando desconectado ou em modo incógnito." "• Filmes ou vídeos pagos podem não reproduzir. • Os vídeos para crianças podem não ser reproduzidos quando desconectado ou em modo incógnito." + Usar cliente iOS + "Cliente iOS adicionado aos clientes disponíveis. + +AVISO: cliente iOS está obsoleto. Quaisquer problemas que surjam ao usá-lo estão por sua conta e risco." + Cliente iOS não adicionado aos clientes disponíveis. Forçar iOS AVC (H.264) O codec de vídeo é forçado para AVC (H.264). O codec de vídeo é determinado automaticamente. diff --git a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml index 0c11595e6..4d5174517 100644 --- a/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml +++ b/patches/src/main/resources/youtube/translations/uk-rUA/strings.xml @@ -1737,10 +1737,12 @@ Старе меню якості відео не показується. Пропущено перед вантажений буфер Пропустити перед вантажений буфер - "Пропуск перед вантаженого буфера під час запуску відео для обходу затримки примусового застосування типової якості відео. + "Пропуск передвантаженого буфера під час запуску відео для обходу затримки примусового застосування типової якості відео. -• Під час запуску відео є затримка приблизно 0.3 секунди, але типова якість відео застосовується відразу. -• Не застосовується на відео HDR, прямі трансляції, менші ніж 15 секунд." +Інформація: +• Під час запуску відео є затримка приблизно 0.3 секунди. +• Не застосовується на Shorts, відео HDR, прямі трансляції, менші ніж 15 секунд. +• Налаштування 'Підробити дані трансляції' також вилучає передвантажений буфер, отже це налаштування не потрібне якщо використовуєте те." Вмикання цього налаштування може спричинити проблеми відтворення відео. Показувати тост, коли пропущено Тост показується. diff --git a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml index c616b7f87..d272eece7 100644 --- a/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml +++ b/patches/src/main/resources/youtube/translations/vi-rVN/strings.xml @@ -1737,7 +1737,8 @@ Chi tiết: Chi tiết: • Khi video bắt đầu, sẽ có độ trễ khoảng 0,3 giây. -• Không áp dụng cho video HDR, video phát trực tiếp, hoặc video ngắn hơn 15 giây." +• Không áp dụng cho Shorts, video HDR, video phát trực tiếp, hoặc video ngắn hơn 15 giây. +• Cài đặt \"Giả mạo dữ liệu phát trực tuyến\" cũng xoá bộ đệm tải trước, do đó bạn không cần thiết phải bật cả hai." Bật cài đặt này có thể gây ra sự cố phát video. Thông báo ngắn khi bỏ qua Thông báo ngắn được hiển thị. diff --git a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml index c63ed3679..cd535e0a9 100644 --- a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml @@ -5,7 +5,7 @@ 由於已啟用無障礙服務,因此你的控制選項已被修改。 RVX - 搜尋設定 + 搜尋 %s 重設為預設值。 實驗性功能 你想繼續嗎? @@ -326,7 +326,7 @@ 頻道標籤篩選器已停用 頻道標籤篩選器 要篩選的頻道標籤名稱清單,每行一個名稱 - "Shorts + "短影音 播放清單 商店" 隱藏頻道會員清單 @@ -460,7 +460,7 @@ 播客 搜尋 購物 - 短片 + 短影音 運動 訂閱 熱門 @@ -543,7 +543,7 @@ 17.41.37 - 恢復舊版的播放清單 18.05.40 - 恢復舊版留言輸入方塊 18.17.43 - 恢復舊版播放器彈出式面板 - 18.33.40 - 恢復舊的 Shorts 頁籤 + 18.33.40 - 恢復舊版短影音操作欄 18.38.45 - 恢復舊版預設影片畫質 18.48.39 - 停用即時更新「觀看次數」和「喜歡次數」 19.01.34 - 禁用影片描述互動 @@ -619,9 +619,9 @@ 隱藏通知按鈕 通知按鈕已隱藏 通知按鈕已顯示 - 隱藏 Shorts 按鈕 - Shorts 按鈕已隱藏 - Shorts 按鈕已顯示 + 隱藏短影音按鈕 + 短影音按鈕已隱藏 + 短影音按鈕已顯示 隱藏訂閱按鈕 訂閱按鈕已隱藏 訂閱按鈕已顯示 @@ -858,18 +858,18 @@ 操作按鈕 隱藏或顯示影片下方的操作按鈕 - 停用讚和反讚按鈕發光 - 讚和反讚按鈕在提及時不會發光。 - 讚和反讚按鈕在提及時會發光。 + 停用讚和不喜歡按鈕高亮顯示 + 讚和不喜歡按鈕在提及時不會高亮顯示。 + 讚和不喜歡按鈕在提及時會高亮顯示。 隱藏剪輯按鈕 剪輯按鈕已隱藏 剪輯按鈕已顯示 隱藏下載按鈕 隱藏下載按鈕 顯示下載按鈕 - 隱藏讚和踩按鈕 - 隱藏讚和踩按鈕 - 顯示讚和踩按鈕 + 隱藏讚和不喜歡按鈕 + 隱藏讚和不喜歡按鈕。 + 顯示讚和不喜歡按鈕。 隱藏混剪按鈕 混剪按鈕已隱藏 混剪按鈕已顯示 @@ -940,9 +940,9 @@ 隱藏首頁動態中的評論部分 首頁動態中評論部分已隱藏 首頁動態中評論部分已顯示 - 隱藏創建短片按鈕 - 創建短片按鈕已隱藏 - 創建短片按鈕已顯示 + 隱藏建立短影音按鈕 + 建立短影音按鈕已隱藏 + 建立短影音按鈕已顯示 隱藏時間戳和表情按鈕 時間戳和表情按鈕已隱藏 時間戳和表情按鈕已顯示 @@ -950,8 +950,8 @@ 被標記的搜尋連結已隱藏 被標記的搜尋連結已顯示 隱藏即時聊天訊息 - 即時聊天訊息已隱藏。\n\n這項設定也適用於 Shorts 直播影片。 - 即時聊天訊息已顯示。\n\n這項設定也適用於 Shorts 直播影片。 + 直播聊天訊息已隱藏。\n\n這項設定也適用於短影音直播影片。 + 直播聊天訊息已顯示。\n\n這項設定也適用於短影音直播影片。 在即時聊天中隱藏聊天摘要 聊天摘要已隱藏。 聊天摘要已顯示。 @@ -1069,12 +1069,12 @@ 隱藏評論按鈕 評論按鈕已隱藏 評論按鈕已顯示 - 隱藏倒讚按鈕 - 倒讚按鈕已隱藏 - 倒讚按鈕已顯示 - 隱藏點贊按鈕 - 點讚按鈕已隱藏 - 點讚按鈕已顯示 + 隱藏不喜歡按鈕 + 不喜歡按鈕已隱藏。 + 不喜歡按鈕已顯示。 + 隱藏點讚按鈕 + 點讚按鈕已隱藏。 + 點讚按鈕已顯示。 隱藏實時聊天按鈕 實時聊天按鈕已隱藏 實時聊天按鈕已顯示 @@ -1358,22 +1358,22 @@ 自動展開影片描述 手動展開影片描述 - 短片 + 短影音 停用 短影音 後台播放 短影音 後台播放已停用。 短影音 後台播放已啟用。 - 停用恢復短片播放器 - 短片播放器在應用程式啟動時不會恢復播放。 - 短片播放器在應用程式啟動時會恢復播放。 + 停用恢復短影音播放器 + 短影音播放器在應用程式啟動時不會恢復播放。 + 短影音播放器在應用程式啟動時會恢復播放。 隱藏浮動按鈕 - "「使用此聲音」等浮動按鈕隱藏在 短片頻道標籤中。" - "「使用此聲音」等浮動按鈕顯示在 短片頻道標籤中。" + "短影音頻道分頁中會顯示「使用此音效」等浮動按鈕。" + "短影音頻道分頁中會顯示「使用此音效」等浮動按鈕。" - 短片欄 - 隱藏短片欄 - "隱藏短片欄 + 短影音專區 + 隱藏短影音專區 + "隱藏短影音專區 -已知問題:搜索結果中的官方標題將被隱藏" +副作用:搜索結果中的官方標題將被隱藏" 隱藏在頻道中 "隱藏在頻道中。 @@ -1386,15 +1386,15 @@ 在搜尋結果中隱藏 隱藏在搜尋結果中。 顯示在搜尋結果中。 - 隱藏訂閱中的短片 - 訂閱中的短片已隱藏 - 訂閱中的短片已顯示 + 在訂閱內容動態中隱藏 + 在訂閱內容動態中隱藏。 + 在訂閱內容動態中顯示。 在觀看歷史中隱藏 在觀看歷史中隱藏 在觀看歷史中顯示 - 變更 短影片背景重複狀態 - 更改短片重複狀態 + 變更 短影音背景重複狀態 + 更改短影音重複播放狀態 自動播放 預設 暫停 @@ -1403,8 +1403,8 @@ 在一般播放器中開啟 Shorts。 不要在普通播放器中開啟 Shorts。 - 短片播放器 - 隱藏或顯示短片播放器中的組件 + 短影音播放器 + 隱藏或顯示短影音播放器中的組件。 隱藏頻道欄 頻道欄已隱藏 頻道欄已顯示 @@ -1478,12 +1478,12 @@ 顯示使用此聲音按鈕。 操作按鈕 - 隱藏點贊按鈕 - 點讚按鈕已隱藏 - 點讚按鈕已顯示 - 隱藏倒讚按鈕 - 倒讚按鈕已隱藏 - 倒讚按鈕已顯示 + 隱藏點讚按鈕 + 點讚按鈕已隱藏。 + 點讚按鈕已顯示。 + 隱藏不喜歡按鈕 + 不喜歡按鈕已隱藏。 + 不喜歡按鈕已顯示。 隱藏評論按鈕 評論按鈕已隱藏 評論按鈕已顯示 @@ -1503,7 +1503,7 @@ 點讚按鈕上方的噴泉動畫已啟用。 雙擊動畫 原始 - 比讚 + 按讚 Cairo 愛心 愛心 (著色) @@ -1558,7 +1558,7 @@ "已知問題:由於這是 Google 開發階段的功能,因此佈局可能會被破壞。" 時間戳已停用。 長按時間戳記 - 按住時間戳記可變更短片重複狀態。 + 長按時間戳記以變更短影音重複播放狀態。 面板下邊距 配置從搜尋欄到面板的間距,範圍為 0-64。 面板底部邊距必須介於 0-64 之間。 重設為預設值。 @@ -1743,38 +1743,37 @@ 如果影片類別為音樂,則預設播放速度將被停用。 YouTube 音樂上可播放的影片的預設播放速度為停用。 - 恢復 YouTube 倒讚 - 啟用恢復 YouTube 倒讚 - 倒讚數已顯示 - 倒讚數已隱藏 - 倒讚 - 短片中顯示的不喜歡內容 %s - "在短片中顯示不喜歡 + 恢復 YouTube 不喜歡 + 啟用恢復 YouTube 不喜歡功能 + 不喜歡數已顯示。 + 不喜歡數已隱藏。 + 在短影音中顯示不喜歡數 + 短影音顯示不喜歡數。 + "在短影音中顯示不喜歡數 -限制:在無痕模式下,倒讚可能不會顯示" - 倒讚已隱藏 - 倒讚百份比 - 倒讚顯示為百份比 - 倒讚顯示為數字 - 緊湊點讚按鈕 - 點讚按鈕樣式:最小寬度 - 點讚按鈕樣式:最佳顯示 +限制:若使用者未登入或使用無痕模式,可能不會顯示不喜歡數。" + 短影音中的不喜歡數已隱藏。 + 不喜歡數的百分比 + 不喜歡數顯示為百分比。 + 不喜歡數顯示為數字。 + 精簡按讚按鈕 + 按讚按鈕設計為最小寬度。 + 按讚按鈕設計為最佳外觀。 顯示估計喜歡的次數 估計喜歡的次數已顯示。 估計喜歡的次數已隱藏。 如果 API 無法使用,顯示提示訊息 - 如果 恢復 YouTube 倒讚 無法使用,則顯示提示訊息 - 如果 恢復 YouTube 倒讚 無法使用,不顯示訊息 + 如果 Return YouTube Dislike 不可用,將會顯示提示訊息。 + 如果 Return YouTube Dislike 不可用,將不顯示提 +示訊息。 關於 ReturnYouTubeDislike.com - 倒讚資訊由 Return YouTube Dislike API 提供 - -點擊了解更多資訊 - 倒讚數暫時不可用(API 連接超時) - 倒讚數不可用(狀態 %d) - 倒讚數不可用(已達到用戶端 API 限制) - 倒讚數不可用(%s) + 不喜歡數據由 Return YouTube Dislike API 提供。點擊這裡了解更多。 + 不喜歡功能暫時無法使用(API 超時)。 + 不喜歡數不可用 (狀態 %d)。 + 不喜歡數不可用(已達到用戶端 API 限制)。 + 不喜歡數不可用 (%s)。 重新載入影片以使用 恢復 YouTube 倒讚 進行投票 隱藏 @@ -1824,7 +1823,7 @@ 無償廣告/自我推廣 類似於「贊助」,非付費或自我推廣除外。這包括有關商品、捐贈或與他人合作的訊息 交互提醒(訂閱) - 影片中間簡短提醒觀眾來點讚、訂閱或關注。 如果片段較長,或是關於某個具體事物,則應分類為自我推廣 + 影片中間簡短提醒觀眾來點讚、訂閱或關注。 如果片段較長,或是關於某個具體事物,則應分類為自我推廣。 重點 大多數人正在尋找的影片重點位置 過場/開場動畫 @@ -1939,7 +1938,7 @@ 無法為片段投票(API 超時) 無法為片段投票(狀態:%1$d %2$s) 無法為片段投票:%s - 贊成 + 按讚 反對 更改類別 沒有可供投票的片段 From 56d2f7c4ad36d8fb687eda885608ce557c5a8beb Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sat, 29 Mar 2025 16:58:52 +0900 Subject: [PATCH 62/77] bump 5.6.1-dev.4 --- README.md | 137 +++++++++++++++++++++--------------------- gradle.properties | 2 +- patches.json | 147 +++++++++++++++++++++++++--------------------- 3 files changed, 150 insertions(+), 136 deletions(-) diff --git a/README.md b/README.md index c5c347884..50553fc70 100644 --- a/README.md +++ b/README.md @@ -11,73 +11,73 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `Alternative thumbnails` | Adds options to replace video thumbnails using the DeArrow API or image captures from the video. | 19.05.36 ~ 20.03.45 | -| `Ambient mode control` | Adds options to disable Ambient mode and to bypass Ambient mode restrictions. | 19.05.36 ~ 20.03.45 | -| `Bypass URL redirects` | Adds an option to bypass URL redirects and open the original URL directly. | 19.05.36 ~ 20.03.45 | -| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 19.05.36 ~ 20.03.45 | -| `Change form factor` | Adds an option to change the UI appearance to a phone, tablet, or automotive device. | 19.05.36 ~ 20.03.45 | -| `Change live ring click action` | Adds an option to open the channel instead of the live stream when clicking on the live ring. | 19.05.36 ~ 20.03.45 | -| `Change player flyout menu toggles` | Adds an option to use text toggles instead of switch toggles within the additional settings menu. | 19.05.36 ~ 20.03.45 | -| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 19.05.36 ~ 20.03.45 | -| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 19.05.36 ~ 20.03.45 | -| `Custom Shorts action buttons` | Changes, at compile time, the icon of the action buttons of the Shorts player. | 19.05.36 ~ 20.03.45 | -| `Custom branding icon for YouTube` | Changes the YouTube app icon to the icon specified in patch options. | 19.05.36 ~ 20.03.45 | -| `Custom branding name for YouTube` | Changes the YouTube app name to the name specified in patch options. | 19.05.36 ~ 20.03.45 | -| `Custom double tap length` | Adds Double-tap to seek values that are specified in patch options. | 19.05.36 ~ 20.03.45 | -| `Custom header for YouTube` | Applies a custom header in the top left corner within the app. | 19.05.36 ~ 20.03.45 | -| `Description components` | Adds options to hide and disable description components. | 19.05.36 ~ 20.03.45 | -| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 19.05.36 ~ 20.03.45 | -| `Disable forced auto audio tracks` | Adds an option to disable audio tracks from being automatically enabled. | 19.05.36 ~ 20.03.45 | -| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 19.05.36 ~ 20.03.45 | -| `Disable haptic feedback` | Adds options to disable haptic feedback when swiping in the video player. | 19.05.36 ~ 20.03.45 | -| `Disable layout updates` | Adds an option to disable layout updates by server. | 19.05.36 ~ 20.03.45 | -| `Disable resuming Miniplayer on startup` | Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup. | 19.05.36 ~ 20.03.45 | -| `Disable resuming Shorts on startup` | Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched. | 19.05.36 ~ 20.03.45 | -| `Disable splash animation` | Adds an option to disable the splash animation on app startup. | 19.05.36 ~ 20.03.45 | -| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 19.05.36 ~ 20.03.45 | -| `Enable debug logging` | Adds an option to enable debug logging. | 19.05.36 ~ 20.03.45 | -| `Enable gradient loading screen` | Adds an option to enable the gradient loading screen. | 19.05.36 ~ 20.03.45 | -| `Force hide player buttons background` | Removes, at compile time, the dark background surrounding the video player controls. | 19.05.36 ~ 20.03.45 | -| `Fullscreen components` | Adds options to hide or change components related to fullscreen. | 19.05.36 ~ 20.03.45 | -| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 19.05.36 ~ 20.03.45 | -| `Hide Shorts dimming` | Removes, at compile time, the dimming effect at the top and bottom of Shorts videos. | 19.05.36 ~ 20.03.45 | -| `Hide accessibility controls dialog` | Removes, at compile time, accessibility controls dialog 'Turn on accessibility controls for the video player?'. | 19.05.36 ~ 20.03.45 | -| `Hide action buttons` | Adds options to hide action buttons under videos. | 19.05.36 ~ 20.03.45 | -| `Hide ads` | Adds options to hide ads. | 19.05.36 ~ 20.03.45 | -| `Hide comments components` | Adds options to hide components related to comments. | 19.05.36 ~ 20.03.45 | -| `Hide feed components` | Adds options to hide components related to feeds. | 19.05.36 ~ 20.03.45 | -| `Hide feed flyout menu` | Adds the ability to hide feed flyout menu components using a custom filter. | 19.05.36 ~ 20.03.45 | -| `Hide layout components` | Adds options to hide general layout components. | 19.05.36 ~ 20.03.45 | -| `Hide player buttons` | Adds options to hide buttons in the video player. | 19.05.36 ~ 20.03.45 | -| `Hide player flyout menu` | Adds options to hide player flyout menu components. | 19.05.36 ~ 20.03.45 | -| `Hide shortcuts` | Remove, at compile time, the app shortcuts that appears when the app icon is long pressed. | 19.05.36 ~ 20.03.45 | -| `Hook YouTube Music actions` | Adds support for opening music in RVX Music using the in-app YouTube Music button. | 19.05.36 ~ 20.03.45 | -| `Hook download actions` | Adds support to download videos with an external downloader app using the in-app download button. | 19.05.36 ~ 20.03.45 | -| `MaterialYou` | Applies the MaterialYou theme for Android 12+ devices. | 19.05.36 ~ 20.03.45 | -| `Miniplayer` | Adds options to change the in-app minimized player, and if patching target 19.16+ adds options to use modern miniplayers. | 19.05.36 ~ 20.03.45 | -| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 19.05.36 ~ 20.03.45 | -| `Open links externally` | Adds an option to always open links in your browser instead of the in-app browser. | 19.05.36 ~ 20.03.45 | -| `Overlay buttons` | Adds options to display useful overlay buttons in the video player. | 19.05.36 ~ 20.03.45 | -| `Player components` | Adds options to hide or change components related to the video player. | 19.05.36 ~ 20.03.45 | -| `Remove background playback restrictions` | Removes restrictions on background playback, including for music and kids videos. | 19.05.36 ~ 20.03.45 | -| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 19.05.36 ~ 20.03.45 | -| `Return YouTube Dislike` | Adds an option to show the dislike count of videos using the Return YouTube Dislike API. | 19.05.36 ~ 20.03.45 | -| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 19.05.36 ~ 20.03.45 | -| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 19.05.36 ~ 20.03.45 | -| `Seekbar components` | Adds options to hide or change components related to the seekbar. | 19.05.36 ~ 20.03.45 | -| `Settings for YouTube` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 19.05.36 ~ 20.03.45 | -| `Shorts components` | Adds options to hide or change components related to YouTube Shorts. | 19.05.36 ~ 20.03.45 | -| `Snack bar components` | Adds options to hide or change components related to the snack bar. | 19.05.36 ~ 20.03.45 | -| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content. | 19.05.36 ~ 20.03.45 | -| `Spoof app version` | Adds options to spoof the YouTube client version. This can be used to restore old UI elements and features. | 19.05.36 ~ 20.03.45 | -| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 19.05.36 ~ 20.03.45 | -| `Swipe controls` | Adds options for controlling volume and brightness with swiping, and whether to enter fullscreen when swiping down below the player. | 19.05.36 ~ 20.03.45 | -| `Theme` | Changes the app's themes to the values specified in patch options. | 19.05.36 ~ 20.03.45 | -| `Toolbar components` | Adds options to hide or change components located on the toolbar, such as the search bar, header, and toolbar buttons. | 19.05.36 ~ 20.03.45 | -| `Translations for YouTube` | Add translations or remove string resources. | 19.05.36 ~ 20.03.45 | -| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 19.05.36 ~ 20.03.45 | -| `Visual preferences icons for YouTube` | Adds icons to specific preferences in the settings. | 19.05.36 ~ 20.03.45 | -| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 19.05.36 ~ 20.03.45 | +| `Alternative thumbnails` | Adds options to replace video thumbnails using the DeArrow API or image captures from the video. | 19.05.36 ~ 20.03.43 | +| `Ambient mode control` | Adds options to disable Ambient mode and to bypass Ambient mode restrictions. | 19.05.36 ~ 20.03.43 | +| `Bypass URL redirects` | Adds an option to bypass URL redirects and open the original URL directly. | 19.05.36 ~ 20.03.43 | +| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 19.05.36 ~ 20.03.43 | +| `Change form factor` | Adds an option to change the UI appearance to a phone, tablet, or automotive device. | 19.05.36 ~ 20.03.43 | +| `Change live ring click action` | Adds an option to open the channel instead of the live stream when clicking on the live ring. | 19.05.36 ~ 20.03.43 | +| `Change player flyout menu toggles` | Adds an option to use text toggles instead of switch toggles within the additional settings menu. | 19.05.36 ~ 20.03.43 | +| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 19.05.36 ~ 20.03.43 | +| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 19.05.36 ~ 20.03.43 | +| `Custom Shorts action buttons` | Changes, at compile time, the icon of the action buttons of the Shorts player. | 19.05.36 ~ 20.03.43 | +| `Custom branding icon for YouTube` | Changes the YouTube app icon to the icon specified in patch options. | 19.05.36 ~ 20.03.43 | +| `Custom branding name for YouTube` | Changes the YouTube app name to the name specified in patch options. | 19.05.36 ~ 20.03.43 | +| `Custom double tap length` | Adds Double-tap to seek values that are specified in patch options. | 19.05.36 ~ 20.03.43 | +| `Custom header for YouTube` | Applies a custom header in the top left corner within the app. | 19.05.36 ~ 20.03.43 | +| `Description components` | Adds options to hide and disable description components. | 19.05.36 ~ 20.03.43 | +| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 19.05.36 ~ 20.03.43 | +| `Disable forced auto audio tracks` | Adds an option to disable audio tracks from being automatically enabled. | 19.05.36 ~ 20.03.43 | +| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 19.05.36 ~ 20.03.43 | +| `Disable haptic feedback` | Adds options to disable haptic feedback when swiping in the video player. | 19.05.36 ~ 20.03.43 | +| `Disable layout updates` | Adds an option to disable layout updates by server. | 19.05.36 ~ 20.03.43 | +| `Disable resuming Miniplayer on startup` | Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup. | 19.05.36 ~ 20.03.43 | +| `Disable resuming Shorts on startup` | Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched. | 19.05.36 ~ 20.03.43 | +| `Disable splash animation` | Adds an option to disable the splash animation on app startup. | 19.05.36 ~ 20.03.43 | +| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 19.05.36 ~ 20.03.43 | +| `Enable debug logging` | Adds an option to enable debug logging. | 19.05.36 ~ 20.03.43 | +| `Enable gradient loading screen` | Adds an option to enable the gradient loading screen. | 19.05.36 ~ 20.03.43 | +| `Force hide player buttons background` | Removes, at compile time, the dark background surrounding the video player controls. | 19.05.36 ~ 20.03.43 | +| `Fullscreen components` | Adds options to hide or change components related to fullscreen. | 19.05.36 ~ 20.03.43 | +| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 19.05.36 ~ 20.03.43 | +| `Hide Shorts dimming` | Removes, at compile time, the dimming effect at the top and bottom of Shorts videos. | 19.05.36 ~ 20.03.43 | +| `Hide accessibility controls dialog` | Removes, at compile time, accessibility controls dialog 'Turn on accessibility controls for the video player?'. | 19.05.36 ~ 20.03.43 | +| `Hide action buttons` | Adds options to hide action buttons under videos. | 19.05.36 ~ 20.03.43 | +| `Hide ads` | Adds options to hide ads. | 19.05.36 ~ 20.03.43 | +| `Hide comments components` | Adds options to hide components related to comments. | 19.05.36 ~ 20.03.43 | +| `Hide feed components` | Adds options to hide components related to feeds. | 19.05.36 ~ 20.03.43 | +| `Hide feed flyout menu` | Adds the ability to hide feed flyout menu components using a custom filter. | 19.05.36 ~ 20.03.43 | +| `Hide layout components` | Adds options to hide general layout components. | 19.05.36 ~ 20.03.43 | +| `Hide player buttons` | Adds options to hide buttons in the video player. | 19.05.36 ~ 20.03.43 | +| `Hide player flyout menu` | Adds options to hide player flyout menu components. | 19.05.36 ~ 20.03.43 | +| `Hide shortcuts` | Remove, at compile time, the app shortcuts that appears when the app icon is long pressed. | 19.05.36 ~ 20.03.43 | +| `Hook YouTube Music actions` | Adds support for opening music in RVX Music using the in-app YouTube Music button. | 19.05.36 ~ 20.03.43 | +| `Hook download actions` | Adds support to download videos with an external downloader app using the in-app download button. | 19.05.36 ~ 20.03.43 | +| `MaterialYou` | Applies the MaterialYou theme for Android 12+ devices. | 19.05.36 ~ 20.03.43 | +| `Miniplayer` | Adds options to change the in-app minimized player, and if patching target 19.16+ adds options to use modern miniplayers. | 19.05.36 ~ 20.03.43 | +| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 19.05.36 ~ 20.03.43 | +| `Open links externally` | Adds an option to always open links in your browser instead of the in-app browser. | 19.05.36 ~ 20.03.43 | +| `Overlay buttons` | Adds options to display useful overlay buttons in the video player. | 19.05.36 ~ 20.03.43 | +| `Player components` | Adds options to hide or change components related to the video player. | 19.05.36 ~ 20.03.43 | +| `Remove background playback restrictions` | Removes restrictions on background playback, including for music and kids videos. | 19.05.36 ~ 20.03.43 | +| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 19.05.36 ~ 20.03.43 | +| `Return YouTube Dislike` | Adds an option to show the dislike count of videos using the Return YouTube Dislike API. | 19.05.36 ~ 20.03.43 | +| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 19.05.36 ~ 20.03.43 | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 19.05.36 ~ 20.03.43 | +| `Seekbar components` | Adds options to hide or change components related to the seekbar. | 19.05.36 ~ 20.03.43 | +| `Settings for YouTube` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 19.05.36 ~ 20.03.43 | +| `Shorts components` | Adds options to hide or change components related to YouTube Shorts. | 19.05.36 ~ 20.03.43 | +| `Snack bar components` | Adds options to hide or change components related to the snack bar. | 19.05.36 ~ 20.03.43 | +| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content. | 19.05.36 ~ 20.03.43 | +| `Spoof app version` | Adds options to spoof the YouTube client version. This can be used to restore old UI elements and features. | 19.05.36 ~ 20.03.43 | +| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 19.05.36 ~ 20.03.43 | +| `Swipe controls` | Adds options for controlling volume and brightness with swiping, and whether to enter fullscreen when swiping down below the player. | 19.05.36 ~ 20.03.43 | +| `Theme` | Changes the app's themes to the values specified in patch options. | 19.05.36 ~ 20.03.43 | +| `Toolbar components` | Adds options to hide or change components located on the toolbar, such as the search bar, header, and toolbar buttons. | 19.05.36 ~ 20.03.43 | +| `Translations for YouTube` | Add translations or remove string resources. | 19.05.36 ~ 20.03.43 | +| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 19.05.36 ~ 20.03.43 | +| `Visual preferences icons for YouTube` | Adds icons to specific preferences in the settings. | 19.05.36 ~ 20.03.43 | +| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 19.05.36 ~ 20.03.43 | ### [📦 `com.google.android.apps.youtube.music`](https://play.google.com/store/apps/details?id=com.google.android.apps.youtube.music) @@ -170,7 +170,7 @@ Example: "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -200,6 +200,7 @@ Example: "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, diff --git a/gradle.properties b/gradle.properties index 1d8ab2764..ad20bee5d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official kotlin.jvm.target.validation.mode = IGNORE -version = 5.6.1-dev.3 +version = 5.6.1-dev.4 diff --git a/patches.json b/patches.json index fbef79d0c..35d5a705a 100644 --- a/patches.json +++ b/patches.json @@ -16,7 +16,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -36,7 +36,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -76,7 +76,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -118,7 +118,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -158,7 +158,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -180,7 +180,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -193,6 +193,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -226,7 +227,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -270,7 +271,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -311,7 +312,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -352,7 +353,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -389,7 +390,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -494,6 +495,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -526,7 +528,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -610,7 +612,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -639,7 +641,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -759,7 +761,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -843,7 +845,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -892,7 +894,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -934,7 +936,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -953,7 +955,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -972,7 +974,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1014,7 +1016,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1034,7 +1036,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1050,6 +1052,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -1070,7 +1073,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1112,7 +1115,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1152,7 +1155,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1171,7 +1174,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1240,7 +1243,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1266,7 +1269,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1353,7 +1356,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -1413,6 +1416,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -1432,7 +1436,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1451,7 +1455,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1521,7 +1525,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1564,6 +1568,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -1588,7 +1593,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1610,7 +1615,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1636,7 +1641,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1656,7 +1661,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1705,7 +1710,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1720,6 +1725,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -1765,7 +1771,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1788,7 +1794,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1822,6 +1828,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -1842,7 +1849,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -1898,7 +1905,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1920,7 +1927,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1940,7 +1947,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -1961,7 +1968,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2009,7 +2016,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2025,6 +2032,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -2041,6 +2049,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -2061,7 +2070,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2086,7 +2095,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -2186,7 +2195,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2199,6 +2208,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -2241,7 +2251,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2256,6 +2266,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -2298,7 +2309,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2364,7 +2375,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2407,7 +2418,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2444,6 +2455,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -2464,7 +2476,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2489,7 +2501,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2505,6 +2517,7 @@ "compatiblePackages": { "com.reddit.frontpage": [ "2024.17.0", + "2025.05.1", "2025.12.0" ] }, @@ -2541,7 +2554,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -2653,7 +2666,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2673,7 +2686,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -2786,7 +2799,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -2848,7 +2861,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2894,7 +2907,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -2928,7 +2941,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -2948,7 +2961,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -3009,7 +3022,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -3028,7 +3041,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -3156,7 +3169,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] @@ -3175,7 +3188,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [ @@ -3280,7 +3293,7 @@ "19.43.41", "19.44.39", "19.47.53", - "20.03.45" + "20.03.43" ] }, "options": [] From 21be41c2a9e354fc55b723effa4bb8fb9fd9593f Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 17:56:59 +0900 Subject: [PATCH 63/77] fix(Reddit - Disable screenshot popup): Screenshot popup not being completely removed https://github.com/inotia00/ReVanced_Extended/issues/1810 --- .../layout/screenshotpopup/Fingerprints.kt | 37 ++------ .../screenshotpopup/ScreenshotPopupPatch.kt | 95 ++++++++++++++----- .../utils/resourceid/SharedResourceIdPatch.kt | 19 ---- 3 files changed, 77 insertions(+), 74 deletions(-) delete mode 100644 patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt index 13cc83e84..01f630b2b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/Fingerprints.kt @@ -1,36 +1,15 @@ package app.revanced.patches.reddit.layout.screenshotpopup -import app.revanced.patches.reddit.utils.resourceid.screenShotShareBanner -import app.revanced.util.containsLiteralInstruction import app.revanced.util.fingerprint.legacyFingerprint -import com.android.tools.smali.dexlib2.Opcode +import app.revanced.util.or +import com.android.tools.smali.dexlib2.AccessFlags -/** - * Reddit 2025.06.0 ~ - */ -internal val screenshotTakenBannerFingerprint = legacyFingerprint( +internal val screenshotBannerContainerFingerprint = legacyFingerprint( name = "screenshotTakenBannerFingerprint", - returnType = "L", - opcodes = listOf( - Opcode.CONST_4, - Opcode.IF_NE, - ), - customFingerprint = { method, classDef -> - method.containsLiteralInstruction(screenShotShareBanner) && - classDef.type.startsWith("Lcom/reddit/sharing/screenshot/composables/") && - method.name == "invoke" - } -) - -/** - * ~ Reddit 2025.05.1 - */ -internal val screenshotTakenBannerLegacyFingerprint = legacyFingerprint( - name = "screenshotTakenBannerLegacyFingerprint", returnType = "V", - parameters = listOf("Landroidx/compose/runtime/", "I"), - customFingerprint = { method, classDef -> - classDef.type.endsWith("\$ScreenshotTakenBannerKt\$lambda-1\$1;") && - method.name == "invoke" - } + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + strings = listOf( + "bannerContainer", + "scope", + ) ) diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt index a8ceffdb9..4de050ce9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/screenshotpopup/ScreenshotPopupPatch.kt @@ -2,22 +2,26 @@ package app.revanced.patches.reddit.layout.screenshotpopup import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.reddit.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.reddit.utils.extension.Constants.PATCHES_PATH import app.revanced.patches.reddit.utils.patch.PatchList.DISABLE_SCREENSHOT_POPUP -import app.revanced.patches.reddit.utils.resourceid.screenShotShareBanner -import app.revanced.patches.reddit.utils.resourceid.sharedResourceIdPatch -import app.revanced.patches.reddit.utils.settings.is_2025_06_or_greater import app.revanced.patches.reddit.utils.settings.settingsPatch import app.revanced.patches.reddit.utils.settings.updatePatchStatus +import app.revanced.util.findMutableMethodOf +import app.revanced.util.fingerprint.methodCall import app.revanced.util.fingerprint.methodOrThrow +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstructionOrThrow -import app.revanced.util.indexOfFirstInstructionReversedOrThrow -import app.revanced.util.indexOfFirstLiteralInstructionOrThrow +import app.revanced.util.indexOfFirstStringInstruction import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference private const val EXTENSION_METHOD_DESCRIPTOR = "$PATCHES_PATH/ScreenshotPopupPatch;->disableScreenshotPopup()Z" @@ -29,41 +33,80 @@ val screenshotPopupPatch = bytecodePatch( ) { compatibleWith(COMPATIBLE_PACKAGE) - dependsOn( - settingsPatch, - sharedResourceIdPatch, - ) + dependsOn(settingsPatch) execute { - if (is_2025_06_or_greater) { - screenshotTakenBannerFingerprint.methodOrThrow().apply { - val literalIndex = indexOfFirstLiteralInstructionOrThrow(screenShotShareBanner) - val insertIndex = indexOfFirstInstructionReversedOrThrow(literalIndex, Opcode.CONST_4) - val insertRegister = getInstruction(insertIndex).registerA - val jumpIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.SGET_OBJECT) + val screenshotTriggerSharingListenerMethodCall = + screenshotBannerContainerFingerprint.methodCall() - addInstructionsWithLabels( - insertIndex, """ - invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR - move-result v$insertRegister - if-nez v$insertRegister, :hidden - """, ExternalLabel("hidden", getInstruction(jumpIndex)) - ) + fun indexOfScreenshotTriggerInstruction(method: Method) = + method.indexOfFirstInstruction { + getReference()?.toString() == screenshotTriggerSharingListenerMethodCall } - } else { - screenshotTakenBannerLegacyFingerprint.methodOrThrow().apply { + + val isScreenshotTriggerMethod: Method.() -> Boolean = { + indexOfScreenshotTriggerInstruction(this) >= 0 + } + + var hookCount = 0 + + fun MutableMethod.hook() { + if (returnType == "V") { addInstructionsWithLabels( 0, """ invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR move-result v0 - if-eqz v0, :dismiss + if-eqz v0, :shown return-void - """, ExternalLabel("dismiss", getInstruction(0)) + """, ExternalLabel("shown", getInstruction(0)) ) + + hookCount++ + } else if (returnType.startsWith("L")) { // Reddit 2025.06+ + val insertIndex = + indexOfFirstStringInstruction("screenshotTriggerSharingListener") + + if (insertIndex >= 0) { + val insertRegister = + getInstruction(insertIndex).registerA + val triggerIndex = + indexOfScreenshotTriggerInstruction(this) + val jumpIndex = + indexOfFirstInstructionOrThrow(triggerIndex, Opcode.RETURN_OBJECT) + + addInstructionsWithLabels( + insertIndex, """ + invoke-static {}, $EXTENSION_METHOD_DESCRIPTOR + move-result v$insertRegister + if-nez v$insertRegister, :hidden + """, ExternalLabel("hidden", getInstruction(jumpIndex)) + ) + + hookCount++ + } } } + screenshotBannerContainerFingerprint + .methodOrThrow() + .hook() + + classes.forEach { classDef -> + classDef.methods.forEach { method -> + if (method.isScreenshotTriggerMethod()) { + proxy(classDef) + .mutableClass + .findMutableMethodOf(method) + .hook() + } + } + } + + if (hookCount == 0) { + throw PatchException("Failed to find hook method") + } + updatePatchStatus( "enableScreenshotPopup", DISABLE_SCREENSHOT_POPUP diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt deleted file mode 100644 index 4f8faec53..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatch.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.reddit.utils.resourceid - -import app.revanced.patcher.patch.resourcePatch -import app.revanced.patches.shared.mapping.ResourceType.STRING -import app.revanced.patches.shared.mapping.getResourceId -import app.revanced.patches.shared.mapping.resourceMappingPatch - -var screenShotShareBanner = -1L - private set - -internal val sharedResourceIdPatch = resourcePatch( - description = "sharedResourceIdPatch" -) { - dependsOn(resourceMappingPatch) - - execute { - screenShotShareBanner = getResourceId(STRING, "screenshot_share_banner_title") - } -} \ No newline at end of file From 82158deaf267d057fe3d44b5c41439eb34911188 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:01:01 +0900 Subject: [PATCH 64/77] chore(YouTube - Fullscreen components): Remove warning for `Keep landscape mode` setting --- .../youtube/player/fullscreen/FullscreenComponentsPatch.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt index 2a56b37c6..11d7c5e3c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/FullscreenComponentsPatch.kt @@ -37,7 +37,6 @@ import app.revanced.patches.youtube.utils.youtubeControlsOverlayFingerprint import app.revanced.patches.youtube.video.information.hookBackgroundPlayVideoInformation import app.revanced.patches.youtube.video.information.videoEndMethod import app.revanced.patches.youtube.video.information.videoInformationPatch -import app.revanced.util.Utils.printWarn import app.revanced.util.addInstructionsAtControlFlowLabel import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.methodOrThrow @@ -313,8 +312,6 @@ val fullscreenComponentsPatch = bytecodePatch( } settingArray += "SETTINGS: KEEP_LANDSCAPE_MODE" - } else { - printWarn("\"Keep landscape mode\" is not supported in this version. Use YouTube 19.16.39 or earlier.") } // endregion From 05195caa5af175d5a81d7ebbce8fdb7e68bc5d49 Mon Sep 17 00:00:00 2001 From: MondayNitro <87489540+MondayNitro@users.noreply.github.com> Date: Sun, 30 Mar 2025 14:35:53 +0530 Subject: [PATCH 65/77] feat(YouTube - Custom branding icon): Update old splash animation background color (#146) * Update revanced_extended_settings_key_icon.xml * Update $avd_anim__0.xml * Update strings.xml --- .../settings/drawable/revanced_extended_settings_key_icon.xml | 4 ++-- .../youtube/branding/youtube/splash/drawable/$avd_anim__0.xml | 4 ++-- .../main/resources/youtube/settings/host/values/strings.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/patches/src/main/resources/youtube/branding/youtube/settings/drawable/revanced_extended_settings_key_icon.xml b/patches/src/main/resources/youtube/branding/youtube/settings/drawable/revanced_extended_settings_key_icon.xml index 274b2e64f..f261ad58c 100644 --- a/patches/src/main/resources/youtube/branding/youtube/settings/drawable/revanced_extended_settings_key_icon.xml +++ b/patches/src/main/resources/youtube/branding/youtube/settings/drawable/revanced_extended_settings_key_icon.xml @@ -13,7 +13,7 @@ - \ No newline at end of file + diff --git a/patches/src/main/resources/youtube/branding/youtube/splash/drawable/$avd_anim__0.xml b/patches/src/main/resources/youtube/branding/youtube/splash/drawable/$avd_anim__0.xml index 4d4459196..661ba43e1 100644 --- a/patches/src/main/resources/youtube/branding/youtube/splash/drawable/$avd_anim__0.xml +++ b/patches/src/main/resources/youtube/branding/youtube/splash/drawable/$avd_anim__0.xml @@ -7,9 +7,9 @@ - + - \ No newline at end of file + diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index 4a6cd861c..cadaf9aef 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -1699,12 +1699,12 @@ No margins on top and bottom of player." Enable brightness gesture "Fullscreen brightness swipe is enabled. - Adjust brightness by swiping vertically on the left side of the screen." +Adjust brightness by swiping vertically on the left side of the screen." Brightness swipe is disabled. Enable volume gesture "Fullscreen volume swipe is enabled. - Adjust volume by swiping vertically on the right side of the screen." +Adjust volume by swiping vertically on the right side of the screen." Volume swipe is disabled. Enable save and restore brightness Save and restore brightness when exiting or entering fullscreen. From 1dd7eda60666bc3bcdd15ec65a95490a0a358b60 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:08:49 +0900 Subject: [PATCH 66/77] chore(YouTube): Reflecting the changes in ReVanced --- .../spoof/SpoofStreamingDataPatch.java | 16 +++++++++++--- .../ReturnYouTubeDislike.java | 4 ++-- .../youtube/utils/ExtendedUtils.java | 21 ++++++++++++------- .../utils/fix/streamingdata/Fingerprints.kt | 15 +++++++++++++ .../streamingdata/SpoofStreamingDataPatch.kt | 16 ++++++++++---- .../utils/playservice/VersionCheckPatch.kt | 3 +++ 6 files changed, 58 insertions(+), 17 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java index fdfdbabc0..40d4ceb8a 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/SpoofStreamingDataPatch.java @@ -69,11 +69,21 @@ public class SpoofStreamingDataPatch extends BlockRequestPatch { * Skip response encryption in OnesiePlayerRequest. */ public static boolean skipResponseEncryption(boolean original) { - if (SPOOF_STREAMING_DATA_SKIP_RESPONSE_ENCRYPTION) { - return false; + if (!SPOOF_STREAMING_DATA_SKIP_RESPONSE_ENCRYPTION) { + return original; } + return false; + } - return original; + /** + * Injection point. + * Turns off a feature flag that interferes with video playback. + */ + public static boolean usePlaybackStartFeatureFlag(boolean original) { + if (!SPOOF_STREAMING_DATA) { + return original; + } + return false; } /** diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/returnyoutubedislike/ReturnYouTubeDislike.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/returnyoutubedislike/ReturnYouTubeDislike.java index ca5ff0aaa..b3b23057c 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/returnyoutubedislike/ReturnYouTubeDislike.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/returnyoutubedislike/ReturnYouTubeDislike.java @@ -115,7 +115,7 @@ public class ReturnYouTubeDislike { private static final Rect middleSeparatorBounds; /** - * Left separator horizontal padding for Rolling Number layout. + * Horizontal padding between the left and middle separator. */ public static final int leftSeparatorShapePaddingPixels; private static final ShapeDrawable leftSeparatorShape; @@ -131,7 +131,7 @@ public class ReturnYouTubeDislike { (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3.7f, dp); middleSeparatorBounds = new Rect(0, 0, middleSeparatorSize, middleSeparatorSize); - leftSeparatorShapePaddingPixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10.0f, dp); + leftSeparatorShapePaddingPixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8.4f, dp); leftSeparatorShape = new ShapeDrawable(new RectShape()); leftSeparatorShape.setBounds(leftSeparatorBounds); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/ExtendedUtils.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/ExtendedUtils.java index 51cc78e31..378ddea77 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/ExtendedUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/utils/ExtendedUtils.java @@ -31,15 +31,20 @@ import app.revanced.extension.shared.utils.PackageUtils; import app.revanced.extension.youtube.settings.Settings; public class ExtendedUtils extends PackageUtils { + + private static boolean isVersionOrGreater(String version) { + return getAppVersionName().compareTo(version) >= 0; + } + @SuppressWarnings("unused") - public static final boolean IS_19_17_OR_GREATER = getAppVersionName().compareTo("19.17.00") >= 0; - public static final boolean IS_19_20_OR_GREATER = getAppVersionName().compareTo("19.20.00") >= 0; - public static final boolean IS_19_21_OR_GREATER = getAppVersionName().compareTo("19.21.00") >= 0; - public static final boolean IS_19_26_OR_GREATER = getAppVersionName().compareTo("19.26.00") >= 0; - public static final boolean IS_19_28_OR_GREATER = getAppVersionName().compareTo("19.28.00") >= 0; - public static final boolean IS_19_29_OR_GREATER = getAppVersionName().compareTo("19.29.00") >= 0; - public static final boolean IS_19_34_OR_GREATER = getAppVersionName().compareTo("19.34.00") >= 0; - public static final boolean IS_20_09_OR_GREATER = getAppVersionName().compareTo("20.09.00") >= 0; + public static final boolean IS_19_17_OR_GREATER = isVersionOrGreater("19.17.00"); + public static final boolean IS_19_20_OR_GREATER = isVersionOrGreater("19.20.00"); + public static final boolean IS_19_21_OR_GREATER = isVersionOrGreater("19.21.00"); + public static final boolean IS_19_26_OR_GREATER = isVersionOrGreater("19.26.00"); + public static final boolean IS_19_28_OR_GREATER = isVersionOrGreater("19.28.00"); + public static final boolean IS_19_29_OR_GREATER = isVersionOrGreater("19.29.00"); + public static final boolean IS_19_34_OR_GREATER = isVersionOrGreater("19.34.00"); + public static final boolean IS_20_09_OR_GREATER = isVersionOrGreater("20.09.00"); public static int validateValue(IntegerSetting settings, int min, int max, String message) { int value = settings.get(); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/Fingerprints.kt index fa1662872..214e81a70 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/Fingerprints.kt @@ -153,3 +153,18 @@ internal val onesieEncryptionAlternativeFeatureFlagFingerprint = legacyFingerpri name = "onesieEncryptionAlternativeFeatureFlagFingerprint", literals = listOf(ONESIE_ENCRYPTION_ALTERNATIVE_FEATURE_FLAG), ) + +// Feature flag that enables different code for parsing and starting video playback, +// but it's exact purpose is not known. If this flag is enabled while stream spoofing +// then videos will never start playback and load forever. +// Flag does not seem to affect playback if spoofing is off. +// YouTube 19.50 ~ +internal const val PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG = 45665455L + +internal val playbackStartDescriptorFeatureFlagFingerprint = legacyFingerprint( + name = "playbackStartDescriptorFeatureFlagFingerprint", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + returnType = ("Z"), + literals = listOf(PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG) +) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt index c1982140f..0ce563db6 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/streamingdata/SpoofStreamingDataPatch.kt @@ -20,6 +20,7 @@ import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PAC import app.revanced.patches.youtube.utils.compatibility.Constants.YOUTUBE_PACKAGE_NAME import app.revanced.patches.youtube.utils.patch.PatchList.SPOOF_STREAMING_DATA import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater +import app.revanced.patches.youtube.utils.playservice.is_19_50_or_greater import app.revanced.patches.youtube.utils.playservice.is_20_10_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch import app.revanced.patches.youtube.utils.request.buildRequestPatch @@ -345,11 +346,18 @@ val spoofStreamingDataPatch = bytecodePatch( "$EXTENSION_CLASS_DESCRIPTOR->skipResponseEncryption(Z)Z" ) - if (is_20_10_or_greater) { - onesieEncryptionAlternativeFeatureFlagFingerprint.injectLiteralInstructionBooleanCall( - ONESIE_ENCRYPTION_ALTERNATIVE_FEATURE_FLAG, - "$EXTENSION_CLASS_DESCRIPTOR->skipResponseEncryption(Z)Z" + if (is_19_50_or_greater) { + playbackStartDescriptorFeatureFlagFingerprint.injectLiteralInstructionBooleanCall( + PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG, + "$EXTENSION_CLASS_DESCRIPTOR->usePlaybackStartFeatureFlag(Z)Z" ) + + if (is_20_10_or_greater) { + onesieEncryptionAlternativeFeatureFlagFingerprint.injectLiteralInstructionBooleanCall( + ONESIE_ENCRYPTION_ALTERNATIVE_FEATURE_FLAG, + "$EXTENSION_CLASS_DESCRIPTOR->skipResponseEncryption(Z)Z" + ) + } } settingArray += "SETTINGS: SKIP_RESPONSE_ENCRYPTION" diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt index fa38cf1db..274ca0687 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt @@ -61,6 +61,8 @@ var is_19_46_or_greater = false private set var is_19_49_or_greater = false private set +var is_19_50_or_greater = false + private set var is_20_02_or_greater = false private set var is_20_03_or_greater = false @@ -116,6 +118,7 @@ val versionCheckPatch = resourcePatch( is_19_44_or_greater = 244505000 <= playStoreServicesVersion is_19_46_or_greater = 244705000 <= playStoreServicesVersion is_19_49_or_greater = 245005000 <= playStoreServicesVersion + is_19_50_or_greater = 245105000 <= playStoreServicesVersion is_20_02_or_greater = 250299000 <= playStoreServicesVersion is_20_03_or_greater = 250405000 <= playStoreServicesVersion is_20_05_or_greater = 250605000 <= playStoreServicesVersion From aac38dc8af29b6e255535b716cc5b89169de5c44 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:12:07 +0900 Subject: [PATCH 67/77] fix(YouTube - Settings): `RVX language` no longer changes the YouTube app language --- .../extension/shared/utils/Utils.java | 82 ++++++++++--------- .../ReVancedPreferenceFragment.java | 1 + .../VideoQualitySettingsActivity.java | 18 +++- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java index bbad47a50..956f60039 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/utils/Utils.java @@ -60,6 +60,7 @@ public class Utils { private static WeakReference activityRef = new WeakReference<>(null); @SuppressLint("StaticFieldLeak") private static volatile Context context; + private static Locale contextLocale; protected Utils() { } // utility class @@ -308,34 +309,51 @@ public class Utils { * @return Context with locale applied. */ public static Context getLocalizedContext(Context mContext) { - Activity mActivity = activityRef.get(); - if (mActivity == null) { - return mContext; - } - if (mContext == null) { - return null; + try { + Activity mActivity = activityRef.get(); + if (mActivity != null && mContext != null) { + AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get(); + + // Locale of Application. + Locale applicationLocale = language == AppLanguage.DEFAULT + ? mActivity.getResources().getConfiguration().locale + : language.getLocale(); + + // Locale of Context. + Locale contextLocale = mContext.getResources().getConfiguration().locale; + + // If they are different, overrides the Locale of the Context and resource. + if (applicationLocale != contextLocale) { + Utils.contextLocale = contextLocale; + + // If they are different, overrides the Locale of the Context and resource. + Locale.setDefault(applicationLocale); + Configuration configuration = new Configuration(mContext.getResources().getConfiguration()); + configuration.setLocale(applicationLocale); + return mContext.createConfigurationContext(configuration); + } + } + } catch (Exception ex) { + Logger.printException(() -> "getLocalizedContext failed", ex); } - AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get(); + return mContext; + } - // Locale of Application. - Locale applicationLocale = language == AppLanguage.DEFAULT - ? mActivity.getResources().getConfiguration().locale - : language.getLocale(); - - // Locale of Context. - Locale contextLocale = mContext.getResources().getConfiguration().locale; - - // If they are identical, no need to override them. - if (applicationLocale == contextLocale) { - return mContext; + public static void resetLocalizedContext() { + try { + if (contextLocale != null) { + Locale.setDefault(contextLocale); + Context mContext = getContext(); + if (mContext != null) { + Configuration config = mContext.getResources().getConfiguration(); + config.setLocale(contextLocale); + setContext(mContext.createConfigurationContext(config)); + } + } + } catch (Exception ex) { + Logger.printException(() -> "resetLocalizedContext failed", ex); } - - // If they are different, overrides the Locale of the Context and resource. - Locale.setDefault(applicationLocale); - Configuration configuration = new Configuration(mContext.getResources().getConfiguration()); - configuration.setLocale(applicationLocale); - return mContext.createConfigurationContext(configuration); } public static void setActivity(Activity mainActivity) { @@ -353,14 +371,6 @@ public class Utils { // Must initially set context to check the app language. context = appContext; Logger.initializationInfo(Utils.class, "Set context: " + appContext); - - AppLanguage language = BaseSettings.REVANCED_LANGUAGE.get(); - if (language != AppLanguage.DEFAULT) { - // Create a new context with the desired language. - Configuration config = appContext.getResources().getConfiguration(); - config.setLocale(language.getLocale()); - context = appContext.createConfigurationContext(config); - } } public static void setClipboard(@NonNull String text) { @@ -538,14 +548,6 @@ public class Utils { return Build.VERSION.SDK_INT >= sdk; } - public static int dpToPx(float dp) { - if (context == null) { - return (int) dp; - } else { - return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); - } - } - public static int dpToPx(int dp) { if (context == null) { return dp; diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java index af2864f36..6a2fd721f 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -377,6 +377,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { @Override public void onDestroy() { mSharedPreferences.unregisterOnSharedPreferenceChangeListener(listener); + Utils.resetLocalizedContext(); super.onDestroy(); } diff --git a/extensions/shared/src/main/java/com/google/android/apps/youtube/app/settings/videoquality/VideoQualitySettingsActivity.java b/extensions/shared/src/main/java/com/google/android/apps/youtube/app/settings/videoquality/VideoQualitySettingsActivity.java index a969c6bd4..f9c0c50f3 100644 --- a/extensions/shared/src/main/java/com/google/android/apps/youtube/app/settings/videoquality/VideoQualitySettingsActivity.java +++ b/extensions/shared/src/main/java/com/google/android/apps/youtube/app/settings/videoquality/VideoQualitySettingsActivity.java @@ -1,7 +1,9 @@ package com.google.android.apps.youtube.app.settings.videoquality; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; +import android.content.res.Resources; import android.os.Bundle; import android.util.TypedValue; import android.view.View; @@ -25,8 +27,8 @@ import app.revanced.extension.youtube.utils.ThemeUtils; @SuppressWarnings("deprecation") public class VideoQualitySettingsActivity extends Activity { - private static final String rvxSettingsLabel = ResourceUtils.getString("revanced_extended_settings_title"); - private static final String searchLabel = ResourceUtils.getString("revanced_extended_settings_search_title"); + private static String rvxSettingsLabel; + private static String searchLabel; private static WeakReference searchViewRef = new WeakReference<>(null); private static WeakReference closeButtonRef = new WeakReference<>(null); private ReVancedPreferenceFragment fragment; @@ -71,6 +73,10 @@ public class VideoQualitySettingsActivity extends Activity { return; } + // Set label + rvxSettingsLabel = getString("revanced_extended_settings_title"); + searchLabel = getString("revanced_extended_settings_search_title"); + // Set toolbar setToolbar(); @@ -85,6 +91,14 @@ public class VideoQualitySettingsActivity extends Activity { } } + @SuppressLint("DiscouragedApi") + private String getString(String str) { + Context baseContext = getBaseContext(); + Resources resources = baseContext.getResources(); + int identifier = resources.getIdentifier(str, "string", baseContext.getPackageName()); + return resources.getString(identifier); + } + private void filterPreferences(String query) { if (fragment == null) return; fragment.filterPreferences(query); From 88d59d05b9584c0f60a6a1178317839cb843b0f3 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:16:34 +0900 Subject: [PATCH 68/77] fix(YouTube - Shorts components): `Custom actions` do not override Shorts flyout menu in YouTube 19.05.36 --- .../patches/shorts/CustomActionsPatch.java | 31 ++++++++++++++++++- .../youtube/shorts/components/Fingerprints.kt | 28 +++++++++++++++++ .../shorts/components/ShortsComponentPatch.kt | 27 ++++++++++++++-- .../utils/playservice/VersionCheckPatch.kt | 3 ++ 4 files changed, 86 insertions(+), 3 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java index bb288a116..d781ba937 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/shorts/CustomActionsPatch.java @@ -155,6 +155,34 @@ public final class CustomActionsPatch { Logger.printInfo(() -> customAction.name() + bottomSheetMenuClass + bottomSheetMenuList + bottomSheetMenuObject); } + /** + * Injection point. + */ + public static boolean onBottomSheetMenuItemClick(View view) { + try { + if (view instanceof ViewGroup viewGroup) { + TextView textView = Utils.getChildView(viewGroup, v -> v instanceof TextView); + if (textView != null) { + String menuTitle = textView.getText().toString(); + for (CustomAction customAction : CustomAction.values()) { + if (customAction.getLabel().equals(menuTitle)) { + View.OnLongClickListener onLongClick = customAction.getOnLongClickListener(); + if (onLongClick != null) { + view.setOnLongClickListener(onLongClick); + } + customAction.getOnClickAction().run(); + return true; + } + } + } + } + } catch (Exception ex) { + Logger.printException(() -> "onBottomSheetMenuItemClick failed"); + } + + return false; + } + /** * Injection point. */ @@ -179,8 +207,9 @@ public final class CustomActionsPatch { if (recyclerView.getChildAt(childCount - i - 1) instanceof ViewGroup parentViewGroup) { childCount = recyclerView.getChildCount(); if (childCount > 3 && parentViewGroup.getChildAt(1) instanceof TextView textView) { + String menuTitle = textView.getText().toString(); for (CustomAction customAction : CustomAction.values()) { - if (customAction.getLabel().equals(textView.getText().toString())) { + if (customAction.getLabel().equals(menuTitle)) { View.OnClickListener onClick = customAction.getOnClickListener(); View.OnLongClickListener onLongClick = customAction.getOnLongClickListener(); recyclerViewRef = new WeakReference<>(recyclerView); diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt index 633d8c019..639a2c4c3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt @@ -24,6 +24,34 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference import kotlin.collections.listOf +internal val bottomSheetMenuDismissFingerprint = legacyFingerprint( + name = "bottomSheetMenuDismissFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = emptyList(), + customFingerprint = { method, _ -> + indexOfDismissInstruction(method) >= 0 + } +) + +fun indexOfDismissInstruction(method: Method) = + method.indexOfFirstInstruction { + val reference = getReference() + reference?.name == "dismiss" && + reference.returnType == "V" && + reference.parameterTypes.isEmpty() + } + +internal val bottomSheetMenuItemClickFingerprint = legacyFingerprint( + name = "bottomSheetMenuItemClickFingerprint", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", + parameters = listOf("Landroid/widget/AdapterView;", "Landroid/view/View;", "I", "J"), + customFingerprint = { method, _ -> + method.name == "onItemClick" + } +) + internal val bottomSheetMenuListBuilderFingerprint = legacyFingerprint( name = "bottomSheetMenuListBuilderFingerprint", returnType = "L", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt index acc000d0d..fc0b76a03 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt @@ -35,6 +35,7 @@ import app.revanced.patches.youtube.utils.playservice.is_18_31_or_greater import app.revanced.patches.youtube.utils.playservice.is_18_34_or_greater import app.revanced.patches.youtube.utils.playservice.is_18_49_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_02_or_greater +import app.revanced.patches.youtube.utils.playservice.is_19_11_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_25_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_28_or_greater import app.revanced.patches.youtube.utils.playservice.is_19_34_or_greater @@ -74,7 +75,6 @@ import app.revanced.patches.youtube.video.videoid.hookPlayerResponseVideoId import app.revanced.patches.youtube.video.videoid.videoIdPatch import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT import app.revanced.util.ResourceGroup -import app.revanced.util.addEntryValues import app.revanced.util.cloneMutable import app.revanced.util.copyResources import app.revanced.util.findMethodOrThrow @@ -339,7 +339,30 @@ private val shortsCustomActionsPatch = bytecodePatch( } } - recyclerViewTreeObserverHook("$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V") + if (is_19_11_or_greater) { + // The type of the Shorts flyout menu is RecyclerView. + recyclerViewTreeObserverHook("$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V") + } else { + // The type of the Shorts flyout menu is ListView. + val dismissReference = with (bottomSheetMenuDismissFingerprint.methodOrThrow(bottomSheetMenuListBuilderFingerprint)) { + val dismissIndex = indexOfDismissInstruction(this) + getInstruction(dismissIndex).reference + } + + bottomSheetMenuItemClickFingerprint + .methodOrThrow(bottomSheetMenuListBuilderFingerprint) + .addInstructionsWithLabels( + 0, """ + invoke-static/range {p2 .. p2}, $EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->onBottomSheetMenuItemClick(Landroid/view/View;)Z + move-result v0 + if-eqz v0, :ignore + invoke-virtual {p0}, $dismissReference + return-void + :ignore + nop + """, + ) + } // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt index 274ca0687..19bf4774f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playservice/VersionCheckPatch.kt @@ -25,6 +25,8 @@ var is_19_05_or_greater = false private set var is_19_09_or_greater = false private set +var is_19_11_or_greater = false + private set var is_19_15_or_greater = false private set var is_19_16_or_greater = false @@ -100,6 +102,7 @@ val versionCheckPatch = resourcePatch( is_19_04_or_greater = 240502000 <= playStoreServicesVersion is_19_05_or_greater = 240602000 <= playStoreServicesVersion is_19_09_or_greater = 241002000 <= playStoreServicesVersion + is_19_11_or_greater = 241199000 <= playStoreServicesVersion is_19_15_or_greater = 241602000 <= playStoreServicesVersion is_19_16_or_greater = 241702000 <= playStoreServicesVersion is_19_17_or_greater = 241802000 <= playStoreServicesVersion From 35e6c268239392a9bafff1320266ad7dcc0f3a90 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:18:46 +0900 Subject: [PATCH 69/77] fix(Extensions): Remove unnecessary Context hooks --- .../utils/extension/SharedExtensionPatch.kt | 6 --- .../hooks/MainActivityBaseContextHook.kt | 32 ------------- .../hooks/CronetEngineContextHook.kt | 48 ------------------- .../hooks/FirebaseInitProviderContextHook.kt | 37 -------------- .../utils/extension/SharedExtensionPatch.kt | 8 ---- .../hooks/MainActivityBaseContextHook.kt | 36 -------------- .../hooks/UrlActivityBaseContextHook.kt | 32 ------------- 7 files changed, 199 deletions(-) delete mode 100644 patches/src/main/kotlin/app/revanced/patches/music/utils/extension/hooks/MainActivityBaseContextHook.kt delete mode 100644 patches/src/main/kotlin/app/revanced/patches/shared/extension/hooks/CronetEngineContextHook.kt delete mode 100644 patches/src/main/kotlin/app/revanced/patches/shared/extension/hooks/FirebaseInitProviderContextHook.kt delete mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/hooks/MainActivityBaseContextHook.kt delete mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/hooks/UrlActivityBaseContextHook.kt diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/extension/SharedExtensionPatch.kt index dd6883783..7e155f261 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/extension/SharedExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/extension/SharedExtensionPatch.kt @@ -1,14 +1,8 @@ package app.revanced.patches.music.utils.extension import app.revanced.patches.music.utils.extension.hooks.applicationInitHook -import app.revanced.patches.music.utils.extension.hooks.mainActivityBaseContextHook -import app.revanced.patches.shared.extension.hooks.cronetEngineContextHook -import app.revanced.patches.shared.extension.hooks.firebaseInitProviderContextHook import app.revanced.patches.shared.extension.sharedExtensionPatch val sharedExtensionPatch = sharedExtensionPatch( applicationInitHook, - cronetEngineContextHook, - firebaseInitProviderContextHook, - mainActivityBaseContextHook, ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/extension/hooks/MainActivityBaseContextHook.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/extension/hooks/MainActivityBaseContextHook.kt deleted file mode 100644 index 549eff2ba..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/extension/hooks/MainActivityBaseContextHook.kt +++ /dev/null @@ -1,32 +0,0 @@ -package app.revanced.patches.music.utils.extension.hooks - -import app.revanced.patches.shared.extension.extensionHook -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -private var attachBaseContextIndex = -1 - -internal val mainActivityBaseContextHook = extensionHook( - insertIndexResolver = { method -> - attachBaseContextIndex = method.indexOfFirstInstructionOrThrow { - getReference()?.name == "attachBaseContext" - } - - attachBaseContextIndex + 1 - }, - contextRegisterResolver = { method -> - val overrideInstruction = - method.implementation!!.instructions.elementAt(attachBaseContextIndex) - as FiveRegisterInstruction - "v${overrideInstruction.registerD}" - }, -) { - returns("V") - parameters("Landroid/content/Context;") - custom { method, classDef -> - classDef.type == "Lcom/google/android/apps/youtube/music/activities/MusicActivity;" && - method.name == "attachBaseContext" - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/extension/hooks/CronetEngineContextHook.kt b/patches/src/main/kotlin/app/revanced/patches/shared/extension/hooks/CronetEngineContextHook.kt deleted file mode 100644 index e31cf801b..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/shared/extension/hooks/CronetEngineContextHook.kt +++ /dev/null @@ -1,48 +0,0 @@ -package app.revanced.patches.shared.extension.hooks - -import app.revanced.patches.shared.extension.extensionHook -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import app.revanced.util.indexOfFirstInstructionOrThrow -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -private var initIndex = -1 -private var isRange = true - -internal val cronetEngineContextHook = extensionHook( - insertIndexResolver = { method -> - initIndex = method.indexOfFirstInstruction(Opcode.INVOKE_DIRECT_RANGE) - - if (initIndex < 0) { - initIndex = method.indexOfFirstInstructionOrThrow(Opcode.INVOKE_DIRECT) - isRange = false - } - - initIndex - }, - contextRegisterResolver = { method -> - val initInstruction = - method.implementation!!.instructions.elementAt(initIndex) - if (isRange) { - val overrideInstruction = initInstruction as Instruction3rc - "v${overrideInstruction.startRegister + 1}" - } else { - val overrideInstruction = initInstruction as FiveRegisterInstruction - "v${overrideInstruction.registerD}" - } - }, -) { - returns("Lorg/chromium/net/CronetEngine;") - accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) - strings("Could not create CronetEngine") - custom { method, classDef -> - method.indexOfFirstInstruction { - (opcode == Opcode.INVOKE_DIRECT || opcode == Opcode.INVOKE_DIRECT_RANGE) && - getReference()?.parameterTypes?.firstOrNull() == "Landroid/content/Context;" - } >= 0 - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/extension/hooks/FirebaseInitProviderContextHook.kt b/patches/src/main/kotlin/app/revanced/patches/shared/extension/hooks/FirebaseInitProviderContextHook.kt deleted file mode 100644 index e52f23dfa..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/shared/extension/hooks/FirebaseInitProviderContextHook.kt +++ /dev/null @@ -1,37 +0,0 @@ -package app.revanced.patches.shared.extension.hooks - -import app.revanced.patches.shared.extension.extensionHook -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstruction -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.Method -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -private var getResourcesIndex = -1 - -internal val firebaseInitProviderContextHook = extensionHook( - insertIndexResolver = { method -> - getResourcesIndex = indexOfGerResourcesInstruction(method) - - getResourcesIndex + 2 - }, - contextRegisterResolver = { method -> - val overrideInstruction = - method.implementation!!.instructions.elementAt(getResourcesIndex) - as FiveRegisterInstruction - - "v${overrideInstruction.registerC}" - }, -) { - strings("firebase_database_url") - custom { method, _ -> - indexOfGerResourcesInstruction(method) >= 0 - } -} - -private fun indexOfGerResourcesInstruction(method: Method) = - method.indexOfFirstInstruction { - opcode == Opcode.INVOKE_VIRTUAL && - getReference()?.toString() =="Landroid/content/Context;->getResources()Landroid/content/res/Resources;" - } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/SharedExtensionPatch.kt index e2ba7dc77..bab6ee3da 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/SharedExtensionPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/SharedExtensionPatch.kt @@ -1,17 +1,9 @@ package app.revanced.patches.youtube.utils.extension -import app.revanced.patches.shared.extension.hooks.cronetEngineContextHook -import app.revanced.patches.shared.extension.hooks.firebaseInitProviderContextHook import app.revanced.patches.shared.extension.sharedExtensionPatch import app.revanced.patches.youtube.utils.extension.hooks.applicationInitHook -import app.revanced.patches.youtube.utils.extension.hooks.mainActivityBaseContextHook -import app.revanced.patches.youtube.utils.extension.hooks.urlActivityBaseContextHook // TODO: Move this to a "Hook.kt" file. Same for other extension hook patches. val sharedExtensionPatch = sharedExtensionPatch( applicationInitHook, - cronetEngineContextHook, - firebaseInitProviderContextHook, - mainActivityBaseContextHook, - urlActivityBaseContextHook, ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/hooks/MainActivityBaseContextHook.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/hooks/MainActivityBaseContextHook.kt deleted file mode 100644 index 1f17ed305..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/hooks/MainActivityBaseContextHook.kt +++ /dev/null @@ -1,36 +0,0 @@ -package app.revanced.patches.youtube.utils.extension.hooks - -import app.revanced.patches.shared.extension.extensionHook -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -private var attachBaseContextIndex = -1 - -internal val mainActivityBaseContextHook = extensionHook( - insertIndexResolver = { method -> - attachBaseContextIndex = method.indexOfFirstInstructionOrThrow { - getReference()?.name == "attachBaseContext" - } - - attachBaseContextIndex + 1 - }, - contextRegisterResolver = { method -> - val overrideInstruction = - method.implementation!!.instructions.elementAt(attachBaseContextIndex) - as FiveRegisterInstruction - "v${overrideInstruction.registerD}" - }, -) { - returns("V") - parameters("Landroid/content/Context;") - custom { method, classDef -> - method.name == "attachBaseContext" && - ( - classDef.endsWith("/MainActivity;") || - // Old versions of YouTube called this class "WatchWhileActivity" instead. - classDef.endsWith("/WatchWhileActivity;") - ) - } -} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/hooks/UrlActivityBaseContextHook.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/hooks/UrlActivityBaseContextHook.kt deleted file mode 100644 index b14d0b71e..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/extension/hooks/UrlActivityBaseContextHook.kt +++ /dev/null @@ -1,32 +0,0 @@ -package app.revanced.patches.youtube.utils.extension.hooks - -import app.revanced.patches.shared.extension.extensionHook -import app.revanced.util.getReference -import app.revanced.util.indexOfFirstInstructionOrThrow -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -private var attachBaseContextIndex = -1 - -internal val urlActivityBaseContextHook = extensionHook( - insertIndexResolver = { method -> - attachBaseContextIndex = method.indexOfFirstInstructionOrThrow { - getReference()?.name == "attachBaseContext" - } - - attachBaseContextIndex + 1 - }, - contextRegisterResolver = { method -> - val overrideInstruction = - method.implementation!!.instructions.elementAt(attachBaseContextIndex) - as FiveRegisterInstruction - "v${overrideInstruction.registerD}" - }, -) { - returns("V") - parameters("Landroid/content/Context;") - custom { method, classDef -> - classDef.endsWith("/Shell_UrlActivity;") && - method.name == "attachBaseContext" - } -} From edccd61e6b53010311534ac77e8956a17e9227d6 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:20:02 +0900 Subject: [PATCH 70/77] fix(YouTube - Custom branding icon): Remove unnecessary hooks --- .../branding/icon/CustomBrandingIconPatch.kt | 50 +++++++++++------ .../fix/splash/DarkModeSplashScreenPatch.kt | 56 +++---------------- 2 files changed, 41 insertions(+), 65 deletions(-) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt index 4b9b2b5cc..d9d8d93b8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt @@ -217,16 +217,30 @@ val customBrandingIconPatch = resourcePatch( } } - val styleMap = mutableMapOf() - styleMap["Base.Theme.YouTube.Launcher"] = - "@style/Theme.AppCompat.DayNight.NoActionBar" + val styleList = if (is_19_32_or_greater) + listOf( + Triple( + "values-night-v31", + "Theme.YouTube.Home", + "@style/Base.V27.Theme.YouTube.Home" + ), + Triple( + "values-v31", + "Theme.YouTube.Home", + "@style/Base.V27.Theme.YouTube.Home" + ), + ) + else + listOf( + Triple( + "values-v31", + "Base.Theme.YouTube.Launcher", + "@style/Theme.AppCompat.DayNight.NoActionBar" + ), + ) - if (is_19_32_or_greater) { - styleMap["Theme.YouTube.Home"] = "@style/Base.V27.Theme.YouTube.Home" - } - - styleMap.forEach { (nodeAttributeName, nodeAttributeParent) -> - document("res/values-v31/styles.xml").use { document -> + styleList.forEach { (directory, nodeAttributeName, nodeAttributeParent) -> + document("res/$directory/styles.xml").use { document -> val resourcesNode = document.getElementsByTagName("resources").item(0) as Element @@ -234,21 +248,23 @@ val customBrandingIconPatch = resourcePatch( style.setAttribute("name", nodeAttributeName) style.setAttribute("parent", nodeAttributeParent) - val primaryItem = document.createElement("item") - primaryItem.setAttribute("name", "android:windowSplashScreenAnimatedIcon") - primaryItem.textContent = "@drawable/avd_anim" - val secondaryItem = document.createElement("item") - secondaryItem.setAttribute( + val splashScreenAnimatedIcon = document.createElement("item") + splashScreenAnimatedIcon.setAttribute("name", "android:windowSplashScreenAnimatedIcon") + splashScreenAnimatedIcon.textContent = "@drawable/avd_anim" + + // Deprecated in Android 13+ + val splashScreenAnimationDuration = document.createElement("item") + splashScreenAnimationDuration.setAttribute( "name", "android:windowSplashScreenAnimationDuration" ) - secondaryItem.textContent = if (appIcon.startsWith("revancify")) + splashScreenAnimationDuration.textContent = if (appIcon.startsWith("revancify")) "1500" else "1000" - style.appendChild(primaryItem) - style.appendChild(secondaryItem) + style.appendChild(splashScreenAnimatedIcon) + style.appendChild(splashScreenAnimationDuration) resourcesNode.appendChild(style) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt index c4fa63890..2e3276993 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/splash/DarkModeSplashScreenPatch.kt @@ -1,12 +1,8 @@ package app.revanced.patches.youtube.utils.fix.splash import app.revanced.patcher.patch.resourcePatch -import app.revanced.patches.youtube.utils.compatibility.Constants.YOUTUBE_PACKAGE_NAME import app.revanced.patches.youtube.utils.playservice.is_19_32_or_greater import app.revanced.patches.youtube.utils.playservice.versionCheckPatch -import app.revanced.patches.youtube.utils.settings.ResourceUtils.restoreOldSplashAnimationIncluded -import app.revanced.patches.youtube.utils.settings.ResourceUtils.youtubePackageName -import app.revanced.util.findElementByAttributeValueOrThrow import org.w3c.dom.Element /** @@ -23,57 +19,21 @@ val darkModeSplashScreenPatch = resourcePatch( ) { dependsOn(versionCheckPatch) - finalize { + execute { if (!is_19_32_or_greater) { - return@finalize + return@execute } - // GmsCore support included - if (youtubePackageName != YOUTUBE_PACKAGE_NAME) { - document("AndroidManifest.xml").use { document -> - val mainActivityElement = document.childNodes.findElementByAttributeValueOrThrow( - "android:name", - "com.google.android.apps.youtube.app.watchwhile.MainActivity", - ) - - mainActivityElement.setAttribute("android:launchMode", "singleTask") - } - } - - if (restoreOldSplashAnimationIncluded) { - document("res/values-night/styles.xml").use { document -> - val resourcesNode = document.getElementsByTagName("resources").item(0) as Element - val childNodes = resourcesNode.childNodes - - for (i in 0 until childNodes.length) { - val node = childNodes.item(i) as? Element ?: continue - val nodeAttributeName = node.getAttribute("name") - if (nodeAttributeName.startsWith("Theme.YouTube.Launcher")) { - val nodeAttributeParent = node.getAttribute("parent") - - val style = document.createElement("style") - style.setAttribute("name", "Theme.YouTube.Home") - style.setAttribute("parent", nodeAttributeParent) - - val windowItem = document.createElement("item") - windowItem.setAttribute("name", "android:windowBackground") - windowItem.textContent = "@color/yt_black1" - style.appendChild(windowItem) - - resourcesNode.removeChild(node) - resourcesNode.appendChild(style) - } - } - } - } else { - document("res/values-night-v27/styles.xml").use { document -> + arrayOf( + "values-night" to "@style/Base.V23.Theme.YouTube.Home", + "values-night-v27" to "@style/Base.V27.Theme.YouTube.Home", + ).forEach { (directory, parent) -> + document("res/$directory/styles.xml").use { document -> // Create a night mode specific override for the splash screen background. val style = document.createElement("style") style.setAttribute("name", "Theme.YouTube.Home") - style.setAttribute("parent", "@style/Base.V27.Theme.YouTube.Home") + style.setAttribute("parent", parent) - // Fix status and navigation bar showing white on some Android devices, - // such as SDK 28 Android 10 medium tablet. val colorSplashBackgroundColor = "@color/yt_black1" arrayOf( "android:navigationBarColor" to colorSplashBackgroundColor, From f19dd5402641caf05baeb9667366fa42650dd8dd Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:22:29 +0900 Subject: [PATCH 71/77] fix(YouTube - Hook download actions, Overlay buttons): `Queue manager` fails to identify brand account --- .../requests/InnerTubeRequestBody.kt | 10 ++ .../youtube/patches/utils/PlaylistPatch.java | 94 ++++++++++--------- .../utils/requests/CreatePlaylistRequest.kt | 45 +++++++-- .../utils/requests/DeletePlaylistRequest.kt | 23 +++-- .../utils/requests/EditPlaylistRequest.kt | 25 +++-- .../utils/requests/GetPlaylistsRequest.kt | 19 ++-- .../utils/requests/SavePlaylistRequest.kt | 24 +++-- .../youtube/utils/playlist/PlaylistPatch.kt | 6 +- 8 files changed, 165 insertions(+), 81 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRequestBody.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRequestBody.kt index 9e6154bbd..6e6a8c0d8 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRequestBody.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/innertube/requests/InnerTubeRequestBody.kt @@ -279,6 +279,7 @@ object InnerTubeRequestBody { route: CompiledRoute, clientType: YouTubeAppClient.ClientType, requestHeader: Map? = null, + dataSyncId: String? = null, connectTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, readTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, ) = getInnerTubeResponseConnectionFromRoute( @@ -288,6 +289,7 @@ object InnerTubeRequestBody { clientVersion = clientType.clientVersion, supportsCookies = clientType.supportsCookies, requestHeader = requestHeader, + dataSyncId = dataSyncId, connectTimeout = connectTimeout, readTimeout = readTimeout, ) @@ -297,6 +299,7 @@ object InnerTubeRequestBody { route: CompiledRoute, clientType: YouTubeWebClient.ClientType, requestHeader: Map? = null, + dataSyncId: String? = null, connectTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, readTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, ) = getInnerTubeResponseConnectionFromRoute( @@ -305,6 +308,7 @@ object InnerTubeRequestBody { clientId = clientType.id.toString(), clientVersion = clientType.clientVersion, requestHeader = requestHeader, + dataSyncId = dataSyncId, connectTimeout = connectTimeout, readTimeout = readTimeout, ) @@ -317,6 +321,7 @@ object InnerTubeRequestBody { clientVersion: String, supportsCookies: Boolean = true, requestHeader: Map? = null, + dataSyncId: String? = null, connectTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, readTimeout: Int = CONNECTION_TIMEOUT_MILLISECONDS, ): HttpURLConnection { @@ -348,6 +353,11 @@ object InnerTubeRequestBody { } } + // Used to identify brand accounts + if (dataSyncId != null && dataSyncId.isNotEmpty()) { + connection.setRequestProperty("X-Goog-PageId", dataSyncId) + } + return connection } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaylistPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaylistPatch.java index b02d81cd0..484ad319a 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaylistPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/PlaylistPatch.java @@ -1,5 +1,7 @@ package app.revanced.extension.youtube.patches.utils; +import static app.revanced.extension.shared.utils.StringRef.str; + import android.content.Context; import android.view.KeyEvent; import android.widget.LinearLayout; @@ -47,43 +49,52 @@ public class PlaylistPatch extends VideoUtils { private static Context mContext; private static volatile String authorization = ""; - private static volatile boolean isIncognito = false; + public static volatile String dataSyncId = ""; + public static volatile boolean isIncognito = false; private static volatile Map requestHeader; private static volatile String playlistId = ""; private static volatile String videoId = ""; - private static final String checkFailedAuth = - ResourceUtils.getString("revanced_queue_manager_check_failed_auth"); - private static final String checkFailedPlaylistId = - ResourceUtils.getString("revanced_queue_manager_check_failed_playlist_id"); - private static final String checkFailedQueue = - ResourceUtils.getString("revanced_queue_manager_check_failed_queue"); - private static final String checkFailedVideoId = - ResourceUtils.getString("revanced_queue_manager_check_failed_video_id"); - private static final String checkFailedGeneric = - ResourceUtils.getString("revanced_queue_manager_check_failed_generic"); + private static String checkFailedAuth; + private static String checkFailedPlaylistId; + private static String checkFailedQueue; + private static String checkFailedVideoId; + private static String checkFailedGeneric; - private static final String fetchFailedAdd = - ResourceUtils.getString("revanced_queue_manager_fetch_failed_add"); - private static final String fetchFailedCreate = - ResourceUtils.getString("revanced_queue_manager_fetch_failed_create"); - private static final String fetchFailedDelete = - ResourceUtils.getString("revanced_queue_manager_fetch_failed_delete"); - private static final String fetchFailedRemove = - ResourceUtils.getString("revanced_queue_manager_fetch_failed_remove"); - private static final String fetchFailedSave = - ResourceUtils.getString("revanced_queue_manager_fetch_failed_save"); + private static String fetchFailedAdd; + private static String fetchFailedCreate; + private static String fetchFailedDelete; + private static String fetchFailedRemove; + private static String fetchFailedSave; - private static final String fetchSucceededAdd = - ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_add"); - private static final String fetchSucceededCreate = - ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_create"); - private static final String fetchSucceededDelete = - ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_delete"); - private static final String fetchSucceededRemove = - ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_remove"); - private static final String fetchSucceededSave = - ResourceUtils.getString("revanced_queue_manager_fetch_succeeded_save"); + private static String fetchSucceededAdd; + private static String fetchSucceededCreate; + private static String fetchSucceededDelete; + private static String fetchSucceededRemove; + private static String fetchSucceededSave; + + static { + Context mContext = Utils.getContext(); + if (mContext != null && mContext.getResources() != null) { + checkFailedAuth = str("revanced_queue_manager_check_failed_auth"); + checkFailedPlaylistId = str("revanced_queue_manager_check_failed_playlist_id"); + checkFailedQueue = str("revanced_queue_manager_check_failed_queue"); + checkFailedVideoId = str("revanced_queue_manager_check_failed_video_id"); + checkFailedGeneric = str("revanced_queue_manager_check_failed_generic"); + + fetchFailedAdd = str("revanced_queue_manager_fetch_failed_add"); + fetchFailedCreate = str("revanced_queue_manager_fetch_failed_create"); + fetchFailedDelete = str("revanced_queue_manager_fetch_failed_delete"); + fetchFailedRemove = str("revanced_queue_manager_fetch_failed_remove"); + fetchFailedSave = str("revanced_queue_manager_fetch_failed_save"); + + fetchSucceededAdd = str("revanced_queue_manager_fetch_succeeded_add"); + fetchSucceededCreate = str("revanced_queue_manager_fetch_succeeded_create"); + fetchSucceededDelete = str("revanced_queue_manager_fetch_succeeded_delete"); + fetchSucceededRemove = str("revanced_queue_manager_fetch_succeeded_remove"); + fetchSucceededSave = str("revanced_queue_manager_fetch_succeeded_save"); + } + } @GuardedBy("itself") private static final BidiMap lastVideoIds = new DualHashBidiMap<>(); @@ -118,15 +129,6 @@ public class PlaylistPatch extends VideoUtils { } } - /** - * Injection point. - */ - public static void setIncognitoStatus(boolean incognito) { - if (QUEUE_MANAGER) { - isIncognito = incognito; - } - } - /** * Injection point. */ @@ -171,7 +173,7 @@ public class PlaylistPatch extends VideoUtils { * Invoked by extension. */ public static void prepareDialogBuilder(@NonNull String currentVideoId) { - if (authorization.isEmpty() || isIncognito) { + if (authorization.isEmpty() || (dataSyncId.isEmpty() && isIncognito)) { handleCheckError(checkFailedAuth); return; } @@ -217,7 +219,7 @@ public class PlaylistPatch extends VideoUtils { String currentVideoId = videoId; synchronized (lastVideoIds) { if (currentPlaylistId.isEmpty()) { // Queue is empty, create new playlist. - CreatePlaylistRequest.fetchRequestIfNeeded(currentVideoId, requestHeader); + CreatePlaylistRequest.fetchRequestIfNeeded(currentVideoId, requestHeader, dataSyncId); runOnMainThreadDelayed(() -> { CreatePlaylistRequest request = CreatePlaylistRequest.getRequestForVideoId(currentVideoId); if (request != null) { @@ -241,7 +243,7 @@ public class PlaylistPatch extends VideoUtils { }, 1000); } else { // Queue is not empty, add or remove video. String setVideoId = lastVideoIds.get(currentVideoId); - EditPlaylistRequest.fetchRequestIfNeeded(currentVideoId, currentPlaylistId, setVideoId, requestHeader); + EditPlaylistRequest.fetchRequestIfNeeded(currentVideoId, currentPlaylistId, setVideoId, requestHeader, dataSyncId); runOnMainThreadDelayed(() -> { EditPlaylistRequest request = EditPlaylistRequest.getRequestForVideoId(currentVideoId); @@ -286,7 +288,7 @@ public class PlaylistPatch extends VideoUtils { return; } try { - GetPlaylistsRequest.fetchRequestIfNeeded(currentPlaylistId, requestHeader); + GetPlaylistsRequest.fetchRequestIfNeeded(currentPlaylistId, requestHeader, dataSyncId); runOnMainThreadDelayed(() -> { GetPlaylistsRequest request = GetPlaylistsRequest.getRequestForPlaylistId(currentPlaylistId); if (request != null) { @@ -328,7 +330,7 @@ public class PlaylistPatch extends VideoUtils { handleCheckError(checkFailedPlaylistId); return; } - SavePlaylistRequest.fetchRequestIfNeeded(playlistId, libraryId, requestHeader); + SavePlaylistRequest.fetchRequestIfNeeded(playlistId, libraryId, requestHeader, dataSyncId); runOnMainThreadDelayed(() -> { SavePlaylistRequest request = SavePlaylistRequest.getRequestForLibraryId(libraryId); @@ -354,7 +356,7 @@ public class PlaylistPatch extends VideoUtils { return; } try { - DeletePlaylistRequest.fetchRequestIfNeeded(currentPlaylistId, requestHeader); + DeletePlaylistRequest.fetchRequestIfNeeded(currentPlaylistId, requestHeader, dataSyncId); runOnMainThreadDelayed(() -> { DeletePlaylistRequest request = DeletePlaylistRequest.getRequestForPlaylistId(currentPlaylistId); if (request != null) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt index 69ad16e98..6496c77c2 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/CreatePlaylistRequest.kt @@ -24,9 +24,14 @@ import java.util.concurrent.TimeoutException class CreatePlaylistRequest private constructor( private val videoId: String, private val requestHeader: Map, + private val dataSyncId: String, ) { private val future: Future> = Utils.submitOnBackgroundThread { - fetch(videoId, requestHeader) + fetch( + videoId, + requestHeader, + dataSyncId, + ) } val playlistId: Pair? @@ -75,11 +80,19 @@ class CreatePlaylistRequest private constructor( } @JvmStatic - fun fetchRequestIfNeeded(videoId: String, requestHeader: Map) { + fun fetchRequestIfNeeded( + videoId: String, + requestHeader: Map, + dataSyncId: String, + ) { Objects.requireNonNull(videoId) synchronized(cache) { if (!cache.containsKey(videoId)) { - cache[videoId] = CreatePlaylistRequest(videoId, requestHeader) + cache[videoId] = CreatePlaylistRequest( + videoId, + requestHeader, + dataSyncId, + ) } } } @@ -97,7 +110,8 @@ class CreatePlaylistRequest private constructor( private fun sendCreatePlaylistRequest( videoId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): JSONObject? { Objects.requireNonNull(videoId) @@ -112,6 +126,7 @@ class CreatePlaylistRequest private constructor( CREATE_PLAYLIST, clientType, requestHeader, + dataSyncId, ) val requestBody = createPlaylistRequestBody(videoId = videoId) @@ -143,7 +158,8 @@ class CreatePlaylistRequest private constructor( private fun sendSetVideoIdRequest( videoId: String, playlistId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): JSONObject? { Objects.requireNonNull(playlistId) @@ -157,7 +173,8 @@ class CreatePlaylistRequest private constructor( val connection = getInnerTubeResponseConnectionFromRoute( GET_SET_VIDEO_ID, clientType, - requestHeader + requestHeader, + dataSyncId, ) val requestBody = createApplicationRequestBody( @@ -232,13 +249,23 @@ class CreatePlaylistRequest private constructor( private fun fetch( videoId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): Pair? { - val createPlaylistJson = sendCreatePlaylistRequest(videoId, requestHeader) + val createPlaylistJson = sendCreatePlaylistRequest( + videoId, + requestHeader, + dataSyncId + ) if (createPlaylistJson != null) { val playlistId = parseCreatePlaylistResponse(createPlaylistJson) if (playlistId != null) { - val setVideoIdJson = sendSetVideoIdRequest(videoId, playlistId, requestHeader) + val setVideoIdJson = sendSetVideoIdRequest( + videoId, + playlistId, + requestHeader, + dataSyncId + ) if (setVideoIdJson != null) { val setVideoId = parseSetVideoIdResponse(setVideoIdJson) if (setVideoId != null) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt index 60675fe30..ea7ca60b2 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/DeletePlaylistRequest.kt @@ -22,11 +22,13 @@ import java.util.concurrent.TimeoutException class DeletePlaylistRequest private constructor( private val playlistId: String, private val requestHeader: Map, + private val dataSyncId: String, ) { private val future: Future = Utils.submitOnBackgroundThread { fetch( playlistId, requestHeader, + dataSyncId, ) } @@ -78,14 +80,16 @@ class DeletePlaylistRequest private constructor( @JvmStatic fun fetchRequestIfNeeded( playlistId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ) { Objects.requireNonNull(playlistId) synchronized(cache) { if (!cache.containsKey(playlistId)) { cache[playlistId] = DeletePlaylistRequest( playlistId, - requestHeader + requestHeader, + dataSyncId, ) } } @@ -104,7 +108,8 @@ class DeletePlaylistRequest private constructor( private fun sendRequest( playlistId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): JSONObject? { Objects.requireNonNull(playlistId) @@ -118,7 +123,8 @@ class DeletePlaylistRequest private constructor( val connection = getInnerTubeResponseConnectionFromRoute( DELETE_PLAYLIST, clientType, - requestHeader + requestHeader, + dataSyncId ) val requestBody = deletePlaylistRequestBody(playlistId) @@ -163,9 +169,14 @@ class DeletePlaylistRequest private constructor( private fun fetch( playlistId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): Boolean? { - val json = sendRequest(playlistId, requestHeader) + val json = sendRequest( + playlistId, + requestHeader, + dataSyncId, + ) if (json != null) { return parseResponse(json) } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt index 826b36b8a..a76277543 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/EditPlaylistRequest.kt @@ -25,6 +25,7 @@ class EditPlaylistRequest private constructor( private val playlistId: String, private val setVideoId: String?, private val requestHeader: Map, + private val dataSyncId: String, ) { private val future: Future = Utils.submitOnBackgroundThread { fetch( @@ -32,6 +33,7 @@ class EditPlaylistRequest private constructor( playlistId, setVideoId, requestHeader, + dataSyncId, ) } @@ -92,7 +94,8 @@ class EditPlaylistRequest private constructor( videoId: String, playlistId: String, setVideoId: String?, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ) { Objects.requireNonNull(videoId) synchronized(cache) { @@ -101,7 +104,8 @@ class EditPlaylistRequest private constructor( videoId, playlistId, setVideoId, - requestHeader + requestHeader, + dataSyncId, ) } } @@ -122,7 +126,8 @@ class EditPlaylistRequest private constructor( videoId: String, playlistId: String, setVideoId: String?, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): JSONObject? { Objects.requireNonNull(videoId) @@ -136,7 +141,8 @@ class EditPlaylistRequest private constructor( val connection = getInnerTubeResponseConnectionFromRoute( EDIT_PLAYLIST, clientType, - requestHeader + requestHeader, + dataSyncId ) val requestBody = editPlaylistRequestBody( @@ -199,9 +205,16 @@ class EditPlaylistRequest private constructor( videoId: String, playlistId: String, setVideoId: String?, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): String? { - val json = sendRequest(videoId, playlistId, setVideoId, requestHeader) + val json = sendRequest( + videoId, + playlistId, + setVideoId, + requestHeader, + dataSyncId, + ) if (json != null) { return parseResponse(json, StringUtils.isNotEmpty(setVideoId)) } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt index 5a57f00e2..94361f9ef 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/GetPlaylistsRequest.kt @@ -22,11 +22,13 @@ import java.util.concurrent.TimeoutException class GetPlaylistsRequest private constructor( private val playlistId: String, private val requestHeader: Map, + private val dataSyncId: String, ) { private val future: Future>> = Utils.submitOnBackgroundThread { fetch( playlistId, requestHeader, + dataSyncId, ) } @@ -78,14 +80,16 @@ class GetPlaylistsRequest private constructor( @JvmStatic fun fetchRequestIfNeeded( playlistId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ) { Objects.requireNonNull(playlistId) synchronized(cache) { if (!cache.containsKey(playlistId)) { cache[playlistId] = GetPlaylistsRequest( playlistId, - requestHeader + requestHeader, + dataSyncId, ) } } @@ -104,7 +108,8 @@ class GetPlaylistsRequest private constructor( private fun sendRequest( playlistId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): JSONObject? { Objects.requireNonNull(playlistId) @@ -118,7 +123,8 @@ class GetPlaylistsRequest private constructor( val connection = getInnerTubeResponseConnectionFromRoute( GET_PLAYLISTS, clientType, - requestHeader + requestHeader, + dataSyncId ) val requestBody = getPlaylistsRequestBody(playlistId) @@ -202,9 +208,10 @@ class GetPlaylistsRequest private constructor( private fun fetch( playlistId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): Array>? { - val json = sendRequest(playlistId, requestHeader) + val json = sendRequest(playlistId, requestHeader, dataSyncId) if (json != null) { return parseResponse(json) } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt index 58b737869..221dfc737 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/utils/requests/SavePlaylistRequest.kt @@ -23,12 +23,14 @@ class SavePlaylistRequest private constructor( private val playlistId: String, private val libraryId: String, private val requestHeader: Map, + private val dataSyncId: String, ) { private val future: Future = Utils.submitOnBackgroundThread { fetch( playlistId, libraryId, requestHeader, + dataSyncId, ) } @@ -81,14 +83,16 @@ class SavePlaylistRequest private constructor( fun fetchRequestIfNeeded( playlistId: String, libraryId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ) { Objects.requireNonNull(playlistId) synchronized(cache) { cache[libraryId] = SavePlaylistRequest( playlistId, libraryId, - requestHeader + requestHeader, + dataSyncId, ) } } @@ -107,7 +111,8 @@ class SavePlaylistRequest private constructor( private fun sendRequest( playlistId: String, libraryId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): JSONObject? { Objects.requireNonNull(playlistId) Objects.requireNonNull(libraryId) @@ -122,7 +127,8 @@ class SavePlaylistRequest private constructor( val connection = getInnerTubeResponseConnectionFromRoute( EDIT_PLAYLIST, clientType, - requestHeader + requestHeader, + dataSyncId ) val requestBody = savePlaylistRequestBody(libraryId, playlistId) @@ -168,9 +174,15 @@ class SavePlaylistRequest private constructor( private fun fetch( playlistId: String, libraryId: String, - requestHeader: Map + requestHeader: Map, + dataSyncId: String, ): Boolean? { - val json = sendRequest(playlistId, libraryId, requestHeader) + val json = sendRequest( + playlistId, + libraryId, + requestHeader, + dataSyncId, + ) if (json != null) { return parseResponse(json) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt index 60c2f821d..ac0f91aa2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt @@ -34,8 +34,10 @@ val playlistPatch = bytecodePatch( execute { // In Incognito mode, sending a request always seems to fail. accountIdentityFingerprint.methodOrThrow().addInstructions( - 1, - "invoke-static/range {p4 .. p4}, $EXTENSION_CLASS_DESCRIPTOR->setIncognitoStatus(Z)V" + 1, """ + sput-object p3, $EXTENSION_CLASS_DESCRIPTOR->dataSyncId:Ljava/lang/String; + sput-boolean p4, $EXTENSION_CLASS_DESCRIPTOR->isIncognito:Z + """ ) // Get the header to use the auth token. From 9342e1f7d272728a7ecdba6f5a312946af368811 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:23:49 +0900 Subject: [PATCH 72/77] fix(Reddit - Disable screenshot popup): Restart dialog is missing --- .../java/app/revanced/extension/reddit/settings/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/reddit/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/reddit/settings/Settings.java index 2efc2eb37..eee9c0ae1 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/reddit/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/reddit/settings/Settings.java @@ -13,7 +13,7 @@ public class Settings extends BaseSettings { public static final BooleanSetting HIDE_NEW_POST_ADS = new BooleanSetting("revanced_hide_new_post_ads", TRUE, true); // Layout - public static final BooleanSetting DISABLE_SCREENSHOT_POPUP = new BooleanSetting("revanced_disable_screenshot_popup", TRUE); + public static final BooleanSetting DISABLE_SCREENSHOT_POPUP = new BooleanSetting("revanced_disable_screenshot_popup", TRUE, true); public static final BooleanSetting HIDE_CHAT_BUTTON = new BooleanSetting("revanced_hide_chat_button", FALSE, true); public static final BooleanSetting HIDE_CREATE_BUTTON = new BooleanSetting("revanced_hide_create_button", FALSE, true); public static final BooleanSetting HIDE_DISCOVER_BUTTON = new BooleanSetting("revanced_hide_discover_button", FALSE, true); From 036e3dad11298d363f533b8222a37e767636c712 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:24:10 +0900 Subject: [PATCH 73/77] feat(Translations): Update translation --- .../youtube/translations/ar/strings.xml | 134 ++++++++++++++++-- .../youtube/translations/el-rGR/strings.xml | 9 +- .../youtube/translations/fr-rFR/strings.xml | 25 ++-- .../youtube/translations/ja-rJP/strings.xml | 4 +- .../youtube/translations/ko-rKR/strings.xml | 8 +- .../youtube/translations/ru-rRU/strings.xml | 6 +- .../youtube/translations/zh-rTW/strings.xml | 25 ++-- 7 files changed, 164 insertions(+), 47 deletions(-) diff --git a/patches/src/main/resources/youtube/translations/ar/strings.xml b/patches/src/main/resources/youtube/translations/ar/strings.xml index bca339310..fead0585a 100644 --- a/patches/src/main/resources/youtube/translations/ar/strings.xml +++ b/patches/src/main/resources/youtube/translations/ar/strings.xml @@ -53,6 +53,116 @@ تم حفظ قائمة الانتظار بنجاح في \'%s\'. لغة RVX لغة التطبيق + "الأمهرية +አማርኛ" + "العربية +العربية" + "الأذربيجانية +Azərbaycan" + "البيلاروسية +беларуская" + "البلغارية +Български" + "البنغالية +বাংলা" + "الكاتالونية +Català" + "التشيكية +Čeština" + "الدانماركية +Dansk" + "الألمانية +Deutsch" + "اليونانية +Ελληνικά" + "الإنجليزية +English" + "الأسبانية +Español" + "الإستونية +Eesti" + "الفارسية +فارسی" + "الفنلندية +Suomi" + "الفرنسية +Français" + "الغوجاراتية +ગુજરાતી" + "العبرية +עברי" + "الهندية +हिन्दी" + "الكرواتية +Hrvatski" + "المجرية +Magyar" + "الإندونيسية +Indonesia" + "الإيطالية +Italiano" + "اليابانية +日本語" + "الكازاخستانية +Қазақ тілі" + "الكورية +한국어" + "الليتوانية +Lietuvių" + "اللاتفية +Latviešu" + "المقدونية +Македонски" + "المنغولية +Монгол" + "الماراثية +मराठी" + "الملايو +Melayu" + "البورمية +ဗမာ" + "الهولندية +Nederlands" + "أوديا +ଓଡ଼ିଆ" + "البنجابية +ਪੰਜਾਬੀ" + "البولندية +Polski" + "البرتغالية +Português" + "الرومانية +Română" + "الروسية +Русский" + "السلوفاكية +Slovenčina" + "الألبانية +Shqip" + "السلوفينية +Slovenščina" + "الصربية +Српски" + "السويدية +Svenska" + "السواحيلية +Kiswahili" + "التاميلية +தமிழ்" + "التيلجو +తెలుగు" + "التايلاندية +ไทย" + "التركية +Türkçe" + "الأوكرانية +Українська" + "الأردية +اردو" + "الفيتنامية +Tiếng Việt" + "الصينية +中文" الإعلانات إخفاء لافتة شاشة المتجر النهائية @@ -256,34 +366,34 @@ قائمة بأسماء القائمة المنبثقة المراد تصفيتها، مفصولة بسطور جديدة. عامل تصفية الفيديو - إخفاء الفيديوهات بواسطة الكلمات الرئيسية أو المشاهدة. + إخفاء الفيديوهات بواسطة الكلمات المفتاحية أو المشاهدة. - تصفية الكلمات الرئيسية - إخفاء التعليقات بواسطة الكلمات الرئيسية + تصفية الكلمات المفتاحية + إخفاء التعليقات بواسطة الكلمات المفتاحية يتم تصفية التعليقات. لا يتم تصفية التعليقات. - إخفاء فيديوهات الصفحة الرئيسية بواسطة الكلمات الرئيسية + إخفاء فيديوهات الصفحة الرئيسية بواسطة الكلمات المفتاحية يتم تصفية الفيديوهات في موجز الصفحة الرئيسية. لا يتم تصفية الفيديوهات في موجز الصفحة الرئيسية. - إخفاء نتائج البحث عن طريق الكلمات الرئيسية + إخفاء نتائج البحث عن طريق الكلمات المفتاحية يتم تصفية نتائج البحث. لا يتم تصفية نتائج البحث. - إخفاء الفيديوهات الخاصة بالاشتراك عن طريق الكلمات الرئيسية + إخفاء الفيديوهات الخاصة بالاشتراك عن طريق الكلمات المفتاحية يتم تصفية الفيديوهات في موجز الاشتراكات. لا يتم تصفية الفيديوهات في موجز الاشتراكات. - الكلمات الرئيسية المراد إخفاؤها - "الكلمات والعبارات الرئيسية التي يجب إخفاؤها، مفصولة بأسطر جديدة. + الكلمات المفتاحية المراد إخفاؤها + "الكلمات والعبارات المفتاحية التي يجب إخفاؤها، مفصولة بأسطر جديدة. -يمكن أن تكون الكلمات الرئيسية عبارة عن أسماء قنوات أو أي نص يظهر في عناوين الفيديو. +يمكن أن تكون الكلمات المفتاحية عبارة عن أسماء قنوات أو أي نص يظهر في عناوين الفيديو. يجب إدخال الكلمات التي تحتوي على أحرف كبيرة في المنتصف باستخدام الأحرف الكبيرة (على سبيل المثال: iPhone، TikTok، LeBlanc)." - حول تصفية الكلمات الرئيسية - "الصفحة الرئيسية / الاشتراكات / يتم تصفية نتائج البحث لإخفاء المحتوى الذي يطابق عبارات الكلمات الرئيسية. + حول تصفية الكلمات المفتاحية + "الصفحة الرئيسية / الاشتراكات / يتم تصفية نتائج البحث لإخفاء المحتوى الذي يطابق عبارات الكلمات المفتاحية. القيود: • لا يمكن إخفاء فيديوهات Shorts حسب اسم القناة. • قد لا تكون بعض مكونات واجهة المستخدم مخفية. - • قد لا يؤدي البحث عن كلمة رئيسية إلى ظهور أية نتائج." + • قد لا يؤدي البحث عن كلمة مفتاحية إلى ظهور أية نتائج." مطابقة الكلمات كاملة سيؤدي وضع علامة اقتباس مزدوجة حول كلمة رئيسية/عبارة إلى منع التطابقات الجزئية لعناوين الفيديو وأسماء القنوات.<br><br>على سبيل المثال،<br><b>\"ai\"</b> سيخفي الفيديو: <b>How does AI work?</b><br>ولكن لن يخفي: <b>What does fair use mean?</b> لا يمكن استخدام الكلمة الرئيسية: %s. diff --git a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml index 12a04b89a..335baf89e 100644 --- a/patches/src/main/resources/youtube/translations/el-rGR/strings.xml +++ b/patches/src/main/resources/youtube/translations/el-rGR/strings.xml @@ -494,10 +494,10 @@ Playlists "Αφαίρεση του παραθύρου προειδοποίησης ηλικιακού περιορισμού. Αυτό δεν παρακάμπτει τον ηλικιακό περιορισμό, απλά τον αποδέχεται αυτόματα." Αλλαγή ενέργειας πατήματος δακτυλίου ζωντανής μετάδοσης - "Το κανάλι ανοίγει όταν πατιέται ο δακτύλιος ζωντανής μετάδοσης. + "Ανοίγει το κανάλι όταν πατιέται ο δακτύλιος ζωντανής μετάδοσης. Περιορισμός: Όταν πρόκειται για ζωντανή μετάδοση Shorts και η λειτουργία «Άνοιγμα των Shorts στην κανονική οθόνη αναπαραγωγής» είναι ενεργοποιημένη, δεν ανοίγει το κανάλι." - Η ζωντανή μετάδοση ανοίγει όταν πατιέται ο δακτύλιος ζωντανής μετάδοσης. + Ανοίγει η ζωντανή μετάδοση όταν πατιέται ο δακτύλιος ζωντανής μετάδοσης. Αλλαγή μορφής διάταξης Προεπιλογή Τηλέφωνο @@ -1334,7 +1334,7 @@ Playlists Απενεργοποίηση κινήσεων αριθμών Οι αριθμοί δεν κινούνται αυξανόμενοι εκθετικά. Οι αριθμοί κινούνται αυξανόμενοι εκθετικά. - Σύνοψη βίντεο παραγμένου με τεχνητή νοημοσύνη + Σύνοψη βίντεο που δημιουργήθηκε από AI Κρυμμένη. Εμφανίζεται. Ενότητα ιδιοτήτων @@ -1750,7 +1750,8 @@ Playlists "Παράλειψη προφόρτωσης στην αρχή του βίντεο, ώστε να γίνει άμεση εφαρμογή της προεπιλεγμένης ποιότητας. • Κατά την έναρξη του βίντεο, υπάρχει μια καθυστέρηση περίπου 0.3 δευτερολέπτων. -• Δεν εφαρμόζεται σε βίντεο HDR, ζωντανές μεταδόσεις ή βίντεο μικρότερα από 15 δευτερόλεπτα." +• Δεν εφαρμόζεται σε βίντεο HDR, ζωντανές μεταδόσεις ή βίντεο μικρότερα από 15 δευτερόλεπτα. +• Η λειτουργία «Παραποίηση δεδομένων ροής» παραλείπει επίσης από μόνη της την προφόρτωση, οπότε αν είναι ενεργοποιημένη τότε αυτή η λειτουργία δε χρειάζεται." Η ενεργοποίηση αυτής της ρύθμισης μπορεί να προκαλέσει προβλήματα αναπαραγωγής βίντεο. Εμφάνιση μηνύματος κατά την παράλειψη Εμφανίζεται μήνυμα στο κάτω μέρος της οθόνης. diff --git a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml index 8873c2d86..810163c3d 100644 --- a/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml +++ b/patches/src/main/resources/youtube/translations/fr-rFR/strings.xml @@ -1725,7 +1725,7 @@ Info : Afficher un message Un message sera affiché lorsque vous modifiez la qualité vidéo des Shorts par défaut. Un message ne sera pas affiché lorsque vous modifiez la qualité vidéo des Shorts par défaut. - Mobiles + mobile Wi-Fi Qualité par défaut %1$s modifiée en : %2$s. Qualité des Shorts %1$s modifiée en : %2$s. @@ -1737,8 +1737,9 @@ Info : "Passe le tampon préchargé au début de la vidéo pour appliquer immédiatement la qualité vidéo. Info : -• Au démarrage de la vidéo, il y a un délai d'environ 0.3 seconde. -• Ne s'applique pas aux vidéos HDR, aux diffusions en direct et aux vidéos de moins de 15 secondes." +• Au démarrage de la vidéo, il y a un délai d'environ 0.3 secondes. +• Ne s'applique pas aux vidéos HDR, aux diffusions en direct et aux vidéos de moins de 15 secondes. +• Le paramètre 'Falsifier les données de lecture en direct' supprime également les tampons préchargés, ce paramètre n'est donc pas nécessaire si vous l'utilisez." Activer ce paramètre peut entraîner des problèmes de lecture vidéo. Affic. message lors du passage Le message est affiché. @@ -1747,8 +1748,7 @@ Info : "Falsifie les dimensions de l'appareil à la valeur maximale. Info : -• Une qualité élevée peut être déverrouillée sur certaines vidéos qui nécessitent des dimensions d'appareil élevées, mais pas toutes les vidéos. - +• La haute qualité peut être débloquée sur certaines vidéos qui nécessitent des dimensions d'appareil élevées, mais pas sur toutes les vidéos. • Ce paramètre n'est pas disponible si l'option 'Falsifier les données de lecture en direct' est activée." Désactiver la vitesse de lecture pour la musique @@ -2084,7 +2084,8 @@ Cliquez sur le bouton Continuer et autorisez les modifications d'optimisations." • La désactivation forcée des pistes audio automatiques n'est pas disponible. • Les vidéos pour enfants peuvent ne pas être lues en cas de déconnexion ou en mode incognito." • Des plages entières d\'ASN/adresses IP peuvent être bloquées par le serveur. - "• Les films ou vidéos payantes peut ne pas être lus. + "• Le volume stable n'es pas disponible. +• Les films ou vidéos payantes peut ne pas être lus. • Les vidéos pour enfants peuvent ne pas être lues en cas de déconnexion ou en mode incognito." Utiliser le client iOS "Le client iOS a été ajouté aux clients disponibles. @@ -2102,19 +2103,19 @@ UTILISEZ À VOS PROPRES RISQUES !" "Activer ceci peut améliorer la durée de vie de la batterie et résoudre les problèmes de lecture saccadée. AVC a une résolution maximale de 1080p, le codec audio Opus n'est pas disponible et la lecture vidéo utilisera plus de données internet que VP9 ou AV1." - Passer le chiffrement de réponse Onesie - "Passer le chiffrement de réponse Onesie + Ignorer le chiffrement de réponse Onesie + "Ignorer le chiffrement de réponse Onesie -• Résout un nouveau type de problème de lecture que certains utilisateurs rencontrent. +• Corrige un nouveau type de problème de lecture rencontré par certains utilisateurs. • Le codec AV1 peut ne pas être disponible." - "Ne pas passer le chiffrement de réponse Onesie + "Ne pas ignorer le cryptage de la réponse d'Onesie. -• Certains utilisateurs peuvent rencontrer un nouveau type de problème de lecture." +- Certains utilisateurs peuvent rencontrer un nouveau type de problème de lecture." Afficher dans \'Statistiques pour les nerds\' Le client utilisé pour récupérer les données de lecture en direct est affiché dans \'Statistiques pour les nerds\'. Le client utilisé pour récupérer les données de lecture en direct est masqué dans \'Statistiques pour les nerds\'. Langue de la piste audio par défaut pour VR - Ne peut pas récupérer les flux des clients. + Impossible de récupérer les flux du client. Vous n\'êtes peut-être pas connecté. PoToken / VisitorData diff --git a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml index 0084f6416..8bd5b2d92 100644 --- a/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml +++ b/patches/src/main/resources/youtube/translations/ja-rJP/strings.xml @@ -1619,7 +1619,7 @@ DeArrow の詳細については、ここをタップしてください。" - VP9 コーデックを無効化します。\n\n注意: \n・最大解像度は 1080p です。\n・動画を再生する際には VP9 コーデックよりも多くの通信量を消費します。\n・HDR 再生を可能にするために、HDR 動画では引き続き VP9 コーデックが使用されます。 + VP9 コーデックを無効化します。\n\n注意: \n・最大解像度は 1080p です。\n・動画を再生する際には VP9 コーデックよりも多くの通信量を消費します。\n・HDR 動画では引き続き VP9 コーデックが使用されます。 AV1 コーデックを置換 AV1 コーデックを VP9 コーデックに置き換えます。 @@ -1666,7 +1666,7 @@ DeArrow の詳細については、ここをタップしてください。"デフォルトの画質を変更した際にトーストが表示されるようにします。 モバイルデータ通信使用時のデフォルト画質 Wi-Fi 使用時のデフォルト画質 - ショートの画質変更を保存 + ショートの画質変更を記憶 現在の設定: 画質の変更はすべてのショートに適用されます。 現在の設定: 画質の変更は現在のショートにのみ適用されます。 トーストを表示 diff --git a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml index 24c5abefe..782ea8c39 100644 --- a/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml +++ b/patches/src/main/resources/youtube/translations/ko-rKR/strings.xml @@ -17,7 +17,7 @@ 외부 다운로더 앱 경고 "%1$s 가 설치되어 있지 않습니다. -웹사이트에서 %2$s 를 다운로드하세요." +웹사이트에서 %2$s 를 다운로드하고 설치하세요." %s가 설치되지 않았습니다. 설치하세요. 현재 재생목록에 추가 현재 재생목록에 추가하고 현재 재생목록 열기 @@ -33,7 +33,9 @@ 시스템 네비게이션 바에서 '뒤로 가기' 버튼을 길게 눌러서 현재 재생목록 관리자를 실행할 수도 있습니다. -이 기능은 아직 개발 중이므로 대부분의 기능이 작동하지 않을 수 있습니다." +이 기능은 아직 개발 중이므로 대부분의 기능이 작동하지 않을 수 있습니다. + +디버깅 목적으로만 사용하세요." 로그인이 요구됨 현재 재생목록 관리자를 실행할 수 없습니다. (%s) 재생목록을 식별할 수 없음 @@ -1673,7 +1675,7 @@ DeArrow에 대해 자세히 알아보려면 여기를 누르세요." • 재생 문제가 없는 계정이거나 VR 또는 iOS 클라이언트는 AV1 코덱까지 지원되기 때문에 2160p까지 재생될 수 있고, 나머지 클라이언트는 VP9 코덱까지만 지원되기 때문에 1080p까지 재생될 수 있습니다. • AVC 코덱 동영상을 재생했을 경우에는 VP9보다 더 많은 데이터가 사용되오니 주의하세요. • HDR 동영상을 재생하기 위해 HDR 동영상에서는 VP9 또는 AV1 코덱이 사용됩니다." - VP9 코덱을 활성화합니다.\n• 예전에 업로드된 동영상에서 일부 화질 값들이 제거되어 360p와 1080p(Premium 기능)만 선택할 수 있거나 화질 메뉴를 선택할 수 없을 수 있습니다. + VP9 코덱을 활성화합니다.\n• 예전에 업로드된 동영상에서 일부 화질 값들이 제거되어 360p와 1080p(Premium 기능)만 선택할 수 있거나 화질 메뉴를 선택하지 못할 수 있습니다. AV1 코덱 변경하기 AV1 코덱을 VP9 코덱으로 변경합니다. diff --git a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml index 1783fb89f..e87a1c83a 100644 --- a/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml +++ b/patches/src/main/resources/youtube/translations/ru-rRU/strings.xml @@ -2091,7 +2091,7 @@ Shorts (Без автора)" "iOS (Устаревшая)" - "iOS + "iOS TV (Необходим вход)" Эффекты от подмены "• Меню аудио дорожки отсутствует. @@ -2112,7 +2112,7 @@ Shorts ИСПОЛЬЗУЙТЕ НА СВОЙ СТРАХ И РИСК!" Принудительно iOS, AVC (H.264) - Принудительно AVC (H.264) включено. + Принудительно AVC (H.264) включен. Принудительно AVC (H.264) отключено. "Включение может: - улучшить время автономной работы @@ -2127,7 +2127,7 @@ Shorts "Пропуск отключен. • Могут быть проблемы просмотра, у некоторых пользователей." - Статистике для сисадминов + Статистика для сисадминов Клиент потоковых данных отображается в Статистике для сисадминов. Клиент потоковых данных скрыт в Статистике для сисадминов. Язык аудио потока по умолчанию VR diff --git a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml index cd535e0a9..290bfe2cc 100644 --- a/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml +++ b/patches/src/main/resources/youtube/translations/zh-rTW/strings.xml @@ -315,9 +315,9 @@ 隱藏相關影片 在相關影片中隱藏 在相關影片中顯示 - 在搜尋結果中隱藏 - 搜尋結果中已隱藏 - 在搜尋結果中顯示 + 在搜尋結果中隱蔵 + 隱藏在搜尋結果中。 + 顯示在搜尋結果中。 頻道簡介 隱藏或顯示頻道簡介中的元件 @@ -382,15 +382,18 @@ 訂閱影片的關鍵字篩選器已啟用 訂閱影片的關鍵字篩選器已停用 要隱藏的關鍵詞 - "需要隱藏的關鍵字和詞組,請用新行分隔。 -具有中間大寫字母的單詞必須依照大小寫輸入(例如:iPhone、TikTok、LeBlanc)。" + "要隱藏的關鍵字和短語,用換行符分隔。 + +關鍵字可以是頻道名稱或影片標題中顯示的任何文字。 + +中間有大寫字母的詞必須保持原有大小寫(例如:iPhone, TikTok, LeBlanc)。" 關於關鍵詞篩選 - "搜尋、首頁、訂閱和留言會篩選隱藏包含關鍵字詞的內容 + "搜尋、首頁、訂閱和留言會篩選隱藏包含關鍵字詞的內容。 限制: - • 部分 Shorts 可能不會隱藏 - • 部分介面元件可能不會隱藏 - • 搜尋關鍵字可能不會顯示任何結果" + • 短影音無法透過頻道名稱隱藏。 + • 部分介面元件可能無法隱藏。 + • 搜尋關鍵字可能不會顯示任何結果。" 匹配整個單字 用雙引號將關鍵字/短語括起來將防止影片標題和頻道名稱部分匹配。<br></b>例如,<br><b>\"ai\"</b>將隱藏影片:<b>人工智慧是如何運作的?</b><br> 但不會隱藏: <b>合理使用是什麼意思?</b> 無效的關鍵字。不能使用:「%s」作為篩選器 @@ -1387,8 +1390,8 @@ 隱藏在搜尋結果中。 顯示在搜尋結果中。 在訂閱內容動態中隱藏 - 在訂閱內容動態中隱藏。 - 在訂閱內容動態中顯示。 + 隱藏在訂閱內容動態中。 + 顯示在訂閱內容動態中。 在觀看歷史中隱藏 在觀看歷史中隱藏 在觀看歷史中顯示 From f249e88ce8a69482c2dad5db2b815b8745897118 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 18:24:50 +0900 Subject: [PATCH 74/77] bump 5.6.1-dev.5 --- gradle.properties | 2 +- patches.json | 3 +-- patches/api/patches.api | 7 +++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/gradle.properties b/gradle.properties index ad20bee5d..c7e4d7d87 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official kotlin.jvm.target.validation.mode = IGNORE -version = 5.6.1-dev.4 +version = 5.6.1-dev.5 diff --git a/patches.json b/patches.json index 35d5a705a..71bfc80d9 100644 --- a/patches.json +++ b/patches.json @@ -1046,8 +1046,7 @@ "description": "Adds an option to disable the popup that appears when taking a screenshot.", "use": true, "dependencies": [ - "Settings for Reddit", - "ResourcePatch" + "Settings for Reddit" ], "compatiblePackages": { "com.reddit.frontpage": [ diff --git a/patches/api/patches.api b/patches/api/patches.api index 40b6e9036..11f542538 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -458,10 +458,6 @@ public final class app/revanced/patches/reddit/utils/extension/SharedExtensionPa public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } -public final class app/revanced/patches/reddit/utils/resourceid/SharedResourceIdPatchKt { - public static final fun getScreenShotShareBanner ()J -} - public final class app/revanced/patches/reddit/utils/settings/SettingsPatchKt { public static final fun getSettingsPatch ()Lapp/revanced/patcher/patch/ResourcePatch; public static final fun is_2024_26_or_greater ()Z @@ -875,6 +871,7 @@ public final class app/revanced/patches/youtube/player/seekbar/SeekbarComponents public final class app/revanced/patches/youtube/shorts/components/FingerprintsKt { public static final fun indexOfAddLiveHeaderElementsContainerInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;)I + public static final fun indexOfDismissInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;)I } public final class app/revanced/patches/youtube/shorts/components/ShortsComponentPatchKt { @@ -1038,6 +1035,7 @@ public final class app/revanced/patches/youtube/utils/playservice/VersionCheckPa public static final fun is_19_04_or_greater ()Z public static final fun is_19_05_or_greater ()Z public static final fun is_19_09_or_greater ()Z + public static final fun is_19_11_or_greater ()Z public static final fun is_19_15_or_greater ()Z public static final fun is_19_16_or_greater ()Z public static final fun is_19_17_or_greater ()Z @@ -1056,6 +1054,7 @@ public final class app/revanced/patches/youtube/utils/playservice/VersionCheckPa public static final fun is_19_44_or_greater ()Z public static final fun is_19_46_or_greater ()Z public static final fun is_19_49_or_greater ()Z + public static final fun is_19_50_or_greater ()Z public static final fun is_20_02_or_greater ()Z public static final fun is_20_03_or_greater ()Z public static final fun is_20_05_or_greater ()Z From 28ff781786a0da816b03cc2e6370012e6c4c9c4d Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 19:13:14 +0900 Subject: [PATCH 75/77] chore: Lint code --- .../spoof/requests/StreamingDataRequest.kt | 6 +- .../patches/video/PlaybackSpeedPatch.java | 2 +- .../extension/youtube/settings/Settings.java | 18 ++-- .../sponsorblock/SponsorBlockUtils.java | 1 - .../sponsorblock/objects/SegmentCategory.java | 32 ++++++- .../views/SwipeControlsOverlayLayout.kt | 85 ++++++++++++++----- .../connectivity/wifi/spoof/SpoofWifiPatch.kt | 16 +++- .../edgetoedge/EdgeToEdgeDisplayPatch.kt | 3 +- .../components/AccountComponentsPatch.kt | 5 +- .../patches/music/ads/general/AdsPatch.kt | 3 +- .../music/layout/header/ChangeHeaderPatch.kt | 3 +- .../misc/watchhistory/WatchHistoryPatch.kt | 4 +- .../NavigationBarComponentsPatch.kt | 9 +- .../music/player/components/Fingerprints.kt | 2 +- .../components/PlayerComponentsPatch.kt | 3 +- .../utils/fix/client/SpoofClientPatch.kt | 2 +- .../utils/resourceid/SharedResourceIdPatch.kt | 6 +- .../utils/videotype/VideoTypeHookPatch.kt | 3 +- .../PlayerResponseMethodHookPatch.kt | 3 +- .../navigation/NavigationButtonsPatch.kt | 10 ++- .../subredditdialog/SubRedditDialogPatch.kt | 3 +- .../patches/shared/ads/BaseAdsPatch.kt | 2 +- .../patches/shared/gms/Fingerprints.kt | 2 - .../patches/shared/gms/GmsCoreSupportPatch.kt | 6 +- .../shared/mapping/ResourceMappingPatch.kt | 1 - .../translations/BaseTranslationsPatch.kt | 3 +- .../feed/components/FeedComponentsPatch.kt | 9 +- .../livering/OpenChannelOfLiveAvatarPatch.kt | 20 +++-- .../snackbar/SnackBarComponentsPatch.kt | 6 +- .../actionbuttons/ShortsActionButtonsPatch.kt | 12 ++- .../branding/icon/CustomBrandingIconPatch.kt | 14 +-- .../youtube/layout/theme/SharedThemePatch.kt | 2 + .../misc/accessibility/AccessibilityPatch.kt | 6 +- .../BackgroundPlaybackPatch.kt | 20 +++-- .../player/action/ActionButtonsPatch.kt | 24 ++++-- .../youtube/player/components/Fingerprints.kt | 2 +- .../components/PlayerComponentsPatch.kt | 16 ++-- .../youtube/player/fullscreen/Fingerprints.kt | 1 - .../player/miniplayer/general/Fingerprints.kt | 1 + .../miniplayer/general/MiniplayerPatch.kt | 3 +- .../overlaybuttons/OverlayButtonsPatch.kt | 8 +- .../youtube/player/seekbar/Fingerprints.kt | 1 - .../player/seekbar/SeekbarComponentsPatch.kt | 8 +- .../youtube/shorts/components/Fingerprints.kt | 1 - .../shorts/components/ShortsComponentPatch.kt | 23 +++-- .../utils/fix/cairo/CairoFragmentPatch.kt | 2 +- .../youtube/utils/fix/cairo/Fingerprints.kt | 4 +- .../fullscreen/FullscreenButtonHookPatch.kt | 6 +- .../youtube/utils/playertype/Fingerprints.kt | 2 +- .../youtube/utils/playlist/PlaylistPatch.kt | 8 +- .../utils/resourceid/SharedResourceIdPatch.kt | 42 ++++++--- .../video/playback/VideoPlaybackPatch.kt | 6 +- .../PlaybackStartDescriptorPatch.kt | 3 +- .../PlayerResponseMethodHookPatch.kt | 3 +- .../kotlin/app/revanced/util/FilesCompat.kt | 2 +- 55 files changed, 336 insertions(+), 152 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt index 3c992b00b..cd8f717cb 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/shared/patches/spoof/requests/StreamingDataRequest.kt @@ -240,7 +240,11 @@ class StreamingDataRequest private constructor( } handleConnectionError(str("revanced_spoof_streaming_data_failed_forbidden"), null, true) - handleConnectionError(str("revanced_spoof_streaming_data_failed_forbidden_suggestion"), null, true) + handleConnectionError( + str("revanced_spoof_streaming_data_failed_forbidden_suggestion"), + null, + true + ) return null } } diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java index e731c0b75..58897b35d 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/video/PlaybackSpeedPatch.java @@ -178,7 +178,7 @@ public class PlaybackSpeedPatch { } }, TOAST_DELAY_MILLISECONDS); } - } else if (!isShorts){ + } else if (!isShorts) { lastSelectedPlaybackSpeed = playbackSpeed; } } catch (Exception ex) { diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java index da959b002..1b0bed356 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/settings/Settings.java @@ -637,31 +637,31 @@ public class Settings extends BaseSettings { public static final FloatSetting SB_CATEGORY_SPONSOR_OPACITY = new FloatSetting("sb_sponsor_opacity", 0.8f); public static final StringSetting SB_CATEGORY_SELF_PROMO = new StringSetting("sb_selfpromo", SKIP_AUTOMATICALLY.reVancedKeyValue); public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color", "#FFFF00"); - public static final FloatSetting SB_CATEGORY_SELF_PROMO_OPACITY = new FloatSetting("sb_selfpromo_opacity", 0.8f); + public static final FloatSetting SB_CATEGORY_SELF_PROMO_OPACITY = new FloatSetting("sb_selfpromo_opacity", 0.8f); public static final StringSetting SB_CATEGORY_INTERACTION = new StringSetting("sb_interaction", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue); public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color", "#CC00FF"); - public static final FloatSetting SB_CATEGORY_INTERACTION_OPACITY = new FloatSetting("sb_interaction_opacity", 0.8f); + public static final FloatSetting SB_CATEGORY_INTERACTION_OPACITY = new FloatSetting("sb_interaction_opacity", 0.8f); public static final StringSetting SB_CATEGORY_HIGHLIGHT = new StringSetting("sb_highlight", MANUAL_SKIP.reVancedKeyValue); public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color", "#FF1684"); - public static final FloatSetting SB_CATEGORY_HIGHLIGHT_OPACITY = new FloatSetting("sb_highlight_opacity", 0.8f); + public static final FloatSetting SB_CATEGORY_HIGHLIGHT_OPACITY = new FloatSetting("sb_highlight_opacity", 0.8f); public static final StringSetting SB_CATEGORY_INTRO = new StringSetting("sb_intro", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue); public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color", "#00FFFF"); - public static final FloatSetting SB_CATEGORY_INTRO_OPACITY = new FloatSetting("sb_intro_opacity", 0.8f); + public static final FloatSetting SB_CATEGORY_INTRO_OPACITY = new FloatSetting("sb_intro_opacity", 0.8f); public static final StringSetting SB_CATEGORY_OUTRO = new StringSetting("sb_outro", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue); public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color", "#0202ED"); - public static final FloatSetting SB_CATEGORY_OUTRO_OPACITY = new FloatSetting("sb_outro_opacity", 0.8f); + public static final FloatSetting SB_CATEGORY_OUTRO_OPACITY = new FloatSetting("sb_outro_opacity", 0.8f); public static final StringSetting SB_CATEGORY_PREVIEW = new StringSetting("sb_preview", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue); public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color", "#008FD6"); - public static final FloatSetting SB_CATEGORY_PREVIEW_OPACITY = new FloatSetting("sb_preview_opacity", 0.8f); + public static final FloatSetting SB_CATEGORY_PREVIEW_OPACITY = new FloatSetting("sb_preview_opacity", 0.8f); public static final StringSetting SB_CATEGORY_FILLER = new StringSetting("sb_filler", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue); public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color", "#7300FF"); - public static final FloatSetting SB_CATEGORY_FILLER_OPACITY = new FloatSetting("sb_filler_opacity", 0.8f); + public static final FloatSetting SB_CATEGORY_FILLER_OPACITY = new FloatSetting("sb_filler_opacity", 0.8f); public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC = new StringSetting("sb_music_offtopic", MANUAL_SKIP.reVancedKeyValue); public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color", "#FF9900"); - public static final FloatSetting SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY = new FloatSetting("sb_music_offtopic_opacity", 0.8f); + public static final FloatSetting SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY = new FloatSetting("sb_music_offtopic_opacity", 0.8f); public static final StringSetting SB_CATEGORY_UNSUBMITTED = new StringSetting("sb_unsubmitted", SKIP_AUTOMATICALLY.reVancedKeyValue); public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color", "#FFFFFF"); - public static final FloatSetting SB_CATEGORY_UNSUBMITTED_OPACITY = new FloatSetting("sb_unsubmitted_opacity", 1.0f); + public static final FloatSetting SB_CATEGORY_UNSUBMITTED_OPACITY = new FloatSetting("sb_unsubmitted_opacity", 1.0f); // SB Setting not exported public static final LongSetting SB_LAST_VIP_CHECK = new LongSetting("sb_last_vip_check", 0L, false, false); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/SponsorBlockUtils.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/SponsorBlockUtils.java index 3d4da44e9..bee1d6a98 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/SponsorBlockUtils.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/SponsorBlockUtils.java @@ -37,7 +37,6 @@ import app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockViewController /** * Not thread safe. All fields/methods must be accessed from the main thread. - * */ public class SponsorBlockUtils { private static final int LOCKED_COLOR = Color.parseColor("#FFC83D"); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/objects/SegmentCategory.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/objects/SegmentCategory.java index fd8360a95..c16fbe3d2 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/objects/SegmentCategory.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/sponsorblock/objects/SegmentCategory.java @@ -1,7 +1,36 @@ package app.revanced.extension.youtube.sponsorblock.objects; import static app.revanced.extension.shared.utils.StringRef.sf; -import static app.revanced.extension.youtube.settings.Settings.*; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_FILLER; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_FILLER_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_FILLER_OPACITY; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_HIGHLIGHT; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_HIGHLIGHT_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_HIGHLIGHT_OPACITY; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTERACTION; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTERACTION_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTERACTION_OPACITY; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTRO; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTRO_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTRO_OPACITY; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_MUSIC_OFFTOPIC; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_MUSIC_OFFTOPIC_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_OUTRO; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_OUTRO_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_OUTRO_OPACITY; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_PREVIEW; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_PREVIEW_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_PREVIEW_OPACITY; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SELF_PROMO; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SELF_PROMO_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SELF_PROMO_OPACITY; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SPONSOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SPONSOR_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SPONSOR_OPACITY; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_UNSUBMITTED; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_UNSUBMITTED_COLOR; +import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_UNSUBMITTED_OPACITY; import android.graphics.Color; import android.graphics.Paint; @@ -56,7 +85,6 @@ public enum SegmentCategory { SB_CATEGORY_MUSIC_OFFTOPIC, SB_CATEGORY_MUSIC_OFFTOPIC_COLOR, SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY), UNSUBMITTED("unsubmitted", StringRef.empty, sf("revanced_sb_skip_button_unsubmitted"), sf("revanced_sb_skipped_unsubmitted"), SB_CATEGORY_UNSUBMITTED, SB_CATEGORY_UNSUBMITTED_COLOR, SB_CATEGORY_UNSUBMITTED_OPACITY); - ; private static final StringRef skipSponsorTextCompact = sf("revanced_sb_skip_button_compact"); private static final StringRef skipSponsorTextCompactHighlight = sf("revanced_sb_skip_button_compact_highlight"); diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt index edc936b75..f3ba568b5 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt @@ -145,8 +145,10 @@ class SwipeControlsOverlayLayout( addView(feedbackTextView) // get icons scaled, assuming square icons val iconHeight = round(feedbackTextView.lineHeight * .8).toInt() - autoBrightnessIcon = getDrawable("revanced_ic_sc_brightness_auto", iconHeight, iconHeight) - manualBrightnessIcon = getDrawable("revanced_ic_sc_brightness_manual", iconHeight, iconHeight) + autoBrightnessIcon = + getDrawable("revanced_ic_sc_brightness_auto", iconHeight, iconHeight) + manualBrightnessIcon = + getDrawable("revanced_ic_sc_brightness_manual", iconHeight, iconHeight) mutedVolumeIcon = getDrawable("revanced_ic_sc_volume_mute", iconHeight, iconHeight) normalVolumeIcon = getDrawable("revanced_ic_sc_volume_normal", iconHeight, iconHeight) } @@ -186,11 +188,18 @@ class SwipeControlsOverlayLayout( /** * Displays the progress bar with the appropriate value, icon, and type (brightness or volume). */ - private fun showFeedbackView(value: String, progress: Int, max: Int, icon: Drawable, isBrightness: Boolean) { + private fun showFeedbackView( + value: String, + progress: Int, + max: Int, + icon: Drawable, + isBrightness: Boolean + ) { feedbackHideHandler.removeCallbacks(feedbackHideCallback) feedbackHideHandler.postDelayed(feedbackHideCallback, config.overlayShowTimeoutMillis) - val viewToShow = if (config.isCircularProgressBar) circularProgressView else horizontalProgressView + val viewToShow = + if (config.isCircularProgressBar) circularProgressView else horizontalProgressView viewToShow.apply { setProgress(progress, max, value, isBrightness) this.icon = icon @@ -241,7 +250,13 @@ class SwipeControlsOverlayLayout( brightnessValue < 75 -> highBrightnessIcon else -> fullBrightnessIcon } - showFeedbackView("$brightnessValue%", brightnessValue, 100, icon, isBrightness = true) + showFeedbackView( + "$brightnessValue%", + brightnessValue, + 100, + icon, + isBrightness = true + ) } else { showFeedbackView("${round(brightness).toInt()}%", manualBrightnessIcon) } @@ -274,7 +289,12 @@ abstract class AbstractProgressView( ) : View(context, attrs, defStyleAttr) { // Combined paint creation function for both fill and stroke styles - private fun createPaint(color: Int, style: Paint.Style = Paint.Style.FILL, strokeCap: Paint.Cap = Paint.Cap.BUTT, strokeWidth: Float = 0f) = Paint(Paint.ANTI_ALIAS_FLAG).apply { + private fun createPaint( + color: Int, + style: Paint.Style = Paint.Style.FILL, + strokeCap: Paint.Cap = Paint.Cap.BUTT, + strokeWidth: Float = 0f + ) = Paint(Paint.ANTI_ALIAS_FLAG).apply { this.style = style this.color = color this.strokeCap = strokeCap @@ -282,13 +302,18 @@ abstract class AbstractProgressView( } // Initialize paints - val backgroundPaint = createPaint(overlayBackgroundOpacity, style = Paint.Style.FILL) - val progressPaint = createPaint(overlayProgressColor, style = Paint.Style.STROKE, strokeCap = Paint.Cap.ROUND, strokeWidth = 20f) + val backgroundPaint = createPaint(overlayBackgroundOpacity, style = Paint.Style.FILL) + val progressPaint = createPaint( + overlayProgressColor, + style = Paint.Style.STROKE, + strokeCap = Paint.Cap.ROUND, + strokeWidth = 20f + ) val fillBackgroundPaint = createPaint(overlayFillBackgroundPaint, style = Paint.Style.FILL) - val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { - color = overlayTextColor + val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { + color = overlayTextColor textAlign = Paint.Align.CENTER - textSize = 40f // Can adjust based on need + textSize = 40f // Can adjust based on need } protected var progress = 0 @@ -337,11 +362,11 @@ class CircularProgressView( init { textPaint.textSize = 40f // Override default text size for circular view - progressPaint.strokeWidth = 20f + progressPaint.strokeWidth = 20f fillBackgroundPaint.strokeWidth = 20f - progressPaint.strokeCap = Paint.Cap.ROUND + progressPaint.strokeCap = Paint.Cap.ROUND fillBackgroundPaint.strokeCap = Paint.Cap.BUTT - progressPaint.style = Paint.Style.STROKE + progressPaint.style = Paint.Style.STROKE fillBackgroundPaint.style = Paint.Style.STROKE } @@ -352,7 +377,12 @@ class CircularProgressView( rectF.set(20f, 20f, size - 20f, size - 20f) canvas.drawOval(rectF, fillBackgroundPaint) // Draw the outer ring. - canvas.drawCircle(width / 2f, height / 2f, size / 3, backgroundPaint) // Draw the inner circle. + canvas.drawCircle( + width / 2f, + height / 2f, + size / 3, + backgroundPaint + ) // Draw the inner circle. // Select the paint for drawing based on whether it's brightness or volume. val sweepAngle = (progress.toFloat() / maxProgress) * 360 @@ -399,13 +429,13 @@ class HorizontalProgressView( ) { private val iconSize = 60f - private val padding = 40f + private val padding = 40f init { - textPaint.textSize = 36f // Override default text size for horizontal view + textPaint.textSize = 36f // Override default text size for horizontal view progressPaint.strokeWidth = 0f - progressPaint.strokeCap = Paint.Cap.BUTT - progressPaint.style = Paint.Style.FILL + progressPaint.strokeCap = Paint.Cap.BUTT + progressPaint.style = Paint.Style.FILL fillBackgroundPaint.style = Paint.Style.FILL } @@ -428,7 +458,15 @@ class HorizontalProgressView( if (!overlayShowOverlayMinimalStyle) { canvas.drawRoundRect(0f, 0f, width, height, cornerRadius, cornerRadius, backgroundPaint) } else { - canvas.drawRoundRect(minimalStartX, 0f, minimalStartX + minimalElementWidth, height, cornerRadius, cornerRadius, backgroundPaint) + canvas.drawRoundRect( + minimalStartX, + 0f, + minimalStartX + minimalElementWidth, + height, + cornerRadius, + cornerRadius, + backgroundPaint + ) } if (!overlayShowOverlayMinimalStyle) { @@ -466,7 +504,12 @@ class HorizontalProgressView( padding + minimalStartX } val iconY = height / 2 - iconSize / 2 - it.setBounds(iconX.toInt(), iconY.toInt(), (iconX + iconSize).toInt(), (iconY + iconSize).toInt()) + it.setBounds( + iconX.toInt(), + iconY.toInt(), + (iconX + iconSize).toInt(), + (iconY + iconSize).toInt() + ) it.draw(canvas) } diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatch.kt index 3758030cd..354e91f3e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/connectivity/wifi/spoof/SpoofWifiPatch.kt @@ -152,7 +152,10 @@ private enum class MethodCall( RegisterNetworkCallback1( "Landroid/net/ConnectivityManager;", "registerNetworkCallback", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"), + arrayOf( + "Landroid/net/NetworkRequest;", + "Landroid/net/ConnectivityManager\$NetworkCallback;" + ), "V", ), RegisterNetworkCallback2( @@ -174,13 +177,20 @@ private enum class MethodCall( RequestNetwork1( "Landroid/net/ConnectivityManager;", "requestNetwork", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;"), + arrayOf( + "Landroid/net/NetworkRequest;", + "Landroid/net/ConnectivityManager\$NetworkCallback;" + ), "V", ), RequestNetwork2( "Landroid/net/ConnectivityManager;", "requestNetwork", - arrayOf("Landroid/net/NetworkRequest;", "Landroid/net/ConnectivityManager\$NetworkCallback;", "I"), + arrayOf( + "Landroid/net/NetworkRequest;", + "Landroid/net/ConnectivityManager\$NetworkCallback;", + "I" + ), "V", ), RequestNetwork3( diff --git a/patches/src/main/kotlin/app/revanced/patches/all/misc/display/edgetoedge/EdgeToEdgeDisplayPatch.kt b/patches/src/main/kotlin/app/revanced/patches/all/misc/display/edgetoedge/EdgeToEdgeDisplayPatch.kt index a3ae247a1..9fdb3fd84 100644 --- a/patches/src/main/kotlin/app/revanced/patches/all/misc/display/edgetoedge/EdgeToEdgeDisplayPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/all/misc/display/edgetoedge/EdgeToEdgeDisplayPatch.kt @@ -19,7 +19,8 @@ val edgeToEdgeDisplayPatch = resourcePatch( // Instead, it checks compileSdkVersion and prints a warning. try { val manifestElement = document.getNode("manifest") as Element - val compileSdkVersion = Integer.parseInt(manifestElement.getAttribute("android:compileSdkVersion")) + val compileSdkVersion = + Integer.parseInt(manifestElement.getAttribute("android:compileSdkVersion")) if (compileSdkVersion < 35) { printWarn("This app may not be forcing edge to edge display (compileSdkVersion: $compileSdkVersion)") } diff --git a/patches/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt index 2ac49689b..f5a9970cd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/account/components/AccountComponentsPatch.kt @@ -88,7 +88,7 @@ val accountComponentsPatch = bytecodePatch( } // account switcher - val textViewField = with ( + val textViewField = with( channelHandleFingerprint .methodOrThrow(namesInactiveAccountThumbnailSizeFingerprint) ) { @@ -117,7 +117,8 @@ val accountComponentsPatch = bytecodePatch( .forEach { index -> val insertIndex = index - 1 if (!hook && getInstruction(insertIndex).opcode == Opcode.IF_NEZ) { - val insertRegister = getInstruction(insertIndex).registerA + val insertRegister = + getInstruction(insertIndex).registerA addInstructions( insertIndex, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/music/ads/general/AdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/ads/general/AdsPatch.kt index 23df8ddbd..84381b787 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/ads/general/AdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/ads/general/AdsPatch.kt @@ -115,7 +115,8 @@ val adsPatch = bytecodePatch( .methodOrThrow(getPremiumDialogParentFingerprint) .apply { val setContentViewIndex = indexOfSetContentViewInstruction(this) - val dialogInstruction = getInstruction(setContentViewIndex) + val dialogInstruction = + getInstruction(setContentViewIndex) val dialogRegister = dialogInstruction.registerC val viewRegister = dialogInstruction.registerD diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt index 7d0b38f5a..3ae23745c 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/header/ChangeHeaderPatch.kt @@ -206,7 +206,8 @@ val changeHeaderPatch = resourcePatch( printWarn(warnings) } - val isLegacyLogoExists = get("res").resolve("drawable-xxhdpi").resolve("ytm_logo.png").exists() + val isLegacyLogoExists = + get("res").resolve("drawable-xxhdpi").resolve("ytm_logo.png").exists() if (is_7_27_or_greater && isLegacyLogoExists) { document("res/layout/signin_fragment.xml").use { document -> document.doRecursively node@{ node -> diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/watchhistory/WatchHistoryPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/watchhistory/WatchHistoryPatch.kt index fdc321bca..9eb30851d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/watchhistory/WatchHistoryPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/watchhistory/WatchHistoryPatch.kt @@ -1,13 +1,13 @@ package app.revanced.patches.music.misc.watchhistory import app.revanced.patcher.patch.bytecodePatch -import app.revanced.patches.shared.trackingurlhook.hookWatchHistory -import app.revanced.patches.shared.trackingurlhook.trackingUrlHookPatch import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE import app.revanced.patches.music.utils.patch.PatchList.WATCH_HISTORY import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.addPreferenceWithIntent import app.revanced.patches.music.utils.settings.settingsPatch +import app.revanced.patches.shared.trackingurlhook.hookWatchHistory +import app.revanced.patches.shared.trackingurlhook.trackingUrlHookPatch @Suppress("unused") val watchHistoryPatch = bytecodePatch( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt index e4b459e25..8cc05af21 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/navigation/components/NavigationBarComponentsPatch.kt @@ -124,14 +124,17 @@ val navigationBarComponentsPatch = bytecodePatch( opcode == Opcode.IGET_OBJECT && getReference()?.type == "Ljava/lang/String;" } - val browseIdReference = getInstruction(browseIdIndex).reference as FieldReference + val browseIdReference = + getInstruction(browseIdIndex).reference as FieldReference val fieldName = browseIdReference.name val componentIndex = indexOfFirstInstructionOrThrow(stringIndex) { opcode == Opcode.IGET_OBJECT && getReference()?.toString() == browseIdReference.toString() } - val browseIdRegister = getInstruction(componentIndex).registerA - val componentRegister = getInstruction(componentIndex).registerB + val browseIdRegister = + getInstruction(componentIndex).registerA + val componentRegister = + getInstruction(componentIndex).registerB val enumIndex = it.patternMatch!!.startIndex + 3 val enumRegister = getInstruction(enumIndex).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt index 20921e3c4..be66489ad 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/player/components/Fingerprints.kt @@ -54,7 +54,7 @@ internal val engagementPanelHeightFingerprint = legacyFingerprint( parameters = emptyList(), customFingerprint = { method, _ -> AccessFlags.FINAL.isSet(method.accessFlags) && - method.containsLiteralInstruction(1) && + method.containsLiteralInstruction(1) && method.indexOfFirstInstruction { opcode == Opcode.INVOKE_VIRTUAL && getReference()?.name == "booleanValue" diff --git a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt index a14bb20e7..cbc3ceffe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/player/components/PlayerComponentsPatch.kt @@ -747,7 +747,8 @@ val playerComponentsPatch = bytecodePatch( getInstruction(bottomSheetBehaviorIndex).registerD val getFieldIndex = bottomSheetBehaviorIndex - 2 - val getFieldReference = getInstruction(getFieldIndex).reference + val getFieldReference = + getInstruction(getFieldIndex).reference val getFieldInstruction = getInstruction(getFieldIndex) addInstructionsWithLabels( diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/fix/client/SpoofClientPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/fix/client/SpoofClientPatch.kt index 1cc9eb807..2a77ff5d3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/fix/client/SpoofClientPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/fix/client/SpoofClientPatch.kt @@ -22,7 +22,6 @@ import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus import app.revanced.patches.music.utils.settings.addPreferenceWithIntent import app.revanced.patches.music.utils.settings.addSwitchPreference import app.revanced.patches.music.utils.settings.settingsPatch -import app.revanced.patches.shared.spoof.blockrequest.blockRequestPatch import app.revanced.patches.shared.createPlayerRequestBodyWithModelFingerprint import app.revanced.patches.shared.customspeed.customPlaybackSpeedPatch import app.revanced.patches.shared.extension.Constants.PATCHES_PATH @@ -31,6 +30,7 @@ import app.revanced.patches.shared.indexOfBrandInstruction import app.revanced.patches.shared.indexOfManufacturerInstruction import app.revanced.patches.shared.indexOfModelInstruction import app.revanced.patches.shared.indexOfReleaseInstruction +import app.revanced.patches.shared.spoof.blockrequest.blockRequestPatch import app.revanced.util.findMethodOrThrow import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall import app.revanced.util.fingerprint.matchOrThrow diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt index 3e7d4187b..7d0682188 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/resourceid/SharedResourceIdPatch.kt @@ -142,7 +142,8 @@ internal val sharedResourceIdPatch = resourcePatch( endButtonsContainer = getResourceId(ID, "end_buttons_container") floatingLayout = getResourceId(ID, "floating_layout") historyMenuItem = getResourceId(ID, "history_menu_item") - inlineTimeBarAdBreakMarkerColor = getResourceId(COLOR, "inline_time_bar_ad_break_marker_color") + inlineTimeBarAdBreakMarkerColor = + getResourceId(COLOR, "inline_time_bar_ad_break_marker_color") inlineTimeBarProgressColor = getResourceId(COLOR, "inline_time_bar_progress_color") interstitialsContainer = getResourceId(ID, "interstitials_container") isTablet = getResourceId(BOOL, "is_tablet") @@ -156,7 +157,8 @@ internal val sharedResourceIdPatch = resourcePatch( modernDialogBackground = getResourceId(DRAWABLE, "modern_dialog_background") musicNotifierShelf = getResourceId(LAYOUT, "music_notifier_shelf") musicTasteBuilderShelf = getResourceId(LAYOUT, "music_tastebuilder_shelf") - namesInactiveAccountThumbnailSize = getResourceId(DIMEN, "names_inactive_account_thumbnail_size") + namesInactiveAccountThumbnailSize = + getResourceId(DIMEN, "names_inactive_account_thumbnail_size") offlineSettingsMenuItem = getResourceId(ID, "offline_settings_menu_item") playerOverlayChip = getResourceId(ID, "player_overlay_chip") playerViewPager = getResourceId(ID, "player_view_pager") diff --git a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt index bc0ec4167..dc4643d26 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/utils/videotype/VideoTypeHookPatch.kt @@ -25,7 +25,8 @@ val videoTypeHookPatch = bytecodePatch( videoTypeFingerprint.methodOrThrow(videoTypeParentFingerprint).apply { val getEnumIndex = indexOfGetEnumInstruction(this) - val enumClass = (getInstruction(getEnumIndex).reference as MethodReference).definingClass + val enumClass = + (getInstruction(getEnumIndex).reference as MethodReference).definingClass val referenceIndex = indexOfFirstInstructionOrThrow(getEnumIndex) { opcode == Opcode.SGET_OBJECT && getReference()?.type == enumClass diff --git a/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/PlayerResponseMethodHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/PlayerResponseMethodHookPatch.kt index 85e51a62b..647b9cc2b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/PlayerResponseMethodHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/video/playerresponse/PlayerResponseMethodHookPatch.kt @@ -71,7 +71,8 @@ val playerResponseMethodHookPatch = bytecodePatch( val beforeVideoIdHooks = hooks.filterIsInstance().asReversed() val videoIdHooks = hooks.filterIsInstance().asReversed() - val videoIdAndPlaylistIdHooks = hooks.filterIsInstance().asReversed() + val videoIdAndPlaylistIdHooks = + hooks.filterIsInstance().asReversed() val afterVideoIdHooks = hooks.filterIsInstance().asReversed() // Add the hooks in this specific order as they insert instructions at the beginning of the method. diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt index 473e2498d..4ab992ec7 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/navigation/NavigationButtonsPatch.kt @@ -56,7 +56,8 @@ val navigationButtonsPatch = bytecodePatch( if (bottomNavScreenFingerprint.resolvable()) { val bottomNavScreenMutableClass = with(bottomNavScreenFingerprint.methodOrThrow()) { val startIndex = indexOfGetDimensionPixelSizeInstruction(this) - val targetIndex = indexOfFirstInstructionOrThrow(startIndex, Opcode.NEW_INSTANCE) + val targetIndex = + indexOfFirstInstructionOrThrow(startIndex, Opcode.NEW_INSTANCE) val targetReference = getInstruction(targetIndex).reference.toString() @@ -65,7 +66,9 @@ val navigationButtonsPatch = bytecodePatch( ?: throw ClassNotFoundException("Failed to find class $targetReference") } - bottomNavScreenOnGlobalLayoutFingerprint.second.matchOrNull(bottomNavScreenMutableClass) + bottomNavScreenOnGlobalLayoutFingerprint.second.matchOrNull( + bottomNavScreenMutableClass + ) ?.let { it.method.apply { val startIndex = it.patternMatch!!.startIndex @@ -82,7 +85,8 @@ val navigationButtonsPatch = bytecodePatch( // Legacy method. bottomNavScreenHandlerFingerprint.methodOrThrow().apply { val targetIndex = indexOfGetItemsInstruction(this) + 1 - val targetRegister = getInstruction(targetIndex).registerA + val targetRegister = + getInstruction(targetIndex).registerA addInstructions( targetIndex + 1, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt index 7d51cb4a0..ccd7e4064 100644 --- a/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/reddit/layout/subredditdialog/SubRedditDialogPatch.kt @@ -42,7 +42,8 @@ val subRedditDialogPatch = bytecodePatch( .apply { listOfIsLoggedInInstruction(this) .forEach { index -> - val register = getInstruction(index + 1).registerA + val register = + getInstruction(index + 1).registerA addInstructions( index + 2, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/ads/BaseAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/ads/BaseAdsPatch.kt index 55f2354d3..16c749ce0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/ads/BaseAdsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/ads/BaseAdsPatch.kt @@ -62,7 +62,7 @@ fun baseAdsPatch( ) } - val getAdvertisingIdMethod = with (advertisingIdFingerprint.methodOrThrow()) { + val getAdvertisingIdMethod = with(advertisingIdFingerprint.methodOrThrow()) { val getAdvertisingIdIndex = indexOfGetAdvertisingIdInstruction(this) getWalkerMethod(getAdvertisingIdIndex) } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/gms/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/gms/Fingerprints.kt index 952b0c350..1e79c58e2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/gms/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/gms/Fingerprints.kt @@ -6,8 +6,6 @@ import app.revanced.util.indexOfFirstInstruction import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.Method -import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.StringReference import com.android.tools.smali.dexlib2.util.MethodUtil diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/gms/GmsCoreSupportPatch.kt index 0a5d12a9a..9fb601010 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/gms/GmsCoreSupportPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/gms/GmsCoreSupportPatch.kt @@ -83,9 +83,9 @@ fun gmsCoreSupportPatch( key = "gmsCoreVendorGroupId", default = "app.revanced", values = - mapOf( - "ReVanced" to "app.revanced", - ), + mapOf( + "ReVanced" to "app.revanced", + ), title = "GmsCore vendor group ID", description = "The vendor's group ID for GmsCore.", required = true, diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt index 4e881a0e8..03c4b24af 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/mapping/ResourceMappingPatch.kt @@ -1,6 +1,5 @@ package app.revanced.patches.shared.mapping -import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.resourcePatch import org.w3c.dom.Element diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt index 82ca978e6..39e251e22 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/translations/BaseTranslationsPatch.kt @@ -147,7 +147,8 @@ fun ResourcePatchContext.baseTranslationsPatch( val length = text.length if (!text.endsWith("DEFAULT") && length >= 2 && - text.subSequence(length - 2, length) !in filteredAppLanguages) { + text.subSequence(length - 2, length) !in filteredAppLanguages + ) { nodesToRemove.add(item) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt index 655606d54..736e1d580 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/feed/components/FeedComponentsPatch.kt @@ -262,8 +262,10 @@ val feedComponentsPatch = bytecodePatch( val insertIndex = indexOfBufferParserInstruction(this) if (is_19_46_or_greater) { - val objectIndex = indexOfFirstInstructionReversedOrThrow(insertIndex, Opcode.IGET_OBJECT) - val objectRegister = getInstruction(objectIndex).registerA + val objectIndex = + indexOfFirstInstructionReversedOrThrow(insertIndex, Opcode.IGET_OBJECT) + val objectRegister = + getInstruction(objectIndex).registerA addInstructionsWithLabels( insertIndex, """ @@ -275,7 +277,8 @@ val feedComponentsPatch = bytecodePatch( ) } else { val objectIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_OBJECT) - val objectRegister = getInstruction(objectIndex).registerA + val objectRegister = + getInstruction(objectIndex).registerA val jumpIndex = it.patternMatch!!.startIndex addInstructionsWithLabels( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt index cb105e27d..fa987061f 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/livering/OpenChannelOfLiveAvatarPatch.kt @@ -90,7 +90,8 @@ val openChannelOfLiveAvatarPatch = bytecodePatch( ) val playbackStartIndex = indexOfPlaybackStartDescriptorInstruction(this) + 1 - val playbackStartRegister = getInstruction(playbackStartIndex).registerA + val playbackStartRegister = + getInstruction(playbackStartIndex).registerA val mapIndex = indexOfFirstInstructionOrThrow(playbackStartIndex) { val reference = getReference() @@ -169,15 +170,24 @@ val openChannelOfLiveAvatarPatch = bytecodePatch( val playbackStartIndex = indexOfFirstInstructionOrThrow { getReference()?.returnType == PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR } - val mapIndex = indexOfFirstInstructionReversedOrThrow(playbackStartIndex, Opcode.IPUT) + val mapIndex = + indexOfFirstInstructionReversedOrThrow(playbackStartIndex, Opcode.IPUT) val mapRegister = getInstruction(mapIndex).registerA - val playbackStartRegister = getInstruction(playbackStartIndex + 1).registerA - val videoIdRegister = getInstruction(playbackStartIndex).registerC + val playbackStartRegister = + getInstruction(playbackStartIndex + 1).registerA + val videoIdRegister = + getInstruction(playbackStartIndex).registerC addInstructionsWithLabels( playbackStartIndex + 2, """ move-object/from16 v$mapRegister, p2 - ${fetchChannelIdInstructions(playbackStartRegister, mapRegister, videoIdRegister)} + ${ + fetchChannelIdInstructions( + playbackStartRegister, + mapRegister, + videoIdRegister + ) + } """ ) } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt index 83821d0e9..1ae0ee983 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/snackbar/SnackBarComponentsPatch.kt @@ -80,7 +80,8 @@ private val snackBarComponentsBytecodePatch = bytecodePatch( bottomUiContainerThemeFingerprint.matchOrThrow().let { it.method.apply { val darkThemeIndex = it.patternMatch!!.startIndex + 2 - val darkThemeReference = getInstruction(darkThemeIndex).reference.toString() + val darkThemeReference = + getInstruction(darkThemeIndex).reference.toString() implementation!!.instructions .withIndex() @@ -91,7 +92,8 @@ private val snackBarComponentsBytecodePatch = bytecodePatch( .map { (index, _) -> index } .reversed() .forEach { index -> - val appThemeIndex = indexOfFirstInstructionReversedOrThrow(index, Opcode.MOVE_RESULT_OBJECT) + val appThemeIndex = + indexOfFirstInstructionReversedOrThrow(index, Opcode.MOVE_RESULT_OBJECT) val appThemeRegister = getInstruction(appThemeIndex).registerA val darkThemeRegister = diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/actionbuttons/ShortsActionButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/actionbuttons/ShortsActionButtonsPatch.kt index af1a960b9..6cb122b1d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/actionbuttons/ShortsActionButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/actionbuttons/ShortsActionButtonsPatch.kt @@ -86,7 +86,11 @@ val shortsActionButtonsPatch = resourcePatch( // Some directory is missing in the bundles. if (inputStreamForLegacy != null && fromFileResolved.exists()) { - Files.copy(inputStreamForLegacy, fromFileResolved.toPath(), StandardCopyOption.REPLACE_EXISTING) + Files.copy( + inputStreamForLegacy, + fromFileResolved.toPath(), + StandardCopyOption.REPLACE_EXISTING + ) } if (is_19_36_or_greater) { @@ -95,7 +99,11 @@ val shortsActionButtonsPatch = resourcePatch( // Some directory is missing in the bundles. if (inputStreamForNew != null && toFileResolved.exists()) { - Files.copy(inputStreamForNew, toFileResolved.toPath(), StandardCopyOption.REPLACE_EXISTING) + Files.copy( + inputStreamForNew, + toFileResolved.toPath(), + StandardCopyOption.REPLACE_EXISTING + ) } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt index d9d8d93b8..1ccc3e575 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/icon/CustomBrandingIconPatch.kt @@ -249,7 +249,10 @@ val customBrandingIconPatch = resourcePatch( style.setAttribute("parent", nodeAttributeParent) val splashScreenAnimatedIcon = document.createElement("item") - splashScreenAnimatedIcon.setAttribute("name", "android:windowSplashScreenAnimatedIcon") + splashScreenAnimatedIcon.setAttribute( + "name", + "android:windowSplashScreenAnimatedIcon" + ) splashScreenAnimatedIcon.textContent = "@drawable/avd_anim" // Deprecated in Android 13+ @@ -258,10 +261,11 @@ val customBrandingIconPatch = resourcePatch( "name", "android:windowSplashScreenAnimationDuration" ) - splashScreenAnimationDuration.textContent = if (appIcon.startsWith("revancify")) - "1500" - else - "1000" + splashScreenAnimationDuration.textContent = + if (appIcon.startsWith("revancify")) + "1500" + else + "1000" style.appendChild(splashScreenAnimatedIcon) style.appendChild(splashScreenAnimationDuration) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/SharedThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/SharedThemePatch.kt index a27467bcd..cdee030cd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/SharedThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/SharedThemePatch.kt @@ -61,8 +61,10 @@ val sharedThemePatch = resourcePatch( 0 -> when (nodeAttributeName) { "Base.Theme.YouTube.Launcher.Dark", "Base.Theme.YouTube.Launcher.Cairo.Dark" -> "@color/yt_black1" + "Base.Theme.YouTube.Launcher.Light", "Base.Theme.YouTube.Launcher.Cairo.Light" -> "@color/yt_white1" + else -> "null" } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/accessibility/AccessibilityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/accessibility/AccessibilityPatch.kt index cf0098362..8a2fd8dde 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/accessibility/AccessibilityPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/accessibility/AccessibilityPatch.kt @@ -32,8 +32,10 @@ val accessibilityPatch = bytecodePatch( .methods .first { method -> method.name == "" } .apply { - val lifecycleObserverIndex = indexOfFirstInstructionReversedOrThrow(Opcode.NEW_INSTANCE) - val lifecycleObserverClass = getInstruction(lifecycleObserverIndex).reference.toString() + val lifecycleObserverIndex = + indexOfFirstInstructionReversedOrThrow(Opcode.NEW_INSTANCE) + val lifecycleObserverClass = + getInstruction(lifecycleObserverIndex).reference.toString() findMethodOrThrow(lifecycleObserverClass) { accessFlags == AccessFlags.PUBLIC or AccessFlags.FINAL && diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt index c6380be34..4865bfbc1 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt @@ -85,17 +85,19 @@ val backgroundPlaybackPatch = bytecodePatch( backgroundPlaybackManagerCairoFragmentPrimaryFingerprint, backgroundPlaybackManagerCairoFragmentSecondaryFingerprint ).forEach { fingerprint -> - fingerprint.matchOrThrow(backgroundPlaybackManagerCairoFragmentParentFingerprint).let { - it.method.apply { - val insertIndex = it.patternMatch!!.startIndex + 4 - val insertRegister = getInstruction(insertIndex).registerA + fingerprint.matchOrThrow(backgroundPlaybackManagerCairoFragmentParentFingerprint) + .let { + it.method.apply { + val insertIndex = it.patternMatch!!.startIndex + 4 + val insertRegister = + getInstruction(insertIndex).registerA - addInstruction( - insertIndex, - "const/4 v$insertRegister, 0x0" - ) + addInstruction( + insertIndex, + "const/4 v$insertRegister, 0x0" + ) + } } - } } pipInputConsumerFeatureFlagFingerprint.injectLiteralInstructionBooleanCall( diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt index ce57443ec..692b78489 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/action/ActionButtonsPatch.kt @@ -57,20 +57,26 @@ val actionButtonsPatch = bytecodePatch( findMethodOrThrow(parameters[1].type) { name == "toString" } - val identifierReference = with (conversionContextToStringMethod) { + val identifierReference = with(conversionContextToStringMethod) { val identifierStringIndex = indexOfFirstStringInstructionOrThrow(", identifierProperty=") val identifierStringAppendIndex = indexOfFirstInstructionOrThrow(identifierStringIndex, Opcode.INVOKE_VIRTUAL) - val identifierStringAppendIndexRegister = getInstruction(identifierStringAppendIndex).registerD + val identifierStringAppendIndexRegister = + getInstruction(identifierStringAppendIndex).registerD val identifierAppendIndex = - indexOfFirstInstructionOrThrow(identifierStringAppendIndex + 1, Opcode.INVOKE_VIRTUAL) - val identifierRegister = getInstruction(identifierAppendIndex).registerD - val identifierIndex = indexOfFirstInstructionReversedOrThrow(identifierAppendIndex) { - opcode == Opcode.IGET_OBJECT && - getReference()?.type == "Ljava/lang/String;" && - (this as? TwoRegisterInstruction)?.registerA == identifierRegister - } + indexOfFirstInstructionOrThrow( + identifierStringAppendIndex + 1, + Opcode.INVOKE_VIRTUAL + ) + val identifierRegister = + getInstruction(identifierAppendIndex).registerD + val identifierIndex = + indexOfFirstInstructionReversedOrThrow(identifierAppendIndex) { + opcode == Opcode.IGET_OBJECT && + getReference()?.type == "Ljava/lang/String;" && + (this as? TwoRegisterInstruction)?.registerA == identifierRegister + } getInstruction(identifierIndex).reference } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt index cd274c9dc..ebfab4be0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/Fingerprints.kt @@ -10,11 +10,11 @@ import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutCircl import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutIcon import app.revanced.patches.youtube.utils.resourceid.endScreenElementLayoutVideo import app.revanced.patches.youtube.utils.resourceid.offlineActionsVideoDeletedUndoSnackbarText -import app.revanced.patches.youtube.utils.resourceid.verticalTouchOffsetToEnterFineScrubbing import app.revanced.patches.youtube.utils.resourceid.seekEasyHorizontalTouchOffsetToStartScrubbing import app.revanced.patches.youtube.utils.resourceid.suggestedAction import app.revanced.patches.youtube.utils.resourceid.tapBloomView import app.revanced.patches.youtube.utils.resourceid.touchArea +import app.revanced.patches.youtube.utils.resourceid.verticalTouchOffsetToEnterFineScrubbing import app.revanced.patches.youtube.utils.resourceid.verticalTouchOffsetToStartFineScrubbing import app.revanced.patches.youtube.utils.resourceid.videoZoomSnapIndicator import app.revanced.util.fingerprint.legacyFingerprint diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt index c6be90e33..2886c7063 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/components/PlayerComponentsPatch.kt @@ -129,9 +129,11 @@ private val speedOverlayPatch = bytecodePatch( // region patch for Custom speed overlay float value - val speedFieldReference = with (speedOverlayFloatValueFingerprint.methodOrThrow()) { - val literalIndex = indexOfFirstLiteralInstructionOrThrow(SPEED_OVERLAY_LEGACY_FEATURE_FLAG) - val floatIndex = indexOfFirstInstructionOrThrow(literalIndex, Opcode.DOUBLE_TO_FLOAT) + val speedFieldReference = with(speedOverlayFloatValueFingerprint.methodOrThrow()) { + val literalIndex = + indexOfFirstLiteralInstructionOrThrow(SPEED_OVERLAY_LEGACY_FEATURE_FLAG) + val floatIndex = + indexOfFirstInstructionOrThrow(literalIndex, Opcode.DOUBLE_TO_FLOAT) val floatRegister = getInstruction(floatIndex).registerA addInstructions( @@ -604,7 +606,9 @@ val playerComponentsPatch = bytecodePatch( ) if (is_20_12_or_greater) { - filmStripOverlayMotionEventPrimaryFingerprint.matchOrThrow(filmStripOverlayStartParentFingerprint).let { + filmStripOverlayMotionEventPrimaryFingerprint.matchOrThrow( + filmStripOverlayStartParentFingerprint + ).let { it.method.apply { val index = it.patternMatch!!.startIndex val register = getInstruction(index).registerA @@ -613,7 +617,9 @@ val playerComponentsPatch = bytecodePatch( } } - filmStripOverlayMotionEventSecondaryFingerprint.matchOrThrow(filmStripOverlayStartParentFingerprint).let { + filmStripOverlayMotionEventSecondaryFingerprint.matchOrThrow( + filmStripOverlayStartParentFingerprint + ).let { it.method.apply { val index = it.patternMatch!!.startIndex + 2 val register = getInstruction(index).registerA diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/Fingerprints.kt index bda5fdde7..cec249b45 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/fullscreen/Fingerprints.kt @@ -7,7 +7,6 @@ import app.revanced.patches.youtube.utils.resourceid.quickActionsElementContaine import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.util.MethodUtil internal val broadcastReceiverFingerprint = legacyFingerprint( name = "broadcastReceiverFingerprint", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/Fingerprints.kt index df9835b17..219f4cd15 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/Fingerprints.kt @@ -63,6 +63,7 @@ internal val miniplayerResponseModelSizeCheckFingerprint = legacyFingerprint( // region modern miniplayer internal const val MINIPLAYER_MODERN_FEATURE_KEY = 45622882L + // In later targets this feature flag does nothing and is dead code. internal const val MINIPLAYER_MODERN_FEATURE_LEGACY_KEY = 45630429L internal const val MINIPLAYER_DOUBLE_TAP_FEATURE_KEY = 45628823L diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/MiniplayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/MiniplayerPatch.kt index a5d331118..18ab867db 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/MiniplayerPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/miniplayer/general/MiniplayerPatch.kt @@ -239,7 +239,8 @@ val miniplayerPatch = bytecodePatch( val register = getInstruction(targetIndex).registerA addInstructions( - targetIndex + 1, """ + targetIndex + 1, + """ invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->getMiniplayerDefaultSize(I)I move-result v$register """, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt index b2134cfc3..0dc46c49b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/overlaybuttons/OverlayButtonsPatch.kt @@ -256,7 +256,8 @@ val overlayButtonsPatch = resourcePatch( width != "0.0dip", ) - val isButton = id.endsWith("_button") && id != "@id/multiview_button" || id == "@id/youtube_controls_fullscreen_button_stub" + val isButton = + id.endsWith("_button") && id != "@id/multiview_button" || id == "@id/youtube_controls_fullscreen_button_stub" // Adjust TimeBar and Chapter bottom padding val timBarItem = mutableMapOf( @@ -286,7 +287,10 @@ val overlayButtonsPatch = resourcePatch( if (id.equals("@+id/bottom_margin")) { node.setAttribute("android:layout_height", marginBottom) } else if (id.equals("@id/time_bar_reference_view")) { - node.setAttribute("yt:layout_constraintBottom_toTopOf", "@id/quick_actions_container") + node.setAttribute( + "yt:layout_constraintBottom_toTopOf", + "@id/quick_actions_container" + ) } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt index d0e9eac5c..aba912974 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/Fingerprints.kt @@ -14,7 +14,6 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import kotlin.collections.listOf internal val shortsSeekbarColorFingerprint = legacyFingerprint( name = "shortsSeekbarColorFingerprint", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt index f549f9d0e..9654b5956 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/player/seekbar/SeekbarComponentsPatch.kt @@ -139,7 +139,8 @@ val seekbarComponentsPatch = bytecodePatch( reference?.returnType == "V" && reference.parameterTypes.isEmpty() } - val thisInstanceRegister = getInstruction(tapSeekIndex).registerC + val thisInstanceRegister = + getInstruction(tapSeekIndex).registerC val tapSeekClass = getInstruction(tapSeekIndex) .getReference()!! @@ -274,7 +275,10 @@ val seekbarComponentsPatch = bytecodePatch( playerSeekbarHandleColorPrimaryFingerprint, playerSeekbarHandleColorSecondaryFingerprint ).forEach { - it.methodOrThrow().addColorChangeInstructions(ytStaticBrandRed, "getVideoPlayerSeekbarColorAccent") + it.methodOrThrow().addColorChangeInstructions( + ytStaticBrandRed, + "getVideoPlayerSeekbarColorAccent" + ) } // If hiding feed seekbar thumbnails, then turn off the cairo gradient // of the watch history menu items as they use the same gradient as the diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt index 639a2c4c3..92d882cd9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/Fingerprints.kt @@ -22,7 +22,6 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference -import kotlin.collections.listOf internal val bottomSheetMenuDismissFingerprint = legacyFingerprint( name = "bottomSheetMenuDismissFingerprint", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt index fc0b76a03..e124d373a 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/shorts/components/ShortsComponentPatch.kt @@ -344,7 +344,11 @@ private val shortsCustomActionsPatch = bytecodePatch( recyclerViewTreeObserverHook("$EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->onFlyoutMenuCreate(Landroid/support/v7/widget/RecyclerView;)V") } else { // The type of the Shorts flyout menu is ListView. - val dismissReference = with (bottomSheetMenuDismissFingerprint.methodOrThrow(bottomSheetMenuListBuilderFingerprint)) { + val dismissReference = with( + bottomSheetMenuDismissFingerprint.methodOrThrow( + bottomSheetMenuListBuilderFingerprint + ) + ) { val dismissIndex = indexOfDismissInstruction(this) getInstruction(dismissIndex).reference } @@ -352,7 +356,8 @@ private val shortsCustomActionsPatch = bytecodePatch( bottomSheetMenuItemClickFingerprint .methodOrThrow(bottomSheetMenuListBuilderFingerprint) .addInstructionsWithLabels( - 0, """ + 0, + """ invoke-static/range {p2 .. p2}, $EXTENSION_CUSTOM_ACTIONS_CLASS_DESCRIPTOR->onBottomSheetMenuItemClick(Landroid/view/View;)Z move-result v0 if-eqz v0, :ignore @@ -430,7 +435,7 @@ private val shortsRepeatPatch = bytecodePatch( "setMainActivity" ) - val endScreenReference = with (reelEnumConstructorFingerprint.methodOrThrow()) { + val endScreenReference = with(reelEnumConstructorFingerprint.methodOrThrow()) { val insertIndex = indexOfFirstInstructionOrThrow(Opcode.RETURN_VOID) addInstructions( @@ -510,7 +515,11 @@ private val shortsRepeatPatch = bytecodePatch( // Manually add the 'Autoplay' code that Google removed. // Tested on YouTube 20.10. if (is_20_09_or_greater) { - val (directReference, virtualReference) = with (reelPlaybackFingerprint.methodOrThrow(videoIdFingerprintShorts)) { + val (directReference, virtualReference) = with( + reelPlaybackFingerprint.methodOrThrow( + videoIdFingerprintShorts + ) + ) { val directIndex = indexOfInitializationInstruction(this) val virtualIndex = indexOfFirstInstructionOrThrow(directIndex) { opcode == Opcode.INVOKE_VIRTUAL && @@ -528,7 +537,8 @@ private val shortsRepeatPatch = bytecodePatch( opcode == Opcode.INVOKE_STATIC && getReference()?.definingClass == EXTENSION_REPEAT_STATE_CLASS_DESCRIPTOR } - val enumRegister = getInstruction(extensionIndex + 1).registerA + val enumRegister = + getInstruction(extensionIndex + 1).registerA val freeIndex = indexOfFirstInstructionOrThrow(extensionIndex) { opcode == Opcode.SGET_OBJECT && getReference()?.name != "a" @@ -1014,7 +1024,8 @@ val shortsComponentPatch = bytecodePatch( getReference()?.returnType == PLAYBACK_START_DESCRIPTOR_CLASS_DESCRIPTOR } val freeRegister = getInstruction(index).registerC - val playbackStartRegister = getInstruction(index + 1).registerA + val playbackStartRegister = + getInstruction(index + 1).registerA addInstructionsWithLabels( index + 2, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/CairoFragmentPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/CairoFragmentPatch.kt index ae2d3c8cf..223de2ee9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/CairoFragmentPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/CairoFragmentPatch.kt @@ -116,7 +116,7 @@ val cairoFragmentPatch = resourcePatch( ?.let { node -> node.insertNode("Preference", node) { for (index in 0 until node.attributes.length) { - with (node.attributes.item(index)) { + with(node.attributes.item(index)) { setAttribute(nodeName, nodeValue) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/Fingerprints.kt index d96edd681..b4f56f4fe 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fix/cairo/Fingerprints.kt @@ -1,10 +1,10 @@ package app.revanced.patches.youtube.utils.fix.cairo +import app.revanced.patches.youtube.utils.resourceid.settingsFragment +import app.revanced.patches.youtube.utils.resourceid.settingsFragmentCairo import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.or import com.android.tools.smali.dexlib2.AccessFlags -import app.revanced.patches.youtube.utils.resourceid.settingsFragment -import app.revanced.patches.youtube.utils.resourceid.settingsFragmentCairo import com.android.tools.smali.dexlib2.Opcode /** diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fullscreen/FullscreenButtonHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fullscreen/FullscreenButtonHookPatch.kt index b40668b3f..97a12da54 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fullscreen/FullscreenButtonHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/fullscreen/FullscreenButtonHookPatch.kt @@ -22,7 +22,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.TypeReference -import kotlin.collections.mutableListOf private const val EXTENSION_VIDEO_UTILS_CLASS_DESCRIPTOR = "$EXTENSION_PATH/utils/VideoUtils;" @@ -59,7 +58,10 @@ val fullscreenButtonHookPatch = bytecodePatch( getReference()?.name == "addListener" } val animatorListenerAdapterClass = getInstruction( - indexOfFirstInstructionReversedOrThrow(addListenerIndex, Opcode.NEW_INSTANCE) + indexOfFirstInstructionReversedOrThrow( + addListenerIndex, + Opcode.NEW_INSTANCE + ) ).reference.toString() return Pair( findMethodOrThrow(animatorListenerAdapterClass) { parameters.isEmpty() }, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/Fingerprints.kt index 3a1f528b5..0446b0376 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/Fingerprints.kt @@ -86,7 +86,7 @@ internal val appCompatToolbarBackButtonFingerprint = legacyFingerprint( accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, returnType = "Landroid/graphics/drawable/Drawable;", parameters = emptyList(), - customFingerprint = { _, classDef -> + customFingerprint = { _, classDef -> classDef.type == "Landroid/support/v7/widget/Toolbar;" }, ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt index ac0f91aa2..c0327377b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playlist/PlaylistPatch.kt @@ -56,7 +56,7 @@ val playlistPatch = bytecodePatch( """ ) - val setVideoIdReference = with (playlistEndpointFingerprint.methodOrThrow()) { + val setVideoIdReference = with(playlistEndpointFingerprint.methodOrThrow()) { val setVideoIdIndex = indexOfSetVideoIdInstruction(this) getInstruction(setVideoIdIndex).reference as FieldReference } @@ -67,14 +67,16 @@ val playlistPatch = bytecodePatch( .let { it.method.apply { val castIndex = it.patternMatch!!.startIndex - val castClass = getInstruction(castIndex).reference.toString() + val castClass = + getInstruction(castIndex).reference.toString() if (castClass != setVideoIdReference.definingClass) { throw PatchException("Method signature parameter did not match: $castClass") } val castRegister = getInstruction(castIndex).registerA val insertIndex = castIndex + 1 - val insertRegister = getInstruction(insertIndex).registerA + val insertRegister = + getInstruction(insertIndex).registerA addInstructions( insertIndex, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index 08816a3d8..edce5c86e 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -316,9 +316,11 @@ internal val sharedResourceIdPatch = resourcePatch( fullScreenEngagementPanel = getResourceId(ID, "fullscreen_engagement_panel_holder") horizontalCardList = getResourceId(LAYOUT, "horizontal_card_list") imageOnlyTab = getResourceId(LAYOUT, "image_only_tab") - inlineTimeBarColorizedBarPlayedColorDark = getResourceId(COLOR, "inline_time_bar_colorized_bar_played_color_dark") + inlineTimeBarColorizedBarPlayedColorDark = + getResourceId(COLOR, "inline_time_bar_colorized_bar_played_color_dark") inlineTimeBarLiveSeekAbleRange = getResourceId(COLOR, "inline_time_bar_live_seekable_range") - inlineTimeBarPlayedNotHighlightedColor = getResourceId(COLOR, "inline_time_bar_played_not_highlighted_color") + inlineTimeBarPlayedNotHighlightedColor = + getResourceId(COLOR, "inline_time_bar_played_not_highlighted_color") insetOverlayViewLayout = getResourceId(ID, "inset_overlay_view_layout") interstitialsContainer = getResourceId(ID, "interstitials_container") insetElementsWrapper = getResourceId(LAYOUT, "inset_elements_wrapper") @@ -328,14 +330,19 @@ internal val sharedResourceIdPatch = resourcePatch( modernMiniPlayerClose = getResourceId(ID, "modern_miniplayer_close") modernMiniPlayerExpand = getResourceId(ID, "modern_miniplayer_expand") modernMiniPlayerForwardButton = getResourceId(ID, "modern_miniplayer_forward_button") - modernMiniPlayerOverlayActionButton = getResourceId(ID, "modern_miniplayer_overlay_action_button") + modernMiniPlayerOverlayActionButton = + getResourceId(ID, "modern_miniplayer_overlay_action_button") modernMiniPlayerRewindButton = getResourceId(ID, "modern_miniplayer_rewind_button") musicAppDeeplinkButtonView = getResourceId(ID, "music_app_deeplink_button_view") - notificationBigPictureIconWidth = getResourceId(DIMEN, "notification_big_picture_icon_width") - offlineActionsVideoDeletedUndoSnackbarText = getResourceId(STRING, "offline_actions_video_deleted_undo_snackbar_text") + notificationBigPictureIconWidth = + getResourceId(DIMEN, "notification_big_picture_icon_width") + offlineActionsVideoDeletedUndoSnackbarText = + getResourceId(STRING, "offline_actions_video_deleted_undo_snackbar_text") playerCollapseButton = getResourceId(ID, "player_collapse_button") - playerControlPreviousButtonTouchArea = getResourceId(ID, "player_control_previous_button_touch_area") - playerControlNextButtonTouchArea = getResourceId(ID, "player_control_next_button_touch_area") + playerControlPreviousButtonTouchArea = + getResourceId(ID, "player_control_previous_button_touch_area") + playerControlNextButtonTouchArea = + getResourceId(ID, "player_control_next_button_touch_area") playerVideoTitleView = getResourceId(ID, "player_video_title_view") posterArtWidthDefault = getResourceId(DIMEN, "poster_art_width_default") qualityAuto = getResourceId(STRING, "quality_auto") @@ -356,7 +363,8 @@ internal val sharedResourceIdPatch = resourcePatch( relatedChipCloudMargin = getResourceId(LAYOUT, "related_chip_cloud_reduced_margins") rightComment = getResourceId(DRAWABLE, "ic_right_comment_32c") scrimOverlay = getResourceId(ID, "scrim_overlay") - seekEasyHorizontalTouchOffsetToStartScrubbing = getResourceId(DIMEN, "seek_easy_horizontal_touch_offset_to_start_scrubbing") + seekEasyHorizontalTouchOffsetToStartScrubbing = + getResourceId(DIMEN, "seek_easy_horizontal_touch_offset_to_start_scrubbing") seekUndoEduOverlayStub = getResourceId(ID, "seek_undo_edu_overlay_stub") settingsFragment = getResourceId(XML, "settings_fragment") settingsFragmentCairo = getResourceId(XML, "settings_fragment_cairo") @@ -369,20 +377,26 @@ internal val sharedResourceIdPatch = resourcePatch( toolTipContentView = getResourceId(LAYOUT, "tooltip_content_view") totalTime = getResourceId(STRING, "total_time") touchArea = getResourceId(ID, "touch_area") - videoQualityBottomSheet = getResourceId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title") + videoQualityBottomSheet = + getResourceId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title") varispeedUnavailableTitle = getResourceId(STRING, "varispeed_unavailable_title") - verticalTouchOffsetToEnterFineScrubbing = getResourceId(DIMEN, "vertical_touch_offset_to_enter_fine_scrubbing") - verticalTouchOffsetToStartFineScrubbing = getResourceId(DIMEN, "vertical_touch_offset_to_start_fine_scrubbing") - videoQualityUnavailableAnnouncement = getResourceId(STRING, "video_quality_unavailable_announcement") + verticalTouchOffsetToEnterFineScrubbing = + getResourceId(DIMEN, "vertical_touch_offset_to_enter_fine_scrubbing") + verticalTouchOffsetToStartFineScrubbing = + getResourceId(DIMEN, "vertical_touch_offset_to_start_fine_scrubbing") + videoQualityUnavailableAnnouncement = + getResourceId(STRING, "video_quality_unavailable_announcement") videoZoomSnapIndicator = getResourceId(ID, "video_zoom_snap_indicator") voiceSearch = getResourceId(ID, "voice_search") - youTubeControlsOverlaySubtitleButton = getResourceId(LAYOUT, "youtube_controls_overlay_subtitle_button") + youTubeControlsOverlaySubtitleButton = + getResourceId(LAYOUT, "youtube_controls_overlay_subtitle_button") youTubeLogo = getResourceId(ID, "youtube_logo") ytCallToAction = getResourceId(ATTR, "ytCallToAction") ytFillBell = getResourceId(DRAWABLE, "yt_fill_bell_black_24") ytOutlineLibrary = getResourceId(DRAWABLE, "yt_outline_library_black_24") ytOutlineMoonZ = getResourceId(DRAWABLE, "yt_outline_moon_z_vd_theme_24") - ytOutlinePictureInPictureWhite = getResourceId(DRAWABLE, "yt_outline_picture_in_picture_white_24") + ytOutlinePictureInPictureWhite = + getResourceId(DRAWABLE, "yt_outline_picture_in_picture_white_24") ytOutlineVideoCamera = getResourceId(DRAWABLE, "yt_outline_video_camera_black_24") ytOutlineXWhite = getResourceId(DRAWABLE, "yt_outline_x_white_24") ytPremiumWordMarkHeader = getResourceId(ATTR, "ytPremiumWordmarkHeader") diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt index 41ed6bdcd..8052b44fd 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playback/VideoPlaybackPatch.kt @@ -162,13 +162,15 @@ val videoPlaybackPatch = bytecodePatch( loadVideoParamsFingerprint.matchOrThrow(loadVideoParamsParentFingerprint).let { it.method.apply { val targetIndex = it.patternMatch!!.endIndex - val targetReference = getInstruction(targetIndex).reference as MethodReference + val targetReference = + getInstruction(targetIndex).reference as MethodReference findMethodOrThrow(definingClass) { name == targetReference.name }.apply { val insertIndex = implementation!!.instructions.lastIndex - val insertRegister = getInstruction(insertIndex).registerA + val insertRegister = + getInstruction(insertIndex).registerA addInstructions( insertIndex, """ diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/PlaybackStartDescriptorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/PlaybackStartDescriptorPatch.kt index 1b4e38b32..39b967dee 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/PlaybackStartDescriptorPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playbackstart/PlaybackStartDescriptorPatch.kt @@ -26,7 +26,8 @@ val playbackStartDescriptorPatch = bytecodePatch( && reference.returnType == "Ljava/lang/String;" } - playbackStartVideoIdReference = getInstruction(stringMethodIndex).reference + playbackStartVideoIdReference = + getInstruction(stringMethodIndex).reference } } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt index 9e8d23aeb..ba1505fe9 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/playerresponse/PlayerResponseMethodHookPatch.kt @@ -39,7 +39,8 @@ val playerResponseMethodHookPatch = bytecodePatch( playerResponseMethod.apply { val setIndex = parameterTypes.indexOfFirst { it == "Ljava/util/Set;" } val parameterSize = parameterTypes.size - val relativeIndex = parameterTypes.subList(setIndex, parameterSize - 1).indexOfFirst { it == "Z" } + val relativeIndex = + parameterTypes.subList(setIndex, parameterSize - 1).indexOfFirst { it == "Z" } // YouTube 18.29 ~ 19.22 : p11 // YouTube 19.23 ~ 20.09 : p12 diff --git a/patches/src/main/kotlin/app/revanced/util/FilesCompat.kt b/patches/src/main/kotlin/app/revanced/util/FilesCompat.kt index 6bd4a93ed..1e54ba551 100644 --- a/patches/src/main/kotlin/app/revanced/util/FilesCompat.kt +++ b/patches/src/main/kotlin/app/revanced/util/FilesCompat.kt @@ -16,7 +16,7 @@ internal object FilesCompat { // Check for the existence of java.nio.file.Files class Class.forName("java.nio.file.Files") false - } catch (_ : ClassNotFoundException) { + } catch (_: ClassNotFoundException) { // Under Android 8.0 true } From b72bb71e30515bce3d9951a9427472287b2db48f Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 19:27:16 +0900 Subject: [PATCH 76/77] feat(YouTube): Remove support version `20.03.43` --- settings.gradle.kts | 1 - 1 file changed, 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index bcff5f42d..73bc68f8d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -19,4 +19,3 @@ pluginManagement { plugins { id("app.revanced.patches") version "1.0.0-dev.6" } - From a037b25c13ba13956f3eaae91bda2189e55a4fc9 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 30 Mar 2025 19:32:31 +0900 Subject: [PATCH 77/77] bump 5.6.1 --- README.md | 137 ++++++++++++++++--------------- gradle.properties | 2 +- patches.json | 201 ++++++++++++++++------------------------------ 3 files changed, 136 insertions(+), 204 deletions(-) diff --git a/README.md b/README.md index 50553fc70..cb7f710c0 100644 --- a/README.md +++ b/README.md @@ -11,73 +11,73 @@ See the [documentation](https://github.com/inotia00/revanced-documentation#readm | 💊 Patch | 📜 Description | 🏹 Target Version | |:--------:|:--------------:|:-----------------:| -| `Alternative thumbnails` | Adds options to replace video thumbnails using the DeArrow API or image captures from the video. | 19.05.36 ~ 20.03.43 | -| `Ambient mode control` | Adds options to disable Ambient mode and to bypass Ambient mode restrictions. | 19.05.36 ~ 20.03.43 | -| `Bypass URL redirects` | Adds an option to bypass URL redirects and open the original URL directly. | 19.05.36 ~ 20.03.43 | -| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 19.05.36 ~ 20.03.43 | -| `Change form factor` | Adds an option to change the UI appearance to a phone, tablet, or automotive device. | 19.05.36 ~ 20.03.43 | -| `Change live ring click action` | Adds an option to open the channel instead of the live stream when clicking on the live ring. | 19.05.36 ~ 20.03.43 | -| `Change player flyout menu toggles` | Adds an option to use text toggles instead of switch toggles within the additional settings menu. | 19.05.36 ~ 20.03.43 | -| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 19.05.36 ~ 20.03.43 | -| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 19.05.36 ~ 20.03.43 | -| `Custom Shorts action buttons` | Changes, at compile time, the icon of the action buttons of the Shorts player. | 19.05.36 ~ 20.03.43 | -| `Custom branding icon for YouTube` | Changes the YouTube app icon to the icon specified in patch options. | 19.05.36 ~ 20.03.43 | -| `Custom branding name for YouTube` | Changes the YouTube app name to the name specified in patch options. | 19.05.36 ~ 20.03.43 | -| `Custom double tap length` | Adds Double-tap to seek values that are specified in patch options. | 19.05.36 ~ 20.03.43 | -| `Custom header for YouTube` | Applies a custom header in the top left corner within the app. | 19.05.36 ~ 20.03.43 | -| `Description components` | Adds options to hide and disable description components. | 19.05.36 ~ 20.03.43 | -| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 19.05.36 ~ 20.03.43 | -| `Disable forced auto audio tracks` | Adds an option to disable audio tracks from being automatically enabled. | 19.05.36 ~ 20.03.43 | -| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 19.05.36 ~ 20.03.43 | -| `Disable haptic feedback` | Adds options to disable haptic feedback when swiping in the video player. | 19.05.36 ~ 20.03.43 | -| `Disable layout updates` | Adds an option to disable layout updates by server. | 19.05.36 ~ 20.03.43 | -| `Disable resuming Miniplayer on startup` | Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup. | 19.05.36 ~ 20.03.43 | -| `Disable resuming Shorts on startup` | Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched. | 19.05.36 ~ 20.03.43 | -| `Disable splash animation` | Adds an option to disable the splash animation on app startup. | 19.05.36 ~ 20.03.43 | -| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 19.05.36 ~ 20.03.43 | -| `Enable debug logging` | Adds an option to enable debug logging. | 19.05.36 ~ 20.03.43 | -| `Enable gradient loading screen` | Adds an option to enable the gradient loading screen. | 19.05.36 ~ 20.03.43 | -| `Force hide player buttons background` | Removes, at compile time, the dark background surrounding the video player controls. | 19.05.36 ~ 20.03.43 | -| `Fullscreen components` | Adds options to hide or change components related to fullscreen. | 19.05.36 ~ 20.03.43 | -| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 19.05.36 ~ 20.03.43 | -| `Hide Shorts dimming` | Removes, at compile time, the dimming effect at the top and bottom of Shorts videos. | 19.05.36 ~ 20.03.43 | -| `Hide accessibility controls dialog` | Removes, at compile time, accessibility controls dialog 'Turn on accessibility controls for the video player?'. | 19.05.36 ~ 20.03.43 | -| `Hide action buttons` | Adds options to hide action buttons under videos. | 19.05.36 ~ 20.03.43 | -| `Hide ads` | Adds options to hide ads. | 19.05.36 ~ 20.03.43 | -| `Hide comments components` | Adds options to hide components related to comments. | 19.05.36 ~ 20.03.43 | -| `Hide feed components` | Adds options to hide components related to feeds. | 19.05.36 ~ 20.03.43 | -| `Hide feed flyout menu` | Adds the ability to hide feed flyout menu components using a custom filter. | 19.05.36 ~ 20.03.43 | -| `Hide layout components` | Adds options to hide general layout components. | 19.05.36 ~ 20.03.43 | -| `Hide player buttons` | Adds options to hide buttons in the video player. | 19.05.36 ~ 20.03.43 | -| `Hide player flyout menu` | Adds options to hide player flyout menu components. | 19.05.36 ~ 20.03.43 | -| `Hide shortcuts` | Remove, at compile time, the app shortcuts that appears when the app icon is long pressed. | 19.05.36 ~ 20.03.43 | -| `Hook YouTube Music actions` | Adds support for opening music in RVX Music using the in-app YouTube Music button. | 19.05.36 ~ 20.03.43 | -| `Hook download actions` | Adds support to download videos with an external downloader app using the in-app download button. | 19.05.36 ~ 20.03.43 | -| `MaterialYou` | Applies the MaterialYou theme for Android 12+ devices. | 19.05.36 ~ 20.03.43 | -| `Miniplayer` | Adds options to change the in-app minimized player, and if patching target 19.16+ adds options to use modern miniplayers. | 19.05.36 ~ 20.03.43 | -| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 19.05.36 ~ 20.03.43 | -| `Open links externally` | Adds an option to always open links in your browser instead of the in-app browser. | 19.05.36 ~ 20.03.43 | -| `Overlay buttons` | Adds options to display useful overlay buttons in the video player. | 19.05.36 ~ 20.03.43 | -| `Player components` | Adds options to hide or change components related to the video player. | 19.05.36 ~ 20.03.43 | -| `Remove background playback restrictions` | Removes restrictions on background playback, including for music and kids videos. | 19.05.36 ~ 20.03.43 | -| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 19.05.36 ~ 20.03.43 | -| `Return YouTube Dislike` | Adds an option to show the dislike count of videos using the Return YouTube Dislike API. | 19.05.36 ~ 20.03.43 | -| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 19.05.36 ~ 20.03.43 | -| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 19.05.36 ~ 20.03.43 | -| `Seekbar components` | Adds options to hide or change components related to the seekbar. | 19.05.36 ~ 20.03.43 | -| `Settings for YouTube` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 19.05.36 ~ 20.03.43 | -| `Shorts components` | Adds options to hide or change components related to YouTube Shorts. | 19.05.36 ~ 20.03.43 | -| `Snack bar components` | Adds options to hide or change components related to the snack bar. | 19.05.36 ~ 20.03.43 | -| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content. | 19.05.36 ~ 20.03.43 | -| `Spoof app version` | Adds options to spoof the YouTube client version. This can be used to restore old UI elements and features. | 19.05.36 ~ 20.03.43 | -| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 19.05.36 ~ 20.03.43 | -| `Swipe controls` | Adds options for controlling volume and brightness with swiping, and whether to enter fullscreen when swiping down below the player. | 19.05.36 ~ 20.03.43 | -| `Theme` | Changes the app's themes to the values specified in patch options. | 19.05.36 ~ 20.03.43 | -| `Toolbar components` | Adds options to hide or change components located on the toolbar, such as the search bar, header, and toolbar buttons. | 19.05.36 ~ 20.03.43 | -| `Translations for YouTube` | Add translations or remove string resources. | 19.05.36 ~ 20.03.43 | -| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 19.05.36 ~ 20.03.43 | -| `Visual preferences icons for YouTube` | Adds icons to specific preferences in the settings. | 19.05.36 ~ 20.03.43 | -| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 19.05.36 ~ 20.03.43 | +| `Alternative thumbnails` | Adds options to replace video thumbnails using the DeArrow API or image captures from the video. | 19.05.36 ~ 19.47.53 | +| `Ambient mode control` | Adds options to disable Ambient mode and to bypass Ambient mode restrictions. | 19.05.36 ~ 19.47.53 | +| `Bypass URL redirects` | Adds an option to bypass URL redirects and open the original URL directly. | 19.05.36 ~ 19.47.53 | +| `Bypass image region restrictions` | Adds an option to use a different host for static images, so that images blocked in some countries can be received. | 19.05.36 ~ 19.47.53 | +| `Change form factor` | Adds an option to change the UI appearance to a phone, tablet, or automotive device. | 19.05.36 ~ 19.47.53 | +| `Change live ring click action` | Adds an option to open the channel instead of the live stream when clicking on the live ring. | 19.05.36 ~ 19.47.53 | +| `Change player flyout menu toggles` | Adds an option to use text toggles instead of switch toggles within the additional settings menu. | 19.05.36 ~ 19.47.53 | +| `Change share sheet` | Adds an option to change the in-app share sheet to the system share sheet. | 19.05.36 ~ 19.47.53 | +| `Change start page` | Adds an option to set which page the app opens in instead of the homepage. | 19.05.36 ~ 19.47.53 | +| `Custom Shorts action buttons` | Changes, at compile time, the icon of the action buttons of the Shorts player. | 19.05.36 ~ 19.47.53 | +| `Custom branding icon for YouTube` | Changes the YouTube app icon to the icon specified in patch options. | 19.05.36 ~ 19.47.53 | +| `Custom branding name for YouTube` | Changes the YouTube app name to the name specified in patch options. | 19.05.36 ~ 19.47.53 | +| `Custom double tap length` | Adds Double-tap to seek values that are specified in patch options. | 19.05.36 ~ 19.47.53 | +| `Custom header for YouTube` | Applies a custom header in the top left corner within the app. | 19.05.36 ~ 19.47.53 | +| `Description components` | Adds options to hide and disable description components. | 19.05.36 ~ 19.47.53 | +| `Disable QUIC protocol` | Adds an option to disable CronetEngine's QUIC protocol. | 19.05.36 ~ 19.47.53 | +| `Disable forced auto audio tracks` | Adds an option to disable audio tracks from being automatically enabled. | 19.05.36 ~ 19.47.53 | +| `Disable forced auto captions` | Adds an option to disable captions from being automatically enabled. | 19.05.36 ~ 19.47.53 | +| `Disable haptic feedback` | Adds options to disable haptic feedback when swiping in the video player. | 19.05.36 ~ 19.47.53 | +| `Disable layout updates` | Adds an option to disable layout updates by server. | 19.05.36 ~ 19.47.53 | +| `Disable resuming Miniplayer on startup` | Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup. | 19.05.36 ~ 19.47.53 | +| `Disable resuming Shorts on startup` | Adds an option to disable the Shorts player from resuming on app startup when Shorts were last being watched. | 19.05.36 ~ 19.47.53 | +| `Disable splash animation` | Adds an option to disable the splash animation on app startup. | 19.05.36 ~ 19.47.53 | +| `Enable OPUS codec` | Adds an option to enable the OPUS audio codec if the player response includes it. | 19.05.36 ~ 19.47.53 | +| `Enable debug logging` | Adds an option to enable debug logging. | 19.05.36 ~ 19.47.53 | +| `Enable gradient loading screen` | Adds an option to enable the gradient loading screen. | 19.05.36 ~ 19.47.53 | +| `Force hide player buttons background` | Removes, at compile time, the dark background surrounding the video player controls. | 19.05.36 ~ 19.47.53 | +| `Fullscreen components` | Adds options to hide or change components related to fullscreen. | 19.05.36 ~ 19.47.53 | +| `GmsCore support` | Allows patched Google apps to run without root and under a different package name by using GmsCore instead of Google Play Services. | 19.05.36 ~ 19.47.53 | +| `Hide Shorts dimming` | Removes, at compile time, the dimming effect at the top and bottom of Shorts videos. | 19.05.36 ~ 19.47.53 | +| `Hide accessibility controls dialog` | Removes, at compile time, accessibility controls dialog 'Turn on accessibility controls for the video player?'. | 19.05.36 ~ 19.47.53 | +| `Hide action buttons` | Adds options to hide action buttons under videos. | 19.05.36 ~ 19.47.53 | +| `Hide ads` | Adds options to hide ads. | 19.05.36 ~ 19.47.53 | +| `Hide comments components` | Adds options to hide components related to comments. | 19.05.36 ~ 19.47.53 | +| `Hide feed components` | Adds options to hide components related to feeds. | 19.05.36 ~ 19.47.53 | +| `Hide feed flyout menu` | Adds the ability to hide feed flyout menu components using a custom filter. | 19.05.36 ~ 19.47.53 | +| `Hide layout components` | Adds options to hide general layout components. | 19.05.36 ~ 19.47.53 | +| `Hide player buttons` | Adds options to hide buttons in the video player. | 19.05.36 ~ 19.47.53 | +| `Hide player flyout menu` | Adds options to hide player flyout menu components. | 19.05.36 ~ 19.47.53 | +| `Hide shortcuts` | Remove, at compile time, the app shortcuts that appears when the app icon is long pressed. | 19.05.36 ~ 19.47.53 | +| `Hook YouTube Music actions` | Adds support for opening music in RVX Music using the in-app YouTube Music button. | 19.05.36 ~ 19.47.53 | +| `Hook download actions` | Adds support to download videos with an external downloader app using the in-app download button. | 19.05.36 ~ 19.47.53 | +| `MaterialYou` | Applies the MaterialYou theme for Android 12+ devices. | 19.05.36 ~ 19.47.53 | +| `Miniplayer` | Adds options to change the in-app minimized player, and if patching target 19.16+ adds options to use modern miniplayers. | 19.05.36 ~ 19.47.53 | +| `Navigation bar components` | Adds options to hide or change components related to the navigation bar. | 19.05.36 ~ 19.47.53 | +| `Open links externally` | Adds an option to always open links in your browser instead of the in-app browser. | 19.05.36 ~ 19.47.53 | +| `Overlay buttons` | Adds options to display useful overlay buttons in the video player. | 19.05.36 ~ 19.47.53 | +| `Player components` | Adds options to hide or change components related to the video player. | 19.05.36 ~ 19.47.53 | +| `Remove background playback restrictions` | Removes restrictions on background playback, including for music and kids videos. | 19.05.36 ~ 19.47.53 | +| `Remove viewer discretion dialog` | Adds an option to remove the dialog that appears when opening a video that has been age-restricted by accepting it automatically. This does not bypass the age restriction. | 19.05.36 ~ 19.47.53 | +| `Return YouTube Dislike` | Adds an option to show the dislike count of videos using the Return YouTube Dislike API. | 19.05.36 ~ 19.47.53 | +| `Return YouTube Username` | Adds an option to replace YouTube handles with usernames in comments using YouTube Data API v3. | 19.05.36 ~ 19.47.53 | +| `Sanitize sharing links` | Adds an option to sanitize sharing links by removing tracking query parameters. | 19.05.36 ~ 19.47.53 | +| `Seekbar components` | Adds options to hide or change components related to the seekbar. | 19.05.36 ~ 19.47.53 | +| `Settings for YouTube` | Applies mandatory patches to implement ReVanced Extended settings into the application. | 19.05.36 ~ 19.47.53 | +| `Shorts components` | Adds options to hide or change components related to YouTube Shorts. | 19.05.36 ~ 19.47.53 | +| `Snack bar components` | Adds options to hide or change components related to the snack bar. | 19.05.36 ~ 19.47.53 | +| `SponsorBlock` | Adds options to enable and configure SponsorBlock, which can skip undesired video segments, such as sponsored content. | 19.05.36 ~ 19.47.53 | +| `Spoof app version` | Adds options to spoof the YouTube client version. This can be used to restore old UI elements and features. | 19.05.36 ~ 19.47.53 | +| `Spoof streaming data` | Adds options to spoof the streaming data to allow playback. | 19.05.36 ~ 19.47.53 | +| `Swipe controls` | Adds options for controlling volume and brightness with swiping, and whether to enter fullscreen when swiping down below the player. | 19.05.36 ~ 19.47.53 | +| `Theme` | Changes the app's themes to the values specified in patch options. | 19.05.36 ~ 19.47.53 | +| `Toolbar components` | Adds options to hide or change components located on the toolbar, such as the search bar, header, and toolbar buttons. | 19.05.36 ~ 19.47.53 | +| `Translations for YouTube` | Add translations or remove string resources. | 19.05.36 ~ 19.47.53 | +| `Video playback` | Adds options to customize settings related to video playback, such as default video quality and playback speed. | 19.05.36 ~ 19.47.53 | +| `Visual preferences icons for YouTube` | Adds icons to specific preferences in the settings. | 19.05.36 ~ 19.47.53 | +| `Watch history` | Adds an option to change the domain of the watch history or check its status. | 19.05.36 ~ 19.47.53 | ### [📦 `com.google.android.apps.youtube.music`](https://play.google.com/store/apps/details?id=com.google.android.apps.youtube.music) @@ -169,8 +169,7 @@ Example: "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] diff --git a/gradle.properties b/gradle.properties index c7e4d7d87..fbb95566f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official kotlin.jvm.target.validation.mode = IGNORE -version = 5.6.1-dev.5 +version = 5.6.1 diff --git a/patches.json b/patches.json index 71bfc80d9..cff3a24c6 100644 --- a/patches.json +++ b/patches.json @@ -15,8 +15,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -35,8 +34,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -75,8 +73,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -117,8 +114,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -157,8 +153,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -179,8 +174,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -226,8 +220,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -270,8 +263,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -311,8 +303,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -352,8 +343,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -389,8 +379,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -527,8 +516,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -611,8 +599,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -640,8 +627,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -760,8 +746,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -844,8 +829,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -893,8 +877,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -935,8 +918,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -954,8 +936,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -973,8 +954,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1015,8 +995,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1035,8 +1014,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1071,8 +1049,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1113,8 +1090,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1153,8 +1129,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1172,8 +1147,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1241,8 +1215,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1267,8 +1240,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1354,8 +1326,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -1434,8 +1405,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1453,8 +1423,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1523,8 +1492,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1591,8 +1559,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1613,8 +1580,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1639,8 +1605,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1659,8 +1624,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1708,8 +1672,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1769,8 +1732,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1792,8 +1754,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1847,8 +1808,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -1903,8 +1863,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1925,8 +1884,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1945,8 +1903,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -1966,8 +1923,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2014,8 +1970,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2068,8 +2023,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2093,8 +2047,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -2193,8 +2146,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2249,8 +2201,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2307,8 +2258,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2373,8 +2323,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2416,8 +2365,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2474,8 +2422,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2499,8 +2446,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2552,8 +2498,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -2664,8 +2609,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2684,8 +2628,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -2797,8 +2740,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -2859,8 +2801,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2905,8 +2846,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -2939,8 +2879,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -2959,8 +2898,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -3020,8 +2958,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -3039,8 +2976,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -3167,8 +3103,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [] @@ -3186,8 +3121,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": [ @@ -3291,8 +3225,7 @@ "19.16.39", "19.43.41", "19.44.39", - "19.47.53", - "20.03.43" + "19.47.53" ] }, "options": []