diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..93e7caf35d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,22 @@ +version: 2 +updates: + - package-ecosystem: github-actions + labels: [] + directory: / + target-branch: dev + schedule: + interval: monthly + + - package-ecosystem: npm + labels: [] + directory: / + target-branch: dev + schedule: + interval: monthly + + - package-ecosystem: gradle + labels: [] + directory: / + target-branch: dev + schedule: + interval: monthly diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0e5a722405..e98b39d889 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,25 +24,24 @@ jobs: persist-credentials: false fetch-depth: 0 - - name: Cache Node modules - uses: actions/cache@v3 - with: - path: | - node_modules - key: npm-${{ hashFiles('package-lock.json') }} - - name: Cache Gradle uses: burrunan/gradle-cache-action@v1 - name: Setup Java run: echo "JAVA_HOME=$JAVA_HOME_17_X64" >> $GITHUB_ENV - - name: Build with Gradle + - name: Build env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./gradlew build clean - - name: Setup semantic-release + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "lts/*" + cache: 'npm' + + - name: Install dependencies run: npm install - name: Release diff --git a/CHANGELOG.md b/CHANGELOG.md index 12bd62585f..90e2bebb8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,60 @@ +# [1.2.0-dev.3](https://github.com/ReVanced/revanced-integrations/compare/v1.2.0-dev.2...v1.2.0-dev.3) (2024-01-27) + + +### Features + +* Move strings to resources for localization ([#420](https://github.com/ReVanced/revanced-integrations/issues/420)) ([7ae10be](https://github.com/ReVanced/revanced-integrations/commit/7ae10be507244594adf6704975fdf4cfd797a96e)) +* **YouTube - Spoof app version:** Add `18.09.39` to restore library tab ([#552](https://github.com/ReVanced/revanced-integrations/issues/552)) ([3bd48dc](https://github.com/ReVanced/revanced-integrations/commit/3bd48dca09094f58f68b8cfb6ff047fafa40b7e3)) + +# [1.2.0-dev.2](https://github.com/ReVanced/revanced-integrations/compare/v1.2.0-dev.1...v1.2.0-dev.2) (2024-01-16) + + +### Features + +* **YouTube:** Support versions `18.48.39`, `18.49.37`, `19.01.34` ([#547](https://github.com/ReVanced/revanced-integrations/issues/547)) ([eaaa6fb](https://github.com/ReVanced/revanced-integrations/commit/eaaa6fbd20630f15bfec7c57713ec353f4072ac2)) + +# [1.2.0-dev.1](https://github.com/ReVanced/revanced-integrations/compare/v1.1.1-dev.5...v1.2.0-dev.1) (2024-01-10) + + +### Features + +* **Tiktok - Playback speed:** Remember playback speed ([#543](https://github.com/ReVanced/revanced-integrations/issues/543)) ([21ced14](https://github.com/ReVanced/revanced-integrations/commit/21ced14791c6c26745ad88af5ce9d4970ad4c951)) + +## [1.1.1-dev.5](https://github.com/ReVanced/revanced-integrations/compare/v1.1.1-dev.4...v1.1.1-dev.5) (2024-01-08) + + +### Bug Fixes + +* **YouTube - DeArrow:** Correctly handle http status 304 ([3e380df](https://github.com/ReVanced/revanced-integrations/commit/3e380dfce27c6fbf68f44d67929a92ca069b1ba2)) + +## [1.1.1-dev.4](https://github.com/ReVanced/revanced-integrations/compare/v1.1.1-dev.3...v1.1.1-dev.4) (2024-01-06) + + +### Bug Fixes + +* **YouTube - Settings:** Correctly initialize default values ([752544b](https://github.com/ReVanced/revanced-integrations/commit/752544b9627c57c1044cc8e93b42aca32cdb8518)) + +## [1.1.1-dev.3](https://github.com/ReVanced/revanced-integrations/compare/v1.1.1-dev.2...v1.1.1-dev.3) (2024-01-05) + + +### Bug Fixes + +* **YouTube - Hide ads:** Do not leave screen at launch non interactable when hiding fullscreen ads ([fbdb490](https://github.com/ReVanced/revanced-integrations/commit/fbdb4908ea96a99b80ced99384b2dfdcc8fccd8a)) + +## [1.1.1-dev.2](https://github.com/ReVanced/revanced-integrations/compare/v1.1.1-dev.1...v1.1.1-dev.2) (2024-01-02) + + +### Bug Fixes + +* **YouTube - SponsorBlock:** Update categories after import JSON import ([211f954](https://github.com/ReVanced/revanced-integrations/commit/211f9542e8a725ca9cbfff9d3b42b4fc40734db3)) + +## [1.1.1-dev.1](https://github.com/ReVanced/revanced-integrations/compare/v1.1.0...v1.1.1-dev.1) (2023-12-29) + + +### Bug Fixes + +* **YouTube - Hide ads:** Fix dimmed screen at launch by not filtering fullscreen ads ([1a1f44d](https://github.com/ReVanced/revanced-integrations/commit/1a1f44d2355bb5e93eefca77b8df41211f6fff42)) + # [1.1.0](https://github.com/ReVanced/revanced-integrations/compare/v1.0.0...v1.1.0) (2023-12-28) diff --git a/app/src/main/java/app/revanced/all/connectivity/wifi/spoof/SpoofWifiPatch.java b/app/src/main/java/app/revanced/integrations/all/connectivity/wifi/spoof/SpoofWifiPatch.java similarity index 99% rename from app/src/main/java/app/revanced/all/connectivity/wifi/spoof/SpoofWifiPatch.java rename to app/src/main/java/app/revanced/integrations/all/connectivity/wifi/spoof/SpoofWifiPatch.java index b102c4a4e4..75bb5bf589 100644 --- a/app/src/main/java/app/revanced/all/connectivity/wifi/spoof/SpoofWifiPatch.java +++ b/app/src/main/java/app/revanced/integrations/all/connectivity/wifi/spoof/SpoofWifiPatch.java @@ -1,4 +1,4 @@ -package app.revanced.all.connectivity.wifi.spoof; +package app.revanced.integrations.all.connectivity.wifi.spoof; import android.app.PendingIntent; import android.content.Context; diff --git a/app/src/main/java/app/revanced/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch.java b/app/src/main/java/app/revanced/integrations/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch.java similarity index 90% rename from app/src/main/java/app/revanced/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch.java rename to app/src/main/java/app/revanced/integrations/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch.java index 7cfa5acdaa..c76d395d77 100644 --- a/app/src/main/java/app/revanced/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch.java +++ b/app/src/main/java/app/revanced/integrations/all/screencapture/removerestriction/RemoveScreencaptureRestrictionPatch.java @@ -1,4 +1,4 @@ -package app.revanced.all.screencapture.removerestriction; +package app.revanced.integrations.all.screencapture.removerestriction; import android.media.AudioAttributes; import android.os.Build; diff --git a/app/src/main/java/app/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch.java b/app/src/main/java/app/revanced/integrations/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch.java similarity index 86% rename from app/src/main/java/app/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch.java rename to app/src/main/java/app/revanced/integrations/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch.java index f43de82ce6..d2ebeb87be 100644 --- a/app/src/main/java/app/revanced/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch.java +++ b/app/src/main/java/app/revanced/integrations/all/screenshot/removerestriction/RemoveScreenshotRestrictionPatch.java @@ -1,4 +1,4 @@ -package app.revanced.all.screenshot.removerestriction; +package app.revanced.integrations.all.screenshot.removerestriction; import android.view.Window; import android.view.WindowManager; diff --git a/app/src/main/java/app/revanced/integrations/patches/AutoRepeatPatch.java b/app/src/main/java/app/revanced/integrations/patches/AutoRepeatPatch.java deleted file mode 100644 index 28cf5372fc..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/AutoRepeatPatch.java +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public class AutoRepeatPatch { - //Used by app.revanced.patches.youtube.layout.autorepeat.patch.AutoRepeatPatch - public static boolean shouldAutoRepeat() { - return SettingsEnum.AUTO_REPEAT.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/ChangeStartPagePatch.java b/app/src/main/java/app/revanced/integrations/patches/ChangeStartPagePatch.java deleted file mode 100644 index ede239a3ad..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/ChangeStartPagePatch.java +++ /dev/null @@ -1,16 +0,0 @@ -package app.revanced.integrations.patches; - -import android.content.Intent; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; - -@SuppressWarnings("unused") -public final class ChangeStartPagePatch { - public static void changeIntent(Intent intent) { - final var startPage = SettingsEnum.START_PAGE.getString(); - if (startPage.isEmpty()) return; - - LogHelper.printDebug(() -> "Changing start page to " + startPage); - intent.setAction("com.google.android.youtube.action." + startPage); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/CustomPlayerOverlayOpacityPatch.java b/app/src/main/java/app/revanced/integrations/patches/CustomPlayerOverlayOpacityPatch.java deleted file mode 100644 index a2b4a94c52..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/CustomPlayerOverlayOpacityPatch.java +++ /dev/null @@ -1,22 +0,0 @@ -package app.revanced.integrations.patches; - -import android.widget.ImageView; - -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.ReVancedUtils; - -public class CustomPlayerOverlayOpacityPatch { - private static final int DEFAULT_OPACITY = (int) SettingsEnum.PLAYER_OVERLAY_OPACITY.defaultValue; - - public static void changeOpacity(ImageView imageView) { - int opacity = SettingsEnum.PLAYER_OVERLAY_OPACITY.getInt(); - - if (opacity < 0 || opacity > 100) { - ReVancedUtils.showToastLong("Player overlay opacity must be between 0-100"); - SettingsEnum.PLAYER_OVERLAY_OPACITY.saveValue(DEFAULT_OPACITY); - opacity = DEFAULT_OPACITY; - } - - imageView.setImageAlpha((opacity * 255) / 100); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/DisableFullscreenAmbientModePatch.java b/app/src/main/java/app/revanced/integrations/patches/DisableFullscreenAmbientModePatch.java deleted file mode 100644 index 546880bf8e..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/DisableFullscreenAmbientModePatch.java +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -/** @noinspection unused*/ -public final class DisableFullscreenAmbientModePatch { - public static boolean enableFullScreenAmbientMode() { - return !SettingsEnum.DISABLE_FULLSCREEN_AMBIENT_MODE.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/DisableRollingNumberAnimationsPatch.java b/app/src/main/java/app/revanced/integrations/patches/DisableRollingNumberAnimationsPatch.java deleted file mode 100644 index 83a05a1c6f..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/DisableRollingNumberAnimationsPatch.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public class DisableRollingNumberAnimationsPatch { - /** - * Injection point. - */ - public static boolean disableRollingNumberAnimations() { - return SettingsEnum.DISABLE_ROLLING_NUMBER_ANIMATIONS.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/EnableTabletLayoutPatch.java b/app/src/main/java/app/revanced/integrations/patches/EnableTabletLayoutPatch.java deleted file mode 100644 index 638abd230b..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/EnableTabletLayoutPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public final class EnableTabletLayoutPatch { - public static boolean enableTabletLayout() { - return SettingsEnum.TABLET_LAYOUT.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/FullscreenPanelsRemoverPatch.java b/app/src/main/java/app/revanced/integrations/patches/FullscreenPanelsRemoverPatch.java deleted file mode 100644 index b737d1ab02..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/FullscreenPanelsRemoverPatch.java +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.integrations.patches; - -import android.view.View; -import app.revanced.integrations.settings.SettingsEnum; - -public class FullscreenPanelsRemoverPatch { - public static int getFullscreenPanelsVisibility() { - return SettingsEnum.HIDE_FULLSCREEN_PANELS.getBoolean() ? View.GONE : View.VISIBLE; - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideAlbumCardsPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideAlbumCardsPatch.java deleted file mode 100644 index b0f42e8985..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideAlbumCardsPatch.java +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.integrations.patches; - -import android.view.View; - -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.ReVancedUtils; - -public class HideAlbumCardsPatch { - public static void hideAlbumCard(View view) { - if (!SettingsEnum.HIDE_ALBUM_CARDS.getBoolean()) return; - ReVancedUtils.hideViewByLayoutParams(view); - } -} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/patches/HideAutoplayButtonPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideAutoplayButtonPatch.java deleted file mode 100644 index 7f42e7f391..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideAutoplayButtonPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public class HideAutoplayButtonPatch { - public static boolean isButtonShown() { - return !SettingsEnum.HIDE_AUTOPLAY_BUTTON.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideCaptionsButtonPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideCaptionsButtonPatch.java deleted file mode 100644 index dab38d5ce6..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideCaptionsButtonPatch.java +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.integrations.patches; - -import android.widget.ImageView; - -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; - -public class HideCaptionsButtonPatch { - //Used by app.revanced.patches.youtube.layout.hidecaptionsbutton.patch.HideCaptionsButtonPatch - public static void hideCaptionsButton(ImageView imageView) { - imageView.setVisibility(SettingsEnum.HIDE_CAPTIONS_BUTTON.getBoolean() ? ImageView.GONE : ImageView.VISIBLE); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideCrowdfundingBoxPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideCrowdfundingBoxPatch.java deleted file mode 100644 index c8b8733976..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideCrowdfundingBoxPatch.java +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.integrations.patches; - -import android.view.View; - -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.ReVancedUtils; - -public class HideCrowdfundingBoxPatch { - //Used by app.revanced.patches.youtube.layout.hidecrowdfundingbox.patch.HideCrowdfundingBoxPatch - public static void hideCrowdfundingBox(View view) { - if (!SettingsEnum.HIDE_CROWDFUNDING_BOX.getBoolean()) return; - ReVancedUtils.hideViewByLayoutParams(view); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideFilterBarPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideFilterBarPatch.java deleted file mode 100644 index 24d117dcc3..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideFilterBarPatch.java +++ /dev/null @@ -1,25 +0,0 @@ -package app.revanced.integrations.patches; - -import android.view.View; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.ReVancedUtils; - -public final class HideFilterBarPatch { - public static int hideInFeed(final int height) { - if (SettingsEnum.HIDE_FILTER_BAR_FEED_IN_FEED.getBoolean()) return 0; - - return height; - } - - public static void hideInRelatedVideos(final View chipView) { - if (!SettingsEnum.HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS.getBoolean()) return; - - ReVancedUtils.hideViewByLayoutParams(chipView); - } - - public static int hideInSearch(final int height) { - if (SettingsEnum.HIDE_FILTER_BAR_FEED_IN_SEARCH.getBoolean()) return 0; - - return height; - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideFloatingMicrophoneButtonPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideFloatingMicrophoneButtonPatch.java deleted file mode 100644 index ece09ff5da..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideFloatingMicrophoneButtonPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public final class HideFloatingMicrophoneButtonPatch { - public static boolean hideFloatingMicrophoneButton(final boolean original) { - return SettingsEnum.HIDE_FLOATING_MICROPHONE_BUTTON.getBoolean() || original; - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideGetPremiumPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideGetPremiumPatch.java deleted file mode 100644 index d246c0402b..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideGetPremiumPatch.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public class HideGetPremiumPatch { - /** - * Injection point. - */ - public static boolean hideGetPremiumView() { - return SettingsEnum.HIDE_GET_PREMIUM.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideInfoCardsPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideInfoCardsPatch.java deleted file mode 100644 index 086a501ea1..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideInfoCardsPatch.java +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.integrations.patches; - -import android.view.View; -import app.revanced.integrations.settings.SettingsEnum; - -public class HideInfoCardsPatch { - public static void hideInfoCardsIncognito(View view) { - if (!SettingsEnum.HIDE_INFO_CARDS.getBoolean()) return; - view.setVisibility(View.GONE); - } - - public static boolean hideInfoCardsMethodCall() { - return SettingsEnum.HIDE_INFO_CARDS.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideLoadMoreButtonPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideLoadMoreButtonPatch.java deleted file mode 100644 index ab77cf2a0d..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideLoadMoreButtonPatch.java +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.integrations.patches; - -import android.view.View; - -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.ReVancedUtils; - -public class HideLoadMoreButtonPatch { - public static void hideLoadMoreButton(View view){ - if(!SettingsEnum.HIDE_LOAD_MORE_BUTTON.getBoolean()) return; - ReVancedUtils.hideViewByLayoutParams(view); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideSeekbarPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideSeekbarPatch.java deleted file mode 100644 index 8601da8a71..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideSeekbarPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public class HideSeekbarPatch { - public static boolean hideSeekbar() { - return SettingsEnum.HIDE_SEEKBAR.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideTimestampPatch.java b/app/src/main/java/app/revanced/integrations/patches/HideTimestampPatch.java deleted file mode 100644 index 9bb85294ac..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/HideTimestampPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public class HideTimestampPatch { - public static boolean hideTimestamp() { - return SettingsEnum.HIDE_TIMESTAMP.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/RestoreOldSeekbarThumbnailsPatch.java b/app/src/main/java/app/revanced/integrations/patches/RestoreOldSeekbarThumbnailsPatch.java deleted file mode 100644 index c5bfeb80f8..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/RestoreOldSeekbarThumbnailsPatch.java +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -@SuppressWarnings("unused") -public final class RestoreOldSeekbarThumbnailsPatch { - public static boolean useFullscreenSeekbarThumbnails() { - return !SettingsEnum.RESTORE_OLD_SEEKBAR_THUMBNAILS.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/SeekbarTappingPatch.java b/app/src/main/java/app/revanced/integrations/patches/SeekbarTappingPatch.java deleted file mode 100644 index 3ac73c0490..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/SeekbarTappingPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public final class SeekbarTappingPatch { - public static boolean seekbarTappingEnabled() { - return SettingsEnum.SEEKBAR_TAPPING.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/SlideToSeekPatch.java b/app/src/main/java/app/revanced/integrations/patches/SlideToSeekPatch.java deleted file mode 100644 index ec739f5fdc..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/SlideToSeekPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public final class SlideToSeekPatch { - public static boolean isSlideToSeekDisabled() { - return !SettingsEnum.SLIDE_TO_SEEK.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/TabletMiniPlayerOverridePatch.java b/app/src/main/java/app/revanced/integrations/patches/TabletMiniPlayerOverridePatch.java deleted file mode 100644 index 44edd85b84..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/TabletMiniPlayerOverridePatch.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public class TabletMiniPlayerOverridePatch { - - public static boolean getTabletMiniPlayerOverride(boolean original) { - if (SettingsEnum.USE_TABLET_MINIPLAYER.getBoolean()) - return true; - return original; - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/WideSearchbarPatch.java b/app/src/main/java/app/revanced/integrations/patches/WideSearchbarPatch.java deleted file mode 100644 index 21701986df..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/WideSearchbarPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public final class WideSearchbarPatch { - public static boolean enableWideSearchbar() { - return SettingsEnum.WIDE_SEARCHBAR.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/ZoomHapticsPatch.java b/app/src/main/java/app/revanced/integrations/patches/ZoomHapticsPatch.java deleted file mode 100644 index 94a07acb98..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/ZoomHapticsPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.integrations.patches; - -import app.revanced.integrations.settings.SettingsEnum; - -public class ZoomHapticsPatch { - public static boolean shouldVibrate() { - return !SettingsEnum.DISABLE_ZOOM_HAPTICS.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch.java b/app/src/main/java/app/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch.java deleted file mode 100644 index f557f1a630..0000000000 --- a/app/src/main/java/app/revanced/integrations/patches/playback/speed/RememberPlaybackSpeedPatch.java +++ /dev/null @@ -1,39 +0,0 @@ -package app.revanced.integrations.patches.playback.speed; - -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; - -public final class RememberPlaybackSpeedPatch { - - /** - * Injection point. - */ - public static void newVideoStarted(Object ignoredPlayerController) { - LogHelper.printDebug(() -> "newVideoStarted"); - VideoInformation.overridePlaybackSpeed(SettingsEnum.PLAYBACK_SPEED_DEFAULT.getFloat()); - } - - /** - * Injection point. - * Called when user selects a playback speed. - * - * @param playbackSpeed The playback speed the user selected - */ - public static void userSelectedPlaybackSpeed(float playbackSpeed) { - if (SettingsEnum.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.getBoolean()) { - SettingsEnum.PLAYBACK_SPEED_DEFAULT.saveValue(playbackSpeed); - ReVancedUtils.showToastLong("Changed default speed to: " + playbackSpeed + "x"); - } - } - - /** - * Injection point. - * Overrides the video speed. Called after video loads, and immediately after user selects a different playback speed - */ - public static float getPlaybackSpeedOverride() { - return VideoInformation.getPlaybackSpeed(); - } - -} diff --git a/app/src/main/java/app/revanced/reddit/patches/FilterPromotedLinksPatch.java b/app/src/main/java/app/revanced/integrations/reddit/patches/FilterPromotedLinksPatch.java similarity index 91% rename from app/src/main/java/app/revanced/reddit/patches/FilterPromotedLinksPatch.java rename to app/src/main/java/app/revanced/integrations/reddit/patches/FilterPromotedLinksPatch.java index 1c825e3db7..de8469e2bb 100644 --- a/app/src/main/java/app/revanced/reddit/patches/FilterPromotedLinksPatch.java +++ b/app/src/main/java/app/revanced/integrations/reddit/patches/FilterPromotedLinksPatch.java @@ -1,4 +1,4 @@ -package app.revanced.reddit.patches; +package app.revanced.integrations.reddit.patches; import com.reddit.domain.model.ILink; diff --git a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java b/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java deleted file mode 100644 index ef628fc623..0000000000 --- a/app/src/main/java/app/revanced/integrations/settings/SettingsEnum.java +++ /dev/null @@ -1,762 +0,0 @@ -package app.revanced.integrations.settings; - -import android.content.Context; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import app.revanced.integrations.sponsorblock.SponsorBlockSettings; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.StringRef; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.*; - -import static app.revanced.integrations.settings.SettingsEnum.ReturnType.*; -import static app.revanced.integrations.settings.SharedPrefCategory.RETURN_YOUTUBE_DISLIKE; -import static app.revanced.integrations.settings.SharedPrefCategory.SPONSOR_BLOCK; -import static app.revanced.integrations.utils.StringRef.str; -import static java.lang.Boolean.FALSE; -import static java.lang.Boolean.TRUE; - - -public enum SettingsEnum { - // External downloader - EXTERNAL_DOWNLOADER("revanced_external_downloader", BOOLEAN, FALSE), - EXTERNAL_DOWNLOADER_PACKAGE_NAME("revanced_external_downloader_name", STRING, - "org.schabi.newpipe" /* NewPipe */, parents(EXTERNAL_DOWNLOADER)), - - // Copy video URL - COPY_VIDEO_URL("revanced_copy_video_url", BOOLEAN, FALSE), - COPY_VIDEO_URL_TIMESTAMP("revanced_copy_video_url_timestamp", BOOLEAN, TRUE), - - // Video - HDR_AUTO_BRIGHTNESS("revanced_hdr_auto_brightness", BOOLEAN, TRUE), - @Deprecated SHOW_OLD_VIDEO_QUALITY_MENU("revanced_show_old_video_quality_menu", BOOLEAN, TRUE), - RESTORE_OLD_VIDEO_QUALITY_MENU("revanced_restore_old_video_quality_menu", BOOLEAN, TRUE), - REMEMBER_VIDEO_QUALITY_LAST_SELECTED("revanced_remember_video_quality_last_selected", BOOLEAN, TRUE), - VIDEO_QUALITY_DEFAULT_WIFI("revanced_video_quality_default_wifi", INTEGER, -2), - VIDEO_QUALITY_DEFAULT_MOBILE("revanced_video_quality_default_mobile", INTEGER, -2), - REMEMBER_PLAYBACK_SPEED_LAST_SELECTED("revanced_remember_playback_speed_last_selected", BOOLEAN, TRUE), - PLAYBACK_SPEED_DEFAULT("revanced_playback_speed_default", FLOAT, 1.0f), - CUSTOM_PLAYBACK_SPEEDS("revanced_custom_playback_speeds", STRING, - "0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true), - - // Ads - HIDE_FULLSCREEN_ADS("revanced_hide_fullscreen_ads", BOOLEAN, TRUE), - HIDE_BUTTONED_ADS("revanced_hide_buttoned_ads", BOOLEAN, TRUE), - HIDE_GENERAL_ADS("revanced_hide_general_ads", BOOLEAN, TRUE), - HIDE_GET_PREMIUM("revanced_hide_get_premium", BOOLEAN, TRUE), - HIDE_HIDE_LATEST_POSTS("revanced_hide_latest_posts_ads", BOOLEAN, TRUE), - HIDE_MERCHANDISE_BANNERS("revanced_hide_merchandise_banners", BOOLEAN, TRUE), - HIDE_PAID_CONTENT("revanced_hide_paid_content_ads", BOOLEAN, TRUE), - HIDE_PRODUCTS_BANNER("revanced_hide_products_banner", BOOLEAN, TRUE), - HIDE_SHOPPING_LINKS("revanced_hide_shopping_links", BOOLEAN, TRUE), - HIDE_SELF_SPONSOR("revanced_hide_self_sponsor_ads", BOOLEAN, TRUE), - HIDE_VIDEO_ADS("revanced_hide_video_ads", BOOLEAN, TRUE, true), - HIDE_WEB_SEARCH_RESULTS("revanced_hide_web_search_results", BOOLEAN, TRUE), - - // Layout - ALT_THUMBNAIL_STILLS("revanced_alt_thumbnail_stills", BOOLEAN, FALSE), - ALT_THUMBNAIL_STILLS_TIME("revanced_alt_thumbnail_stills_time", INTEGER, 2, parents(ALT_THUMBNAIL_STILLS)), - ALT_THUMBNAIL_STILLS_FAST("revanced_alt_thumbnail_stills_fast", BOOLEAN, FALSE, parents(ALT_THUMBNAIL_STILLS)), - ALT_THUMBNAIL_DEARROW("revanced_alt_thumbnail_dearrow", BOOLEAN, false), - ALT_THUMBNAIL_DEARROW_API_URL("revanced_alt_thumbnail_dearrow_api_url", STRING, - "https://dearrow-thumb.ajay.app/api/v1/getThumbnail", true, parents(ALT_THUMBNAIL_DEARROW)), - ALT_THUMBNAIL_DEARROW_CONNECTION_TOAST("revanced_alt_thumbnail_dearrow_connection_toast", BOOLEAN, TRUE, parents(ALT_THUMBNAIL_DEARROW)), - CUSTOM_FILTER("revanced_custom_filter", BOOLEAN, FALSE), - CUSTOM_FILTER_STRINGS("revanced_custom_filter_strings", STRING, "", true, parents(CUSTOM_FILTER)), - DISABLE_FULLSCREEN_AMBIENT_MODE("revanced_disable_fullscreen_ambient_mode", BOOLEAN, TRUE, true), - DISABLE_RESUMING_SHORTS_PLAYER("revanced_disable_resuming_shorts_player", BOOLEAN, FALSE), - DISABLE_ROLLING_NUMBER_ANIMATIONS("revanced_disable_rolling_number_animations", BOOLEAN, FALSE), - DISABLE_SUGGESTED_VIDEO_END_SCREEN("revanced_disable_suggested_video_end_screen", BOOLEAN, TRUE), - GRADIENT_LOADING_SCREEN("revanced_gradient_loading_screen", BOOLEAN, FALSE), - HIDE_ALBUM_CARDS("revanced_hide_album_cards", BOOLEAN, FALSE, true), - HIDE_ARTIST_CARDS("revanced_hide_artist_cards", BOOLEAN, FALSE), - HIDE_AUTOPLAY_BUTTON("revanced_hide_autoplay_button", BOOLEAN, TRUE, true), - HIDE_BREAKING_NEWS("revanced_hide_breaking_news", BOOLEAN, TRUE, true), - HIDE_CAPTIONS_BUTTON("revanced_hide_captions_button", BOOLEAN, FALSE), - HIDE_CAST_BUTTON("revanced_hide_cast_button", BOOLEAN, TRUE, true), - HIDE_CHANNEL_BAR("revanced_hide_channel_bar", BOOLEAN, FALSE), - HIDE_CHANNEL_MEMBER_SHELF("revanced_hide_channel_member_shelf", BOOLEAN, TRUE), - HIDE_CHIPS_SHELF("revanced_hide_chips_shelf", BOOLEAN, TRUE), - HIDE_COMMENTS_SECTION("revanced_hide_comments_section", BOOLEAN, FALSE, true), - HIDE_COMMUNITY_GUIDELINES("revanced_hide_community_guidelines", BOOLEAN, TRUE), - HIDE_COMMUNITY_POSTS("revanced_hide_community_posts", BOOLEAN, FALSE), - HIDE_COMPACT_BANNER("revanced_hide_compact_banner", BOOLEAN, TRUE), - HIDE_CREATE_BUTTON("revanced_hide_create_button", BOOLEAN, TRUE, true), - HIDE_CROWDFUNDING_BOX("revanced_hide_crowdfunding_box", BOOLEAN, FALSE, true), - HIDE_EMAIL_ADDRESS("revanced_hide_email_address", BOOLEAN, FALSE), - HIDE_EMERGENCY_BOX("revanced_hide_emergency_box", BOOLEAN, TRUE), - HIDE_ENDSCREEN_CARDS("revanced_hide_endscreen_cards", BOOLEAN, TRUE), - HIDE_EXPANDABLE_CHIP("revanced_hide_expandable_chip", BOOLEAN, TRUE), - HIDE_FEED_SURVEY("revanced_hide_feed_survey", BOOLEAN, TRUE), - HIDE_FILTER_BAR_FEED_IN_FEED("revanced_hide_filter_bar_feed_in_feed", BOOLEAN, FALSE, true), - HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS("revanced_hide_filter_bar_feed_in_related_videos", BOOLEAN, FALSE, true), - HIDE_FILTER_BAR_FEED_IN_SEARCH("revanced_hide_filter_bar_feed_in_search", BOOLEAN, FALSE, true), - HIDE_FLOATING_MICROPHONE_BUTTON("revanced_hide_floating_microphone_button", BOOLEAN, TRUE, true), - HIDE_FULLSCREEN_PANELS("revanced_hide_fullscreen_panels", BOOLEAN, TRUE, true), - HIDE_GRAY_SEPARATOR("revanced_hide_gray_separator", BOOLEAN, TRUE), - HIDE_HIDE_CHANNEL_GUIDELINES("revanced_hide_channel_guidelines", BOOLEAN, TRUE), - HIDE_HIDE_INFO_PANELS("revanced_hide_info_panels", BOOLEAN, TRUE), - HIDE_HOME_BUTTON("revanced_hide_home_button", BOOLEAN, FALSE, true), - HIDE_IMAGE_SHELF("revanced_hide_image_shelf", BOOLEAN, TRUE), - HIDE_INFO_CARDS("revanced_hide_info_cards", BOOLEAN, TRUE), - HIDE_JOIN_MEMBERSHIP_BUTTON("revanced_hide_join_membership_button", BOOLEAN, TRUE), - HIDE_LOAD_MORE_BUTTON("revanced_hide_load_more_button", BOOLEAN, TRUE, true), - HIDE_MEDICAL_PANELS("revanced_hide_medical_panels", BOOLEAN, TRUE), - HIDE_MIX_PLAYLISTS("revanced_hide_mix_playlists", BOOLEAN, TRUE), - HIDE_MOVIES_SECTION("revanced_hide_movies_section", BOOLEAN, TRUE), - HIDE_NOTIFY_ME_BUTTON("revanced_hide_notify_me_button", BOOLEAN, TRUE), - HIDE_PLAYER_BUTTONS("revanced_hide_player_buttons", BOOLEAN, FALSE), - HIDE_PREVIEW_COMMENT("revanced_hide_preview_comment", BOOLEAN, FALSE, true), - HIDE_QUICK_ACTIONS("revanced_hide_quick_actions", BOOLEAN, FALSE), - HIDE_RELATED_VIDEOS("revanced_hide_related_videos", BOOLEAN, FALSE), - HIDE_SEARCH_RESULT_SHELF_HEADER("revanced_hide_search_result_shelf_header", BOOLEAN, FALSE), - HIDE_SHORTS_BUTTON("revanced_hide_shorts_button", BOOLEAN, TRUE, true), - HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES("revanced_hide_subscribers_community_guidelines", BOOLEAN, TRUE), - HIDE_SUBSCRIPTIONS_BUTTON("revanced_hide_subscriptions_button", BOOLEAN, FALSE, true), - HIDE_TIMED_REACTIONS("revanced_hide_timed_reactions", BOOLEAN, TRUE), - HIDE_TIMESTAMP("revanced_hide_timestamp", BOOLEAN, FALSE), - @Deprecated HIDE_VIDEO_WATERMARK("revanced_hide_video_watermark", BOOLEAN, TRUE), - HIDE_VIDEO_CHANNEL_WATERMARK("revanced_hide_channel_watermark", BOOLEAN, TRUE), - HIDE_FOR_YOU_SHELF("revanced_hide_for_you_shelf", BOOLEAN, TRUE), - HIDE_VIDEO_QUALITY_MENU_FOOTER("revanced_hide_video_quality_menu_footer", BOOLEAN, TRUE), - HIDE_SEARCH_RESULT_RECOMMENDATIONS("revanced_hide_search_result_recommendations", BOOLEAN, TRUE), - PLAYER_OVERLAY_OPACITY("revanced_player_overlay_opacity", INTEGER, 100, true), - PLAYER_POPUP_PANELS("revanced_hide_player_popup_panels", BOOLEAN, FALSE), - SPOOF_APP_VERSION("revanced_spoof_app_version", BOOLEAN, FALSE, true, "revanced_spoof_app_version_user_dialog_message"), - SPOOF_APP_VERSION_TARGET("revanced_spoof_app_version_target", STRING, "17.08.35", true, parents(SPOOF_APP_VERSION)), - SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON("revanced_switch_create_with_notifications_button", BOOLEAN, TRUE, true), - TABLET_LAYOUT("revanced_tablet_layout", BOOLEAN, FALSE, true, "revanced_tablet_layout_user_dialog_message"), - USE_TABLET_MINIPLAYER("revanced_tablet_miniplayer", BOOLEAN, FALSE, true), - WIDE_SEARCHBAR("revanced_wide_searchbar", BOOLEAN, FALSE, true), - START_PAGE("revanced_start_page", STRING, ""), - - // Description - HIDE_CHAPTERS("revanced_hide_chapters", BOOLEAN, TRUE), - HIDE_INFO_CARDS_SECTION("revanced_hide_info_cards_section", BOOLEAN, TRUE), - HIDE_GAME_SECTION("revanced_hide_game_section", BOOLEAN, TRUE), - HIDE_MUSIC_SECTION("revanced_hide_music_section", BOOLEAN, TRUE), - HIDE_PODCAST_SECTION("revanced_hide_podcast_section", BOOLEAN, TRUE), - HIDE_TRANSCIPT_SECTION("revanced_hide_transcript_section", BOOLEAN, TRUE), - - // Shorts - HIDE_SHORTS("revanced_hide_shorts", BOOLEAN, FALSE, true), - HIDE_SHORTS_JOIN_BUTTON("revanced_hide_shorts_join_button", BOOLEAN, TRUE), - HIDE_SHORTS_SUBSCRIBE_BUTTON("revanced_hide_shorts_subscribe_button", BOOLEAN, TRUE), - HIDE_SHORTS_SUBSCRIBE_BUTTON_PAUSED("revanced_hide_shorts_subscribe_button_paused", BOOLEAN, FALSE), - HIDE_SHORTS_THANKS_BUTTON("revanced_hide_shorts_thanks_button", BOOLEAN, TRUE), - HIDE_SHORTS_COMMENTS_BUTTON("revanced_hide_shorts_comments_button", BOOLEAN, FALSE), - HIDE_SHORTS_REMIX_BUTTON("revanced_hide_shorts_remix_button", BOOLEAN, TRUE), - HIDE_SHORTS_SHARE_BUTTON("revanced_hide_shorts_share_button", BOOLEAN, FALSE), - HIDE_SHORTS_INFO_PANEL("revanced_hide_shorts_info_panel", BOOLEAN, TRUE), - HIDE_SHORTS_SOUND_BUTTON("revanced_hide_shorts_sound_button", BOOLEAN, FALSE), - HIDE_SHORTS_CHANNEL_BAR("revanced_hide_shorts_channel_bar", BOOLEAN, FALSE), - HIDE_SHORTS_NAVIGATION_BAR("revanced_hide_shorts_navigation_bar", BOOLEAN, TRUE, true), - - // Seekbar - @Deprecated ENABLE_OLD_SEEKBAR_THUMBNAILS("revanced_enable_old_seekbar_thumbnails", BOOLEAN, TRUE), - RESTORE_OLD_SEEKBAR_THUMBNAILS("revanced_restore_old_seekbar_thumbnails", BOOLEAN, TRUE), - HIDE_SEEKBAR("revanced_hide_seekbar", BOOLEAN, FALSE), - HIDE_SEEKBAR_THUMBNAIL("revanced_hide_seekbar_thumbnail", BOOLEAN, FALSE), - SEEKBAR_CUSTOM_COLOR("revanced_seekbar_custom_color", BOOLEAN, TRUE, true), - SEEKBAR_CUSTOM_COLOR_VALUE("revanced_seekbar_custom_color_value", STRING, "#FF0000", true, parents(SEEKBAR_CUSTOM_COLOR)), - - // Action buttons - HIDE_LIKE_DISLIKE_BUTTON("revanced_hide_like_dislike_button", BOOLEAN, FALSE), - HIDE_LIVE_CHAT_BUTTON("revanced_hide_live_chat_button", BOOLEAN, FALSE), - HIDE_SHARE_BUTTON("revanced_hide_share_button", BOOLEAN, FALSE), - HIDE_REPORT_BUTTON("revanced_hide_report_button", BOOLEAN, FALSE), - HIDE_REMIX_BUTTON("revanced_hide_remix_button", BOOLEAN, TRUE), - HIDE_DOWNLOAD_BUTTON("revanced_hide_download_button", BOOLEAN, FALSE), - HIDE_THANKS_BUTTON("revanced_hide_thanks_button", BOOLEAN, TRUE), - HIDE_CLIP_BUTTON("revanced_hide_clip_button", BOOLEAN, TRUE), - HIDE_PLAYLIST_BUTTON("revanced_hide_playlist_button", BOOLEAN, FALSE), - HIDE_SHOP_BUTTON("revanced_hide_shop_button", BOOLEAN, TRUE), - - // Player flyout menu items - HIDE_CAPTIONS_MENU("revanced_hide_player_flyout_captions", BOOLEAN, FALSE), - HIDE_ADDITIONAL_SETTINGS_MENU("revanced_hide_player_flyout_additional_settings", BOOLEAN, FALSE), - HIDE_LOOP_VIDEO_MENU("revanced_hide_player_flyout_loop_video", BOOLEAN, FALSE), - HIDE_AMBIENT_MODE_MENU("revanced_hide_player_flyout_ambient_mode", BOOLEAN, FALSE), - HIDE_REPORT_MENU("revanced_hide_player_flyout_report", BOOLEAN, TRUE), - HIDE_HELP_MENU("revanced_hide_player_flyout_help", BOOLEAN, TRUE), - HIDE_SPEED_MENU("revanced_hide_player_flyout_speed", BOOLEAN, FALSE), - HIDE_MORE_INFO_MENU("revanced_hide_player_flyout_more_info", BOOLEAN, TRUE), - HIDE_AUDIO_TRACK_MENU("revanced_hide_player_flyout_audio_track", BOOLEAN, FALSE), - HIDE_WATCH_IN_VR_MENU("revanced_hide_player_flyout_watch_in_vr", BOOLEAN, TRUE), - - // Misc - AUTO_CAPTIONS("revanced_auto_captions", BOOLEAN, FALSE), - DISABLE_ZOOM_HAPTICS("revanced_disable_zoom_haptics", BOOLEAN, TRUE), - EXTERNAL_BROWSER("revanced_external_browser", BOOLEAN, TRUE, true), - AUTO_REPEAT("revanced_auto_repeat", BOOLEAN, FALSE), - SEEKBAR_TAPPING("revanced_seekbar_tapping", BOOLEAN, TRUE), - SLIDE_TO_SEEK("revanced_slide_to_seek", BOOLEAN, FALSE), - @Deprecated DISABLE_FINE_SCRUBBING_GESTURE("revanced_disable_fine_scrubbing_gesture", BOOLEAN, TRUE), - DISABLE_PRECISE_SEEKING_GESTURE("revanced_disable_precise_seeking_gesture", BOOLEAN, TRUE), - SPOOF_SIGNATURE("revanced_spoof_signature_verification_enabled", BOOLEAN, TRUE, true, - "revanced_spoof_signature_verification_enabled_user_dialog_message"), - SPOOF_SIGNATURE_IN_FEED("revanced_spoof_signature_in_feed_enabled", BOOLEAN, FALSE, false, - parents(SPOOF_SIGNATURE)), - SPOOF_STORYBOARD_RENDERER("revanced_spoof_storyboard", BOOLEAN, TRUE, true, - parents(SPOOF_SIGNATURE)), - - SPOOF_DEVICE_DIMENSIONS("revanced_spoof_device_dimensions", BOOLEAN, FALSE, true), - BYPASS_URL_REDIRECTS("revanced_bypass_url_redirects", BOOLEAN, TRUE), - ANNOUNCEMENTS("revanced_announcements", BOOLEAN, TRUE), - ANNOUNCEMENT_CONSUMER("revanced_announcement_consumer", STRING, ""), - ANNOUNCEMENT_LAST_HASH("revanced_announcement_last_hash", STRING, ""), - REMOVE_TRACKING_QUERY_PARAMETER("revanced_remove_tracking_query_parameter", BOOLEAN, TRUE), - REMOVE_VIEWER_DISCRETION_DIALOG("revanced_remove_viewer_discretion_dialog", BOOLEAN, FALSE, - "revanced_remove_viewer_discretion_dialog_user_dialog_message"), - - // Swipe controls - SWIPE_BRIGHTNESS("revanced_swipe_brightness", BOOLEAN, TRUE), - SWIPE_VOLUME("revanced_swipe_volume", BOOLEAN, TRUE), - SWIPE_PRESS_TO_ENGAGE("revanced_swipe_press_to_engage", BOOLEAN, FALSE, true, - parents(SWIPE_BRIGHTNESS, SWIPE_VOLUME)), - SWIPE_HAPTIC_FEEDBACK("revanced_swipe_haptic_feedback", BOOLEAN, TRUE, true, - parents(SWIPE_BRIGHTNESS, SWIPE_VOLUME)), - SWIPE_MAGNITUDE_THRESHOLD("revanced_swipe_threshold", INTEGER, 30, true, - parents(SWIPE_BRIGHTNESS, SWIPE_VOLUME)), - SWIPE_OVERLAY_BACKGROUND_ALPHA("revanced_swipe_overlay_background_alpha", INTEGER, 127, true, - parents(SWIPE_BRIGHTNESS, SWIPE_VOLUME)), - SWIPE_OVERLAY_TEXT_SIZE("revanced_swipe_text_overlay_size", INTEGER, 22, true, - parents(SWIPE_BRIGHTNESS, SWIPE_VOLUME)), - SWIPE_OVERLAY_TIMEOUT("revanced_swipe_overlay_timeout", LONG, 500L, true, - parents(SWIPE_BRIGHTNESS, SWIPE_VOLUME)), - SWIPE_SAVE_AND_RESTORE_BRIGHTNESS("revanced_swipe_save_and_restore_brightness", BOOLEAN, TRUE, true, - parents(SWIPE_BRIGHTNESS, SWIPE_VOLUME)), - - // Debugging - DEBUG("revanced_debug", BOOLEAN, FALSE), - DEBUG_STACKTRACE("revanced_debug_stacktrace", BOOLEAN, FALSE, parents(DEBUG)), - DEBUG_PROTOBUFFER("revanced_debug_protobuffer", BOOLEAN, FALSE, parents(DEBUG)), - DEBUG_TOAST_ON_ERROR("revanced_debug_toast_on_error", BOOLEAN, TRUE, "revanced_debug_toast_on_error_user_dialog_message"), - - // ReturnYoutubeDislike - RYD_ENABLED("ryd_enabled", BOOLEAN, TRUE, RETURN_YOUTUBE_DISLIKE), - RYD_USER_ID("ryd_user_id", STRING, "", RETURN_YOUTUBE_DISLIKE), - RYD_SHORTS("ryd_shorts", BOOLEAN, TRUE, RETURN_YOUTUBE_DISLIKE, parents(RYD_ENABLED)), - RYD_DISLIKE_PERCENTAGE("ryd_dislike_percentage", BOOLEAN, FALSE, RETURN_YOUTUBE_DISLIKE, parents(RYD_ENABLED)), - RYD_COMPACT_LAYOUT("ryd_compact_layout", BOOLEAN, FALSE, RETURN_YOUTUBE_DISLIKE, parents(RYD_ENABLED)), - RYD_TOAST_ON_CONNECTION_ERROR("ryd_toast_on_connection_error", BOOLEAN, TRUE, RETURN_YOUTUBE_DISLIKE, parents(RYD_ENABLED)), - - // SponsorBlock - SB_ENABLED("sb_enabled", BOOLEAN, TRUE, SPONSOR_BLOCK), - SB_PRIVATE_USER_ID("sb_private_user_id_Do_Not_Share", STRING, "", SPONSOR_BLOCK), /** Do not use directly, instead use {@link SponsorBlockSettings} */ - DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING("uuid", STRING, "", SPONSOR_BLOCK), // Delete sometime in 2024 - SB_CREATE_NEW_SEGMENT_STEP("sb_create_new_segment_step", INTEGER, 150, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_VOTING_BUTTON("sb_voting_button", BOOLEAN, FALSE, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_CREATE_NEW_SEGMENT("sb_create_new_segment", BOOLEAN, FALSE, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_COMPACT_SKIP_BUTTON("sb_compact_skip_button", BOOLEAN, FALSE, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_AUTO_HIDE_SKIP_BUTTON("sb_auto_hide_skip_button", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_TOAST_ON_SKIP("sb_toast_on_skip", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_TOAST_ON_CONNECTION_ERROR("sb_toast_on_connection_error", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_TRACK_SKIP_COUNT("sb_track_skip_count", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_SEGMENT_MIN_DURATION("sb_min_segment_duration", FLOAT, 0F, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_VIDEO_LENGTH_WITHOUT_SEGMENTS("sb_video_length_without_segments", BOOLEAN, TRUE, SPONSOR_BLOCK, parents(SB_ENABLED)), - SB_API_URL("sb_api_url", STRING, "https://sponsor.ajay.app", SPONSOR_BLOCK), - SB_USER_IS_VIP("sb_user_is_vip", BOOLEAN, FALSE, SPONSOR_BLOCK), - // SB settings not exported - SB_LAST_VIP_CHECK("sb_last_vip_check", LONG, 0L, SPONSOR_BLOCK), - SB_HIDE_EXPORT_WARNING("sb_hide_export_warning", BOOLEAN, FALSE, SPONSOR_BLOCK), - SB_SEEN_GUIDELINES("sb_seen_guidelines", BOOLEAN, FALSE, SPONSOR_BLOCK), - SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS("sb_local_time_saved_number_segments", INTEGER, 0, SPONSOR_BLOCK), - SB_LOCAL_TIME_SAVED_MILLISECONDS("sb_local_time_saved_milliseconds", LONG, 0L, SPONSOR_BLOCK); - - private static SettingsEnum[] parents(SettingsEnum... parents) { - return parents; - } - - @NonNull - public final String path; - @NonNull - public final Object defaultValue; - @NonNull - public final SharedPrefCategory sharedPref; - @NonNull - public final ReturnType returnType; - /** - * If the app should be rebooted, if this setting is changed - */ - public final boolean rebootApp; - /** - * Set of boolean parent settings. - * If any of the parents are enabled, then this setting is available to configure. - * - * For example: {@link #DEBUG_STACKTRACE} is non-functional and cannot be configured, - * unless it's parent {@link #DEBUG} is enabled. - * - * Declaration is not needed for items that do not appear in the ReVanced Settings UI. - */ - @Nullable - private final SettingsEnum[] parents; - - /** - * Confirmation message to display, if the user tries to change the setting from the default value. - * Can only be used for {@link ReturnType#BOOLEAN} setting types. - */ - @Nullable - public final StringRef userDialogMessage; - - // Must be volatile, as some settings are read/write from different threads. - // Of note, the object value is persistently stored using SharedPreferences (which is thread safe). - @NonNull - private volatile Object value; - - SettingsEnum(String path, ReturnType returnType, Object defaultValue) { - this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, false, null, null); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, - boolean rebootApp) { - this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, null, null); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, - String userDialogMessage) { - this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, false, userDialogMessage, null); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, - SettingsEnum[] parents) { - this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, false, null, parents); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, - boolean rebootApp, String userDialogMessage) { - this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, userDialogMessage, null); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, - boolean rebootApp, SettingsEnum[] parents) { - this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, null, parents); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, - boolean rebootApp, String userDialogMessage, SettingsEnum[] parents) { - this(path, returnType, defaultValue, SharedPrefCategory.YOUTUBE, rebootApp, userDialogMessage, parents); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName) { - this(path, returnType, defaultValue, prefName, false, null, null); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName, - boolean rebootApp) { - this(path, returnType, defaultValue, prefName, rebootApp, null, null); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName, - String userDialogMessage) { - this(path, returnType, defaultValue, prefName, false, userDialogMessage, null); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName, - SettingsEnum[] parents) { - this(path, returnType, defaultValue, prefName, false, null, parents); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, SharedPrefCategory prefName, - boolean rebootApp, @Nullable String userDialogMessage, @Nullable SettingsEnum[] parents) { - this.path = Objects.requireNonNull(path); - this.returnType = Objects.requireNonNull(returnType); - this.value = this.defaultValue = Objects.requireNonNull(defaultValue); - this.sharedPref = Objects.requireNonNull(prefName); - this.rebootApp = rebootApp; - - if (userDialogMessage == null) { - this.userDialogMessage = null; - } else { - if (returnType != ReturnType.BOOLEAN) { - throw new IllegalArgumentException("must be Boolean type: " + path); - } - this.userDialogMessage = new StringRef(userDialogMessage); - } - - this.parents = parents; - if (parents != null) { - for (SettingsEnum parent : parents) { - if (parent.returnType != ReturnType.BOOLEAN) { - throw new IllegalArgumentException("parent must be Boolean type: " + parent); - } - } - } - } - - private static final Map pathToSetting = new HashMap<>(2* values().length); - - static { - loadAllSettings(); - - for (SettingsEnum setting : values()) { - pathToSetting.put(setting.path, setting); - } - } - - @Nullable - public static SettingsEnum settingFromPath(@NonNull String str) { - return pathToSetting.get(str); - } - - private static void loadAllSettings() { - for (SettingsEnum setting : values()) { - setting.load(); - } - - // region Migration - - migrateOldSettingToNew(HIDE_VIDEO_WATERMARK, HIDE_VIDEO_CHANNEL_WATERMARK); - migrateOldSettingToNew(DISABLE_FINE_SCRUBBING_GESTURE, DISABLE_PRECISE_SEEKING_GESTURE); - migrateOldSettingToNew(SHOW_OLD_VIDEO_QUALITY_MENU, RESTORE_OLD_VIDEO_QUALITY_MENU); - migrateOldSettingToNew(ENABLE_OLD_SEEKBAR_THUMBNAILS, RESTORE_OLD_SEEKBAR_THUMBNAILS); - - // Do _not_ delete this SB private user id migration property until sometime in 2024. - // This is the only setting that cannot be reconfigured if lost, - // and more time should be given for users who rarely upgrade. - migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID); - - // This migration may need to remain here for a while. - // Older online guides will still reference using commas, - // and this code will automatically convert anything the user enters to newline format, - // and also migrate any imported older settings that using commas. - String componentsToFilter = SettingsEnum.CUSTOM_FILTER_STRINGS.getString(); - if (componentsToFilter.contains(",")) { - LogHelper.printInfo(() -> "Migrating custom filter strings to new line format"); - SettingsEnum.CUSTOM_FILTER_STRINGS.saveValue(componentsToFilter.replace(",", "\n")); - } - - // endregion - } - - /** - * Migrate a setting value if the path is renamed but otherwise the old and new settings are identical. - */ - private static void migrateOldSettingToNew(SettingsEnum oldSetting, SettingsEnum newSetting) { - if (!oldSetting.isSetToDefault()) { - LogHelper.printInfo(() -> "Migrating old setting of '" + oldSetting.value - + "' from: " + oldSetting + " into replacement setting: " + newSetting); - newSetting.saveValue(oldSetting.value); - oldSetting.resetToDefault(); - } - } - - private void load() { - switch (returnType) { - case BOOLEAN: - value = sharedPref.getBoolean(path, (boolean) defaultValue); - break; - case INTEGER: - value = sharedPref.getIntegerString(path, (Integer) defaultValue); - break; - case LONG: - value = sharedPref.getLongString(path, (Long) defaultValue); - break; - case FLOAT: - value = sharedPref.getFloatString(path, (Float) defaultValue); - break; - case STRING: - value = sharedPref.getString(path, (String) defaultValue); - break; - default: - throw new IllegalStateException(name()); - } - } - - /** - * Sets, but does _not_ persistently save the value. - *

- * This intentionally is a static method, to deter accidental usage - * when {@link #saveValue(Object)} was intended. - *

- * This method is only to be used by the Settings preference code. - */ - public static void setValue(@NonNull SettingsEnum setting, @NonNull String newValue) { - Objects.requireNonNull(newValue); - switch (setting.returnType) { - case BOOLEAN: - setting.value = Boolean.valueOf(newValue); - break; - case INTEGER: - setting.value = Integer.valueOf(newValue); - break; - case LONG: - setting.value = Long.valueOf(newValue); - break; - case FLOAT: - setting.value = Float.valueOf(newValue); - break; - case STRING: - setting.value = newValue; - break; - default: - throw new IllegalStateException(setting.name()); - } - } - - /** - * This method is only to be used by the Settings preference code. - */ - public static void setValue(@NonNull SettingsEnum setting, @NonNull Boolean newValue) { - setting.returnType.validate(newValue); - setting.value = newValue; - } - - /** - * Sets the value, and persistently saves it. - */ - public void saveValue(@NonNull Object newValue) { - returnType.validate(newValue); - value = newValue; // Must set before saving to preferences (otherwise importing fails to update UI correctly). - switch (returnType) { - case BOOLEAN: - sharedPref.saveBoolean(path, (boolean) newValue); - break; - case INTEGER: - sharedPref.saveIntegerString(path, (Integer) newValue); - break; - case LONG: - sharedPref.saveLongString(path, (Long) newValue); - break; - case FLOAT: - sharedPref.saveFloatString(path, (Float) newValue); - break; - case STRING: - sharedPref.saveString(path, (String) newValue); - break; - default: - throw new IllegalStateException(name()); - } - } - - /** - * Identical to calling {@link #saveValue(Object)} using {@link #defaultValue}. - */ - public void resetToDefault() { - saveValue(defaultValue); - } - - /** - * @return if this setting can be configured and used. - *

- * Not to be confused with {@link #getBoolean()} - */ - public boolean isAvailable() { - if (parents == null) { - return true; - } - for (SettingsEnum parent : parents) { - if (parent.getBoolean()) return true; - } - return false; - } - - /** - * @return if the currently set value is the same as {@link #defaultValue} - */ - public boolean isSetToDefault() { - return value.equals(defaultValue); - } - - public boolean getBoolean() { - return (Boolean) value; - } - - public int getInt() { - return (Integer) value; - } - - public long getLong() { - return (Long) value; - } - - public float getFloat() { - return (Float) value; - } - - @NonNull - public String getString() { - return (String) value; - } - - /** - * @return the value of this setting as as generic object type. - */ - @NonNull - public Object getObjectValue() { - return value; - } - - /** - * This could be yet another field, - * for now use a simple switch statement since this method is not used outside this class. - */ - private boolean includeWithImportExport() { - switch (this) { - case RYD_USER_ID: // Not useful to export, no reason to include it. - case ANNOUNCEMENT_CONSUMER: // Not useful to export, no reason to include it. - case SB_LAST_VIP_CHECK: - case SB_HIDE_EXPORT_WARNING: - case SB_SEEN_GUIDELINES: - return false; - } - return true; - } - - // Begin import / export - - /** - * If a setting path has this prefix, then remove it before importing/exporting. - */ - private static final String OPTIONAL_REVANCED_SETTINGS_PREFIX = "revanced_"; - - /** - * The path, minus any 'revanced' prefix to keep json concise. - */ - private String getImportExportKey() { - if (path.startsWith(OPTIONAL_REVANCED_SETTINGS_PREFIX)) { - return path.substring(OPTIONAL_REVANCED_SETTINGS_PREFIX.length()); - } - return path; - } - - private static SettingsEnum[] valuesSortedForExport() { - SettingsEnum[] sorted = values(); - Arrays.sort(sorted, (SettingsEnum o1, SettingsEnum o2) -> { - // Organize SponsorBlock settings last. - final boolean o1IsSb = o1.sharedPref == SPONSOR_BLOCK; - final boolean o2IsSb = o2.sharedPref == SPONSOR_BLOCK; - if (o1IsSb != o2IsSb) { - return o1IsSb ? 1 : -1; - } - return o1.path.compareTo(o2.path); - }); - return sorted; - } - - @NonNull - public static String exportJSON(@Nullable Context alertDialogContext) { - try { - JSONObject json = new JSONObject(); - for (SettingsEnum setting : valuesSortedForExport()) { - String importExportKey = setting.getImportExportKey(); - if (json.has(importExportKey)) { - throw new IllegalArgumentException("duplicate key found: " + importExportKey); - } - final boolean exportDefaultValues = false; // Enable to see what all settings looks like in the UI. - if (setting.includeWithImportExport() && (!setting.isSetToDefault() | exportDefaultValues)) { - json.put(importExportKey, setting.getObjectValue()); - } - } - SponsorBlockSettings.exportCategoriesToFlatJson(alertDialogContext, json); - - if (json.length() == 0) { - return ""; - } - String export = json.toString(0); - // Remove the outer JSON braces to make the output more compact, - // and leave less chance of the user forgetting to copy it - return export.substring(2, export.length() - 2); - } catch (JSONException e) { - LogHelper.printException(() -> "Export failure", e); // should never happen - return ""; - } - } - - /** - * @return if any settings that require a reboot were changed. - */ - public static boolean importJSON(@NonNull String settingsJsonString) { - try { - if (!settingsJsonString.matches("[\\s\\S]*\\{")) { - settingsJsonString = '{' + settingsJsonString + '}'; // Restore outer JSON braces - } - JSONObject json = new JSONObject(settingsJsonString); - - boolean rebootSettingChanged = false; - int numberOfSettingsImported = 0; - for (SettingsEnum setting : values()) { - String key = setting.getImportExportKey(); - if (json.has(key)) { - Object value; - switch (setting.returnType) { - case BOOLEAN: - value = json.getBoolean(key); - break; - case INTEGER: - value = json.getInt(key); - break; - case LONG: - value = json.getLong(key); - break; - case FLOAT: - value = (float) json.getDouble(key); - break; - case STRING: - value = json.getString(key); - break; - default: - throw new IllegalStateException(); - } - if (!setting.getObjectValue().equals(value)) { - rebootSettingChanged |= setting.rebootApp; - setting.saveValue(value); - } - numberOfSettingsImported++; - } else if (setting.includeWithImportExport() && !setting.isSetToDefault()) { - LogHelper.printDebug(() -> "Resetting to default: " + setting); - rebootSettingChanged |= setting.rebootApp; - setting.resetToDefault(); - } - } - numberOfSettingsImported += SponsorBlockSettings.importCategoriesFromFlatJson(json); - - ReVancedUtils.showToastLong(numberOfSettingsImported == 0 - ? str("revanced_settings_import_reset") - : str("revanced_settings_import_success", numberOfSettingsImported)); - - return rebootSettingChanged; - } catch (JSONException | IllegalArgumentException ex) { - ReVancedUtils.showToastLong(str("revanced_settings_import_failure_parse", ex.getMessage())); - LogHelper.printInfo(() -> "", ex); - } catch (Exception ex) { - LogHelper.printException(() -> "Import failure: " + ex.getMessage(), ex); // should never happen - } - return false; - } - - // End import / export - - public enum ReturnType { - BOOLEAN, - INTEGER, - LONG, - FLOAT, - STRING; - - public void validate(@Nullable Object obj) throws IllegalArgumentException { - if (!matches(obj)) { - throw new IllegalArgumentException("'" + obj + "' does not match:" + this); - } - } - - public boolean matches(@Nullable Object obj) { - switch (this) { - case BOOLEAN: - return obj instanceof Boolean; - case INTEGER: - return obj instanceof Integer; - case LONG: - return obj instanceof Long; - case FLOAT: - return obj instanceof Float; - case STRING: - return obj instanceof String; - } - return false; - } - } -} diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java b/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java deleted file mode 100644 index 6a33a628e2..0000000000 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingsFragment.java +++ /dev/null @@ -1,196 +0,0 @@ -package app.revanced.integrations.settingsmenu; - -import static app.revanced.integrations.utils.StringRef.str; - -import android.annotation.SuppressLint; -import android.app.AlertDialog; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.preference.SwitchPreference; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import app.revanced.integrations.patches.playback.speed.CustomPlaybackSpeedPatch; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.settings.SharedPrefCategory; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.shared.settings.SettingsUtils; - -public class ReVancedSettingsFragment extends PreferenceFragment { - /** - * Indicates that if a preference changes, - * to apply the change from the Setting to the UI component. - */ - static boolean settingImportInProgress; - - static void showRestartDialog(@NonNull Context contxt) { - String positiveButton = str("in_app_update_restart_button"); - new AlertDialog.Builder(contxt).setMessage(str("pref_refresh_config")) - .setPositiveButton(positiveButton, (dialog, id) -> { - SettingsUtils.restartApp(contxt); - }) - .setNegativeButton(android.R.string.cancel, null) - .setCancelable(false) - .show(); - } - - /** - * Used to prevent showing reboot dialog, if user cancels a setting user dialog. - */ - private boolean showingUserDialogMessage; - - SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { - try { - SettingsEnum setting = SettingsEnum.settingFromPath(str); - if (setting == null) { - return; - } - Preference pref = findPreference(str); - LogHelper.printDebug(() -> setting.name() + ": " + " setting value:" + setting.getObjectValue() + " pref:" + pref); - if (pref == null) { - return; - } - - if (pref instanceof SwitchPreference) { - SwitchPreference switchPref = (SwitchPreference) pref; - if (settingImportInProgress) { - switchPref.setChecked(setting.getBoolean()); - } else { - SettingsEnum.setValue(setting, switchPref.isChecked()); - } - } else if (pref instanceof EditTextPreference) { - EditTextPreference editPreference = (EditTextPreference) pref; - if (settingImportInProgress) { - editPreference.getEditText().setText(setting.getObjectValue().toString()); - } else { - SettingsEnum.setValue(setting, editPreference.getText()); - } - } else if (pref instanceof ListPreference) { - ListPreference listPref = (ListPreference) pref; - if (settingImportInProgress) { - listPref.setValue(setting.getObjectValue().toString()); - } else { - SettingsEnum.setValue(setting, listPref.getValue()); - } - updateListPreferenceSummary((ListPreference) pref, setting); - } else { - LogHelper.printException(() -> "Setting cannot be handled: " + pref.getClass() + " " + pref); - return; - } - - enableDisablePreferences(); - - if (settingImportInProgress) { - return; - } - - if (!showingUserDialogMessage) { - if (setting.userDialogMessage != null && ((SwitchPreference) pref).isChecked() != (Boolean) setting.defaultValue) { - showSettingUserDialogConfirmation(getContext(), (SwitchPreference) pref, setting); - } else if (setting.rebootApp) { - showRestartDialog(getContext()); - } - } - - } catch (Exception ex) { - LogHelper.printException(() -> "OnSharedPreferenceChangeListener failure", ex); - } - }; - - @SuppressLint("ResourceType") - @Override - public void onActivityCreated(@Nullable Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - try { - PreferenceManager preferenceManager = getPreferenceManager(); - preferenceManager.setSharedPreferencesName(SharedPrefCategory.YOUTUBE.prefName); - addPreferencesFromResource(ReVancedUtils.getResourceIdentifier("revanced_prefs", "xml")); - - enableDisablePreferences(); - - // if the preference was included, then initialize it based on the available playback speed - Preference defaultSpeedPreference = findPreference(SettingsEnum.PLAYBACK_SPEED_DEFAULT.path); - if (defaultSpeedPreference instanceof ListPreference) { - CustomPlaybackSpeedPatch.initializeListPreference((ListPreference) defaultSpeedPreference); - } - - // Set current value from SettingsEnum - for (SettingsEnum setting : SettingsEnum.values()) { - Preference preference = findPreference(setting.path); - if (preference instanceof SwitchPreference) { - ((SwitchPreference) preference).setChecked(setting.getBoolean()); - } else if (preference instanceof EditTextPreference) { - ((EditTextPreference) preference).setText(setting.getObjectValue().toString()); - } else if (preference instanceof ListPreference) { - updateListPreferenceSummary((ListPreference) preference, setting); - } - } - - preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener); - } catch (Exception ex) { - LogHelper.printException(() -> "onActivityCreated() failure", ex); - } - } - - @Override // android.preference.PreferenceFragment, android.app.Fragment - public void onDestroy() { - getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener); - super.onDestroy(); - } - - private void enableDisablePreferences() { - for (SettingsEnum setting : SettingsEnum.values()) { - Preference preference = this.findPreference(setting.path); - if (preference != null) { - preference.setEnabled(setting.isAvailable()); - } - } - } - - /** - * Sets summary text to the currently selected list option. - */ - private void updateListPreferenceSummary(ListPreference listPreference, SettingsEnum setting) { - String objectStringValue = setting.getObjectValue().toString(); - final int entryIndex = listPreference.findIndexOfValue(objectStringValue); - if (entryIndex >= 0) { - listPreference.setSummary(listPreference.getEntries()[entryIndex]); - listPreference.setValue(objectStringValue); - } else { - // Value is not an available option. - // User manually edited import data, or options changed and current selection is no longer available. - // Still show the value in the summary so it's clear that something is selected. - listPreference.setSummary(objectStringValue); - } - } - - private void showSettingUserDialogConfirmation(@NonNull Context context, SwitchPreference switchPref, SettingsEnum setting) { - showingUserDialogMessage = true; - new AlertDialog.Builder(context) - .setTitle(str("revanced_settings_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) -> { - Boolean defaultBooleanValue = (Boolean) setting.defaultValue; - SettingsEnum.setValue(setting, defaultBooleanValue); - switchPref.setChecked(defaultBooleanValue); - }) - .setOnDismissListener(dialog -> { - showingUserDialogMessage = false; - }) - .setCancelable(false) - .show(); - } -} diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/ReturnYouTubeDislikeSettingsFragment.java b/app/src/main/java/app/revanced/integrations/settingsmenu/ReturnYouTubeDislikeSettingsFragment.java deleted file mode 100644 index 5ee90efa71..0000000000 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/ReturnYouTubeDislikeSettingsFragment.java +++ /dev/null @@ -1,230 +0,0 @@ -package app.revanced.integrations.settingsmenu; - -import static app.revanced.integrations.utils.StringRef.str; - -import android.app.Activity; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.preference.Preference; -import android.preference.PreferenceCategory; -import android.preference.PreferenceFragment; -import android.preference.PreferenceScreen; -import android.preference.SwitchPreference; - -import app.revanced.integrations.patches.ReturnYouTubeDislikePatch; -import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike; -import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.settings.SharedPrefCategory; - -public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment { - - /** - * If dislikes are shown on Shorts. - */ - private SwitchPreference shortsPreference; - - /** - * If dislikes are shown as percentage. - */ - private SwitchPreference percentagePreference; - - /** - * If segmented like/dislike button uses smaller compact layout. - */ - private SwitchPreference compactLayoutPreference; - - /** - * If segmented like/dislike button uses smaller compact layout. - */ - private SwitchPreference toastOnRYDNotAvailable; - - private void updateUIState() { - shortsPreference.setEnabled(SettingsEnum.RYD_SHORTS.isAvailable()); - percentagePreference.setEnabled(SettingsEnum.RYD_DISLIKE_PERCENTAGE.isAvailable()); - compactLayoutPreference.setEnabled(SettingsEnum.RYD_COMPACT_LAYOUT.isAvailable()); - toastOnRYDNotAvailable.setEnabled(SettingsEnum.RYD_TOAST_ON_CONNECTION_ERROR.isAvailable()); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - getPreferenceManager().setSharedPreferencesName(SharedPrefCategory.RETURN_YOUTUBE_DISLIKE.prefName); - - Activity context = this.getActivity(); - PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context); - setPreferenceScreen(preferenceScreen); - - SwitchPreference enabledPreference = new SwitchPreference(context); - enabledPreference.setChecked(SettingsEnum.RYD_ENABLED.getBoolean()); - enabledPreference.setTitle(str("revanced_ryd_enable_title")); - enabledPreference.setSummaryOn(str("revanced_ryd_enable_summary_on")); - enabledPreference.setSummaryOff(str("revanced_ryd_enable_summary_off")); - enabledPreference.setOnPreferenceChangeListener((pref, newValue) -> { - final boolean rydIsEnabled = (Boolean) newValue; - SettingsEnum.RYD_ENABLED.saveValue(rydIsEnabled); - ReturnYouTubeDislikePatch.onRYDStatusChange(rydIsEnabled); - - updateUIState(); - return true; - }); - preferenceScreen.addPreference(enabledPreference); - - shortsPreference = new SwitchPreference(context); - shortsPreference.setChecked(SettingsEnum.RYD_SHORTS.getBoolean()); - shortsPreference.setTitle(str("revanced_ryd_shorts_title")); - String shortsSummary = str("revanced_ryd_shorts_summary_on", - ReturnYouTubeDislikePatch.IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER - ? "" - : "\n\n" + str("revanced_ryd_shorts_summary_disclaimer")); - shortsPreference.setSummaryOn(shortsSummary); - shortsPreference.setSummaryOff(str("revanced_ryd_shorts_summary_off")); - shortsPreference.setOnPreferenceChangeListener((pref, newValue) -> { - SettingsEnum.RYD_SHORTS.saveValue(newValue); - updateUIState(); - return true; - }); - preferenceScreen.addPreference(shortsPreference); - - percentagePreference = new SwitchPreference(context); - percentagePreference.setChecked(SettingsEnum.RYD_DISLIKE_PERCENTAGE.getBoolean()); - percentagePreference.setTitle(str("revanced_ryd_dislike_percentage_title")); - percentagePreference.setSummaryOn(str("revanced_ryd_dislike_percentage_summary_on")); - percentagePreference.setSummaryOff(str("revanced_ryd_dislike_percentage_summary_off")); - percentagePreference.setOnPreferenceChangeListener((pref, newValue) -> { - SettingsEnum.RYD_DISLIKE_PERCENTAGE.saveValue(newValue); - ReturnYouTubeDislike.clearAllUICaches(); - updateUIState(); - return true; - }); - preferenceScreen.addPreference(percentagePreference); - - compactLayoutPreference = new SwitchPreference(context); - compactLayoutPreference.setChecked(SettingsEnum.RYD_COMPACT_LAYOUT.getBoolean()); - compactLayoutPreference.setTitle(str("revanced_ryd_compact_layout_title")); - compactLayoutPreference.setSummaryOn(str("revanced_ryd_compact_layout_summary_on")); - compactLayoutPreference.setSummaryOff(str("revanced_ryd_compact_layout_summary_off")); - compactLayoutPreference.setOnPreferenceChangeListener((pref, newValue) -> { - SettingsEnum.RYD_COMPACT_LAYOUT.saveValue(newValue); - ReturnYouTubeDislike.clearAllUICaches(); - updateUIState(); - return true; - }); - preferenceScreen.addPreference(compactLayoutPreference); - - toastOnRYDNotAvailable = new SwitchPreference(context); - toastOnRYDNotAvailable.setChecked(SettingsEnum.RYD_TOAST_ON_CONNECTION_ERROR.getBoolean()); - toastOnRYDNotAvailable.setTitle(str("ryd_toast_on_connection_error_title")); - toastOnRYDNotAvailable.setSummaryOn(str("ryd_toast_on_connection_error_summary_on")); - toastOnRYDNotAvailable.setSummaryOff(str("ryd_toast_on_connection_error_summary_off")); - toastOnRYDNotAvailable.setOnPreferenceChangeListener((pref, newValue) -> { - SettingsEnum.RYD_TOAST_ON_CONNECTION_ERROR.saveValue(newValue); - updateUIState(); - return true; - }); - preferenceScreen.addPreference(toastOnRYDNotAvailable); - - updateUIState(); - - - // About category - - PreferenceCategory aboutCategory = new PreferenceCategory(context); - aboutCategory.setTitle(str("revanced_ryd_about")); - preferenceScreen.addPreference(aboutCategory); - - // ReturnYouTubeDislike Website - - Preference aboutWebsitePreference = new Preference(context); - aboutWebsitePreference.setTitle(str("revanced_ryd_attribution_title")); - aboutWebsitePreference.setSummary(str("revanced_ryd_attribution_summary")); - aboutWebsitePreference.setOnPreferenceClickListener(pref -> { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse("https://returnyoutubedislike.com")); - pref.getContext().startActivity(i); - return false; - }); - preferenceScreen.addPreference(aboutWebsitePreference); - - // RYD API connection statistics - - if (SettingsEnum.DEBUG.getBoolean()) { - PreferenceCategory emptyCategory = new PreferenceCategory(context); // vertical padding - preferenceScreen.addPreference(emptyCategory); - - PreferenceCategory statisticsCategory = new PreferenceCategory(context); - statisticsCategory.setTitle(str("revanced_ryd_statistics_category_title")); - preferenceScreen.addPreference(statisticsCategory); - - Preference statisticPreference; - - statisticPreference = new Preference(context); - statisticPreference.setSelectable(false); - statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeAverage_title")); - statisticPreference.setSummary(createMillisecondStringFromNumber(ReturnYouTubeDislikeApi.getFetchCallResponseTimeAverage())); - preferenceScreen.addPreference(statisticPreference); - - statisticPreference = new Preference(context); - statisticPreference.setSelectable(false); - statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeMin_title")); - statisticPreference.setSummary(createMillisecondStringFromNumber(ReturnYouTubeDislikeApi.getFetchCallResponseTimeMin())); - preferenceScreen.addPreference(statisticPreference); - - statisticPreference = new Preference(context); - statisticPreference.setSelectable(false); - statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeMax_title")); - statisticPreference.setSummary(createMillisecondStringFromNumber(ReturnYouTubeDislikeApi.getFetchCallResponseTimeMax())); - preferenceScreen.addPreference(statisticPreference); - - String fetchCallTimeWaitingLastSummary; - final long fetchCallTimeWaitingLast = ReturnYouTubeDislikeApi.getFetchCallResponseTimeLast(); - if (fetchCallTimeWaitingLast == ReturnYouTubeDislikeApi.FETCH_CALL_RESPONSE_TIME_VALUE_RATE_LIMIT) { - fetchCallTimeWaitingLastSummary = str("revanced_ryd_statistics_getFetchCallResponseTimeLast_rate_limit_summary"); - } else { - fetchCallTimeWaitingLastSummary = createMillisecondStringFromNumber(fetchCallTimeWaitingLast); - } - statisticPreference = new Preference(context); - statisticPreference.setSelectable(false); - statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeLast_title")); - statisticPreference.setSummary(fetchCallTimeWaitingLastSummary); - preferenceScreen.addPreference(statisticPreference); - - statisticPreference = new Preference(context); - statisticPreference.setSelectable(false); - statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallCount_title")); - statisticPreference.setSummary(createSummaryText(ReturnYouTubeDislikeApi.getFetchCallCount(), - "revanced_ryd_statistics_getFetchCallCount_zero_summary", - "revanced_ryd_statistics_getFetchCallCount_non_zero_summary")); - preferenceScreen.addPreference(statisticPreference); - - statisticPreference = new Preference(context); - statisticPreference.setSelectable(false); - statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallNumberOfFailures_title")); - statisticPreference.setSummary(createSummaryText(ReturnYouTubeDislikeApi.getFetchCallNumberOfFailures(), - "revanced_ryd_statistics_getFetchCallNumberOfFailures_zero_summary", - "revanced_ryd_statistics_getFetchCallNumberOfFailures_non_zero_summary")); - preferenceScreen.addPreference(statisticPreference); - - statisticPreference = new Preference(context); - statisticPreference.setSelectable(false); - statisticPreference.setTitle(str("revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_title")); - statisticPreference.setSummary(createSummaryText(ReturnYouTubeDislikeApi.getNumberOfRateLimitRequestsEncountered(), - "revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_zero_summary", - "revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_non_zero_summary")); - preferenceScreen.addPreference(statisticPreference); - } - } - - private static String createSummaryText(int value, String summaryStringZeroKey, String summaryStringOneOrMoreKey) { - if (value == 0) { - return str(summaryStringZeroKey); - } - return String.format(str(summaryStringOneOrMoreKey), value); - } - - private static String createMillisecondStringFromNumber(long number) { - return String.format(str("revanced_ryd_statistics_millisecond_text"), number); - } - -} diff --git a/app/src/main/java/app/revanced/integrations/utils/LogHelper.java b/app/src/main/java/app/revanced/integrations/shared/Logger.java similarity index 82% rename from app/src/main/java/app/revanced/integrations/utils/LogHelper.java rename to app/src/main/java/app/revanced/integrations/shared/Logger.java index b0f96635b2..f8c5c87eee 100644 --- a/app/src/main/java/app/revanced/integrations/utils/LogHelper.java +++ b/app/src/main/java/app/revanced/integrations/shared/Logger.java @@ -1,16 +1,19 @@ -package app.revanced.integrations.utils; +package app.revanced.integrations.shared; -import android.util.Log; +import static app.revanced.integrations.shared.settings.BaseSettings.DEBUG; +import static app.revanced.integrations.shared.settings.BaseSettings.DEBUG_STACKTRACE; +import static app.revanced.integrations.shared.settings.BaseSettings.DEBUG_TOAST_ON_ERROR; +import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import app.revanced.integrations.shared.settings.BaseSettings; + import java.io.PrintWriter; import java.io.StringWriter; -import app.revanced.integrations.settings.SettingsEnum; - -public class LogHelper { +public class Logger { /** * Log messages using lambdas. @@ -52,13 +55,13 @@ private String findOuterClassSimpleName() { /** * Logs debug messages under the outer class name of the code calling this method. * Whenever possible, the log string should be constructed entirely inside {@link LogMessage#buildMessageString()} - * so the performance cost of building strings is paid only if {@link SettingsEnum#DEBUG} is enabled. + * so the performance cost of building strings is paid only if {@link BaseSettings#DEBUG} is enabled. */ public static void printDebug(@NonNull LogMessage message) { - if (SettingsEnum.DEBUG.getBoolean()) { + if (DEBUG.get()) { var messageString = message.buildMessageString(); - if (SettingsEnum.DEBUG_STACKTRACE.getBoolean()) { + if (DEBUG_STACKTRACE.get()) { var builder = new StringBuilder(messageString); var sw = new StringWriter(); new Throwable().printStackTrace(new PrintWriter(sw)); @@ -125,12 +128,21 @@ public static void printException(@NonNull LogMessage message, @Nullable Throwab } else { Log.e(logMessage, messageString, ex); } - if (SettingsEnum.DEBUG_TOAST_ON_ERROR.getBoolean()) { + if (DEBUG_TOAST_ON_ERROR.get()) { String toastMessageToDisplay = (userToastMessage != null) ? userToastMessage : outerClassSimpleName + ": " + messageString; - ReVancedUtils.showToastLong(toastMessageToDisplay); + Utils.showToastLong(toastMessageToDisplay); } } + /** + * Logging to use if {@link BaseSettings#DEBUG} or {@link Utils#context} may not be initialized. + * Always logs even if Debugging is not enabled. + * Normally this method should not be used. + */ + public static void initializationError(@NonNull Class callingClass, @NonNull String message, @Nullable Exception ex) { + Log.e(REVANCED_LOG_PREFIX + callingClass.getSimpleName(), message, ex); + } + } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/utils/StringRef.java b/app/src/main/java/app/revanced/integrations/shared/StringRef.java similarity index 92% rename from app/src/main/java/app/revanced/integrations/utils/StringRef.java rename to app/src/main/java/app/revanced/integrations/shared/StringRef.java index e30a1d7d76..2c3b9110dd 100644 --- a/app/src/main/java/app/revanced/integrations/utils/StringRef.java +++ b/app/src/main/java/app/revanced/integrations/shared/StringRef.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.utils; +package app.revanced.integrations.shared; import android.content.Context; import android.content.res.Resources; @@ -102,7 +102,7 @@ public StringRef(@NonNull String resName) { public String toString() { if (!resolved) { if (resources == null || packageName == null) { - Context context = ReVancedUtils.getContext(); + Context context = Utils.getContext(); resources = context.getResources(); packageName = context.getPackageName(); } @@ -110,11 +110,11 @@ public String toString() { if (resources != null) { final int identifier = resources.getIdentifier(value, "string", packageName); if (identifier == 0) - LogHelper.printException(() -> "Resource not found: " + value); + Logger.printException(() -> "Resource not found: " + value); else value = resources.getString(identifier); } else { - LogHelper.printException(() -> "Could not resolve resources!"); + Logger.printException(() -> "Could not resolve resources!"); } } return value; diff --git a/app/src/main/java/app/revanced/integrations/utils/ReVancedUtils.java b/app/src/main/java/app/revanced/integrations/shared/Utils.java similarity index 75% rename from app/src/main/java/app/revanced/integrations/utils/ReVancedUtils.java rename to app/src/main/java/app/revanced/integrations/shared/Utils.java index ac32c8f455..279abdead2 100644 --- a/app/src/main/java/app/revanced/integrations/utils/ReVancedUtils.java +++ b/app/src/main/java/app/revanced/integrations/shared/Utils.java @@ -1,7 +1,8 @@ -package app.revanced.integrations.utils; +package app.revanced.integrations.shared; import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Resources; @@ -9,28 +10,43 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; +import android.preference.Preference; +import android.preference.PreferenceGroup; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; -import android.widget.*; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.RelativeLayout; +import android.widget.Toast; +import android.widget.Toolbar; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.revanced.integrations.settings.SettingsEnum; import java.text.Bidi; import java.util.Locale; import java.util.Objects; -import java.util.concurrent.*; +import java.util.SortedMap; +import java.util.TreeMap; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import app.revanced.integrations.shared.settings.BooleanSetting; +import kotlin.text.Regex; -public class ReVancedUtils { +public class Utils { @SuppressLint("StaticFieldLeak") public static Context context; private static String versionName; - private ReVancedUtils() { + private Utils() { } // utility class public static String getVersionName() { @@ -51,7 +67,7 @@ public static String getVersionName() { 0 ); } catch (PackageManager.NameNotFoundException e) { - LogHelper.printException(() -> "Failed to get package info", e); + Logger.printException(() -> "Failed to get package info", e); return null; } @@ -64,10 +80,10 @@ public static String getVersionName() { * @param condition The setting to check for hiding the view. * @param view The view to hide. */ - public static void hideViewBy1dpUnderCondition(SettingsEnum condition, View view) { - if (!condition.getBoolean()) return; + public static void hideViewBy1dpUnderCondition(BooleanSetting condition, View view) { + if (!condition.get()) return; - LogHelper.printDebug(() -> "Hiding view with setting: " + condition); + Logger.printDebug(() -> "Hiding view with setting: " + condition); hideViewByLayoutParams(view); } @@ -78,10 +94,10 @@ public static void hideViewBy1dpUnderCondition(SettingsEnum condition, View view * @param condition The setting to check for hiding the view. * @param view The view to hide. */ - public static void hideViewUnderCondition(SettingsEnum condition, View view) { - if (!condition.getBoolean()) return; + public static void hideViewUnderCondition(BooleanSetting condition, View view) { + if (!condition.get()) return; - LogHelper.printDebug(() -> "Hiding view with setting: " + condition); + Logger.printDebug(() -> "Hiding view with setting: " + condition); view.setVisibility(View.GONE); } @@ -119,7 +135,7 @@ public static Future submitOnBackgroundThread(@NonNull Callable call) @SuppressWarnings("UnusedReturnValue") public static long doNothingForDuration(long amountOfTimeToWaste) { final long timeCalculationStarted = System.currentTimeMillis(); - LogHelper.printDebug(() -> "Artificially creating delay of: " + amountOfTimeToWaste + "ms"); + Logger.printDebug(() -> "Artificially creating delay of: " + amountOfTimeToWaste + "ms"); long meaninglessValue = 0; while (System.currentTimeMillis() - timeCalculationStarted < amountOfTimeToWaste) { @@ -196,16 +212,26 @@ public static T getChildView(@NonNull ViewGroup viewGroup, @Non return null; } + public static void restartApp(@NonNull Context context) { + String packageName = context.getPackageName(); + Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName); + Intent mainIntent = Intent.makeRestartActivityTask(intent.getComponent()); + // Required for API 34 and later + // Ref: https://developer.android.com/about/versions/14/behavior-changes-14#safer-intents + mainIntent.setPackage(packageName); + context.startActivity(mainIntent); + System.exit(0); + } + public interface MatchFilter { boolean matches(T object); } public static Context getContext() { - if (context != null) { - return context; + if (context == null) { + Logger.initializationError(Utils.class, "Context is null, returning null!", null); } - LogHelper.printException(() -> "Context is null, returning null!"); - return null; + return context; } public static void setClipboard(@NonNull String text) { @@ -249,11 +275,10 @@ public static void showToastLong(@NonNull String messageToToast) { private static void showToast(@NonNull String messageToToast, int toastDuration) { Objects.requireNonNull(messageToToast); runOnMainThreadNowOrLater(() -> { - // cannot use getContext(), otherwise if context is null it will cause infinite recursion of error logging if (context == null) { - LogHelper.printDebug(() -> "Cannot show toast (context is null)"); + Logger.initializationError(Utils.class, "Cannot show toast (context is null): " + messageToToast, null); } else { - LogHelper.printDebug(() -> "Showing toast: " + messageToToast); + Logger.printDebug(() -> "Showing toast: " + messageToToast); Toast.makeText(context, messageToToast, toastDuration).show(); } } @@ -277,7 +302,7 @@ public static void runOnMainThreadDelayed(@NonNull Runnable runnable, long delay try { runnable.run(); } catch (Exception ex) { - LogHelper.printException(() -> runnable.getClass() + ": " + ex.getMessage(), ex); + Logger.printException(() -> runnable.getClass() + ": " + ex.getMessage(), ex); } }; new Handler(Looper.getMainLooper()).postDelayed(loggingRunnable, delayMillis); @@ -364,13 +389,52 @@ public static void hideViewByLayoutParams(View view) { ViewGroup.LayoutParams layoutParams5 = new ViewGroup.LayoutParams(1, 1); view.setLayoutParams(layoutParams5); } else { - LogHelper.printDebug(() -> "Hidden view with id " + view.getId()); + Logger.printDebug(() -> "Hidden view with id " + view.getId()); } } + private static final Regex punctuationRegex = new Regex("\\p{P}+"); + + /** + * Sort the preferences by title and ignore the casing. + * + * Android Preferences are automatically sorted by title, + * but if using a localized string key it sorts on the key and not the actual title text that's used at runtime. + * + * @param menuDepthToSort Maximum menu depth to sort. Menus deeper than this value + * will show preferences in the order created in patches. + */ + public static void sortPreferenceGroupByTitle(PreferenceGroup group, int menuDepthToSort) { + if (menuDepthToSort == 0) return; + + SortedMap preferences = new TreeMap<>(); + for (int i = 0, prefCount = group.getPreferenceCount(); i < prefCount; i++) { + Preference preference = group.getPreference(i); + if (preference instanceof PreferenceGroup) { + sortPreferenceGroupByTitle((PreferenceGroup) preference, menuDepthToSort - 1); + } + preferences.put(removePunctuationConvertToLowercase(preference.getTitle()), preference); + } + + int prefIndex = 0; + for (Preference pref : preferences.values()) { + int indexToSet = prefIndex++; + if (pref instanceof PreferenceGroup || pref.getIntent() != null) { + // Place preference groups last. + // Use an offset to push the group to the end. + indexToSet += 1000; + } + pref.setOrder(indexToSet); + } + } + + public static String removePunctuationConvertToLowercase(CharSequence original) { + return punctuationRegex.replace(original, "").toLowerCase(); + } + public enum NetworkType { NONE, MOBILE, OTHER, } -} \ No newline at end of file +} diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/BaseSettings.java b/app/src/main/java/app/revanced/integrations/shared/settings/BaseSettings.java new file mode 100644 index 0000000000..c5283491d7 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/shared/settings/BaseSettings.java @@ -0,0 +1,17 @@ +package app.revanced.integrations.shared.settings; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static app.revanced.integrations.shared.settings.Setting.parent; + +/** + * Settings shared across multiple apps. + * + * To ensure this class is loaded when the UI is created, app specific setting bundles should extend + * or reference this class. + */ +public class BaseSettings { + public static final BooleanSetting DEBUG = new BooleanSetting("revanced_debug", FALSE); + public static final BooleanSetting DEBUG_STACKTRACE = new BooleanSetting("revanced_debug_stacktrace", FALSE, parent(DEBUG)); + public static final BooleanSetting DEBUG_TOAST_ON_ERROR = new BooleanSetting("revanced_debug_toast_on_error", TRUE, "revanced_debug_toast_on_error_user_dialog_message"); +} diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/BooleanSetting.java b/app/src/main/java/app/revanced/integrations/shared/settings/BooleanSetting.java new file mode 100644 index 0000000000..bc20f8c294 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/shared/settings/BooleanSetting.java @@ -0,0 +1,79 @@ +package app.revanced.integrations.shared.settings; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Objects; + +@SuppressWarnings("unused") +public class BooleanSetting extends Setting { + public BooleanSetting(String key, Boolean defaultValue) { + super(key, defaultValue); + } + public BooleanSetting(String key, Boolean defaultValue, boolean rebootApp) { + super(key, defaultValue, rebootApp); + } + public BooleanSetting(String key, Boolean defaultValue, boolean rebootApp, boolean includeWithImportExport) { + super(key, defaultValue, rebootApp, includeWithImportExport); + } + public BooleanSetting(String key, Boolean defaultValue, String userDialogMessage) { + super(key, defaultValue, userDialogMessage); + } + public BooleanSetting(String key, Boolean defaultValue, Availability availability) { + super(key, defaultValue, availability); + } + public BooleanSetting(String key, Boolean defaultValue, boolean rebootApp, String userDialogMessage) { + super(key, defaultValue, rebootApp, userDialogMessage); + } + public BooleanSetting(String key, Boolean defaultValue, boolean rebootApp, Availability availability) { + super(key, defaultValue, rebootApp, availability); + } + public BooleanSetting(String key, Boolean defaultValue, boolean rebootApp, String userDialogMessage, Availability availability) { + super(key, defaultValue, rebootApp, userDialogMessage, availability); + } + public BooleanSetting(@NonNull String key, @NonNull Boolean defaultValue, boolean rebootApp, boolean includeWithImportExport, @Nullable String userDialogMessage, @Nullable Availability availability) { + super(key, defaultValue, rebootApp, includeWithImportExport, userDialogMessage, availability); + } + + /** + * Sets, but does _not_ persistently save the value. + * This method is only to be used by the Settings preference code. + * + * This intentionally is a static method to deter + * accidental usage when {@link #save(Boolean)} was intnded. + */ + public static void privateSetValue(@NonNull BooleanSetting setting, @NonNull Boolean newValue) { + setting.value = Objects.requireNonNull(newValue); + } + + @Override + protected void load() { + value = preferences.getBoolean(key, defaultValue); + } + + @Override + protected Boolean readFromJSON(JSONObject json, String importExportKey) throws JSONException { + return json.getBoolean(importExportKey); + } + + @Override + protected void setValueFromString(@NonNull String newValue) { + value = Boolean.valueOf(Objects.requireNonNull(newValue)); + } + + @Override + public void save(@NonNull Boolean newValue) { + // Must set before saving to preferences (otherwise importing fails to update UI correctly). + value = Objects.requireNonNull(newValue); + preferences.saveBoolean(key, newValue); + } + + @NonNull + @Override + public Boolean get() { + return value; + } +} diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/FloatSetting.java b/app/src/main/java/app/revanced/integrations/shared/settings/FloatSetting.java new file mode 100644 index 0000000000..6729f67a83 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/shared/settings/FloatSetting.java @@ -0,0 +1,69 @@ +package app.revanced.integrations.shared.settings; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Objects; + +@SuppressWarnings("unused") +public class FloatSetting extends Setting { + + public FloatSetting(String key, Float defaultValue) { + super(key, defaultValue); + } + public FloatSetting(String key, Float defaultValue, boolean rebootApp) { + super(key, defaultValue, rebootApp); + } + public FloatSetting(String key, Float defaultValue, boolean rebootApp, boolean includeWithImportExport) { + super(key, defaultValue, rebootApp, includeWithImportExport); + } + public FloatSetting(String key, Float defaultValue, String userDialogMessage) { + super(key, defaultValue, userDialogMessage); + } + public FloatSetting(String key, Float defaultValue, Availability availability) { + super(key, defaultValue, availability); + } + public FloatSetting(String key, Float defaultValue, boolean rebootApp, String userDialogMessage) { + super(key, defaultValue, rebootApp, userDialogMessage); + } + public FloatSetting(String key, Float defaultValue, boolean rebootApp, Availability availability) { + super(key, defaultValue, rebootApp, availability); + } + public FloatSetting(String key, Float defaultValue, boolean rebootApp, String userDialogMessage, Availability availability) { + super(key, defaultValue, rebootApp, userDialogMessage, availability); + } + public FloatSetting(@NonNull String key, @NonNull Float defaultValue, boolean rebootApp, boolean includeWithImportExport, @Nullable String userDialogMessage, @Nullable Availability availability) { + super(key, defaultValue, rebootApp, includeWithImportExport, userDialogMessage, availability); + } + + @Override + protected void load() { + value = preferences.getFloatString(key, defaultValue); + } + + @Override + protected Float readFromJSON(JSONObject json, String importExportKey) throws JSONException { + return (float) json.getDouble(importExportKey); + } + + @Override + protected void setValueFromString(@NonNull String newValue) { + value = Float.valueOf(Objects.requireNonNull(newValue)); + } + + @Override + public void save(@NonNull Float newValue) { + // Must set before saving to preferences (otherwise importing fails to update UI correctly). + value = Objects.requireNonNull(newValue); + preferences.saveFloatString(key, newValue); + } + + @NonNull + @Override + public Float get() { + return value; + } +} diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/IntegerSetting.java b/app/src/main/java/app/revanced/integrations/shared/settings/IntegerSetting.java new file mode 100644 index 0000000000..414de1569a --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/shared/settings/IntegerSetting.java @@ -0,0 +1,69 @@ +package app.revanced.integrations.shared.settings; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Objects; + +@SuppressWarnings("unused") +public class IntegerSetting extends Setting { + + public IntegerSetting(String key, Integer defaultValue) { + super(key, defaultValue); + } + public IntegerSetting(String key, Integer defaultValue, boolean rebootApp) { + super(key, defaultValue, rebootApp); + } + public IntegerSetting(String key, Integer defaultValue, boolean rebootApp, boolean includeWithImportExport) { + super(key, defaultValue, rebootApp, includeWithImportExport); + } + public IntegerSetting(String key, Integer defaultValue, String userDialogMessage) { + super(key, defaultValue, userDialogMessage); + } + public IntegerSetting(String key, Integer defaultValue, Availability availability) { + super(key, defaultValue, availability); + } + public IntegerSetting(String key, Integer defaultValue, boolean rebootApp, String userDialogMessage) { + super(key, defaultValue, rebootApp, userDialogMessage); + } + public IntegerSetting(String key, Integer defaultValue, boolean rebootApp, Availability availability) { + super(key, defaultValue, rebootApp, availability); + } + public IntegerSetting(String key, Integer defaultValue, boolean rebootApp, String userDialogMessage, Availability availability) { + super(key, defaultValue, rebootApp, userDialogMessage, availability); + } + public IntegerSetting(@NonNull String key, @NonNull Integer defaultValue, boolean rebootApp, boolean includeWithImportExport, @Nullable String userDialogMessage, @Nullable Availability availability) { + super(key, defaultValue, rebootApp, includeWithImportExport, userDialogMessage, availability); + } + + @Override + protected void load() { + value = preferences.getIntegerString(key, defaultValue); + } + + @Override + protected Integer readFromJSON(JSONObject json, String importExportKey) throws JSONException { + return json.getInt(importExportKey); + } + + @Override + protected void setValueFromString(@NonNull String newValue) { + value = Integer.valueOf(Objects.requireNonNull(newValue)); + } + + @Override + public void save(@NonNull Integer newValue) { + // Must set before saving to preferences (otherwise importing fails to update UI correctly). + value = Objects.requireNonNull(newValue); + preferences.saveIntegerString(key, newValue); + } + + @NonNull + @Override + public Integer get() { + return value; + } +} diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/LongSetting.java b/app/src/main/java/app/revanced/integrations/shared/settings/LongSetting.java new file mode 100644 index 0000000000..1c7287a8f7 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/shared/settings/LongSetting.java @@ -0,0 +1,69 @@ +package app.revanced.integrations.shared.settings; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Objects; + +@SuppressWarnings("unused") +public class LongSetting extends Setting { + + public LongSetting(String key, Long defaultValue) { + super(key, defaultValue); + } + public LongSetting(String key, Long defaultValue, boolean rebootApp) { + super(key, defaultValue, rebootApp); + } + public LongSetting(String key, Long defaultValue, boolean rebootApp, boolean includeWithImportExport) { + super(key, defaultValue, rebootApp, includeWithImportExport); + } + public LongSetting(String key, Long defaultValue, String userDialogMessage) { + super(key, defaultValue, userDialogMessage); + } + public LongSetting(String key, Long defaultValue, Availability availability) { + super(key, defaultValue, availability); + } + public LongSetting(String key, Long defaultValue, boolean rebootApp, String userDialogMessage) { + super(key, defaultValue, rebootApp, userDialogMessage); + } + public LongSetting(String key, Long defaultValue, boolean rebootApp, Availability availability) { + super(key, defaultValue, rebootApp, availability); + } + public LongSetting(String key, Long defaultValue, boolean rebootApp, String userDialogMessage, Availability availability) { + super(key, defaultValue, rebootApp, userDialogMessage, availability); + } + public LongSetting(@NonNull String key, @NonNull Long defaultValue, boolean rebootApp, boolean includeWithImportExport, @Nullable String userDialogMessage, @Nullable Availability availability) { + super(key, defaultValue, rebootApp, includeWithImportExport, userDialogMessage, availability); + } + + @Override + protected void load() { + value = preferences.getLongString(key, defaultValue); + } + + @Override + protected Long readFromJSON(JSONObject json, String importExportKey) throws JSONException { + return json.getLong(importExportKey); + } + + @Override + protected void setValueFromString(@NonNull String newValue) { + value = Long.valueOf(Objects.requireNonNull(newValue)); + } + + @Override + public void save(@NonNull Long newValue) { + // Must set before saving to preferences (otherwise importing fails to update UI correctly). + value = Objects.requireNonNull(newValue); + preferences.saveLongString(key, newValue); + } + + @NonNull + @Override + public Long get() { + return value; + } +} diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/Setting.java b/app/src/main/java/app/revanced/integrations/shared/settings/Setting.java new file mode 100644 index 0000000000..33dc8f0557 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/shared/settings/Setting.java @@ -0,0 +1,429 @@ +package app.revanced.integrations.shared.settings; + +import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.StringRef; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.settings.preference.SharedPrefCategory; +import app.revanced.integrations.youtube.sponsorblock.SponsorBlockSettings; +import org.jetbrains.annotations.NotNull; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.*; + +import static app.revanced.integrations.shared.StringRef.str; + +@SuppressWarnings("unused") +public abstract class Setting { + + /** + * Indicates if a {@link Setting} is available to edit and use. + * Typically this is dependent upon other BooleanSetting(s) set to 'true', + * but this can be used to call into integrations code and check other conditions. + */ + public interface Availability { + boolean isAvailable(); + } + + /** + * Availability based on a single parent setting being enabled. + */ + @NonNull + public static Availability parent(@NonNull BooleanSetting parent) { + return parent::get; + } + + /** + * Availability based on all parents being enabled. + */ + @NonNull + public static Availability parentsAll(@NonNull BooleanSetting... parents) { + return () -> { + for (BooleanSetting parent : parents) { + if (!parent.get()) return false; + } + return true; + }; + } + + /** + * Availability based on any parent being enabled. + */ + @NonNull + public static Availability parentsAny(@NonNull BooleanSetting... parents) { + return () -> { + for (BooleanSetting parent : parents) { + if (parent.get()) return true; + } + return false; + }; + } + + /** + * All settings that were instantiated. + * When a new setting is created, it is automatically added to this list. + */ + private static final List> SETTINGS = new ArrayList<>(); + + /** + * Map of setting path to setting object. + */ + private static final Map> PATH_TO_SETTINGS = new HashMap<>(); + + /** + * Preference all instances are saved to. + */ + public static final SharedPrefCategory preferences = new SharedPrefCategory("revanced_prefs"); + + @Nullable + public static Setting getSettingFromPath(@NonNull String str) { + return PATH_TO_SETTINGS.get(str); + } + + /** + * @return All settings that have been created. + */ + @NonNull + public static List> allLoadedSettings() { + return Collections.unmodifiableList(SETTINGS); + } + + /** + * @return All settings that have been created, sorted by keys. + */ + @NonNull + private static List> allLoadedSettingsSorted() { + Collections.sort(SETTINGS, (Setting o1, Setting o2) -> o1.key.compareTo(o2.key)); + return Collections.unmodifiableList(SETTINGS); + } + + /** + * The key used to store the value in the shared preferences. + */ + @NonNull + public final String key; + + /** + * The default value of the setting. + */ + @NonNull + public final T defaultValue; + + /** + * If the app should be rebooted, if this setting is changed + */ + public final boolean rebootApp; + + /** + * If this setting should be included when importing/exporting settings. + */ + public final boolean includeWithImportExport; + + /** + * If this setting is available to edit and use. + * Not to be confused with it's status returned from {@link #get()}. + */ + @Nullable + private final Availability availability; + + /** + * Confirmation message to display, if the user tries to change the setting from the default value. + */ + @Nullable + public final StringRef userDialogMessage; + + // Must be volatile, as some settings are read/write from different threads. + // Of note, the object value is persistently stored using SharedPreferences (which is thread safe). + /** + * The value of the setting. + */ + @NonNull + protected volatile T value; + + public Setting(String key, T defaultValue) { + this(key, defaultValue, false, true, null, null); + } + public Setting(String key, T defaultValue, boolean rebootApp) { + this(key, defaultValue, rebootApp, true, null, null); + } + public Setting(String key, T defaultValue, boolean rebootApp, boolean includeWithImportExport) { + this(key, defaultValue, rebootApp, includeWithImportExport, null, null); + } + public Setting(String key, T defaultValue, String userDialogMessage) { + this(key, defaultValue, false, true, userDialogMessage, null); + } + public Setting(String key, T defaultValue, Availability availability) { + this(key, defaultValue, false, true, null, availability); + } + public Setting(String key, T defaultValue, boolean rebootApp, String userDialogMessage) { + this(key, defaultValue, rebootApp, true, userDialogMessage, null); + } + public Setting(String key, T defaultValue, boolean rebootApp, Availability availability) { + this(key, defaultValue, rebootApp, true, null, availability); + } + public Setting(String key, T defaultValue, boolean rebootApp, String userDialogMessage, Availability availability) { + this(key, defaultValue, rebootApp, true, userDialogMessage, availability); + } + + /** + * A setting backed by a shared preference. + * + * @param key The key used to store the value in the shared preferences. + * @param defaultValue The default value of the setting. + * @param rebootApp If the app should be rebooted, if this setting is changed. + * @param includeWithImportExport If this setting should be shown in the import/export dialog. + * @param userDialogMessage Confirmation message to display, if the user tries to change the setting from the default value. + * @param availability Condition that must be true, for this setting to be available to configure. + */ + public Setting(@NonNull String key, + @NonNull T defaultValue, + boolean rebootApp, + boolean includeWithImportExport, + @Nullable String userDialogMessage, + @Nullable Availability availability + ) { + this.key = Objects.requireNonNull(key); + this.value = this.defaultValue = Objects.requireNonNull(defaultValue); + this.rebootApp = rebootApp; + this.includeWithImportExport = includeWithImportExport; + this.userDialogMessage = (userDialogMessage == null) ? null : new StringRef(userDialogMessage); + this.availability = availability; + + SETTINGS.add(this); + if (PATH_TO_SETTINGS.put(key, this) != null) { + // Debug setting may not be created yet so using Logger may cause an initialization crash. + // Show a toast instead. + Utils.showToastLong(this.getClass().getSimpleName() + + " error: Duplicate Setting key found: " + key); + } + + load(); + } + + /** + * Migrate a setting value if the path is renamed but otherwise the old and new settings are identical. + */ + public static void migrateOldSettingToNew(@NonNull Setting oldSetting, @NonNull Setting newSetting) { + if (!oldSetting.isSetToDefault()) { + Logger.printInfo(() -> "Migrating old setting value: " + oldSetting + " into replacement setting: " + newSetting); + //noinspection unchecked + newSetting.save(oldSetting.value); + oldSetting.resetToDefault(); + } + } + + /** + * Migrate an old Setting value previously stored in a different SharedPreference. + * + * This method will be deleted in the future. + */ + public static void migrateFromOldPreferences(@NonNull SharedPrefCategory oldPrefs, @NonNull Setting setting, String settingKey) { + if (!oldPrefs.preferences.contains(settingKey)) { + return; // Nothing to do. + } + Object newValue = setting.get(); + final Object migratedValue; + if (setting instanceof BooleanSetting) { + migratedValue = oldPrefs.getBoolean(settingKey, (Boolean) newValue); + } else if (setting instanceof IntegerSetting) { + migratedValue = oldPrefs.getIntegerString(settingKey, (Integer) newValue); + } else if (setting instanceof LongSetting) { + migratedValue = oldPrefs.getLongString(settingKey, (Long) newValue); + } else if (setting instanceof FloatSetting) { + migratedValue = oldPrefs.getFloatString(settingKey, (Float) newValue); + } else if (setting instanceof StringSetting) { + migratedValue = oldPrefs.getString(settingKey, (String) newValue); + } else { + Logger.printException(() -> "Unknown setting: " + setting); + return; + } + oldPrefs.preferences.edit().remove(settingKey).apply(); // Remove the old setting. + if (migratedValue.equals(newValue)) { + Logger.printDebug(() -> "Value does not need migrating: " + settingKey); + return; // Old value is already equal to the new setting value. + } + Logger.printDebug(() -> "Migrating old preference value into current preference: " + settingKey); + //noinspection unchecked + setting.save(migratedValue); + } + + /** + * Sets, but does _not_ persistently save the value. + * This method is only to be used by the Settings preference code. + * + * This intentionally is a static method to deter + * accidental usage when {@link #save(Object)} was intended. + */ + public static void privateSetValueFromString(@NonNull Setting setting, @NonNull String newValue) { + setting.setValueFromString(newValue); + } + + /** + * Sets the value of {@link #value}, but do not save to {@link #preferences}. + */ + protected abstract void setValueFromString(@NonNull String newValue); + + /** + * Load and set the value of {@link #value}. + */ + protected abstract void load(); + + /** + * Persistently saves the value. + */ + public abstract void save(@NonNull T newValue); + + @NonNull + public abstract T get(); + + /** + * Identical to calling {@link #save(Object)} using {@link #defaultValue}. + */ + public void resetToDefault() { + save(defaultValue); + } + + /** + * @return if this setting can be configured and used. + */ + public boolean isAvailable() { + return availability == null || availability.isAvailable(); + } + + /** + * @return if the currently set value is the same as {@link #defaultValue} + */ + public boolean isSetToDefault() { + return value.equals(defaultValue); + } + + @NotNull + @Override + public String toString() { + return key + "=" + get(); + } + + // region Import / export + + /** + * If a setting path has this prefix, then remove it before importing/exporting. + */ + private static final String OPTIONAL_REVANCED_SETTINGS_PREFIX = "revanced_"; + + /** + * The path, minus any 'revanced' prefix to keep json concise. + */ + private String getImportExportKey() { + if (key.startsWith(OPTIONAL_REVANCED_SETTINGS_PREFIX)) { + return key.substring(OPTIONAL_REVANCED_SETTINGS_PREFIX.length()); + } + return key; + } + + /** + * @return the value stored using the import/export key. Do not set any values in this method. + */ + protected abstract T readFromJSON(JSONObject json, String importExportKey) throws JSONException; + + /** + * Saves this instance to JSON. + *

+ * To keep the JSON simple and readable, + * subclasses should not write out any embedded types (such as JSON Array or Dictionaries). + *

+ * If this instance is not a type supported natively by JSON (ie: it's not a String/Integer/Float/Long), + * then subclasses can override this method and write out a String value representing the value. + */ + protected void writeToJSON(JSONObject json, String importExportKey) throws JSONException { + json.put(importExportKey, value); + } + + @NonNull + public static String exportToJson(@Nullable Context alertDialogContext) { + try { + JSONObject json = new JSONObject(); + for (Setting setting : allLoadedSettingsSorted()) { + String importExportKey = setting.getImportExportKey(); + if (json.has(importExportKey)) { + throw new IllegalArgumentException("duplicate key found: " + importExportKey); + } + + final boolean exportDefaultValues = false; // Enable to see what all settings looks like in the UI. + //noinspection ConstantValue + if (setting.includeWithImportExport && (!setting.isSetToDefault() || exportDefaultValues)) { + setting.writeToJSON(json, importExportKey); + } + } + SponsorBlockSettings.showExportWarningIfNeeded(alertDialogContext); + + if (json.length() == 0) { + return ""; + } + + String export = json.toString(0); + + // Remove the outer JSON braces to make the output more compact, + // and leave less chance of the user forgetting to copy it + return export.substring(2, export.length() - 2); + } catch (JSONException e) { + Logger.printException(() -> "Export failure", e); // should never happen + return ""; + } + } + + /** + * @return if any settings that require a reboot were changed. + */ + public static boolean importFromJSON(@NonNull String settingsJsonString) { + try { + if (!settingsJsonString.matches("[\\s\\S]*\\{")) { + settingsJsonString = '{' + settingsJsonString + '}'; // Restore outer JSON braces + } + JSONObject json = new JSONObject(settingsJsonString); + + boolean rebootSettingChanged = false; + int numberOfSettingsImported = 0; + for (Setting setting : SETTINGS) { + String key = setting.getImportExportKey(); + if (json.has(key)) { + Object value = setting.readFromJSON(json, key); + if (!setting.get().equals(value)) { + rebootSettingChanged |= setting.rebootApp; + //noinspection unchecked + setting.save(value); + } + numberOfSettingsImported++; + } else if (setting.includeWithImportExport && !setting.isSetToDefault()) { + Logger.printDebug(() -> "Resetting to default: " + setting); + rebootSettingChanged |= setting.rebootApp; + setting.resetToDefault(); + } + } + + // SB Enum categories are saved using StringSettings. + // Which means they need to reload again if changed by other code (such as here). + // This call could be removed by creating a custom Setting class that manages the + // "String <-> Enum" logic or by adding an event hook of when settings are imported. + // But for now this is simple and works. + SponsorBlockSettings.updateFromImportedSettings(); + + Utils.showToastLong(numberOfSettingsImported == 0 + ? str("revanced_settings_import_reset") + : str("revanced_settings_import_success", numberOfSettingsImported)); + + return rebootSettingChanged; + } catch (JSONException | IllegalArgumentException ex) { + Utils.showToastLong(str("revanced_settings_import_failure_parse", ex.getMessage())); + Logger.printInfo(() -> "", ex); + } catch (Exception ex) { + Logger.printException(() -> "Import failure: " + ex.getMessage(), ex); // should never happen + } + return false; + } + + // End import / export + +} diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/StringSetting.java b/app/src/main/java/app/revanced/integrations/shared/settings/StringSetting.java new file mode 100644 index 0000000000..247cc00cac --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/shared/settings/StringSetting.java @@ -0,0 +1,69 @@ +package app.revanced.integrations.shared.settings; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Objects; + +@SuppressWarnings("unused") +public class StringSetting extends Setting { + + public StringSetting(String key, String defaultValue) { + super(key, defaultValue); + } + public StringSetting(String key, String defaultValue, boolean rebootApp) { + super(key, defaultValue, rebootApp); + } + public StringSetting(String key, String defaultValue, boolean rebootApp, boolean includeWithImportExport) { + super(key, defaultValue, rebootApp, includeWithImportExport); + } + public StringSetting(String key, String defaultValue, String userDialogMessage) { + super(key, defaultValue, userDialogMessage); + } + public StringSetting(String key, String defaultValue, Availability availability) { + super(key, defaultValue, availability); + } + public StringSetting(String key, String defaultValue, boolean rebootApp, String userDialogMessage) { + super(key, defaultValue, rebootApp, userDialogMessage); + } + public StringSetting(String key, String defaultValue, boolean rebootApp, Availability availability) { + super(key, defaultValue, rebootApp, availability); + } + public StringSetting(String key, String defaultValue, boolean rebootApp, String userDialogMessage, Availability availability) { + super(key, defaultValue, rebootApp, userDialogMessage, availability); + } + public StringSetting(@NonNull String key, @NonNull String defaultValue, boolean rebootApp, boolean includeWithImportExport, @Nullable String userDialogMessage, @Nullable Availability availability) { + super(key, defaultValue, rebootApp, includeWithImportExport, userDialogMessage, availability); + } + + @Override + protected void load() { + value = preferences.getString(key, defaultValue); + } + + @Override + protected String readFromJSON(JSONObject json, String importExportKey) throws JSONException { + return json.getString(importExportKey); + } + + @Override + protected void setValueFromString(@NonNull String newValue) { + value = Objects.requireNonNull(newValue); + } + + @Override + public void save(@NonNull String newValue) { + // Must set before saving to preferences (otherwise importing fails to update UI correctly). + value = Objects.requireNonNull(newValue); + preferences.saveString(key, newValue); + } + + @NonNull + @Override + public String get() { + return value; + } +} diff --git a/app/src/main/java/app/revanced/integrations/shared/settings/preference/AbstractPreferenceFragment.java b/app/src/main/java/app/revanced/integrations/shared/settings/preference/AbstractPreferenceFragment.java new file mode 100644 index 0000000000..1f36ac4305 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/shared/settings/preference/AbstractPreferenceFragment.java @@ -0,0 +1,240 @@ +package app.revanced.integrations.shared.settings.preference; + +import android.annotation.SuppressLint; +import android.app.AlertDialog; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.*; +import androidx.annotation.NonNull; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.settings.BooleanSetting; +import app.revanced.integrations.shared.settings.Setting; + +import static app.revanced.integrations.shared.StringRef.str; + +/** + * + * + * @noinspection deprecation, DataFlowIssue , unused */ +public abstract class AbstractPreferenceFragment extends PreferenceFragment { + /** + * Indicates that if a preference changes, + * to apply the change from the Setting to the UI component. + */ + public static boolean settingImportInProgress; + + /** + * Used to prevent showing reboot dialog, if user cancels a setting user dialog. + */ + private boolean showingUserDialogMessage; + + private final SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { + try { + Setting setting = Setting.getSettingFromPath(str); + if (setting == null) { + return; + } + Preference pref = findPreference(str); + if (pref == null) { + return; + } + Logger.printDebug(() -> "Preference changed: " + setting.key); + + // Apply 'Setting <- Preference', unless during importing when it needs to be 'Setting -> Preference'. + updatePreference(pref, setting, true, settingImportInProgress); + // Update any other preference availability that may now be different. + updateUIAvailability(); + + if (settingImportInProgress) { + return; + } + + if (!showingUserDialogMessage) { + if (setting.userDialogMessage != null && ((SwitchPreference) pref).isChecked() != (Boolean) setting.defaultValue) { + showSettingUserDialogConfirmation((SwitchPreference) pref, (BooleanSetting) setting); + } else if (setting.rebootApp) { + showRestartDialog(getContext()); + } + } + + } catch (Exception ex) { + Logger.printException(() -> "OnSharedPreferenceChangeListener failure", ex); + } + }; + + /** + * Initialize this instance, and do any custom behavior. + *

+ * To ensure all {@link Setting} instances are correctly synced to the UI, + * it is important that subclasses make a call or otherwise reference their Settings class bundle + * so all app specific {@link Setting} instances are loaded before this method returns. + */ + protected void initialize() { + final var identifier = Utils.getResourceIdentifier("revanced_prefs", "xml"); + + if (identifier == 0) return; + addPreferencesFromResource(identifier); + Utils.sortPreferenceGroupByTitle(getPreferenceScreen(), 2); + } + + private void showSettingUserDialogConfirmation(SwitchPreference switchPref, BooleanSetting setting) { + final var context = getContext(); + + showingUserDialogMessage = true; + new AlertDialog.Builder(context) + .setTitle(str("revanced_settings_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) -> { + switchPref.setChecked(setting.defaultValue); // Recursive call that resets the Setting value. + }) + .setOnDismissListener(dialog -> { + showingUserDialogMessage = false; + }) + .setCancelable(false) + .show(); + } + + /** + * Updates all Preferences values and their availability using the current values in {@link Setting}. + */ + protected void updateUIToSettingValues() { + updatePreferenceScreen(getPreferenceScreen(), true,true); + } + + /** + * Updates Preferences availability only using the status of {@link Setting}. + */ + protected void updateUIAvailability() { + updatePreferenceScreen(getPreferenceScreen(), false, false); + } + + /** + * Syncs all UI Preferences to any {@link Setting} they represent. + */ + private void updatePreferenceScreen(@NonNull PreferenceScreen screen, + boolean syncSettingValue, + boolean applySettingToPreference) { + // Alternatively this could iterate thru all Settings and check for any matching Preferences, + // but there are many more Settings than UI preferences so it's more efficient to only check + // the Preferences. + for (int i = 0, prefCount = screen.getPreferenceCount(); i < prefCount; i++) { + Preference pref = screen.getPreference(i); + if (pref instanceof PreferenceScreen) { + updatePreferenceScreen((PreferenceScreen) pref, syncSettingValue, applySettingToPreference); + } else if (pref.hasKey()) { + String key = pref.getKey(); + Setting setting = Setting.getSettingFromPath(key); + if (setting != null) { + updatePreference(pref, setting, syncSettingValue, applySettingToPreference); + } + } + } + } + + /** + * Updates a UI Preference with the {@link Setting} that backs it. + * If needed, subclasses can override this to handle additional UI Preference types. + * + * @param syncSetting If the UI should be synced {@link Setting} <-> Preference + * @param applySettingToPreference If true, then apply {@link Setting} -> Preference. + * If false, then apply {@link Setting} <- Preference. + */ + protected void updatePreference(@NonNull Preference pref, @NonNull Setting setting, + boolean syncSetting, boolean applySettingToPreference) { + if (!syncSetting && applySettingToPreference) { + throw new IllegalArgumentException(); + } + if (syncSetting) { + if (pref instanceof SwitchPreference) { + SwitchPreference switchPref = (SwitchPreference) pref; + BooleanSetting boolSetting = (BooleanSetting) setting; + if (applySettingToPreference) { + switchPref.setChecked(boolSetting.get()); + } else { + BooleanSetting.privateSetValue(boolSetting, switchPref.isChecked()); + } + } else if (pref instanceof EditTextPreference) { + EditTextPreference editPreference = (EditTextPreference) pref; + if (applySettingToPreference) { + editPreference.setText(setting.get().toString()); + } else { + Setting.privateSetValueFromString(setting, editPreference.getText()); + } + } else if (pref instanceof ListPreference) { + ListPreference listPref = (ListPreference) pref; + if (applySettingToPreference) { + listPref.setValue(setting.get().toString()); + } else { + Setting.privateSetValueFromString(setting, listPref.getValue()); + } + updateListPreferenceSummary(listPref, setting); + } else { + Logger.printException(() -> "Setting cannot be handled: " + pref.getClass() + ": " + pref); + return; + } + } + updatePreferenceAvailability(pref, setting); + } + + protected void updatePreferenceAvailability(@NonNull Preference pref, @NonNull Setting setting) { + pref.setEnabled(setting.isAvailable()); + } + + protected void updateListPreferenceSummary(ListPreference listPreference, Setting setting) { + String objectStringValue = setting.get().toString(); + final int entryIndex = listPreference.findIndexOfValue(objectStringValue); + if (entryIndex >= 0) { + listPreference.setSummary(listPreference.getEntries()[entryIndex]); + } else { + // Value is not an available option. + // User manually edited import data, or options changed and current selection is no longer available. + // Still show the value in the summary, so it's clear that something is selected. + listPreference.setSummary(objectStringValue); + } + } + + public static void showRestartDialog(@NonNull final Context context) { + String positiveButton = str("revanced_settings_restart"); + + new AlertDialog.Builder(context).setMessage(str("revanced_settings_restart_title")) + .setPositiveButton(positiveButton, (dialog, id) -> { + Utils.restartApp(context); + }) + .setNegativeButton(android.R.string.cancel, null) + .setCancelable(false) + .show(); + } + + @SuppressLint("ResourceType") + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + try { + PreferenceManager preferenceManager = getPreferenceManager(); + preferenceManager.setSharedPreferencesName(Setting.preferences.name); + + // Must initialize before adding change listener, + // otherwise the syncing of Setting -> UI + // causes a callback to the listener even though nothing changed. + initialize(); + updateUIToSettingValues(); + + preferenceManager.getSharedPreferences().registerOnSharedPreferenceChangeListener(listener); + } catch (Exception ex) { + Logger.printException(() -> "onCreate() failure", ex); + } + } + + @Override + public void onDestroy() { + getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(listener); + super.onDestroy(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/ImportExportPreference.java b/app/src/main/java/app/revanced/integrations/shared/settings/preference/ImportExportPreference.java similarity index 73% rename from app/src/main/java/app/revanced/integrations/settingsmenu/ImportExportPreference.java rename to app/src/main/java/app/revanced/integrations/shared/settings/preference/ImportExportPreference.java index d66c8ab110..0a9b54c1dd 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/ImportExportPreference.java +++ b/app/src/main/java/app/revanced/integrations/shared/settings/preference/ImportExportPreference.java @@ -1,6 +1,4 @@ -package app.revanced.integrations.settingsmenu; - -import static app.revanced.integrations.utils.StringRef.str; +package app.revanced.integrations.shared.settings.preference; import android.app.AlertDialog; import android.content.Context; @@ -11,11 +9,13 @@ import android.util.AttributeSet; import android.util.TypedValue; import android.widget.EditText; +import app.revanced.integrations.shared.settings.Setting; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import static app.revanced.integrations.shared.StringRef.str; +/** @noinspection deprecation, unused */ public class ImportExportPreference extends EditTextPreference implements Preference.OnPreferenceClickListener { private String existingSettings; @@ -55,10 +55,10 @@ public ImportExportPreference(Context context) { public boolean onPreferenceClick(Preference preference) { try { // Must set text before preparing dialog, otherwise text is non selectable if this preference is later reopened. - existingSettings = SettingsEnum.exportJSON(getContext()); + existingSettings = Setting.exportToJson(getContext()); getEditText().setText(existingSettings); } catch (Exception ex) { - LogHelper.printException(() -> "showDialog failure", ex); + Logger.printException(() -> "showDialog failure", ex); } return true; } @@ -68,12 +68,12 @@ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { try { // Show the user the settings in JSON format. builder.setNeutralButton(str("revanced_settings_import_copy"), (dialog, which) -> { - ReVancedUtils.setClipboard(getEditText().getText().toString()); + Utils.setClipboard(getEditText().getText().toString()); }).setPositiveButton(str("revanced_settings_import"), (dialog, which) -> { importSettings(getEditText().getText().toString()); }); } catch (Exception ex) { - LogHelper.printException(() -> "onPrepareDialogBuilder failure", ex); + Logger.printException(() -> "onPrepareDialogBuilder failure", ex); } } @@ -82,15 +82,15 @@ private void importSettings(String replacementSettings) { if (replacementSettings.equals(existingSettings)) { return; } - ReVancedSettingsFragment.settingImportInProgress = true; - final boolean rebootNeeded = SettingsEnum.importJSON(replacementSettings); + AbstractPreferenceFragment.settingImportInProgress = true; + final boolean rebootNeeded = Setting.importFromJSON(replacementSettings); if (rebootNeeded) { - ReVancedSettingsFragment.showRestartDialog(getContext()); + AbstractPreferenceFragment.showRestartDialog(getContext()); } } catch (Exception ex) { - LogHelper.printException(() -> "importSettings failure", ex); + Logger.printException(() -> "importSettings failure", ex); } finally { - ReVancedSettingsFragment.settingImportInProgress = false; + AbstractPreferenceFragment.settingImportInProgress = false; } } diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/ResettableEditTextPreference.java b/app/src/main/java/app/revanced/integrations/shared/settings/preference/ResettableEditTextPreference.java similarity index 79% rename from app/src/main/java/app/revanced/integrations/settingsmenu/ResettableEditTextPreference.java rename to app/src/main/java/app/revanced/integrations/shared/settings/preference/ResettableEditTextPreference.java index f4a47e8a8f..804b51c400 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/ResettableEditTextPreference.java +++ b/app/src/main/java/app/revanced/integrations/shared/settings/preference/ResettableEditTextPreference.java @@ -1,6 +1,4 @@ -package app.revanced.integrations.settingsmenu; - -import static app.revanced.integrations.utils.StringRef.str; +package app.revanced.integrations.shared.settings.preference; import android.app.AlertDialog; import android.content.Context; @@ -9,12 +7,14 @@ import android.util.AttributeSet; import android.widget.Button; import android.widget.EditText; +import app.revanced.integrations.shared.settings.Setting; +import app.revanced.integrations.shared.Logger; import java.util.Objects; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; +import static app.revanced.integrations.shared.StringRef.str; +@SuppressWarnings("unused") public class ResettableEditTextPreference extends EditTextPreference { public ResettableEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { @@ -33,7 +33,7 @@ public ResettableEditTextPreference(Context context) { @Override protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { super.onPrepareDialogBuilder(builder); - SettingsEnum setting = SettingsEnum.settingFromPath(getKey()); + Setting setting = Setting.getSettingFromPath(getKey()); if (setting != null) { builder.setNeutralButton(str("revanced_settings_reset"), null); } @@ -50,13 +50,13 @@ protected void showDialog(Bundle state) { } button.setOnClickListener(v -> { try { - SettingsEnum setting = Objects.requireNonNull(SettingsEnum.settingFromPath(getKey())); + Setting setting = Objects.requireNonNull(Setting.getSettingFromPath(getKey())); String defaultStringValue = setting.defaultValue.toString(); EditText editText = getEditText(); editText.setText(defaultStringValue); editText.setSelection(defaultStringValue.length()); // move cursor to end of text } catch (Exception ex) { - LogHelper.printException(() -> "reset failure", ex); + Logger.printException(() -> "reset failure", ex); } }); } diff --git a/app/src/main/java/app/revanced/integrations/settings/SharedPrefCategory.java b/app/src/main/java/app/revanced/integrations/shared/settings/preference/SharedPrefCategory.java similarity index 84% rename from app/src/main/java/app/revanced/integrations/settings/SharedPrefCategory.java rename to app/src/main/java/app/revanced/integrations/shared/settings/preference/SharedPrefCategory.java index 17799e2538..1a92e9f072 100644 --- a/app/src/main/java/app/revanced/integrations/settings/SharedPrefCategory.java +++ b/app/src/main/java/app/revanced/integrations/shared/settings/preference/SharedPrefCategory.java @@ -1,43 +1,37 @@ -package app.revanced.integrations.settings; +package app.revanced.integrations.shared.settings.preference; import android.content.Context; import android.content.SharedPreferences; - +import android.preference.PreferenceFragment; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; import java.util.Objects; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; - /** * Shared categories, and helper methods. * * The various save methods store numbers as Strings, - * which is required if using {@link android.preference.PreferenceFragment}. + * which is required if using {@link PreferenceFragment}. * * If saved numbers will not be used with a preference fragment, - * then store the primitive numbers using {@link #preferences}. + * then store the primitive numbers using the {@link #preferences} itself. */ -public enum SharedPrefCategory { - YOUTUBE("youtube"), - RETURN_YOUTUBE_DISLIKE("ryd"), - SPONSOR_BLOCK("sponsor-block"), - REVANCED_PREFS("revanced_prefs"); - +public class SharedPrefCategory { @NonNull - public final String prefName; + public final String name; @NonNull public final SharedPreferences preferences; - SharedPrefCategory(@NonNull String prefName) { - this.prefName = Objects.requireNonNull(prefName); - preferences = Objects.requireNonNull(ReVancedUtils.getContext()).getSharedPreferences(prefName, Context.MODE_PRIVATE); + public SharedPrefCategory(@NonNull String name) { + this.name = Objects.requireNonNull(name); + preferences = Objects.requireNonNull(Utils.getContext()).getSharedPreferences(name, Context.MODE_PRIVATE); } private void removeConflictingPreferenceKeyValue(@NonNull String key) { - LogHelper.printException(() -> "Found conflicting preference: " + key); + Logger.printException(() -> "Found conflicting preference: " + key); preferences.edit().remove(key).apply(); } @@ -89,7 +83,6 @@ public String getString(@NonNull String key, @NonNull String _default) { } } - public boolean getBoolean(@NonNull String key, boolean _default) { try { return preferences.getBoolean(key, _default); @@ -159,6 +152,6 @@ public Float getFloatString(@NonNull String key, @NonNull Float _default) { @NonNull @Override public String toString() { - return prefName; + return name; } } diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategory.java b/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategory.java deleted file mode 100644 index ed34bf10d2..0000000000 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategory.java +++ /dev/null @@ -1,396 +0,0 @@ -package app.revanced.integrations.sponsorblock.objects; - -import static app.revanced.integrations.sponsorblock.objects.CategoryBehaviour.IGNORE; -import static app.revanced.integrations.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP; -import static app.revanced.integrations.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY; -import static app.revanced.integrations.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE; -import static app.revanced.integrations.utils.StringRef.sf; - -import android.content.SharedPreferences; -import android.graphics.Color; -import android.graphics.Paint; -import android.text.Html; -import android.text.Spanned; -import android.text.TextUtils; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.settings.SharedPrefCategory; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.StringRef; - -public enum SegmentCategory { - SPONSOR("sponsor", sf("sb_segments_sponsor"), sf("sb_segments_sponsor_sum"), sf("sb_skip_button_sponsor"), sf("sb_skipped_sponsor"), - SKIP_AUTOMATICALLY_ONCE, 0x00D400), - SELF_PROMO("selfpromo", sf("sb_segments_selfpromo"), sf("sb_segments_selfpromo_sum"), sf("sb_skip_button_selfpromo"), sf("sb_skipped_selfpromo"), - MANUAL_SKIP, 0xFFFF00), - INTERACTION("interaction", sf("sb_segments_interaction"), sf("sb_segments_interaction_sum"), sf("sb_skip_button_interaction"), sf("sb_skipped_interaction"), - MANUAL_SKIP, 0xCC00FF), - /** - * Unique category that is treated differently than the rest. - */ - HIGHLIGHT("poi_highlight", sf("sb_segments_highlight"), sf("sb_segments_highlight_sum"), sf("sb_skip_button_highlight"), sf("sb_skipped_highlight"), - MANUAL_SKIP, 0xFF1684), - INTRO("intro", sf("sb_segments_intro"), sf("sb_segments_intro_sum"), - sf("sb_skip_button_intro_beginning"), sf("sb_skip_button_intro_middle"), sf("sb_skip_button_intro_end"), - sf("sb_skipped_intro_beginning"), sf("sb_skipped_intro_middle"), sf("sb_skipped_intro_end"), - MANUAL_SKIP, 0x00FFFF), - OUTRO("outro", sf("sb_segments_outro"), sf("sb_segments_outro_sum"), sf("sb_skip_button_outro"), sf("sb_skipped_outro"), - MANUAL_SKIP, 0x0202ED), - PREVIEW("preview", sf("sb_segments_preview"), sf("sb_segments_preview_sum"), - sf("sb_skip_button_preview_beginning"), sf("sb_skip_button_preview_middle"), sf("sb_skip_button_preview_end"), - sf("sb_skipped_preview_beginning"), sf("sb_skipped_preview_middle"), sf("sb_skipped_preview_end"), - IGNORE, 0x008FD6), - FILLER("filler", sf("sb_segments_filler"), sf("sb_segments_filler_sum"), sf("sb_skip_button_filler"), sf("sb_skipped_filler"), - IGNORE, 0x7300FF), - MUSIC_OFFTOPIC("music_offtopic", sf("sb_segments_nomusic"), sf("sb_segments_nomusic_sum"), sf("sb_skip_button_nomusic"), sf("sb_skipped_nomusic"), - MANUAL_SKIP, 0xFF9900), - UNSUBMITTED("unsubmitted", StringRef.empty, StringRef.empty, sf("sb_skip_button_unsubmitted"), sf("sb_skipped_unsubmitted"), - SKIP_AUTOMATICALLY, 0xFFFFFF); - - private static final StringRef skipSponsorTextCompact = sf("sb_skip_button_compact"); - private static final StringRef skipSponsorTextCompactHighlight = sf("sb_skip_button_compact_highlight"); - - /** - * Prefix to use when serializing to flat JSON layout used with ReVanced import/export. - */ - private static final String FLAT_JSON_IMPORT_EXPORT_PREFIX = "sb_"; - - private static final SegmentCategory[] categoriesWithoutHighlights = new SegmentCategory[]{ - SPONSOR, - SELF_PROMO, - INTERACTION, - INTRO, - OUTRO, - PREVIEW, - FILLER, - MUSIC_OFFTOPIC, - }; - - private static final SegmentCategory[] categoriesWithoutUnsubmitted = new SegmentCategory[]{ - SPONSOR, - SELF_PROMO, - INTERACTION, - HIGHLIGHT, - INTRO, - OUTRO, - PREVIEW, - FILLER, - MUSIC_OFFTOPIC, - }; - private static final Map mValuesMap = new HashMap<>(2 * categoriesWithoutUnsubmitted.length); - - private static final String COLOR_PREFERENCE_KEY_SUFFIX = "_color"; - - /** - * Categories currently enabled, formatted for an API call - */ - public static String sponsorBlockAPIFetchCategories = "[]"; - - static { - for (SegmentCategory value : categoriesWithoutUnsubmitted) - mValuesMap.put(value.key, value); - } - - @NonNull - public static SegmentCategory[] categoriesWithoutUnsubmitted() { - return categoriesWithoutUnsubmitted; - } - - @NonNull - public static SegmentCategory[] categoriesWithoutHighlights() { - return categoriesWithoutHighlights; - } - - @Nullable - public static SegmentCategory byCategoryKey(@NonNull String key) { - return mValuesMap.get(key); - } - - public static void loadFromPreferences() { - SharedPreferences preferences = SharedPrefCategory.SPONSOR_BLOCK.preferences; - LogHelper.printDebug(() -> "loadFromPreferences"); - for (SegmentCategory category : categoriesWithoutUnsubmitted()) { - category.load(preferences); - } - updateEnabledCategories(); - } - - /** - * Must be called if behavior of any category is changed - */ - public static void updateEnabledCategories() { - SegmentCategory[] categories = categoriesWithoutUnsubmitted(); - List enabledCategories = new ArrayList<>(categories.length); - for (SegmentCategory category : categories) { - if (category.behaviour != CategoryBehaviour.IGNORE) { - enabledCategories.add(category.key); - } - } - - //"[%22sponsor%22,%22outro%22,%22music_offtopic%22,%22intro%22,%22selfpromo%22,%22interaction%22,%22preview%22]"; - if (enabledCategories.isEmpty()) - sponsorBlockAPIFetchCategories = "[]"; - else - sponsorBlockAPIFetchCategories = "[%22" + TextUtils.join("%22,%22", enabledCategories) + "%22]"; - } - - @NonNull - public final String key; - @NonNull - public final StringRef title; - @NonNull - public final StringRef description; - - /** - * Skip button text, if the skip occurs in the first quarter of the video - */ - @NonNull - public final StringRef skipButtonTextBeginning; - /** - * Skip button text, if the skip occurs in the middle half of the video - */ - @NonNull - public final StringRef skipButtonTextMiddle; - /** - * Skip button text, if the skip occurs in the last quarter of the video - */ - @NonNull - public final StringRef skipButtonTextEnd; - /** - * Skipped segment toast, if the skip occurred in the first quarter of the video - */ - @NonNull - public final StringRef skippedToastBeginning; - /** - * Skipped segment toast, if the skip occurred in the middle half of the video - */ - @NonNull - public final StringRef skippedToastMiddle; - /** - * Skipped segment toast, if the skip occurred in the last quarter of the video - */ - @NonNull - public final StringRef skippedToastEnd; - - @NonNull - public final Paint paint; - public final int defaultColor; - /** - * If value is changed, then also call {@link #save(SharedPreferences.Editor)} - */ - public int color; - - /** - * If value is changed, then also call {@link #updateEnabledCategories()} - */ - @NonNull - public CategoryBehaviour behaviour; - @NonNull - public final CategoryBehaviour defaultBehaviour; - - SegmentCategory(String key, StringRef title, StringRef description, - StringRef skipButtonText, - StringRef skippedToastText, - CategoryBehaviour defaultBehavior, int defaultColor) { - this(key, title, description, - skipButtonText, skipButtonText, skipButtonText, - skippedToastText, skippedToastText, skippedToastText, - defaultBehavior, defaultColor); - } - - SegmentCategory(String key, StringRef title, StringRef description, - StringRef skipButtonTextBeginning, StringRef skipButtonTextMiddle, StringRef skipButtonTextEnd, - StringRef skippedToastBeginning, StringRef skippedToastMiddle, StringRef skippedToastEnd, - CategoryBehaviour defaultBehavior, int defaultColor) { - this.key = Objects.requireNonNull(key); - this.title = Objects.requireNonNull(title); - this.description = Objects.requireNonNull(description); - this.skipButtonTextBeginning = Objects.requireNonNull(skipButtonTextBeginning); - this.skipButtonTextMiddle = Objects.requireNonNull(skipButtonTextMiddle); - this.skipButtonTextEnd = Objects.requireNonNull(skipButtonTextEnd); - this.skippedToastBeginning = Objects.requireNonNull(skippedToastBeginning); - this.skippedToastMiddle = Objects.requireNonNull(skippedToastMiddle); - this.skippedToastEnd = Objects.requireNonNull(skippedToastEnd); - this.behaviour = this.defaultBehaviour = Objects.requireNonNull(defaultBehavior); - this.color = this.defaultColor = defaultColor; - this.paint = new Paint(); - setColor(defaultColor); - } - - /** - * Caller must also call {@link #updateEnabledCategories()} - */ - private void load(SharedPreferences preferences) { - String categoryColor = preferences.getString(key + COLOR_PREFERENCE_KEY_SUFFIX, null); - if (categoryColor == null) { - setColor(defaultColor); - } else { - setColor(categoryColor); - } - - String behaviorString = preferences.getString(key, null); - if (behaviorString == null) { - behaviour = defaultBehaviour; - } else { - CategoryBehaviour preferenceBehavior = CategoryBehaviour.byStringKey(behaviorString); - if (preferenceBehavior == null) { - LogHelper.printException(() -> "Unknown behavior: " + behaviorString); // should never happen - behaviour = defaultBehaviour; - } else { - behaviour = preferenceBehavior; - } - } - } - - /** - * Saves the current color and behavior. - * Calling code is responsible for calling {@link SharedPreferences.Editor#apply()} - */ - public void save(SharedPreferences.Editor editor) { - String colorString = (color == defaultColor) - ? null // remove any saved preference, so default is used on the next load - : colorString(); - editor.putString(key + COLOR_PREFERENCE_KEY_SUFFIX, colorString); - editor.putString(key, behaviour.key); - } - - private String getFlatJsonBehaviorKey() { - return FLAT_JSON_IMPORT_EXPORT_PREFIX + key; - } - private String getFlatJsonColorKey() { - return FLAT_JSON_IMPORT_EXPORT_PREFIX + key + COLOR_PREFERENCE_KEY_SUFFIX; - } - - public void exportToFlatJSON(JSONObject json) throws JSONException { - if (behaviour != defaultBehaviour) { - json.put(getFlatJsonBehaviorKey(), behaviour.key); - } - if (color != defaultColor) { - json.put(getFlatJsonColorKey(), colorString()); - } - } - - /** - * Calling code is responsible for calling {@link #updateEnabledCategories()} and {@link SharedPreferences.Editor#apply()} - */ - public int importFromFlatJSON(JSONObject json, SharedPreferences.Editor editor) throws JSONException { - int numberOfSettingsImported = 0; - String behaviorKey = getFlatJsonBehaviorKey(); - if (json.has(behaviorKey)) { - String behaviorString = json.getString(behaviorKey); - CategoryBehaviour importedBehavior = CategoryBehaviour.byStringKey(behaviorString); - if (importedBehavior == null) { - throw new IllegalArgumentException("unknown behavior: " + behaviorString); - } - behaviour = importedBehavior; - numberOfSettingsImported++; - } else { - behaviour = defaultBehaviour; - } - String colorKey = getFlatJsonColorKey(); - if (json.has(colorKey)) { - setColor(json.getString(colorKey)); - numberOfSettingsImported++; - } else { - color = defaultColor; - } - save(editor); - return numberOfSettingsImported; - } - - /** - * @return HTML color format string - */ - @NonNull - public String colorString() { - return String.format("#%06X", color); - } - - public void setColor(@NonNull String colorString) throws IllegalArgumentException { - setColor(Color.parseColor(colorString)); - } - - public void setColor(int color) { - color &= 0xFFFFFF; - this.color = color; - paint.setColor(color); - paint.setAlpha(255); - } - - @NonNull - private static String getCategoryColorDotHTML(int color) { - color &= 0xFFFFFF; - return String.format("⬤", color); - } - - @NonNull - public static Spanned getCategoryColorDot(int color) { - return Html.fromHtml(getCategoryColorDotHTML(color)); - } - - @NonNull - public Spanned getCategoryColorDot() { - return getCategoryColorDot(color); - } - - @NonNull - public Spanned getTitleWithColorDot() { - return Html.fromHtml(getCategoryColorDotHTML(color) + " " + title); - } - - /** - * @param segmentStartTime video time the segment category started - * @param videoLength length of the video - * @return the skip button text - */ - @NonNull - StringRef getSkipButtonText(long segmentStartTime, long videoLength) { - if (SettingsEnum.SB_COMPACT_SKIP_BUTTON.getBoolean()) { - return (this == SegmentCategory.HIGHLIGHT) - ? skipSponsorTextCompactHighlight - : skipSponsorTextCompact; - } - - if (videoLength == 0) { - return skipButtonTextBeginning; // video is still loading. Assume it's the beginning - } - final float position = segmentStartTime / (float) videoLength; - if (position < 0.25f) { - return skipButtonTextBeginning; - } else if (position < 0.75f) { - return skipButtonTextMiddle; - } - return skipButtonTextEnd; - } - - /** - * @param segmentStartTime video time the segment category started - * @param videoLength length of the video - * @return 'skipped segment' toast message - */ - @NonNull - StringRef getSkippedToastText(long segmentStartTime, long videoLength) { - if (videoLength == 0) { - return skippedToastBeginning; // video is still loading. Assume it's the beginning - } - final float position = segmentStartTime / (float) videoLength; - if (position < 0.25f) { - return skippedToastBeginning; - } else if (position < 0.75f) { - return skippedToastMiddle; - } - return skippedToastEnd; - } -} diff --git a/app/src/main/java/app/revanced/integrations/tiktok/Utils.java b/app/src/main/java/app/revanced/integrations/tiktok/Utils.java new file mode 100644 index 0000000000..526622e746 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/tiktok/Utils.java @@ -0,0 +1,25 @@ +package app.revanced.integrations.tiktok; + +import app.revanced.integrations.shared.settings.StringSetting; + +public class Utils { + + // Edit: This could be handled using a custom Setting class + // that saves its value to preferences and JSON using the formatted String created here. + public static long[] parseMinMax(StringSetting setting) { + final String[] minMax = setting.get().split("-"); + if (minMax.length == 2) { + try { + final long min = Long.parseLong(minMax[0]); + final long max = Long.parseLong(minMax[1]); + + if (min <= max && min >= 0) return new long[]{min, max}; + + } catch (NumberFormatException ignored) { + } + } + + setting.save("0-" + Long.MAX_VALUE); + return new long[]{0L, Long.MAX_VALUE}; + } +} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch.java b/app/src/main/java/app/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch.java new file mode 100644 index 0000000000..1070723d06 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/tiktok/cleardisplay/RememberClearDisplayPatch.java @@ -0,0 +1,13 @@ +package app.revanced.integrations.tiktok.cleardisplay; + +import app.revanced.integrations.tiktok.settings.Settings; + +@SuppressWarnings("unused") +public class RememberClearDisplayPatch { + public static boolean getClearDisplayState() { + return Settings.CLEAR_DISPLAY.get(); + } + public static void rememberClearDisplayState(boolean newState) { + Settings.CLEAR_DISPLAY.save(newState); + } +} diff --git a/app/src/main/java/app/revanced/integrations/tiktok/download/DownloadsPatch.java b/app/src/main/java/app/revanced/integrations/tiktok/download/DownloadsPatch.java new file mode 100644 index 0000000000..61db32ddae --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/tiktok/download/DownloadsPatch.java @@ -0,0 +1,14 @@ +package app.revanced.integrations.tiktok.download; + +import app.revanced.integrations.tiktok.settings.Settings; + +@SuppressWarnings("unused") +public class DownloadsPatch { + public static String getDownloadPath() { + return Settings.DOWNLOAD_PATH.get(); + } + + public static boolean shouldRemoveWatermark() { + return Settings.DOWNLOAD_WATERMARK.get(); + } +} diff --git a/app/src/main/java/app/revanced/tiktok/feedfilter/AdsFilter.java b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/AdsFilter.java similarity index 64% rename from app/src/main/java/app/revanced/tiktok/feedfilter/AdsFilter.java rename to app/src/main/java/app/revanced/integrations/tiktok/feedfilter/AdsFilter.java index 8270cff35a..c246e6226d 100644 --- a/app/src/main/java/app/revanced/tiktok/feedfilter/AdsFilter.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/AdsFilter.java @@ -1,12 +1,12 @@ -package app.revanced.tiktok.feedfilter; +package app.revanced.integrations.tiktok.feedfilter; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.tiktok.settings.Settings; import com.ss.android.ugc.aweme.feed.model.Aweme; public class AdsFilter implements IFilter { @Override public boolean getEnabled() { - return SettingsEnum.REMOVE_ADS.getBoolean(); + return Settings.REMOVE_ADS.get(); } @Override diff --git a/app/src/main/java/app/revanced/tiktok/feedfilter/FeedItemsFilter.java b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/FeedItemsFilter.java similarity index 95% rename from app/src/main/java/app/revanced/tiktok/feedfilter/FeedItemsFilter.java rename to app/src/main/java/app/revanced/integrations/tiktok/feedfilter/FeedItemsFilter.java index e8ba843278..d74ea59ecc 100644 --- a/app/src/main/java/app/revanced/tiktok/feedfilter/FeedItemsFilter.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/FeedItemsFilter.java @@ -1,4 +1,4 @@ -package app.revanced.tiktok.feedfilter; +package app.revanced.integrations.tiktok.feedfilter; import com.ss.android.ugc.aweme.feed.model.Aweme; import com.ss.android.ugc.aweme.feed.model.FeedItemList; diff --git a/app/src/main/java/app/revanced/tiktok/feedfilter/IFilter.java b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/IFilter.java similarity index 73% rename from app/src/main/java/app/revanced/tiktok/feedfilter/IFilter.java rename to app/src/main/java/app/revanced/integrations/tiktok/feedfilter/IFilter.java index 5ddcddf439..96b7bdfe4a 100644 --- a/app/src/main/java/app/revanced/tiktok/feedfilter/IFilter.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/IFilter.java @@ -1,4 +1,4 @@ -package app.revanced.tiktok.feedfilter; +package app.revanced.integrations.tiktok.feedfilter; import com.ss.android.ugc.aweme.feed.model.Aweme; diff --git a/app/src/main/java/app/revanced/tiktok/feedfilter/ImageVideoFilter.java b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/ImageVideoFilter.java similarity index 64% rename from app/src/main/java/app/revanced/tiktok/feedfilter/ImageVideoFilter.java rename to app/src/main/java/app/revanced/integrations/tiktok/feedfilter/ImageVideoFilter.java index b1d23c692d..50472197e8 100644 --- a/app/src/main/java/app/revanced/tiktok/feedfilter/ImageVideoFilter.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/ImageVideoFilter.java @@ -1,12 +1,12 @@ -package app.revanced.tiktok.feedfilter; +package app.revanced.integrations.tiktok.feedfilter; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.tiktok.settings.Settings; import com.ss.android.ugc.aweme.feed.model.Aweme; public class ImageVideoFilter implements IFilter { @Override public boolean getEnabled() { - return SettingsEnum.HIDE_IMAGE.getBoolean(); + return Settings.HIDE_IMAGE.get(); } @Override diff --git a/app/src/main/java/app/revanced/tiktok/feedfilter/LikeCountFilter.java b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/LikeCountFilter.java similarity index 73% rename from app/src/main/java/app/revanced/tiktok/feedfilter/LikeCountFilter.java rename to app/src/main/java/app/revanced/integrations/tiktok/feedfilter/LikeCountFilter.java index 80657e38ad..7815283dbf 100644 --- a/app/src/main/java/app/revanced/tiktok/feedfilter/LikeCountFilter.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/LikeCountFilter.java @@ -1,17 +1,17 @@ -package app.revanced.tiktok.feedfilter; +package app.revanced.integrations.tiktok.feedfilter; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.tiktok.settings.Settings; import com.ss.android.ugc.aweme.feed.model.Aweme; import com.ss.android.ugc.aweme.feed.model.AwemeStatistics; -import static app.revanced.tiktok.utils.ReVancedUtils.parseMinMax; +import static app.revanced.integrations.tiktok.Utils.parseMinMax; public final class LikeCountFilter implements IFilter { final long minLike; final long maxLike; LikeCountFilter() { - long[] minMax = parseMinMax(SettingsEnum.MIN_MAX_LIKES); + long[] minMax = parseMinMax(Settings.MIN_MAX_LIKES); minLike = minMax[0]; maxLike = minMax[1]; } diff --git a/app/src/main/java/app/revanced/tiktok/feedfilter/LiveFilter.java b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/LiveFilter.java similarity index 64% rename from app/src/main/java/app/revanced/tiktok/feedfilter/LiveFilter.java rename to app/src/main/java/app/revanced/integrations/tiktok/feedfilter/LiveFilter.java index 4a97c2d10c..bec7f11c48 100644 --- a/app/src/main/java/app/revanced/tiktok/feedfilter/LiveFilter.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/LiveFilter.java @@ -1,12 +1,12 @@ -package app.revanced.tiktok.feedfilter; +package app.revanced.integrations.tiktok.feedfilter; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.tiktok.settings.Settings; import com.ss.android.ugc.aweme.feed.model.Aweme; public class LiveFilter implements IFilter { @Override public boolean getEnabled() { - return SettingsEnum.HIDE_LIVE.getBoolean(); + return Settings.HIDE_LIVE.get(); } @Override diff --git a/app/src/main/java/app/revanced/tiktok/feedfilter/StoryFilter.java b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/StoryFilter.java similarity index 62% rename from app/src/main/java/app/revanced/tiktok/feedfilter/StoryFilter.java rename to app/src/main/java/app/revanced/integrations/tiktok/feedfilter/StoryFilter.java index 0260fff0b9..2c209d0dd9 100644 --- a/app/src/main/java/app/revanced/tiktok/feedfilter/StoryFilter.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/StoryFilter.java @@ -1,12 +1,12 @@ -package app.revanced.tiktok.feedfilter; +package app.revanced.integrations.tiktok.feedfilter; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.tiktok.settings.Settings; import com.ss.android.ugc.aweme.feed.model.Aweme; public class StoryFilter implements IFilter { @Override public boolean getEnabled() { - return SettingsEnum.HIDE_STORY.getBoolean(); + return Settings.HIDE_STORY.get(); } @Override diff --git a/app/src/main/java/app/revanced/tiktok/feedfilter/ViewCountFilter.java b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/ViewCountFilter.java similarity index 73% rename from app/src/main/java/app/revanced/tiktok/feedfilter/ViewCountFilter.java rename to app/src/main/java/app/revanced/integrations/tiktok/feedfilter/ViewCountFilter.java index ef8699580f..637401af17 100644 --- a/app/src/main/java/app/revanced/tiktok/feedfilter/ViewCountFilter.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/feedfilter/ViewCountFilter.java @@ -1,17 +1,17 @@ -package app.revanced.tiktok.feedfilter; +package app.revanced.integrations.tiktok.feedfilter; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.tiktok.settings.Settings; import com.ss.android.ugc.aweme.feed.model.Aweme; import com.ss.android.ugc.aweme.feed.model.AwemeStatistics; -import static app.revanced.tiktok.utils.ReVancedUtils.parseMinMax; +import static app.revanced.integrations.tiktok.Utils.parseMinMax; public class ViewCountFilter implements IFilter { final long minView; final long maxView; ViewCountFilter() { - long[] minMax = parseMinMax(SettingsEnum.MIN_MAX_VIEWS); + long[] minMax = parseMinMax(Settings.MIN_MAX_VIEWS); minView = minMax[0]; maxView = minMax[1]; } diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/SettingsMenu.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/AdPersonalizationActivityHook.java similarity index 78% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/SettingsMenu.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/AdPersonalizationActivityHook.java index 4521409a3a..2e4812e4c9 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/SettingsMenu.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/AdPersonalizationActivityHook.java @@ -1,4 +1,4 @@ -package app.revanced.tiktok.settingsmenu; +package app.revanced.integrations.tiktok.settings; import android.content.Context; import android.content.Intent; @@ -7,17 +7,22 @@ import android.view.View; import android.widget.FrameLayout; import android.widget.LinearLayout; - +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.tiktok.settings.preference.ReVancedPreferenceFragment; import com.bytedance.ies.ugc.aweme.commercialize.compliance.personalization.AdPersonalizationActivity; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import app.revanced.tiktok.utils.LogHelper; -import app.revanced.tiktok.utils.ReVancedUtils; - - -public class SettingsMenu { +/** + * Hooks AdPersonalizationActivity. + *

+ * This class is responsible for injecting our own fragment by replacing the AdPersonalizationActivity. + * + * @noinspection unused + */ +public class AdPersonalizationActivityHook { public static Object createSettingsEntry(String entryClazzName, String entryInfoClazzName) { try { Class entryClazz = Class.forName(entryClazzName); @@ -26,7 +31,8 @@ public static Object createSettingsEntry(String entryClazzName, String entryInfo Constructor entryInfoConstructor = entryInfoClazz.getDeclaredConstructors()[0]; Object buttonInfo = entryInfoConstructor.newInstance("ReVanced settings", null, (View.OnClickListener) view -> startSettingsActivity(), "revanced"); return entryConstructor.newInstance(buttonInfo); - } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException | InstantiationException e) { + } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException | + InstantiationException e) { throw new RuntimeException(e); } } @@ -36,7 +42,7 @@ public static Object createSettingsEntry(String entryClazzName, String entryInfo * @param base The activity to initialize the settings menu on. * @return Whether the settings menu should be initialized. */ - public static boolean initializeSettings(AdPersonalizationActivity base) { + public static boolean initialize(AdPersonalizationActivity base) { Bundle extras = base.getIntent().getExtras(); if (extras != null && !extras.getBoolean("revanced", false)) return false; @@ -63,14 +69,14 @@ public static boolean initializeSettings(AdPersonalizationActivity base) { } private static void startSettingsActivity() { - Context appContext = ReVancedUtils.getAppContext(); + Context appContext = Utils.getContext(); if (appContext != null) { Intent intent = new Intent(appContext, AdPersonalizationActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra("revanced", true); appContext.startActivity(intent); } else { - LogHelper.debug(SettingsMenu.class, "ReVancedUtils.getAppContext() return null"); + Logger.printDebug(() -> "Utils.getContext() return null"); } } } diff --git a/app/src/main/java/app/revanced/integrations/tiktok/settings/Settings.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/Settings.java new file mode 100644 index 0000000000..4517b02f58 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/Settings.java @@ -0,0 +1,26 @@ +package app.revanced.integrations.tiktok.settings; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + +import app.revanced.integrations.shared.settings.BaseSettings; +import app.revanced.integrations.shared.settings.BooleanSetting; +import app.revanced.integrations.shared.settings.FloatSetting; +import app.revanced.integrations.shared.settings.StringSetting; + +public class Settings extends BaseSettings { + public static final BooleanSetting REMOVE_ADS = new BooleanSetting("remove_ads", TRUE, true); + public static final BooleanSetting HIDE_LIVE = new BooleanSetting("hide_live", FALSE, true); + public static final BooleanSetting HIDE_STORY = new BooleanSetting("hide_story", FALSE, true); + public static final BooleanSetting HIDE_IMAGE = new BooleanSetting("hide_image", FALSE, true); + public static final StringSetting MIN_MAX_VIEWS = new StringSetting("min_max_views", "0-" + Long.MAX_VALUE, true); + public static final StringSetting MIN_MAX_LIKES = new StringSetting("min_max_likes", "0-" + Long.MAX_VALUE, true); + public static final StringSetting DOWNLOAD_PATH = new StringSetting("down_path", "DCIM/TikTok"); + public static final BooleanSetting DOWNLOAD_WATERMARK = new BooleanSetting("down_watermark", TRUE); + public static final BooleanSetting CLEAR_DISPLAY = new BooleanSetting("clear_display", FALSE); + public static final FloatSetting REMEMBERED_SPEED = new FloatSetting("REMEMBERED_SPEED", 1.0f); + public static final BooleanSetting SIM_SPOOF = new BooleanSetting("simspoof", TRUE, true); + public static final StringSetting SIM_SPOOF_ISO = new StringSetting("simspoof_iso", "us"); + public static final StringSetting SIMSPOOF_MCCMNC = new StringSetting("simspoof_mccmnc", "310160"); + public static final StringSetting SIMSPOOF_OP_NAME = new StringSetting("simspoof_op_name", "T-Mobile"); +} diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/SettingsStatus.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/SettingsStatus.java similarity index 90% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/SettingsStatus.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/SettingsStatus.java index 2b8eb12ca7..81c74be4b4 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/SettingsStatus.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/SettingsStatus.java @@ -1,4 +1,4 @@ -package app.revanced.tiktok.settingsmenu; +package app.revanced.integrations.tiktok.settings; public class SettingsStatus { public static boolean feedFilterEnabled = false; diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/DownloadPathPreference.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/DownloadPathPreference.java similarity index 94% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/preference/DownloadPathPreference.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/preference/DownloadPathPreference.java index 734a2b591a..8bf8a40f36 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/DownloadPathPreference.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/DownloadPathPreference.java @@ -1,4 +1,4 @@ -package app.revanced.tiktok.settingsmenu.preference; +package app.revanced.integrations.tiktok.settings.preference; import android.app.AlertDialog; import android.content.Context; @@ -15,7 +15,7 @@ import android.widget.RadioButton; import android.widget.RadioGroup; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.shared.settings.StringSetting; @SuppressWarnings("deprecation") public class DownloadPathPreference extends DialogPreference { @@ -27,13 +27,13 @@ public class DownloadPathPreference extends DialogPreference { private int mediaPathIndex; private String childDownloadPath; - public DownloadPathPreference(Context context, String title, SettingsEnum setting) { + public DownloadPathPreference(Context context, String title, StringSetting setting) { super(context); this.context = context; this.setTitle(title); - this.setSummary(Environment.getExternalStorageDirectory().getPath() + "/" + setting.getString()); - this.setKey(setting.path); - this.setValue(setting.getString()); + this.setSummary(Environment.getExternalStorageDirectory().getPath() + "/" + setting.get()); + this.setKey(setting.key); + this.setValue(setting.get()); } public String getValue() { diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/InputTextPreference.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/InputTextPreference.java similarity index 56% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/preference/InputTextPreference.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/preference/InputTextPreference.java index 0ee0e77310..7a10339159 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/InputTextPreference.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/InputTextPreference.java @@ -1,17 +1,17 @@ -package app.revanced.tiktok.settingsmenu.preference; +package app.revanced.integrations.tiktok.settings.preference; import android.content.Context; import android.preference.EditTextPreference; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.shared.settings.StringSetting; public class InputTextPreference extends EditTextPreference { - public InputTextPreference(Context context, String title, String summary, SettingsEnum setting) { + public InputTextPreference(Context context, String title, String summary, StringSetting setting) { super(context); this.setTitle(title); this.setSummary(summary); - this.setKey(setting.path); - this.setText(setting.getString()); + this.setKey(setting.key); + this.setText(setting.get()); } } diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/RangeValuePreference.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/RangeValuePreference.java similarity index 94% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/preference/RangeValuePreference.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/preference/RangeValuePreference.java index 7934433978..1c83b18cbd 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/RangeValuePreference.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/RangeValuePreference.java @@ -1,4 +1,4 @@ -package app.revanced.tiktok.settingsmenu.preference; +package app.revanced.integrations.tiktok.settings.preference; import android.app.AlertDialog; import android.content.Context; @@ -13,7 +13,7 @@ import android.widget.LinearLayout; import android.widget.TextView; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.shared.settings.StringSetting; @SuppressWarnings("deprecation") public class RangeValuePreference extends DialogPreference { @@ -27,13 +27,13 @@ public class RangeValuePreference extends DialogPreference { private boolean mValueSet; - public RangeValuePreference(Context context, String title, String summary, SettingsEnum setting) { + public RangeValuePreference(Context context, String title, String summary, StringSetting setting) { super(context); this.context = context; setTitle(title); setSummary(summary); - setKey(setting.path); - setValue(setting.getString()); + setKey(setting.key); + setValue(setting.get()); } public void setValue(String value) { diff --git a/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/ReVancedPreferenceFragment.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/ReVancedPreferenceFragment.java new file mode 100644 index 0000000000..9f62a2ab9b --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/ReVancedPreferenceFragment.java @@ -0,0 +1,29 @@ +package app.revanced.integrations.tiktok.settings.preference; + +import android.preference.PreferenceScreen; +import app.revanced.integrations.shared.settings.preference.AbstractPreferenceFragment; +import app.revanced.integrations.tiktok.settings.preference.categories.DownloadsPreferenceCategory; +import app.revanced.integrations.tiktok.settings.preference.categories.FeedFilterPreferenceCategory; +import app.revanced.integrations.tiktok.settings.preference.categories.IntegrationsPreferenceCategory; +import app.revanced.integrations.tiktok.settings.preference.categories.SimSpoofPreferenceCategory; + +/** + * Preference fragment for ReVanced settings + */ +@SuppressWarnings("deprecation") +public class ReVancedPreferenceFragment extends AbstractPreferenceFragment { + + @Override + protected void initialize() { + final var context = getContext(); + + PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context); + setPreferenceScreen(preferenceScreen); + + // Custom categories reference app specific Settings class. + new FeedFilterPreferenceCategory(context, preferenceScreen); + new DownloadsPreferenceCategory(context, preferenceScreen); + new SimSpoofPreferenceCategory(context, preferenceScreen); + new IntegrationsPreferenceCategory(context, preferenceScreen); + } +} diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/TogglePreference.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/TogglePreference.java similarity index 58% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/preference/TogglePreference.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/preference/TogglePreference.java index f729920e08..0af4a44ffa 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/TogglePreference.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/TogglePreference.java @@ -1,17 +1,17 @@ -package app.revanced.tiktok.settingsmenu.preference; +package app.revanced.integrations.tiktok.settings.preference; import android.content.Context; import android.preference.SwitchPreference; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.shared.settings.BooleanSetting; @SuppressWarnings("deprecation") public class TogglePreference extends SwitchPreference { - public TogglePreference(Context context, String title, String summary, SettingsEnum setting) { + public TogglePreference(Context context, String title, String summary, BooleanSetting setting) { super(context); this.setTitle(title); this.setSummary(summary); - this.setKey(setting.path); - this.setChecked(setting.getBoolean()); + this.setKey(setting.key); + this.setChecked(setting.get()); } } diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/ConditionalPreferenceCategory.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/ConditionalPreferenceCategory.java similarity index 88% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/ConditionalPreferenceCategory.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/ConditionalPreferenceCategory.java index 5d3bed4619..24eaa1e9a3 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/ConditionalPreferenceCategory.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/ConditionalPreferenceCategory.java @@ -1,4 +1,4 @@ -package app.revanced.tiktok.settingsmenu.preference.categories; +package app.revanced.integrations.tiktok.settings.preference.categories; import android.content.Context; import android.preference.PreferenceCategory; diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/DownloadsPreferenceCategory.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/DownloadsPreferenceCategory.java similarity index 63% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/DownloadsPreferenceCategory.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/DownloadsPreferenceCategory.java index 40f73d64fc..8ecbfb3661 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/DownloadsPreferenceCategory.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/DownloadsPreferenceCategory.java @@ -1,11 +1,11 @@ -package app.revanced.tiktok.settingsmenu.preference.categories; +package app.revanced.integrations.tiktok.settings.preference.categories; import android.content.Context; import android.preference.PreferenceScreen; -import app.revanced.tiktok.settings.SettingsEnum; -import app.revanced.tiktok.settingsmenu.SettingsStatus; -import app.revanced.tiktok.settingsmenu.preference.DownloadPathPreference; -import app.revanced.tiktok.settingsmenu.preference.TogglePreference; +import app.revanced.integrations.tiktok.settings.Settings; +import app.revanced.integrations.tiktok.settings.SettingsStatus; +import app.revanced.integrations.tiktok.settings.preference.DownloadPathPreference; +import app.revanced.integrations.tiktok.settings.preference.TogglePreference; @SuppressWarnings("deprecation") public class DownloadsPreferenceCategory extends ConditionalPreferenceCategory { @@ -24,12 +24,12 @@ public void addPreferences(Context context) { addPreference(new DownloadPathPreference( context, "Download path", - SettingsEnum.DOWNLOAD_PATH + Settings.DOWNLOAD_PATH )); addPreference(new TogglePreference( context, "Remove watermark", "", - SettingsEnum.DOWNLOAD_WATERMARK + Settings.DOWNLOAD_WATERMARK )); } } diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/FeedFilterPreferenceCategory.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/FeedFilterPreferenceCategory.java similarity index 71% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/FeedFilterPreferenceCategory.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/FeedFilterPreferenceCategory.java index b5fbbdeb71..5bb40a2ea3 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/FeedFilterPreferenceCategory.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/FeedFilterPreferenceCategory.java @@ -1,11 +1,11 @@ -package app.revanced.tiktok.settingsmenu.preference.categories; +package app.revanced.integrations.tiktok.settings.preference.categories; import android.content.Context; import android.preference.PreferenceScreen; -import app.revanced.tiktok.settings.SettingsEnum; -import app.revanced.tiktok.settingsmenu.SettingsStatus; -import app.revanced.tiktok.settingsmenu.preference.RangeValuePreference; -import app.revanced.tiktok.settingsmenu.preference.TogglePreference; +import app.revanced.integrations.tiktok.settings.preference.RangeValuePreference; +import app.revanced.integrations.tiktok.settings.Settings; +import app.revanced.integrations.tiktok.settings.SettingsStatus; +import app.revanced.integrations.tiktok.settings.preference.TogglePreference; @SuppressWarnings("deprecation") public class FeedFilterPreferenceCategory extends ConditionalPreferenceCategory { @@ -24,32 +24,32 @@ public void addPreferences(Context context) { addPreference(new TogglePreference( context, "Remove feed ads", "Remove ads from feed.", - SettingsEnum.REMOVE_ADS + Settings.REMOVE_ADS )); addPreference(new TogglePreference( context, "Hide livestreams", "Hide livestreams from feed.", - SettingsEnum.HIDE_LIVE + Settings.HIDE_LIVE )); addPreference(new TogglePreference( context, "Hide story", "Hide story from feed.", - SettingsEnum.HIDE_STORY + Settings.HIDE_STORY )); addPreference(new TogglePreference( context, "Hide image video", "Hide image video from feed.", - SettingsEnum.HIDE_IMAGE + Settings.HIDE_IMAGE )); addPreference(new RangeValuePreference( context, "Min/Max views", "The minimum or maximum views of a video to show.", - SettingsEnum.MIN_MAX_VIEWS + Settings.MIN_MAX_VIEWS )); addPreference(new RangeValuePreference( context, "Min/Max likes", "The minimum or maximum likes of a video to show.", - SettingsEnum.MIN_MAX_LIKES + Settings.MIN_MAX_LIKES )); } } diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/IntegrationsPreferenceCategory.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/IntegrationsPreferenceCategory.java similarity index 72% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/IntegrationsPreferenceCategory.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/IntegrationsPreferenceCategory.java index 9fcb450f77..96e6e892de 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/IntegrationsPreferenceCategory.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/IntegrationsPreferenceCategory.java @@ -1,9 +1,10 @@ -package app.revanced.tiktok.settingsmenu.preference.categories; +package app.revanced.integrations.tiktok.settings.preference.categories; import android.content.Context; import android.preference.PreferenceScreen; -import app.revanced.tiktok.settings.SettingsEnum; -import app.revanced.tiktok.settingsmenu.preference.TogglePreference; + +import app.revanced.integrations.shared.settings.BaseSettings; +import app.revanced.integrations.tiktok.settings.preference.TogglePreference; @SuppressWarnings("deprecation") public class IntegrationsPreferenceCategory extends ConditionalPreferenceCategory { @@ -22,7 +23,7 @@ public void addPreferences(Context context) { addPreference(new TogglePreference(context, "Enable debug log", "Show integration debug log.", - SettingsEnum.DEBUG + BaseSettings.DEBUG )); } } diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/SimSpoofPreferenceCategory.java b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/SimSpoofPreferenceCategory.java similarity index 69% rename from app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/SimSpoofPreferenceCategory.java rename to app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/SimSpoofPreferenceCategory.java index 86f82a1d75..b09834208a 100644 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/preference/categories/SimSpoofPreferenceCategory.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/settings/preference/categories/SimSpoofPreferenceCategory.java @@ -1,11 +1,11 @@ -package app.revanced.tiktok.settingsmenu.preference.categories; +package app.revanced.integrations.tiktok.settings.preference.categories; import android.content.Context; import android.preference.PreferenceScreen; -import app.revanced.tiktok.settings.SettingsEnum; -import app.revanced.tiktok.settingsmenu.SettingsStatus; -import app.revanced.tiktok.settingsmenu.preference.InputTextPreference; -import app.revanced.tiktok.settingsmenu.preference.TogglePreference; +import app.revanced.integrations.tiktok.settings.Settings; +import app.revanced.integrations.tiktok.settings.SettingsStatus; +import app.revanced.integrations.tiktok.settings.preference.InputTextPreference; +import app.revanced.integrations.tiktok.settings.preference.TogglePreference; @SuppressWarnings("deprecation") public class SimSpoofPreferenceCategory extends ConditionalPreferenceCategory { @@ -26,22 +26,22 @@ public void addPreferences(Context context) { context, "Fake sim card info", "Bypass regional restriction by fake sim card information.", - SettingsEnum.SIM_SPOOF + Settings.SIM_SPOOF )); addPreference(new InputTextPreference( context, "Country ISO", "us, uk, jp, ...", - SettingsEnum.SIM_SPOOF_ISO + Settings.SIM_SPOOF_ISO )); addPreference(new InputTextPreference( context, "Operator mcc+mnc", "mcc+mnc", - SettingsEnum.SIMSPOOF_MCCMNC + Settings.SIMSPOOF_MCCMNC )); addPreference(new InputTextPreference( context, "Operator name", "Name of the operator.", - SettingsEnum.SIMSPOOF_OP_NAME + Settings.SIMSPOOF_OP_NAME )); } } diff --git a/app/src/main/java/app/revanced/integrations/tiktok/speed/PlaybackSpeedPatch.java b/app/src/main/java/app/revanced/integrations/tiktok/speed/PlaybackSpeedPatch.java new file mode 100644 index 0000000000..1681ad0ca3 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/tiktok/speed/PlaybackSpeedPatch.java @@ -0,0 +1,13 @@ +package app.revanced.integrations.tiktok.speed; + +import app.revanced.integrations.tiktok.settings.Settings; + +public class PlaybackSpeedPatch { + public static void rememberPlaybackSpeed(float newSpeed) { + Settings.REMEMBERED_SPEED.save(newSpeed); + } + + public static float getPlaybackSpeed() { + return Settings.REMEMBERED_SPEED.get(); + } +} diff --git a/app/src/main/java/app/revanced/tiktok/spoof/sim/SpoofSimPatch.java b/app/src/main/java/app/revanced/integrations/tiktok/spoof/sim/SpoofSimPatch.java similarity index 60% rename from app/src/main/java/app/revanced/tiktok/spoof/sim/SpoofSimPatch.java rename to app/src/main/java/app/revanced/integrations/tiktok/spoof/sim/SpoofSimPatch.java index 799ec95c4e..311453470b 100644 --- a/app/src/main/java/app/revanced/tiktok/spoof/sim/SpoofSimPatch.java +++ b/app/src/main/java/app/revanced/integrations/tiktok/spoof/sim/SpoofSimPatch.java @@ -1,14 +1,15 @@ -package app.revanced.tiktok.spoof.sim; +package app.revanced.integrations.tiktok.spoof.sim; -import app.revanced.tiktok.settings.SettingsEnum; +import app.revanced.integrations.tiktok.settings.Settings; +@SuppressWarnings("unused") public class SpoofSimPatch { public static boolean isEnable() { - return SettingsEnum.SIM_SPOOF.getBoolean(); + return Settings.SIM_SPOOF.get(); } public static String getCountryIso(String value) { if (isEnable()) { - return SettingsEnum.SIM_SPOOF_ISO.getString(); + return Settings.SIM_SPOOF_ISO.get(); } else { return value; } @@ -16,14 +17,14 @@ public static String getCountryIso(String value) { } public static String getOperator(String value) { if (isEnable()) { - return SettingsEnum.SIMSPOOF_MCCMNC.getString(); + return Settings.SIMSPOOF_MCCMNC.get(); } else { return value; } } public static String getOperatorName(String value) { if (isEnable()) { - return SettingsEnum.SIMSPOOF_OP_NAME.getString(); + return Settings.SIMSPOOF_OP_NAME.get(); } else { return value; } diff --git a/app/src/main/java/app/revanced/tudortmund/lockscreen/ShowOnLockscreenPatch.java b/app/src/main/java/app/revanced/integrations/tudortmund/lockscreen/ShowOnLockscreenPatch.java similarity index 96% rename from app/src/main/java/app/revanced/tudortmund/lockscreen/ShowOnLockscreenPatch.java rename to app/src/main/java/app/revanced/integrations/tudortmund/lockscreen/ShowOnLockscreenPatch.java index 2260de24d7..0d05c9d92c 100644 --- a/app/src/main/java/app/revanced/tudortmund/lockscreen/ShowOnLockscreenPatch.java +++ b/app/src/main/java/app/revanced/integrations/tudortmund/lockscreen/ShowOnLockscreenPatch.java @@ -1,4 +1,4 @@ -package app.revanced.tudortmund.lockscreen; +package app.revanced.integrations.tudortmund.lockscreen; import android.content.Context; import android.hardware.display.DisplayManager; diff --git a/app/src/main/java/app/revanced/tumblr/patches/TimelineFilterPatch.java b/app/src/main/java/app/revanced/integrations/tumblr/patches/TimelineFilterPatch.java similarity index 96% rename from app/src/main/java/app/revanced/tumblr/patches/TimelineFilterPatch.java rename to app/src/main/java/app/revanced/integrations/tumblr/patches/TimelineFilterPatch.java index 1a4d50eff3..1c1da707cc 100644 --- a/app/src/main/java/app/revanced/tumblr/patches/TimelineFilterPatch.java +++ b/app/src/main/java/app/revanced/integrations/tumblr/patches/TimelineFilterPatch.java @@ -1,4 +1,4 @@ -package app.revanced.tumblr.patches; +package app.revanced.integrations.tumblr.patches; import com.tumblr.rumblr.model.TimelineObject; import com.tumblr.rumblr.model.Timelineable; diff --git a/app/src/main/java/app/revanced/integrations/twitch/Utils.java b/app/src/main/java/app/revanced/integrations/twitch/Utils.java new file mode 100644 index 0000000000..597da5d3ae --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/twitch/Utils.java @@ -0,0 +1,14 @@ +package app.revanced.integrations.twitch; + +public class Utils { + + /* Called from SettingsPatch smali */ + public static int getStringId(String name) { + return app.revanced.integrations.shared.Utils.getResourceIdentifier(name, "string"); + } + + /* Called from SettingsPatch smali */ + public static int getDrawableId(String name) { + return app.revanced.integrations.shared.Utils.getResourceIdentifier(name, "drawable"); + } +} diff --git a/app/src/main/java/app/revanced/twitch/adblock/IAdblockService.java b/app/src/main/java/app/revanced/integrations/twitch/adblock/IAdblockService.java similarity index 92% rename from app/src/main/java/app/revanced/twitch/adblock/IAdblockService.java rename to app/src/main/java/app/revanced/integrations/twitch/adblock/IAdblockService.java index 612730af62..6eff77b4c1 100644 --- a/app/src/main/java/app/revanced/twitch/adblock/IAdblockService.java +++ b/app/src/main/java/app/revanced/integrations/twitch/adblock/IAdblockService.java @@ -1,4 +1,4 @@ -package app.revanced.twitch.adblock; +package app.revanced.integrations.twitch.adblock; import okhttp3.Request; diff --git a/app/src/main/java/app/revanced/twitch/adblock/LuminousService.java b/app/src/main/java/app/revanced/integrations/twitch/adblock/LuminousService.java similarity index 77% rename from app/src/main/java/app/revanced/twitch/adblock/LuminousService.java rename to app/src/main/java/app/revanced/integrations/twitch/adblock/LuminousService.java index 34acece3f9..72f19ca07f 100644 --- a/app/src/main/java/app/revanced/twitch/adblock/LuminousService.java +++ b/app/src/main/java/app/revanced/integrations/twitch/adblock/LuminousService.java @@ -1,14 +1,15 @@ -package app.revanced.twitch.adblock; +package app.revanced.integrations.twitch.adblock; -import app.revanced.twitch.utils.LogHelper; -import app.revanced.twitch.utils.ReVancedUtils; +import app.revanced.integrations.shared.Logger; import okhttp3.HttpUrl; import okhttp3.Request; +import static app.revanced.integrations.shared.StringRef.str; + public class LuminousService implements IAdblockService { @Override public String friendlyName() { - return ReVancedUtils.getString("revanced_proxy_luminous"); + return str("revanced_proxy_luminous"); } @Override @@ -33,7 +34,7 @@ public Request rewriteHlsRequest(Request originalRequest) { ); if (url == null) { - LogHelper.error("Failed to parse rewritten URL"); + Logger.printException(() -> "Failed to parse rewritten URL"); return null; } diff --git a/app/src/main/java/app/revanced/twitch/adblock/PurpleAdblockService.java b/app/src/main/java/app/revanced/integrations/twitch/adblock/PurpleAdblockService.java similarity index 62% rename from app/src/main/java/app/revanced/twitch/adblock/PurpleAdblockService.java rename to app/src/main/java/app/revanced/integrations/twitch/adblock/PurpleAdblockService.java index 07e47dca30..c40b06e57e 100644 --- a/app/src/main/java/app/revanced/twitch/adblock/PurpleAdblockService.java +++ b/app/src/main/java/app/revanced/integrations/twitch/adblock/PurpleAdblockService.java @@ -1,14 +1,16 @@ -package app.revanced.twitch.adblock; +package app.revanced.integrations.twitch.adblock; -import app.revanced.twitch.api.RetrofitClient; -import app.revanced.twitch.utils.LogHelper; -import app.revanced.twitch.utils.ReVancedUtils; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.twitch.api.RetrofitClient; import okhttp3.HttpUrl; import okhttp3.Request; +import java.io.IOException; import java.util.HashMap; import java.util.Map; +import static app.revanced.integrations.shared.StringRef.str; + public class PurpleAdblockService implements IAdblockService { private final Map tunnels = new HashMap<>() {{ put("https://eu1.jupter.ga", false); @@ -17,7 +19,7 @@ public class PurpleAdblockService implements IAdblockService { @Override public String friendlyName() { - return ReVancedUtils.getString("revanced_proxy_purpleadblock"); + return str("revanced_proxy_purpleadblock"); } @Override @@ -33,19 +35,27 @@ public Boolean isAvailable() { try { var response = RetrofitClient.getInstance().getPurpleAdblockApi().ping(tunnel).execute(); if (!response.isSuccessful()) { - LogHelper.error("PurpleAdBlock tunnel $tunnel returned an error: HTTP code %d", response.code()); - LogHelper.debug(response.message()); + Logger.printException(() -> + "PurpleAdBlock tunnel $tunnel returned an error: HTTP code " + response.code() + ); + Logger.printDebug(response::message); try (var errorBody = response.errorBody()) { if (errorBody != null) { - LogHelper.debug(errorBody.string()); + Logger.printDebug(() -> { + try { + return errorBody.string(); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); } } success = false; } } catch (Exception ex) { - LogHelper.printException("PurpleAdBlock tunnel $tunnel is unavailable", ex); + Logger.printException(() -> "PurpleAdBlock tunnel $tunnel is unavailable", ex); success = false; } @@ -69,7 +79,7 @@ public Request rewriteHlsRequest(Request originalRequest) { // Compose new URL var url = HttpUrl.parse(server + "/channel/" + IAdblockService.channelName(originalRequest)); if (url == null) { - LogHelper.error("Failed to parse rewritten URL"); + Logger.printException(() -> "Failed to parse rewritten URL"); return null; } @@ -80,7 +90,7 @@ public Request rewriteHlsRequest(Request originalRequest) { .build(); } - LogHelper.error("No tunnels are available"); + Logger.printException(() -> "No tunnels are available"); return null; } } diff --git a/app/src/main/java/app/revanced/twitch/api/PurpleAdblockApi.java b/app/src/main/java/app/revanced/integrations/twitch/api/PurpleAdblockApi.java similarity index 84% rename from app/src/main/java/app/revanced/twitch/api/PurpleAdblockApi.java rename to app/src/main/java/app/revanced/integrations/twitch/api/PurpleAdblockApi.java index 31a70729ff..43f98d5103 100644 --- a/app/src/main/java/app/revanced/twitch/api/PurpleAdblockApi.java +++ b/app/src/main/java/app/revanced/integrations/twitch/api/PurpleAdblockApi.java @@ -1,4 +1,4 @@ -package app.revanced.twitch.api; +package app.revanced.integrations.twitch.api; import okhttp3.ResponseBody; import retrofit2.Call; diff --git a/app/src/main/java/app/revanced/integrations/twitch/api/RequestInterceptor.java b/app/src/main/java/app/revanced/integrations/twitch/api/RequestInterceptor.java new file mode 100644 index 0000000000..a841eecfe7 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/twitch/api/RequestInterceptor.java @@ -0,0 +1,120 @@ +package app.revanced.integrations.twitch.api; + +import androidx.annotation.NonNull; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.twitch.adblock.IAdblockService; +import app.revanced.integrations.twitch.adblock.LuminousService; +import app.revanced.integrations.twitch.adblock.PurpleAdblockService; +import app.revanced.integrations.twitch.settings.Settings; +import okhttp3.Interceptor; +import okhttp3.Response; + +import java.io.IOException; + +import static app.revanced.integrations.shared.StringRef.str; + +public class RequestInterceptor implements Interceptor { + private IAdblockService activeService = null; + + private static final String PROXY_DISABLED = str("key_revanced_proxy_disabled"); + private static final String LUMINOUS_SERVICE = str("key_revanced_proxy_luminous"); + private static final String PURPLE_ADBLOCK_SERVICE = str("key_revanced_proxy_purpleadblock"); + + + @NonNull + @Override + public Response intercept(@NonNull Chain chain) throws IOException { + var originalRequest = chain.request(); + + if (Settings.BLOCK_EMBEDDED_ADS.get().equals(PROXY_DISABLED)) { + return chain.proceed(originalRequest); + } + + Logger.printDebug(() -> "Intercepted request to URL:" + originalRequest.url()); + + // Skip if not HLS manifest request + if (!originalRequest.url().host().contains("usher.ttvnw.net")) { + return chain.proceed(originalRequest); + } + + final String isVod; + if (IAdblockService.isVod(originalRequest)) isVod = "yes"; + else isVod = "no"; + + Logger.printDebug(() -> "Found HLS manifest request. Is VOD? " + + isVod + + "; Channel: " + + IAdblockService.channelName(originalRequest) + ); + + // None of the services support VODs currently + if (IAdblockService.isVod(originalRequest)) return chain.proceed(originalRequest); + + updateActiveService(); + + if (activeService != null) { + var available = activeService.isAvailable(); + var rewritten = activeService.rewriteHlsRequest(originalRequest); + + + if (!available || rewritten == null) { + Utils.showToastShort(String.format( + str("revanced_embedded_ads_service_unavailable"), activeService.friendlyName() + )); + return chain.proceed(originalRequest); + } + + Logger.printDebug(() -> "Rewritten HLS stream URL: " + rewritten.url()); + + var maxAttempts = activeService.maxAttempts(); + + for (var i = 1; i <= maxAttempts; i++) { + // Execute rewritten request and close body to allow multiple proceed() calls + var response = chain.proceed(rewritten); + response.close(); + + if (!response.isSuccessful()) { + int attempt = i; + Logger.printException(() -> "Request failed (attempt " + + attempt + + "/" + maxAttempts + "): HTTP error " + + response.code() + + " (" + response.message() + ")" + ); + + try { + Thread.sleep(50); + } catch (InterruptedException e) { + Logger.printException(() -> "Failed to sleep", e); + } + } else { + // Accept response from ad blocker + Logger.printDebug(() -> "Ad-blocker used"); + return chain.proceed(rewritten); + } + } + + // maxAttempts exceeded; giving up on using the ad blocker + Utils.showToastLong(String.format( + str("revanced_embedded_ads_service_failed"), + activeService.friendlyName()) + ); + } + + // Adblock disabled + return chain.proceed(originalRequest); + + } + + private void updateActiveService() { + var current = Settings.BLOCK_EMBEDDED_ADS.get(); + + if (current.equals(LUMINOUS_SERVICE) && !(activeService instanceof LuminousService)) + activeService = new LuminousService(); + else if (current.equals(PURPLE_ADBLOCK_SERVICE) && !(activeService instanceof PurpleAdblockService)) + activeService = new PurpleAdblockService(); + else if (current.equals(PROXY_DISABLED)) + activeService = null; + } +} diff --git a/app/src/main/java/app/revanced/twitch/api/RetrofitClient.java b/app/src/main/java/app/revanced/integrations/twitch/api/RetrofitClient.java similarity index 93% rename from app/src/main/java/app/revanced/twitch/api/RetrofitClient.java rename to app/src/main/java/app/revanced/integrations/twitch/api/RetrofitClient.java index 9d5014c581..abe8c848fb 100644 --- a/app/src/main/java/app/revanced/twitch/api/RetrofitClient.java +++ b/app/src/main/java/app/revanced/integrations/twitch/api/RetrofitClient.java @@ -1,4 +1,4 @@ -package app.revanced.twitch.api; +package app.revanced.integrations.twitch.api; import retrofit2.Retrofit; diff --git a/app/src/main/java/app/revanced/integrations/twitch/patches/AudioAdsPatch.java b/app/src/main/java/app/revanced/integrations/twitch/patches/AudioAdsPatch.java new file mode 100644 index 0000000000..8b9a9b5779 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/twitch/patches/AudioAdsPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.twitch.patches; + +import app.revanced.integrations.twitch.settings.Settings; + +@SuppressWarnings("unused") +public class AudioAdsPatch { + public static boolean shouldBlockAudioAds() { + return Settings.BLOCK_AUDIO_ADS.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/twitch/patches/AutoClaimChannelPointsPatch.java b/app/src/main/java/app/revanced/integrations/twitch/patches/AutoClaimChannelPointsPatch.java new file mode 100644 index 0000000000..0edf29b001 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/twitch/patches/AutoClaimChannelPointsPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.twitch.patches; + +import app.revanced.integrations.twitch.settings.Settings; + +@SuppressWarnings("unused") +public class AutoClaimChannelPointsPatch { + public static boolean shouldAutoClaim() { + return Settings.AUTO_CLAIM_CHANNEL_POINTS.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/twitch/patches/DebugModePatch.java b/app/src/main/java/app/revanced/integrations/twitch/patches/DebugModePatch.java new file mode 100644 index 0000000000..1fba625eda --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/twitch/patches/DebugModePatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.twitch.patches; + +import app.revanced.integrations.twitch.settings.Settings; + +@SuppressWarnings("unused") +public class DebugModePatch { + public static boolean isDebugModeEnabled() { + return Settings.TWITCH_DEBUG_MODE.get(); + } +} diff --git a/app/src/main/java/app/revanced/twitch/patches/EmbeddedAdsPatch.java b/app/src/main/java/app/revanced/integrations/twitch/patches/EmbeddedAdsPatch.java similarity index 51% rename from app/src/main/java/app/revanced/twitch/patches/EmbeddedAdsPatch.java rename to app/src/main/java/app/revanced/integrations/twitch/patches/EmbeddedAdsPatch.java index 3f86fb9a54..4120c3a23b 100644 --- a/app/src/main/java/app/revanced/twitch/patches/EmbeddedAdsPatch.java +++ b/app/src/main/java/app/revanced/integrations/twitch/patches/EmbeddedAdsPatch.java @@ -1,7 +1,8 @@ -package app.revanced.twitch.patches; +package app.revanced.integrations.twitch.patches; -import app.revanced.twitch.api.RequestInterceptor; +import app.revanced.integrations.twitch.api.RequestInterceptor; +@SuppressWarnings("unused") public class EmbeddedAdsPatch { public static RequestInterceptor createRequestInterceptor() { return new RequestInterceptor(); diff --git a/app/src/main/java/app/revanced/twitch/patches/ShowDeletedMessagesPatch.java b/app/src/main/java/app/revanced/integrations/twitch/patches/ShowDeletedMessagesPatch.java similarity index 70% rename from app/src/main/java/app/revanced/twitch/patches/ShowDeletedMessagesPatch.java rename to app/src/main/java/app/revanced/integrations/twitch/patches/ShowDeletedMessagesPatch.java index 44ceb4c43a..bdf06ed740 100644 --- a/app/src/main/java/app/revanced/twitch/patches/ShowDeletedMessagesPatch.java +++ b/app/src/main/java/app/revanced/integrations/twitch/patches/ShowDeletedMessagesPatch.java @@ -1,4 +1,6 @@ -package app.revanced.twitch.patches; +package app.revanced.integrations.twitch.patches; + +import static app.revanced.integrations.shared.StringRef.str; import android.graphics.Color; import android.graphics.Typeface; @@ -9,28 +11,33 @@ import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; -import java.util.Objects; +import androidx.annotation.Nullable; -import app.revanced.twitch.settings.SettingsEnum; -import app.revanced.twitch.utils.ReVancedUtils; +import app.revanced.integrations.twitch.settings.Settings; import tv.twitch.android.shared.chat.util.ClickableUsernameSpan; +@SuppressWarnings("unused") public class ShowDeletedMessagesPatch { + + /** + * Injection point. + */ public static boolean shouldUseSpoiler() { - return Objects.equals(SettingsEnum.SHOW_DELETED_MESSAGES.getString(), "spoiler"); + return "spoiler".equals(Settings.SHOW_DELETED_MESSAGES.get()); } public static boolean shouldCrossOut() { - return Objects.equals(SettingsEnum.SHOW_DELETED_MESSAGES.getString(), "cross-out"); + return "cross-out".equals(Settings.SHOW_DELETED_MESSAGES.get()); } + @Nullable public static Spanned reformatDeletedMessage(Spanned original) { if (!shouldCrossOut()) return null; SpannableStringBuilder ssb = new SpannableStringBuilder(original); ssb.setSpan(new StrikethroughSpan(), 0, original.length(), 0); - ssb.append(" (").append(ReVancedUtils.getString("revanced_deleted_msg")).append(")"); + ssb.append(" (").append(str("revanced_deleted_msg")).append(")"); ssb.setSpan(new StyleSpan(Typeface.ITALIC), original.length(), ssb.length(), 0); // Gray-out username diff --git a/app/src/main/java/app/revanced/integrations/twitch/patches/VideoAdsPatch.java b/app/src/main/java/app/revanced/integrations/twitch/patches/VideoAdsPatch.java new file mode 100644 index 0000000000..0079d673ca --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/twitch/patches/VideoAdsPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.twitch.patches; + +import app.revanced.integrations.twitch.settings.Settings; + +@SuppressWarnings("unused") +public class VideoAdsPatch { + public static boolean shouldBlockVideoAds() { + return Settings.BLOCK_VIDEO_ADS.get(); + } +} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/twitch/settingsmenu/SettingsHooks.java b/app/src/main/java/app/revanced/integrations/twitch/settings/AppCompatActivityHook.java similarity index 60% rename from app/src/main/java/app/revanced/twitch/settingsmenu/SettingsHooks.java rename to app/src/main/java/app/revanced/integrations/twitch/settings/AppCompatActivityHook.java index 749a188acf..f08fec13b2 100644 --- a/app/src/main/java/app/revanced/twitch/settingsmenu/SettingsHooks.java +++ b/app/src/main/java/app/revanced/integrations/twitch/settings/AppCompatActivityHook.java @@ -1,23 +1,24 @@ -package app.revanced.twitch.settingsmenu; - -import static app.revanced.twitch.utils.ReVancedUtils.getIdentifier; -import static app.revanced.twitch.utils.ReVancedUtils.getStringId; +package app.revanced.integrations.twitch.settings; import android.content.Intent; import android.os.Bundle; - import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.twitch.settings.preference.ReVancedPreferenceFragment; +import tv.twitch.android.feature.settings.menu.SettingsMenuGroup; +import tv.twitch.android.settings.SettingsActivity; import java.util.ArrayList; import java.util.List; -import app.revanced.twitch.utils.ReVancedUtils; -import app.revanced.twitch.utils.LogHelper; -import tv.twitch.android.feature.settings.menu.SettingsMenuGroup; -import tv.twitch.android.settings.SettingsActivity; - -public class SettingsHooks { +/** + * Hooks AppCompatActivity. + *

+ * This class is responsible for injecting our own fragment by replacing the AppCompatActivity. + * @noinspection unused + */ +public class AppCompatActivityHook { private static final int REVANCED_SETTINGS_MENU_ITEM_ID = 0x7; private static final String EXTRA_REVANCED_SETTINGS = "app.revanced.twitch.settings"; @@ -25,16 +26,18 @@ public class SettingsHooks { * Launches SettingsActivity and show ReVanced settings */ public static void startSettingsActivity() { - LogHelper.debug("Launching ReVanced settings"); + Logger.printDebug(() -> "Launching ReVanced settings"); + + final var context = app.revanced.integrations.shared.Utils.getContext(); - ReVancedUtils.ifContextAttached((c) -> { - Intent intent = new Intent(c, SettingsActivity.class); + if (context != null) { + Intent intent = new Intent(context, SettingsActivity.class); Bundle bundle = new Bundle(); bundle.putBoolean(EXTRA_REVANCED_SETTINGS, true); intent.putExtras(bundle); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - c.startActivity(intent); - }); + context.startActivity(intent); + } } /** @@ -42,7 +45,7 @@ public static void startSettingsActivity() { * @return Returns string resource id */ public static int getReVancedSettingsString() { - return getStringId("revanced_settings"); + return app.revanced.integrations.twitch.Utils.getStringId("revanced_settings"); } /** @@ -52,13 +55,12 @@ public static int getReVancedSettingsString() { public static List handleSettingMenuCreation(List settingGroups, Object revancedEntry) { List groups = new ArrayList<>(settingGroups); - if(groups.size() < 1) { + if (groups.isEmpty()) { // Create new menu group if none exist yet List items = new ArrayList<>(); items.add(revancedEntry); groups.add(new SettingsMenuGroup(items)); - } - else { + } else { // Add to last menu group int groupIdx = groups.size() - 1; List items = new ArrayList<>(groups.remove(groupIdx).getSettingsMenuItems()); @@ -66,7 +68,7 @@ public static List handleSettingMenuCreation(List settingGroups.size() + " menu groups in list"); return groups; } @@ -76,8 +78,8 @@ public static List handleSettingMenuCreation(List "item " + item.ordinal() + " clicked"); + if (item.ordinal() != REVANCED_SETTINGS_MENU_ITEM_ID) { return false; } @@ -89,21 +91,21 @@ public static boolean handleSettingMenuOnClick(Enum item) { * Intercepts fragment loading in SettingsActivity.onCreate * @return Returns true if the revanced settings have been requested by the user, otherwise false */ - public static boolean handleSettingsCreation(AppCompatActivity base) { - if(!base.getIntent().getBooleanExtra(EXTRA_REVANCED_SETTINGS, false)) { - LogHelper.debug("Revanced settings not requested"); + public static boolean handleSettingsCreation(androidx.appcompat.app.AppCompatActivity base) { + if (!base.getIntent().getBooleanExtra(EXTRA_REVANCED_SETTINGS, false)) { + Logger.printDebug(() -> "Revanced settings not requested"); return false; // User wants to enter another settings fragment } - LogHelper.debug("ReVanced settings requested"); + Logger.printDebug(() -> "ReVanced settings requested"); - ReVancedSettingsFragment fragment = new ReVancedSettingsFragment(); + ReVancedPreferenceFragment fragment = new ReVancedPreferenceFragment(); ActionBar supportActionBar = base.getSupportActionBar(); - if(supportActionBar != null) - supportActionBar.setTitle(getStringId("revanced_settings")); + if (supportActionBar != null) + supportActionBar.setTitle(app.revanced.integrations.twitch.Utils.getStringId("revanced_settings")); base.getFragmentManager() .beginTransaction() - .replace(getIdentifier("fragment_container", "id"), fragment) + .replace(Utils.getResourceIdentifier("fragment_container", "id"), fragment) .commit(); return true; } diff --git a/app/src/main/java/app/revanced/integrations/twitch/settings/Settings.java b/app/src/main/java/app/revanced/integrations/twitch/settings/Settings.java new file mode 100644 index 0000000000..8f3969b79d --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/twitch/settings/Settings.java @@ -0,0 +1,25 @@ +package app.revanced.integrations.twitch.settings; + +import app.revanced.integrations.shared.settings.BooleanSetting; +import app.revanced.integrations.shared.settings.BaseSettings; +import app.revanced.integrations.shared.settings.StringSetting; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; + +public class Settings extends BaseSettings { + /* Ads */ + public static final BooleanSetting BLOCK_VIDEO_ADS = new BooleanSetting("revanced_block_video_ads", TRUE); + public static final BooleanSetting BLOCK_AUDIO_ADS = new BooleanSetting("revanced_block_audio_ads", TRUE); + public static final StringSetting BLOCK_EMBEDDED_ADS = new StringSetting("revanced_block_embedded_ads", "luminous"); + + /* Chat */ + public static final StringSetting SHOW_DELETED_MESSAGES = new StringSetting("revanced_show_deleted_messages", "cross-out"); + public static final BooleanSetting AUTO_CLAIM_CHANNEL_POINTS = new BooleanSetting("revanced_auto_claim_channel_points", TRUE); + + /* Misc */ + /** + * Not to be confused with {@link BaseSettings#DEBUG}. + */ + public static final BooleanSetting TWITCH_DEBUG_MODE = new BooleanSetting("revanced_twitch_debug_mode", FALSE, true); +} diff --git a/app/src/main/java/app/revanced/twitch/settingsmenu/preference/CustomPreferenceCategory.java b/app/src/main/java/app/revanced/integrations/twitch/settings/preference/CustomPreferenceCategory.java similarity index 90% rename from app/src/main/java/app/revanced/twitch/settingsmenu/preference/CustomPreferenceCategory.java rename to app/src/main/java/app/revanced/integrations/twitch/settings/preference/CustomPreferenceCategory.java index ec92a50528..64f0a3d811 100644 --- a/app/src/main/java/app/revanced/twitch/settingsmenu/preference/CustomPreferenceCategory.java +++ b/app/src/main/java/app/revanced/integrations/twitch/settings/preference/CustomPreferenceCategory.java @@ -1,4 +1,4 @@ -package app.revanced.twitch.settingsmenu.preference; +package app.revanced.integrations.twitch.settings.preference; import android.content.Context; import android.graphics.Color; diff --git a/app/src/main/java/app/revanced/integrations/twitch/settings/preference/ReVancedPreferenceFragment.java b/app/src/main/java/app/revanced/integrations/twitch/settings/preference/ReVancedPreferenceFragment.java new file mode 100644 index 0000000000..1d3cca4b2e --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/twitch/settings/preference/ReVancedPreferenceFragment.java @@ -0,0 +1,21 @@ +package app.revanced.integrations.twitch.settings.preference; + +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.settings.preference.AbstractPreferenceFragment; +import app.revanced.integrations.twitch.settings.Settings; + +/** + * Preference fragment for ReVanced settings + */ +public class ReVancedPreferenceFragment extends AbstractPreferenceFragment { + + @Override + protected void initialize() { + super.initialize(); + + // Do anything that forces this apps Settings bundle to load. + if (Settings.BLOCK_VIDEO_ADS.get()) { + Logger.printDebug(() -> "Block video ads enabled"); // Any statement that references the app settings. + } + } +} diff --git a/app/src/main/java/app/revanced/twitter/patches/hook/json/BaseJsonHook.kt b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/json/BaseJsonHook.kt similarity index 75% rename from app/src/main/java/app/revanced/twitter/patches/hook/json/BaseJsonHook.kt rename to app/src/main/java/app/revanced/integrations/twitter/patches/hook/json/BaseJsonHook.kt index 9683837044..536a43e1f9 100644 --- a/app/src/main/java/app/revanced/twitter/patches/hook/json/BaseJsonHook.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/json/BaseJsonHook.kt @@ -1,4 +1,4 @@ -package app.revanced.twitter.patches.hook.json +package app.revanced.integrations.twitter.patches.hook.json import org.json.JSONObject diff --git a/app/src/main/java/app/revanced/twitter/patches/hook/json/JsonHook.kt b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/json/JsonHook.kt similarity index 68% rename from app/src/main/java/app/revanced/twitter/patches/hook/json/JsonHook.kt rename to app/src/main/java/app/revanced/integrations/twitter/patches/hook/json/JsonHook.kt index e5c2f0ef6a..3edfca4e6a 100644 --- a/app/src/main/java/app/revanced/twitter/patches/hook/json/JsonHook.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/json/JsonHook.kt @@ -1,6 +1,6 @@ -package app.revanced.twitter.patches.hook.json +package app.revanced.integrations.twitter.patches.hook.json -import app.revanced.twitter.patches.hook.patch.Hook +import app.revanced.integrations.twitter.patches.hook.patch.Hook import org.json.JSONObject interface JsonHook : Hook { diff --git a/app/src/main/java/app/revanced/twitter/patches/hook/json/JsonHookPatch.kt b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/json/JsonHookPatch.kt similarity index 71% rename from app/src/main/java/app/revanced/twitter/patches/hook/json/JsonHookPatch.kt rename to app/src/main/java/app/revanced/integrations/twitter/patches/hook/json/JsonHookPatch.kt index d8c47d714c..6e4067b923 100644 --- a/app/src/main/java/app/revanced/twitter/patches/hook/json/JsonHookPatch.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/json/JsonHookPatch.kt @@ -1,8 +1,8 @@ -package app.revanced.twitter.patches.hook.json +package app.revanced.integrations.twitter.patches.hook.json -import app.revanced.twitter.patches.hook.patch.dummy.DummyHook -import app.revanced.twitter.utils.json.JsonUtils.parseJson -import app.revanced.twitter.utils.stream.StreamUtils +import app.revanced.integrations.twitter.patches.hook.patch.dummy.DummyHook +import app.revanced.integrations.twitter.utils.json.JsonUtils.parseJson +import app.revanced.integrations.twitter.utils.stream.StreamUtils import org.json.JSONException import java.io.IOException import java.io.InputStream diff --git a/app/src/main/java/app/revanced/twitter/patches/hook/patch/Hook.kt b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/Hook.kt similarity index 67% rename from app/src/main/java/app/revanced/twitter/patches/hook/patch/Hook.kt rename to app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/Hook.kt index b57c4077b1..d6d163ef97 100644 --- a/app/src/main/java/app/revanced/twitter/patches/hook/patch/Hook.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/Hook.kt @@ -1,4 +1,4 @@ -package app.revanced.twitter.patches.hook.patch +package app.revanced.integrations.twitter.patches.hook.patch interface Hook { /** diff --git a/app/src/main/java/app/revanced/twitter/patches/hook/patch/ads/AdsHook.kt b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/ads/AdsHook.kt similarity index 53% rename from app/src/main/java/app/revanced/twitter/patches/hook/patch/ads/AdsHook.kt rename to app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/ads/AdsHook.kt index cf84a52be0..7c33a5b21a 100644 --- a/app/src/main/java/app/revanced/twitter/patches/hook/patch/ads/AdsHook.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/ads/AdsHook.kt @@ -1,7 +1,7 @@ -package app.revanced.twitter.patches.hook.patch.ads +package app.revanced.integrations.twitter.patches.hook.patch.ads -import app.revanced.twitter.patches.hook.json.BaseJsonHook -import app.revanced.twitter.patches.hook.twifucker.TwiFucker +import app.revanced.integrations.twitter.patches.hook.json.BaseJsonHook +import app.revanced.integrations.twitter.patches.hook.twifucker.TwiFucker import org.json.JSONObject diff --git a/app/src/main/java/app/revanced/twitter/patches/hook/patch/dummy/DummyHook.kt b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/dummy/DummyHook.kt similarity index 50% rename from app/src/main/java/app/revanced/twitter/patches/hook/patch/dummy/DummyHook.kt rename to app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/dummy/DummyHook.kt index 56a7a08e43..1a4f583c7b 100644 --- a/app/src/main/java/app/revanced/twitter/patches/hook/patch/dummy/DummyHook.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/dummy/DummyHook.kt @@ -1,7 +1,7 @@ -package app.revanced.twitter.patches.hook.patch.dummy +package app.revanced.integrations.twitter.patches.hook.patch.dummy -import app.revanced.twitter.patches.hook.json.BaseJsonHook -import app.revanced.twitter.patches.hook.json.JsonHookPatch +import app.revanced.integrations.twitter.patches.hook.json.BaseJsonHook +import app.revanced.integrations.twitter.patches.hook.json.JsonHookPatch import org.json.JSONObject /** diff --git a/app/src/main/java/app/revanced/twitter/patches/hook/patch/recommendation/RecommendedUsersHook.kt b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/recommendation/RecommendedUsersHook.kt similarity index 54% rename from app/src/main/java/app/revanced/twitter/patches/hook/patch/recommendation/RecommendedUsersHook.kt rename to app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/recommendation/RecommendedUsersHook.kt index 29bf3cc20f..dfbb1ffb23 100644 --- a/app/src/main/java/app/revanced/twitter/patches/hook/patch/recommendation/RecommendedUsersHook.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/patch/recommendation/RecommendedUsersHook.kt @@ -1,7 +1,7 @@ -package app.revanced.twitter.patches.hook.patch.recommendation +package app.revanced.integrations.twitter.patches.hook.patch.recommendation -import app.revanced.twitter.patches.hook.json.BaseJsonHook -import app.revanced.twitter.patches.hook.twifucker.TwiFucker +import app.revanced.integrations.twitter.patches.hook.json.BaseJsonHook +import app.revanced.integrations.twitter.patches.hook.twifucker.TwiFucker import org.json.JSONObject diff --git a/app/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFucker.kt b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/twifucker/TwiFucker.kt similarity index 97% rename from app/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFucker.kt rename to app/src/main/java/app/revanced/integrations/twitter/patches/hook/twifucker/TwiFucker.kt index 5c4323e353..247ef0a344 100644 --- a/app/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFucker.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/twifucker/TwiFucker.kt @@ -1,8 +1,8 @@ -package app.revanced.twitter.patches.hook.twifucker +package app.revanced.integrations.twitter.patches.hook.twifucker import android.util.Log -import app.revanced.twitter.patches.hook.twifucker.TwiFuckerUtils.forEach -import app.revanced.twitter.patches.hook.twifucker.TwiFuckerUtils.forEachIndexed +import app.revanced.integrations.twitter.patches.hook.twifucker.TwiFuckerUtils.forEach +import app.revanced.integrations.twitter.patches.hook.twifucker.TwiFuckerUtils.forEachIndexed import org.json.JSONArray import org.json.JSONObject diff --git a/app/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFuckerUtils.kt b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/twifucker/TwiFuckerUtils.kt similarity index 89% rename from app/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFuckerUtils.kt rename to app/src/main/java/app/revanced/integrations/twitter/patches/hook/twifucker/TwiFuckerUtils.kt index 33e44cb474..f6c05e1fb4 100644 --- a/app/src/main/java/app/revanced/twitter/patches/hook/twifucker/TwiFuckerUtils.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/patches/hook/twifucker/TwiFuckerUtils.kt @@ -1,4 +1,4 @@ -package app.revanced.twitter.patches.hook.twifucker +package app.revanced.integrations.twitter.patches.hook.twifucker import org.json.JSONArray import org.json.JSONObject diff --git a/app/src/main/java/app/revanced/twitter/utils/json/JsonUtils.kt b/app/src/main/java/app/revanced/integrations/twitter/utils/json/JsonUtils.kt similarity index 71% rename from app/src/main/java/app/revanced/twitter/utils/json/JsonUtils.kt rename to app/src/main/java/app/revanced/integrations/twitter/utils/json/JsonUtils.kt index e0102a4e93..4b7a5002a6 100644 --- a/app/src/main/java/app/revanced/twitter/utils/json/JsonUtils.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/utils/json/JsonUtils.kt @@ -1,6 +1,6 @@ -package app.revanced.twitter.utils.json +package app.revanced.integrations.twitter.utils.json -import app.revanced.twitter.utils.stream.StreamUtils +import app.revanced.integrations.twitter.utils.stream.StreamUtils import org.json.JSONException import org.json.JSONObject import java.io.IOException diff --git a/app/src/main/java/app/revanced/twitter/utils/stream/StreamUtils.kt b/app/src/main/java/app/revanced/integrations/twitter/utils/stream/StreamUtils.kt similarity index 92% rename from app/src/main/java/app/revanced/twitter/utils/stream/StreamUtils.kt rename to app/src/main/java/app/revanced/integrations/twitter/utils/stream/StreamUtils.kt index ccbcc8239f..7e008eb849 100644 --- a/app/src/main/java/app/revanced/twitter/utils/stream/StreamUtils.kt +++ b/app/src/main/java/app/revanced/integrations/twitter/utils/stream/StreamUtils.kt @@ -1,4 +1,4 @@ -package app.revanced.twitter.utils.stream +package app.revanced.integrations.twitter.utils.stream import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream diff --git a/app/src/main/java/app/revanced/integrations/utils/ByteTrieSearch.java b/app/src/main/java/app/revanced/integrations/youtube/ByteTrieSearch.java similarity index 96% rename from app/src/main/java/app/revanced/integrations/utils/ByteTrieSearch.java rename to app/src/main/java/app/revanced/integrations/youtube/ByteTrieSearch.java index 4e47d5551b..bc564675fe 100644 --- a/app/src/main/java/app/revanced/integrations/utils/ByteTrieSearch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/ByteTrieSearch.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.utils; +package app.revanced.integrations.youtube; public final class ByteTrieSearch extends TrieSearch { diff --git a/app/src/main/java/app/revanced/integrations/utils/Event.kt b/app/src/main/java/app/revanced/integrations/youtube/Event.kt similarity index 93% rename from app/src/main/java/app/revanced/integrations/utils/Event.kt rename to app/src/main/java/app/revanced/integrations/youtube/Event.kt index 7f7b144916..7b25af7f43 100644 --- a/app/src/main/java/app/revanced/integrations/utils/Event.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/Event.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.utils +package app.revanced.integrations.youtube /** * generic event provider class diff --git a/app/src/main/java/app/revanced/integrations/utils/StringTrieSearch.java b/app/src/main/java/app/revanced/integrations/youtube/StringTrieSearch.java similarity index 96% rename from app/src/main/java/app/revanced/integrations/utils/StringTrieSearch.java rename to app/src/main/java/app/revanced/integrations/youtube/StringTrieSearch.java index 8c7aeeb103..d2fb7f78b5 100644 --- a/app/src/main/java/app/revanced/integrations/utils/StringTrieSearch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/StringTrieSearch.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.utils; +package app.revanced.integrations.youtube; /** * Text pattern searching using a prefix tree (trie). diff --git a/app/src/main/java/app/revanced/integrations/utils/ThemeHelper.java b/app/src/main/java/app/revanced/integrations/youtube/ThemeHelper.java similarity index 67% rename from app/src/main/java/app/revanced/integrations/utils/ThemeHelper.java rename to app/src/main/java/app/revanced/integrations/youtube/ThemeHelper.java index 99fe57d33e..0faa46b14c 100644 --- a/app/src/main/java/app/revanced/integrations/utils/ThemeHelper.java +++ b/app/src/main/java/app/revanced/integrations/youtube/ThemeHelper.java @@ -1,6 +1,8 @@ -package app.revanced.integrations.utils; +package app.revanced.integrations.youtube; import android.app.Activity; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; public class ThemeHelper { private static int themeValue; @@ -9,7 +11,7 @@ public static void setTheme(Object value) { final int newOrdinalValue = ((Enum) value).ordinal(); if (themeValue != newOrdinalValue) { themeValue = newOrdinalValue; - LogHelper.printDebug(() -> "Theme value: " + newOrdinalValue); + Logger.printDebug(() -> "Theme value: " + newOrdinalValue); } } @@ -21,7 +23,7 @@ public static void setActivityTheme(Activity activity) { final var theme = isDarkTheme() ? "Theme.YouTube.Settings.Dark" : "Theme.YouTube.Settings"; - activity.setTheme(ReVancedUtils.getResourceIdentifier(theme, "style")); + activity.setTheme(Utils.getResourceIdentifier(theme, "style")); } } diff --git a/app/src/main/java/app/revanced/integrations/utils/TrieSearch.java b/app/src/main/java/app/revanced/integrations/youtube/TrieSearch.java similarity index 99% rename from app/src/main/java/app/revanced/integrations/utils/TrieSearch.java rename to app/src/main/java/app/revanced/integrations/youtube/TrieSearch.java index 437c791604..778b6c9066 100644 --- a/app/src/main/java/app/revanced/integrations/utils/TrieSearch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/TrieSearch.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.utils; +package app.revanced.integrations.youtube; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/app/src/main/java/app/revanced/integrations/patches/AlternativeThumbnailsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/AlternativeThumbnailsPatch.java similarity index 83% rename from app/src/main/java/app/revanced/integrations/patches/AlternativeThumbnailsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/AlternativeThumbnailsPatch.java index 49d8410301..9cedb96e2e 100644 --- a/app/src/main/java/app/revanced/integrations/patches/AlternativeThumbnailsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/AlternativeThumbnailsPatch.java @@ -1,12 +1,13 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.net.Uri; import androidx.annotation.GuardedBy; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; + +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; import org.chromium.net.UrlRequest; import org.chromium.net.UrlResponseInfo; import org.chromium.net.impl.CronetUrlRequest; @@ -19,7 +20,7 @@ import java.util.Map; import java.util.concurrent.ExecutionException; -import static app.revanced.integrations.utils.StringRef.str; +import static app.revanced.integrations.shared.StringRef.str; /** * Alternative YouTube thumbnails. @@ -27,7 +28,7 @@ * Can show YouTube provided screen captures of beginning/middle/end of the video. * (ie: sd1.jpg, sd2.jpg, sd3.jpg). *

- * Or can show crowdsourced thumbnails provided by DeArrow (...). + * Or can show crowd-sourced thumbnails provided by DeArrow (...). *

* Or can use DeArrow and fall back to screen captures if DeArrow is not available. *

@@ -70,37 +71,37 @@ public final class AlternativeThumbnailsPatch { final int port = dearrowApiUri.getPort(); String portString = port == -1 ? "" : (":" + port); deArrowApiUrlPrefix = dearrowApiUri.getScheme() + "://" + dearrowApiUri.getHost() + portString + "/"; - LogHelper.printDebug(() -> "Using DeArrow API address: " + deArrowApiUrlPrefix); + Logger.printDebug(() -> "Using DeArrow API address: " + deArrowApiUrlPrefix); } /** * Fix any bad imported data. */ private static Uri validateSettings() { - final int altThumbnailType = SettingsEnum.ALT_THUMBNAIL_STILLS_TIME.getInt(); + final int altThumbnailType = Settings.ALT_THUMBNAIL_STILLS_TIME.get(); if (altThumbnailType < 1 || altThumbnailType > 3) { - ReVancedUtils.showToastLong("Invalid Alternative still thumbnail type: " + Utils.showToastLong("Invalid Alternative still thumbnail type: " + altThumbnailType + ". Using default"); - SettingsEnum.ALT_THUMBNAIL_STILLS_TIME.resetToDefault(); + Settings.ALT_THUMBNAIL_STILLS_TIME.resetToDefault(); } - Uri apiUri = Uri.parse(SettingsEnum.ALT_THUMBNAIL_DEARROW_API_URL.getString()); + Uri apiUri = Uri.parse(Settings.ALT_THUMBNAIL_DEARROW_API_URL.get()); // Cannot use unsecured 'http', otherwise the connections fail to start and no callbacks hooks are made. String scheme = apiUri.getScheme(); if (scheme == null || scheme.equals("http") || apiUri.getHost() == null) { - ReVancedUtils.showToastLong("Invalid DeArrow API URL. Using default"); - SettingsEnum.ALT_THUMBNAIL_DEARROW_API_URL.resetToDefault(); + Utils.showToastLong("Invalid DeArrow API URL. Using default"); + Settings.ALT_THUMBNAIL_DEARROW_API_URL.resetToDefault(); return validateSettings(); } return apiUri; } private static boolean usingDeArrow() { - return SettingsEnum.ALT_THUMBNAIL_DEARROW.getBoolean(); + return Settings.ALT_THUMBNAIL_DEARROW.get(); } private static boolean usingVideoStills() { - return SettingsEnum.ALT_THUMBNAIL_STILLS.getBoolean(); + return Settings.ALT_THUMBNAIL_STILLS.get(); } /** @@ -150,7 +151,7 @@ private static boolean canUseDeArrowAPI() { return true; } if (timeToResumeDeArrowAPICalls < System.currentTimeMillis()) { - LogHelper.printDebug(() -> "Resuming DeArrow API calls"); + Logger.printDebug(() -> "Resuming DeArrow API calls"); timeToResumeDeArrowAPICalls = 0; return true; } @@ -158,15 +159,15 @@ private static boolean canUseDeArrowAPI() { } private static void handleDeArrowError(@NonNull String url, int statusCode) { - LogHelper.printDebug(() -> "Encountered DeArrow error. Url: " + url); + Logger.printDebug(() -> "Encountered DeArrow error. Url: " + url); final long now = System.currentTimeMillis(); if (timeToResumeDeArrowAPICalls < now) { timeToResumeDeArrowAPICalls = now + DEARROW_FAILURE_API_BACKOFF_MILLISECONDS; - if (SettingsEnum.ALT_THUMBNAIL_DEARROW_CONNECTION_TOAST.getBoolean()) { + if (Settings.ALT_THUMBNAIL_DEARROW_CONNECTION_TOAST.get()) { String toastMessage = (statusCode != 0) ? str("revanced_alt_thumbnail_dearrow_error", statusCode) : str("revanced_alt_thumbnail_dearrow_error_generic"); - ReVancedUtils.showToastLong(toastMessage); + Utils.showToastLong(toastMessage); } } } @@ -189,7 +190,7 @@ public static String overrideImageURL(String originalUrl) { return originalUrl; // Not a thumbnail. } - LogHelper.printDebug(() -> "Original url: " + decodedUrl.sanitizedUrl); + Logger.printDebug(() -> "Original url: " + decodedUrl.sanitizedUrl); ThumbnailQuality qualityToUse = ThumbnailQuality.getQualityToUse(decodedUrl.imageQuality); if (qualityToUse == null) { @@ -214,13 +215,13 @@ public static String overrideImageURL(String originalUrl) { } // Do not log any tracking parameters. - LogHelper.printDebug(() -> "Replacement url: " + sanitizedReplacementUrl); + Logger.printDebug(() -> "Replacement url: " + sanitizedReplacementUrl); return includeTracking ? sanitizedReplacementUrl + decodedUrl.viewTrackingParameters : sanitizedReplacementUrl; } catch (Exception ex) { - LogHelper.printException(() -> "overrideImageURL failure", ex); + Logger.printException(() -> "overrideImageURL failure", ex); return originalUrl; } } @@ -233,42 +234,48 @@ public static String overrideImageURL(String originalUrl) { public static void handleCronetSuccess(UrlRequest request, @NonNull UrlResponseInfo responseInfo) { try { final int statusCode = responseInfo.getHttpStatusCode(); - if (statusCode != 200) { - String url = responseInfo.getUrl(); + if (statusCode == 200) { + return; + } - if (usingDeArrow() && urlIsDeArrow(url)) { - LogHelper.printDebug(() -> "handleCronetSuccess, statusCode: " + statusCode); - handleDeArrowError(url, statusCode); - return; - } + String url = responseInfo.getUrl(); - if (usingVideoStills() && statusCode == 404) { - // Fast alt thumbnails is enabled and the thumbnail is not available. - // The video is: - // - live stream - // - upcoming unreleased video - // - very old - // - very low view count - // Take note of this, so if the image reloads the original thumbnail will be used. - DecodedThumbnailUrl decodedUrl = DecodedThumbnailUrl.decodeImageUrl(url); - if (decodedUrl == null) { - return; // Not a thumbnail. - } + if (usingDeArrow() && urlIsDeArrow(url)) { + Logger.printDebug(() -> "handleCronetSuccess, statusCode: " + statusCode); + if (statusCode == 304) { + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304 + return; // Normal response. + } + handleDeArrowError(url, statusCode); + return; + } - LogHelper.printDebug(() -> "handleCronetSuccess, image not available: " + url); + if (usingVideoStills() && statusCode == 404) { + // Fast alt thumbnails is enabled and the thumbnail is not available. + // The video is: + // - live stream + // - upcoming unreleased video + // - very old + // - very low view count + // Take note of this, so if the image reloads the original thumbnail will be used. + DecodedThumbnailUrl decodedUrl = DecodedThumbnailUrl.decodeImageUrl(url); + if (decodedUrl == null) { + return; // Not a thumbnail. + } - ThumbnailQuality quality = ThumbnailQuality.altImageNameToQuality(decodedUrl.imageQuality); - if (quality == null) { - // Video is a short or a seekbar thumbnail, but somehow did not load. Should not happen. - LogHelper.printDebug(() -> "Failed to recognize image quality of url: " + decodedUrl.sanitizedUrl); - return; - } + Logger.printDebug(() -> "handleCronetSuccess, image not available: " + url); - VerifiedQualities.setAltThumbnailDoesNotExist(decodedUrl.videoId, quality); + ThumbnailQuality quality = ThumbnailQuality.altImageNameToQuality(decodedUrl.imageQuality); + if (quality == null) { + // Video is a short or a seekbar thumbnail, but somehow did not load. Should not happen. + Logger.printDebug(() -> "Failed to recognize image quality of url: " + decodedUrl.sanitizedUrl); + return; } + + VerifiedQualities.setAltThumbnailDoesNotExist(decodedUrl.videoId, quality); } } catch (Exception ex) { - LogHelper.printException(() -> "Callback success error", ex); + Logger.printException(() -> "Callback success error", ex); } } @@ -279,7 +286,7 @@ public static void handleCronetSuccess(UrlRequest request, @NonNull UrlResponseI * - A non-existent domain. * - A url path of something incorrect (ie: /v1/nonExistentEndPoint). *

- * Known limitation: YT uses an infinite timeout, so this hook is never called if a host never responds. + * Cronet uses a very timeout (several minutes), so if the API never responds this hook can take a while to be called. * But this does not appear to be a problem, as the DeArrow API has not been observed to 'go silent' * Instead if there's a problem it returns an error code status response, which is handled in this patch. */ @@ -290,7 +297,7 @@ public static void handleCronetFailure(UrlRequest request, if (usingDeArrow()) { String url = ((CronetUrlRequest) request).getHookedUrl(); if (urlIsDeArrow(url)) { - LogHelper.printDebug(() -> "handleCronetFailure, exception: " + exception); + Logger.printDebug(() -> "handleCronetFailure, exception: " + exception); final int statusCode = (responseInfo != null) ? responseInfo.getHttpStatusCode() : 0; @@ -298,7 +305,7 @@ public static void handleCronetFailure(UrlRequest request, } } } catch (Exception ex) { - LogHelper.printException(() -> "Callback failure error", ex); + Logger.printException(() -> "Callback failure error", ex); } } @@ -356,7 +363,7 @@ static ThumbnailQuality getQualityToUse(@NonNull String originalSize) { return null; // Not a thumbnail for a regular video. } - final boolean useFastQuality = SettingsEnum.ALT_THUMBNAIL_STILLS_FAST.getBoolean(); + final boolean useFastQuality = Settings.ALT_THUMBNAIL_STILLS_FAST.get(); switch (quality) { case SDDEFAULT: // SD alt images have somewhat worse quality with washed out color and poor contrast. @@ -391,7 +398,7 @@ static ThumbnailQuality getQualityToUse(@NonNull String originalSize) { } String getAltImageNameToUse() { - return altImageName + SettingsEnum.ALT_THUMBNAIL_STILLS_TIME.getInt(); + return altImageName + Settings.ALT_THUMBNAIL_STILLS_TIME.get(); } } @@ -436,7 +443,7 @@ private static VerifiedQualities getVerifiedQualities(@NonNull String videoId, b static boolean verifyAltThumbnailExist(@NonNull String videoId, @NonNull ThumbnailQuality quality, @NonNull String imageUrl) { - VerifiedQualities verified = getVerifiedQualities(videoId, SettingsEnum.ALT_THUMBNAIL_STILLS_FAST.getBoolean()); + VerifiedQualities verified = getVerifiedQualities(videoId, Settings.ALT_THUMBNAIL_STILLS_FAST.get()); if (verified == null) return true; // Fast alt thumbnails is enabled. return verified.verifyYouTubeThumbnailExists(videoId, quality, imageUrl); } @@ -474,7 +481,7 @@ private synchronized void setQualityVerified(String videoId, ThumbnailQuality qu lowestQualityNotAvailable = quality; timeToReVerifyLowestQuality = System.currentTimeMillis() + NOT_AVAILABLE_TIMEOUT_MILLISECONDS; } - LogHelper.printDebug(() -> quality + " not available for video: " + videoId); + Logger.printDebug(() -> quality + " not available for video: " + videoId); } } @@ -487,13 +494,13 @@ synchronized boolean verifyYouTubeThumbnailExists(@NonNull String videoId, @NonN return true; // Previously verified as existing. } - final boolean fastQuality = SettingsEnum.ALT_THUMBNAIL_STILLS_FAST.getBoolean(); + final boolean fastQuality = Settings.ALT_THUMBNAIL_STILLS_FAST.get(); if (lowestQualityNotAvailable != null && lowestQualityNotAvailable.ordinal() <= quality.ordinal()) { if (fastQuality || System.currentTimeMillis() < timeToReVerifyLowestQuality) { return false; // Previously verified as not existing. } // Enough time has passed, and should re-verify again. - LogHelper.printDebug(() -> "Resetting lowest verified quality for: " + videoId); + Logger.printDebug(() -> "Resetting lowest verified quality for: " + videoId); lowestQualityNotAvailable = null; } @@ -503,11 +510,11 @@ synchronized boolean verifyYouTubeThumbnailExists(@NonNull String videoId, @NonN boolean imageFileFound; try { - LogHelper.printDebug(() -> "Verifying image: " + imageUrl); + Logger.printDebug(() -> "Verifying image: " + imageUrl); // This hooked code is running on a low priority thread, and it's slightly faster // to run the url connection thru the integrations thread pool which runs at the highest priority. final long start = System.currentTimeMillis(); - imageFileFound = ReVancedUtils.submitOnBackgroundThread(() -> { + imageFileFound = Utils.submitOnBackgroundThread(() -> { final int connectionTimeoutMillis = 5000; HttpURLConnection connection = (HttpURLConnection) new URL(imageUrl).openConnection(); connection.setConnectTimeout(connectionTimeoutMillis); @@ -522,13 +529,13 @@ synchronized boolean verifyYouTubeThumbnailExists(@NonNull String videoId, @NonN return (contentType != null && contentType.startsWith("image")); } if (responseCode != HttpURLConnection.HTTP_NOT_FOUND) { - LogHelper.printDebug(() -> "Unexpected response code: " + responseCode + " for url: " + imageUrl); + Logger.printDebug(() -> "Unexpected response code: " + responseCode + " for url: " + imageUrl); } return false; }).get(); - LogHelper.printDebug(() -> "Alt verification took: " + (System.currentTimeMillis() - start) + "ms"); + Logger.printDebug(() -> "Alt verification took: " + (System.currentTimeMillis() - start) + "ms"); } catch (ExecutionException | InterruptedException ex) { - LogHelper.printInfo(() -> "Could not verify alt url: " + imageUrl, ex); + Logger.printInfo(() -> "Could not verify alt url: " + imageUrl, ex); imageFileFound = false; } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/AutoRepeatPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/AutoRepeatPatch.java new file mode 100644 index 0000000000..38dd2095b9 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/AutoRepeatPatch.java @@ -0,0 +1,11 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class AutoRepeatPatch { + //Used by app.revanced.patches.youtube.layout.autorepeat.patch.AutoRepeatPatch + public static boolean shouldAutoRepeat() { + return Settings.AUTO_REPEAT.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/BypassURLRedirectsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/BypassURLRedirectsPatch.java similarity index 60% rename from app/src/main/java/app/revanced/integrations/patches/BypassURLRedirectsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/BypassURLRedirectsPatch.java index dd062e0372..c49f8bbd0f 100644 --- a/app/src/main/java/app/revanced/integrations/patches/BypassURLRedirectsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/BypassURLRedirectsPatch.java @@ -1,9 +1,11 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.net.Uri; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; + +@SuppressWarnings("unused") public class BypassURLRedirectsPatch { private static final String YOUTUBE_REDIRECT_PATH = "/redirect"; @@ -16,10 +18,10 @@ public class BypassURLRedirectsPatch { public static Uri parseRedirectUri(String uri) { final var parsed = Uri.parse(uri); - if (SettingsEnum.BYPASS_URL_REDIRECTS.getBoolean() && parsed.getPath().equals(YOUTUBE_REDIRECT_PATH)) { + if (Settings.BYPASS_URL_REDIRECTS.get() && parsed.getPath().equals(YOUTUBE_REDIRECT_PATH)) { var query = Uri.parse(Uri.decode(parsed.getQueryParameter("q"))); - LogHelper.printDebug(() -> "Bypassing YouTube redirect URI: " + query); + Logger.printDebug(() -> "Bypassing YouTube redirect URI: " + query); return query; } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/ChangeStartPagePatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/ChangeStartPagePatch.java new file mode 100644 index 0000000000..2e3f007a41 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/ChangeStartPagePatch.java @@ -0,0 +1,17 @@ +package app.revanced.integrations.youtube.patches; + +import android.content.Intent; + +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; + +@SuppressWarnings("unused") +public final class ChangeStartPagePatch { + public static void changeIntent(final Intent intent) { + final var startPage = Settings.START_PAGE.get(); + if (startPage.isEmpty()) return; + + Logger.printDebug(() -> "Changing start page to " + startPage); + intent.setAction("com.google.android.youtube.action." + startPage); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/CopyVideoUrlPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/CopyVideoUrlPatch.java similarity index 78% rename from app/src/main/java/app/revanced/integrations/patches/CopyVideoUrlPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/CopyVideoUrlPatch.java index f21e488918..fec49a3445 100644 --- a/app/src/main/java/app/revanced/integrations/patches/CopyVideoUrlPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/CopyVideoUrlPatch.java @@ -1,11 +1,11 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import static app.revanced.integrations.utils.StringRef.str; +import static app.revanced.integrations.shared.StringRef.str; import android.os.Build; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; public class CopyVideoUrlPatch { @@ -30,17 +30,17 @@ public static void copyUrl(boolean withTimestamp) { } } - ReVancedUtils.setClipboard(builder.toString()); + Utils.setClipboard(builder.toString()); // Do not show a toast if using Android 13+ as it shows it's own toast. // But if the user copied with a timestamp then show a toast. // Unfortunately this will show 2 toasts on Android 13+, but no way around this. if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2 || (withTimestamp && currentVideoTimeInSeconds > 0)) { - ReVancedUtils.showToastShort(withTimestamp && currentVideoTimeInSeconds > 0 + Utils.showToastShort(withTimestamp && currentVideoTimeInSeconds > 0 ? str("revanced_share_copy_url_timestamp_success") : str("revanced_share_copy_url_success")); } } catch (Exception e) { - LogHelper.printException(() -> "Failed to generate video url", e); + Logger.printException(() -> "Failed to generate video url", e); } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/CustomPlayerOverlayOpacityPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/CustomPlayerOverlayOpacityPatch.java new file mode 100644 index 0000000000..26bedbb0d6 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/CustomPlayerOverlayOpacityPatch.java @@ -0,0 +1,22 @@ +package app.revanced.integrations.youtube.patches; + +import android.widget.ImageView; + +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Utils; + +@SuppressWarnings("unused") +public class CustomPlayerOverlayOpacityPatch { + + public static void changeOpacity(ImageView imageView) { + int opacity = Settings.PLAYER_OVERLAY_OPACITY.get(); + + if (opacity < 0 || opacity > 100) { + Utils.showToastLong("Player overlay opacity must be between 0-100"); + Settings.PLAYER_OVERLAY_OPACITY.resetToDefault(); + opacity = Settings.PLAYER_OVERLAY_OPACITY.defaultValue; + } + + imageView.setImageAlpha((opacity * 255) / 100); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/DisableAutoCaptionsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableAutoCaptionsPatch.java similarity index 53% rename from app/src/main/java/app/revanced/integrations/patches/DisableAutoCaptionsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/DisableAutoCaptionsPatch.java index 0e61b26121..e35ac70b06 100644 --- a/app/src/main/java/app/revanced/integrations/patches/DisableAutoCaptionsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableAutoCaptionsPatch.java @@ -1,7 +1,8 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public class DisableAutoCaptionsPatch { /** @@ -10,7 +11,7 @@ public class DisableAutoCaptionsPatch { public static boolean captionsButtonDisabled; public static boolean autoCaptionsEnabled() { - return SettingsEnum.AUTO_CAPTIONS.getBoolean(); + return Settings.AUTO_CAPTIONS.get(); } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/DisableFullscreenAmbientModePatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableFullscreenAmbientModePatch.java new file mode 100644 index 0000000000..b5a88cc802 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableFullscreenAmbientModePatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +/** @noinspection unused*/ +public final class DisableFullscreenAmbientModePatch { + public static boolean enableFullScreenAmbientMode() { + return !Settings.DISABLE_FULLSCREEN_AMBIENT_MODE.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/DisablePlayerPopupPanelsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/DisablePlayerPopupPanelsPatch.java similarity index 52% rename from app/src/main/java/app/revanced/integrations/patches/DisablePlayerPopupPanelsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/DisablePlayerPopupPanelsPatch.java index e2e8be134b..2b1c68b7a5 100644 --- a/app/src/main/java/app/revanced/integrations/patches/DisablePlayerPopupPanelsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/DisablePlayerPopupPanelsPatch.java @@ -1,10 +1,11 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public class DisablePlayerPopupPanelsPatch { //Used by app.revanced.patches.youtube.layout.playerpopuppanels.patch.PlayerPopupPanelsPatch public static boolean disablePlayerPopupPanels() { - return SettingsEnum.PLAYER_POPUP_PANELS.getBoolean(); + return Settings.PLAYER_POPUP_PANELS.get(); } } diff --git a/app/src/main/java/app/revanced/integrations/patches/DisablePreciseSeekingGesturePatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/DisablePreciseSeekingGesturePatch.java similarity index 70% rename from app/src/main/java/app/revanced/integrations/patches/DisablePreciseSeekingGesturePatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/DisablePreciseSeekingGesturePatch.java index 8043bd2114..5e3eca57e7 100644 --- a/app/src/main/java/app/revanced/integrations/patches/DisablePreciseSeekingGesturePatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/DisablePreciseSeekingGesturePatch.java @@ -1,9 +1,11 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.view.MotionEvent; import android.view.VelocityTracker; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") public final class DisablePreciseSeekingGesturePatch { /** * Disables the gesture that is used to seek precisely. @@ -11,7 +13,7 @@ public final class DisablePreciseSeekingGesturePatch { * @param event The motion event that is used to determine the gesture. */ public static void disableGesture(VelocityTracker tracker, MotionEvent event) { - if (SettingsEnum.DISABLE_PRECISE_SEEKING_GESTURE.getBoolean()) return; + if (Settings.DISABLE_PRECISE_SEEKING_GESTURE.get()) return; tracker.addMovement(event); } diff --git a/app/src/main/java/app/revanced/integrations/patches/DisableResumingStartupShortsPlayerPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableResumingStartupShortsPlayerPatch.java similarity index 53% rename from app/src/main/java/app/revanced/integrations/patches/DisableResumingStartupShortsPlayerPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/DisableResumingStartupShortsPlayerPatch.java index 0fccefea6f..a8ab498366 100644 --- a/app/src/main/java/app/revanced/integrations/patches/DisableResumingStartupShortsPlayerPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableResumingStartupShortsPlayerPatch.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; /** @noinspection unused*/ public class DisableResumingStartupShortsPlayerPatch { @@ -9,6 +9,6 @@ public class DisableResumingStartupShortsPlayerPatch { * Injection point. */ public static boolean disableResumingStartupShortsPlayer() { - return SettingsEnum.DISABLE_RESUMING_SHORTS_PLAYER.getBoolean(); + return Settings.DISABLE_RESUMING_SHORTS_PLAYER.get(); } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/DisableRollingNumberAnimationsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableRollingNumberAnimationsPatch.java new file mode 100644 index 0000000000..8acca94a17 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableRollingNumberAnimationsPatch.java @@ -0,0 +1,13 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class DisableRollingNumberAnimationsPatch { + /** + * Injection point. + */ + public static boolean disableRollingNumberAnimations() { + return Settings.DISABLE_ROLLING_NUMBER_ANIMATIONS.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/DisableSuggestedVideoEndScreenPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableSuggestedVideoEndScreenPatch.java similarity index 83% rename from app/src/main/java/app/revanced/integrations/patches/DisableSuggestedVideoEndScreenPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/DisableSuggestedVideoEndScreenPatch.java index 117238cd55..3ceea0cc14 100644 --- a/app/src/main/java/app/revanced/integrations/patches/DisableSuggestedVideoEndScreenPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/DisableSuggestedVideoEndScreenPatch.java @@ -1,10 +1,11 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.annotation.SuppressLint; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; -import app.revanced.integrations.settings.SettingsEnum; + +import app.revanced.integrations.youtube.settings.Settings; /** @noinspection unused*/ public final class DisableSuggestedVideoEndScreenPatch { @@ -12,7 +13,7 @@ public final class DisableSuggestedVideoEndScreenPatch { private static View lastView; public static void closeEndScreen(final ImageView imageView) { - if (!SettingsEnum.DISABLE_SUGGESTED_VIDEO_END_SCREEN.getBoolean()) return; + if (!Settings.DISABLE_SUGGESTED_VIDEO_END_SCREEN.get()) return; // Get a parent view which can be listened to for layout changes. final var parent = imageView.getParent().getParent(); diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/EnableTabletLayoutPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/EnableTabletLayoutPatch.java new file mode 100644 index 0000000000..c7b5364bc5 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/EnableTabletLayoutPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public final class EnableTabletLayoutPatch { + public static boolean enableTabletLayout() { + return Settings.TABLET_LAYOUT.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/FixBackToExitGesturePatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/FixBackToExitGesturePatch.java similarity index 63% rename from app/src/main/java/app/revanced/integrations/patches/FixBackToExitGesturePatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/FixBackToExitGesturePatch.java index ab210d2768..d3408a62b0 100644 --- a/app/src/main/java/app/revanced/integrations/patches/FixBackToExitGesturePatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/FixBackToExitGesturePatch.java @@ -1,8 +1,10 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import com.google.android.apps.youtube.app.watchwhile.WatchWhileActivity; -import app.revanced.integrations.utils.LogHelper; +import android.app.Activity; +import app.revanced.integrations.shared.Logger; + +@SuppressWarnings("unused") public class FixBackToExitGesturePatch { /** * State whether the scroll position reaches the top. @@ -14,10 +16,10 @@ public class FixBackToExitGesturePatch { * * @param activity The activity, the app is launched with to finish. */ - public static void onBackPressed(WatchWhileActivity activity) { + public static void onBackPressed(Activity activity) { if (!isTopView) return; - LogHelper.printDebug(() -> "Activity is closed"); + Logger.printDebug(() -> "Activity is closed"); activity.finish(); } @@ -26,7 +28,7 @@ public static void onBackPressed(WatchWhileActivity activity) { * Handle the event when the homepage list of views is being scrolled. */ public static void onScrollingViews() { - LogHelper.printDebug(() -> "Views are scrolling"); + Logger.printDebug(() -> "Views are scrolling"); isTopView = false; } @@ -35,7 +37,7 @@ public static void onScrollingViews() { * Handle the event when the homepage list of views reached the top. */ public static void onTopView() { - LogHelper.printDebug(() -> "Scrolling reached the top"); + Logger.printDebug(() -> "Scrolling reached the top"); isTopView = true; } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/FullscreenPanelsRemoverPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/FullscreenPanelsRemoverPatch.java new file mode 100644 index 0000000000..6dd8e66705 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/FullscreenPanelsRemoverPatch.java @@ -0,0 +1,12 @@ +package app.revanced.integrations.youtube.patches; + +import android.view.View; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class FullscreenPanelsRemoverPatch { + public static int getFullscreenPanelsVisibility() { + return Settings.HIDE_FULLSCREEN_PANELS.get() ? View.GONE : View.VISIBLE; + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/GmsCoreSupport.java b/app/src/main/java/app/revanced/integrations/youtube/patches/GmsCoreSupport.java similarity index 80% rename from app/src/main/java/app/revanced/integrations/patches/GmsCoreSupport.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/GmsCoreSupport.java index 633b01c202..ea1273fee2 100644 --- a/app/src/main/java/app/revanced/integrations/patches/GmsCoreSupport.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/GmsCoreSupport.java @@ -1,4 +1,6 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; + +import static app.revanced.integrations.shared.StringRef.str; import android.app.SearchManager; import android.content.Context; @@ -6,13 +8,13 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; + import androidx.annotation.RequiresApi; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; import java.util.Objects; -import static app.revanced.integrations.utils.StringRef.str; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; /** * @noinspection unused @@ -26,7 +28,7 @@ public class GmsCoreSupport { = Uri.parse("content://" + getGmsCoreVendor() + ".android.gsf.gservices/prefix"); private static void search(Context context, String uriString, String message) { - ReVancedUtils.showToastLong(message); + Utils.showToastLong(message); var intent = new Intent(Intent.ACTION_WEB_SEARCH); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -36,22 +38,24 @@ private static void search(Context context, String uriString, String message) { @RequiresApi(api = Build.VERSION_CODES.N) public static void checkAvailability() { - var context = Objects.requireNonNull(ReVancedUtils.getContext()); + var context = Objects.requireNonNull(Utils.getContext()); try { context.getPackageManager().getPackageInfo(GMS_CORE_PACKAGE_NAME, PackageManager.GET_ACTIVITIES); } catch (PackageManager.NameNotFoundException exception) { - LogHelper.printInfo(() -> "GmsCore was not found", exception); + Logger.printInfo(() -> "GmsCore was not found", exception); search(context, getGmsCoreDownloadLink(), str("gms_core_not_installed_warning")); - // Gracefully exit the app, so it does not crash. System.exit(0); } try (var client = context.getContentResolver().acquireContentProviderClient(GMS_CORE_PROVIDER)) { if (client != null) return; - LogHelper.printInfo(() -> "GmsCore is not running in the background"); + + Logger.printInfo(() -> "GmsCore is not running in the background"); search(context, DONT_KILL_MY_APP_LINK, str("gms_core_not_running_warning")); + + System.exit(0); } } diff --git a/app/src/main/java/app/revanced/integrations/patches/HDRAutoBrightnessPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HDRAutoBrightnessPatch.java similarity index 73% rename from app/src/main/java/app/revanced/integrations/patches/HDRAutoBrightnessPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/HDRAutoBrightnessPatch.java index 86271d5d01..9ed0591cb2 100644 --- a/app/src/main/java/app/revanced/integrations/patches/HDRAutoBrightnessPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HDRAutoBrightnessPatch.java @@ -1,27 +1,24 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.view.WindowManager; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.swipecontrols.SwipeControlsHostActivity; /** * Patch class for 'hdr-auto-brightness' patch - * - * @usedBy app/revanced/patches/youtube/misc/hdrbrightness/patch/HDRBrightnessPatch - * @smali app/revanced/integrations/patches/HDRAutoBrightnessPatch */ +@SuppressWarnings("unused") public class HDRAutoBrightnessPatch { /** * get brightness override for HDR brightness * * @param original brightness youtube would normally set * @return brightness to set on HRD video - * @smali getHDRBrightness(F)F */ public static float getHDRBrightness(float original) { // do nothing if disabled - if (!SettingsEnum.HDR_AUTO_BRIGHTNESS.getBoolean()) { + if (!Settings.HDR_AUTO_BRIGHTNESS.get()) { return original; } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideAlbumCardsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideAlbumCardsPatch.java new file mode 100644 index 0000000000..e0d8519446 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideAlbumCardsPatch.java @@ -0,0 +1,14 @@ +package app.revanced.integrations.youtube.patches; + +import android.view.View; + +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Utils; + +@SuppressWarnings("unused") +public class HideAlbumCardsPatch { + public static void hideAlbumCard(View view) { + if (!Settings.HIDE_ALBUM_CARDS.get()) return; + Utils.hideViewByLayoutParams(view); + } +} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideAutoplayButtonPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideAutoplayButtonPatch.java new file mode 100644 index 0000000000..79a40d64e4 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideAutoplayButtonPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class HideAutoplayButtonPatch { + public static boolean isButtonShown() { + return !Settings.HIDE_AUTOPLAY_BUTTON.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideBreakingNewsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideBreakingNewsPatch.java similarity index 65% rename from app/src/main/java/app/revanced/integrations/patches/HideBreakingNewsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/HideBreakingNewsPatch.java index bb2d76b2f9..fe9e57c0b0 100644 --- a/app/src/main/java/app/revanced/integrations/patches/HideBreakingNewsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideBreakingNewsPatch.java @@ -1,11 +1,12 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.view.View; -import app.revanced.integrations.patches.spoof.SpoofAppVersionPatch; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.youtube.patches.spoof.SpoofAppVersionPatch; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Utils; +@SuppressWarnings("unused") public class HideBreakingNewsPatch { /** @@ -21,8 +22,8 @@ public class HideBreakingNewsPatch { * Injection point. */ public static void hideBreakingNews(View view) { - if (!SettingsEnum.HIDE_BREAKING_NEWS.getBoolean() + if (!Settings.HIDE_BREAKING_NEWS.get() || isSpoofingOldVersionWithHorizontalCardListWatchHistory) return; - ReVancedUtils.hideViewByLayoutParams(view); + Utils.hideViewByLayoutParams(view); } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideCaptionsButtonPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideCaptionsButtonPatch.java new file mode 100644 index 0000000000..d6487b4458 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideCaptionsButtonPatch.java @@ -0,0 +1,13 @@ +package app.revanced.integrations.youtube.patches; + +import android.widget.ImageView; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class HideCaptionsButtonPatch { + //Used by app.revanced.patches.youtube.layout.hidecaptionsbutton.patch.HideCaptionsButtonPatch + public static void hideCaptionsButton(ImageView imageView) { + imageView.setVisibility(Settings.HIDE_CAPTIONS_BUTTON.get() ? ImageView.GONE : ImageView.VISIBLE); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideCastButtonPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideCastButtonPatch.java similarity index 51% rename from app/src/main/java/app/revanced/integrations/patches/HideCastButtonPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/HideCastButtonPatch.java index b30bde63af..aec2fbfc08 100644 --- a/app/src/main/java/app/revanced/integrations/patches/HideCastButtonPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideCastButtonPatch.java @@ -1,13 +1,14 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.view.View; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public class HideCastButtonPatch { // Used by app.revanced.patches.youtube.layout.castbutton.patch.HideCastButonPatch public static int getCastButtonOverrideV2(int original) { - return SettingsEnum.HIDE_CAST_BUTTON.getBoolean() ? View.GONE : original; + return Settings.HIDE_CAST_BUTTON.get() ? View.GONE : original; } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideCrowdfundingBoxPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideCrowdfundingBoxPatch.java new file mode 100644 index 0000000000..6546da78de --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideCrowdfundingBoxPatch.java @@ -0,0 +1,15 @@ +package app.revanced.integrations.youtube.patches; + +import android.view.View; + +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Utils; + +@SuppressWarnings("unused") +public class HideCrowdfundingBoxPatch { + //Used by app.revanced.patches.youtube.layout.hidecrowdfundingbox.patch.HideCrowdfundingBoxPatch + public static void hideCrowdfundingBox(View view) { + if (!Settings.HIDE_CROWDFUNDING_BOX.get()) return; + Utils.hideViewByLayoutParams(view); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/HideEmailAddressPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideEmailAddressPatch.java similarity index 58% rename from app/src/main/java/app/revanced/integrations/patches/HideEmailAddressPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/HideEmailAddressPatch.java index 04406e5ead..74b9f5ff8c 100644 --- a/app/src/main/java/app/revanced/integrations/patches/HideEmailAddressPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideEmailAddressPatch.java @@ -1,11 +1,12 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public class HideEmailAddressPatch { //Used by app.revanced.patches.youtube.layout.personalinformation.patch.HideEmailAddressPatch public static int hideEmailAddress(int originalValue) { - if (SettingsEnum.HIDE_EMAIL_ADDRESS.getBoolean()) + if (Settings.HIDE_EMAIL_ADDRESS.get()) return 8; return originalValue; } diff --git a/app/src/main/java/app/revanced/integrations/patches/HideEndscreenCardsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideEndscreenCardsPatch.java similarity index 57% rename from app/src/main/java/app/revanced/integrations/patches/HideEndscreenCardsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/HideEndscreenCardsPatch.java index 026dbeab05..36e4727cee 100644 --- a/app/src/main/java/app/revanced/integrations/patches/HideEndscreenCardsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideEndscreenCardsPatch.java @@ -1,13 +1,14 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.view.View; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public class HideEndscreenCardsPatch { //Used by app.revanced.patches.youtube.layout.hideendscreencards.bytecode.patch.HideEndscreenCardsPatch public static void hideEndscreen(View view) { - if (!SettingsEnum.HIDE_ENDSCREEN_CARDS.getBoolean()) return; + if (!Settings.HIDE_ENDSCREEN_CARDS.get()) return; view.setVisibility(View.GONE); } } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideFilterBarPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideFilterBarPatch.java new file mode 100644 index 0000000000..dd15c9528c --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideFilterBarPatch.java @@ -0,0 +1,27 @@ +package app.revanced.integrations.youtube.patches; + +import android.view.View; + +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Utils; + +@SuppressWarnings("unused") +public final class HideFilterBarPatch { + public static int hideInFeed(final int height) { + if (Settings.HIDE_FILTER_BAR_FEED_IN_FEED.get()) return 0; + + return height; + } + + public static void hideInRelatedVideos(final View chipView) { + if (!Settings.HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS.get()) return; + + Utils.hideViewByLayoutParams(chipView); + } + + public static int hideInSearch(final int height) { + if (Settings.HIDE_FILTER_BAR_FEED_IN_SEARCH.get()) return 0; + + return height; + } +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideFloatingMicrophoneButtonPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideFloatingMicrophoneButtonPatch.java new file mode 100644 index 0000000000..c2074ba6a1 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideFloatingMicrophoneButtonPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public final class HideFloatingMicrophoneButtonPatch { + public static boolean hideFloatingMicrophoneButton(final boolean original) { + return Settings.HIDE_FLOATING_MICROPHONE_BUTTON.get() || original; + } +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideGetPremiumPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideGetPremiumPatch.java new file mode 100644 index 0000000000..96e96a722e --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideGetPremiumPatch.java @@ -0,0 +1,13 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class HideGetPremiumPatch { + /** + * Injection point. + */ + public static boolean hideGetPremiumView() { + return Settings.HIDE_GET_PREMIUM.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideInfoCardsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideInfoCardsPatch.java new file mode 100644 index 0000000000..764326dc18 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideInfoCardsPatch.java @@ -0,0 +1,17 @@ +package app.revanced.integrations.youtube.patches; + +import android.view.View; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class HideInfoCardsPatch { + public static void hideInfoCardsIncognito(View view) { + if (!Settings.HIDE_INFO_CARDS.get()) return; + view.setVisibility(View.GONE); + } + + public static boolean hideInfoCardsMethodCall() { + return Settings.HIDE_INFO_CARDS.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideLoadMoreButtonPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideLoadMoreButtonPatch.java new file mode 100644 index 0000000000..fa3a0e70ef --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideLoadMoreButtonPatch.java @@ -0,0 +1,14 @@ +package app.revanced.integrations.youtube.patches; + +import android.view.View; + +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Utils; + +@SuppressWarnings("unused") +public class HideLoadMoreButtonPatch { + public static void hideLoadMoreButton(View view){ + if(!Settings.HIDE_LOAD_MORE_BUTTON.get()) return; + Utils.hideViewByLayoutParams(view); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/HidePlayerButtonsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HidePlayerButtonsPatch.java similarity index 58% rename from app/src/main/java/app/revanced/integrations/patches/HidePlayerButtonsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/HidePlayerButtonsPatch.java index 466f0a7153..aa501280b3 100644 --- a/app/src/main/java/app/revanced/integrations/patches/HidePlayerButtonsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HidePlayerButtonsPatch.java @@ -1,14 +1,15 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public final class HidePlayerButtonsPatch { /** * Injection point. */ public static boolean previousOrNextButtonIsVisible(boolean previousOrNextButtonVisible) { - if (SettingsEnum.HIDE_PLAYER_BUTTONS.getBoolean()) { + if (Settings.HIDE_PLAYER_BUTTONS.get()) { return false; } return previousOrNextButtonVisible; diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideSeekbarPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideSeekbarPatch.java new file mode 100644 index 0000000000..6e5da083d3 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideSeekbarPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class HideSeekbarPatch { + public static boolean hideSeekbar() { + return Settings.HIDE_SEEKBAR.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/HideTimestampPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/HideTimestampPatch.java new file mode 100644 index 0000000000..0c8128b5f9 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/HideTimestampPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class HideTimestampPatch { + public static boolean hideTimestamp() { + return Settings.HIDE_TIMESTAMP.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/MinimizedPlaybackPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/MinimizedPlaybackPatch.java similarity index 93% rename from app/src/main/java/app/revanced/integrations/patches/MinimizedPlaybackPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/MinimizedPlaybackPatch.java index 43bf49fa09..6dc3cc7a51 100644 --- a/app/src/main/java/app/revanced/integrations/patches/MinimizedPlaybackPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/MinimizedPlaybackPatch.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import app.revanced.integrations.shared.PlayerType; +import app.revanced.integrations.youtube.shared.PlayerType; @SuppressWarnings("unused") public class MinimizedPlaybackPatch { diff --git a/app/src/main/java/app/revanced/integrations/patches/NavigationButtonsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/NavigationButtonsPatch.java similarity index 61% rename from app/src/main/java/app/revanced/integrations/patches/NavigationButtonsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/NavigationButtonsPatch.java index d47f7aa003..c063d418a2 100644 --- a/app/src/main/java/app/revanced/integrations/patches/NavigationButtonsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/NavigationButtonsPatch.java @@ -1,18 +1,20 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.view.View; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") public final class NavigationButtonsPatch { public static Enum lastNavigationButton; public static void hideCreateButton(final View view) { - view.setVisibility(SettingsEnum.HIDE_CREATE_BUTTON.getBoolean() ? View.GONE : View.VISIBLE); + view.setVisibility(Settings.HIDE_CREATE_BUTTON.get() ? View.GONE : View.VISIBLE); } public static boolean switchCreateWithNotificationButton() { - return SettingsEnum.SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON.getBoolean(); + return Settings.SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON.get(); } public static void hideButton(final View buttonView) { @@ -24,9 +26,9 @@ public static void hideButton(final View buttonView) { } private enum NavigationButton { - HOME("PIVOT_HOME", SettingsEnum.HIDE_HOME_BUTTON.getBoolean()), - SHORTS("TAB_SHORTS", SettingsEnum.HIDE_SHORTS_BUTTON.getBoolean()), - SUBSCRIPTIONS("PIVOT_SUBSCRIPTIONS", SettingsEnum.HIDE_SUBSCRIPTIONS_BUTTON.getBoolean()); + HOME("PIVOT_HOME", Settings.HIDE_HOME_BUTTON.get()), + SHORTS("TAB_SHORTS", Settings.HIDE_SHORTS_BUTTON.get()), + SUBSCRIPTIONS("PIVOT_SUBSCRIPTIONS", Settings.HIDE_SUBSCRIPTIONS_BUTTON.get()); private final boolean enabled; private final String name; diff --git a/app/src/main/java/app/revanced/integrations/patches/OpenLinksExternallyPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/OpenLinksExternallyPatch.java similarity index 69% rename from app/src/main/java/app/revanced/integrations/patches/OpenLinksExternallyPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/OpenLinksExternallyPatch.java index bc23e1bd32..043d1caee9 100644 --- a/app/src/main/java/app/revanced/integrations/patches/OpenLinksExternallyPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/OpenLinksExternallyPatch.java @@ -1,7 +1,8 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public class OpenLinksExternallyPatch { /** * Return the intent to open links with. If empty, the link will be opened with the default browser. @@ -10,7 +11,7 @@ public class OpenLinksExternallyPatch { * @return The intent to open links with. Empty means the link will be opened with the default browser. */ public static String getIntent(String originalIntent) { - if (SettingsEnum.EXTERNAL_BROWSER.getBoolean()) return ""; + if (Settings.EXTERNAL_BROWSER.get()) return ""; return originalIntent; } diff --git a/app/src/main/java/app/revanced/integrations/patches/PlayerOverlaysHookPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/PlayerOverlaysHookPatch.java similarity index 87% rename from app/src/main/java/app/revanced/integrations/patches/PlayerOverlaysHookPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/PlayerOverlaysHookPatch.java index 4f1969dfe0..7070d8a564 100644 --- a/app/src/main/java/app/revanced/integrations/patches/PlayerOverlaysHookPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/PlayerOverlaysHookPatch.java @@ -1,10 +1,10 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.view.ViewGroup; import androidx.annotation.Nullable; -import app.revanced.integrations.shared.PlayerOverlays; +import app.revanced.integrations.youtube.shared.PlayerOverlays; /** * Hook receiver class for 'player-overlays-hook' patch diff --git a/app/src/main/java/app/revanced/integrations/patches/PlayerTypeHookPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/PlayerTypeHookPatch.java similarity index 76% rename from app/src/main/java/app/revanced/integrations/patches/PlayerTypeHookPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/PlayerTypeHookPatch.java index 49296e5cac..a669ca9486 100644 --- a/app/src/main/java/app/revanced/integrations/patches/PlayerTypeHookPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/PlayerTypeHookPatch.java @@ -1,9 +1,9 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import androidx.annotation.Nullable; -import app.revanced.integrations.shared.PlayerType; -import app.revanced.integrations.shared.VideoState; +import app.revanced.integrations.youtube.shared.PlayerType; +import app.revanced.integrations.youtube.shared.VideoState; @SuppressWarnings("unused") public class PlayerTypeHookPatch { diff --git a/app/src/main/java/app/revanced/integrations/patches/RemoveTrackingQueryParameterPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/RemoveTrackingQueryParameterPatch.java similarity index 65% rename from app/src/main/java/app/revanced/integrations/patches/RemoveTrackingQueryParameterPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/RemoveTrackingQueryParameterPatch.java index 4910f5865c..25c70810e4 100644 --- a/app/src/main/java/app/revanced/integrations/patches/RemoveTrackingQueryParameterPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/RemoveTrackingQueryParameterPatch.java @@ -1,13 +1,14 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public final class RemoveTrackingQueryParameterPatch { private static final String NEW_TRACKING_PARAMETER_REGEX = ".si=.+"; private static final String OLD_TRACKING_PARAMETER_REGEX = ".feature=.+"; public static String sanitize(String url) { - if (!SettingsEnum.REMOVE_TRACKING_QUERY_PARAMETER.getBoolean()) return url; + if (!Settings.REMOVE_TRACKING_QUERY_PARAMETER.get()) return url; return url .replaceAll(NEW_TRACKING_PARAMETER_REGEX, "") diff --git a/app/src/main/java/app/revanced/integrations/patches/RemoveViewerDiscretionDialogPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/RemoveViewerDiscretionDialogPatch.java similarity index 70% rename from app/src/main/java/app/revanced/integrations/patches/RemoveViewerDiscretionDialogPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/RemoveViewerDiscretionDialogPatch.java index c0d013e546..020552ed2f 100644 --- a/app/src/main/java/app/revanced/integrations/patches/RemoveViewerDiscretionDialogPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/RemoveViewerDiscretionDialogPatch.java @@ -1,11 +1,12 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.app.AlertDialog; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +/** @noinspection unused*/ public class RemoveViewerDiscretionDialogPatch { public static void confirmDialog(AlertDialog dialog) { - if (!SettingsEnum.REMOVE_VIEWER_DISCRETION_DIALOG.getBoolean()) { + if (!Settings.REMOVE_VIEWER_DISCRETION_DIALOG.get()) { // Since the patch replaces the AlertDialog#show() method, we need to call the original method here. dialog.show(); return; diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/RestoreOldSeekbarThumbnailsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/RestoreOldSeekbarThumbnailsPatch.java new file mode 100644 index 0000000000..d9f8c4dff7 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/RestoreOldSeekbarThumbnailsPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public final class RestoreOldSeekbarThumbnailsPatch { + public static boolean useFullscreenSeekbarThumbnails() { + return !Settings.RESTORE_OLD_SEEKBAR_THUMBNAILS.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/ReturnYouTubeDislikePatch.java similarity index 84% rename from app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/ReturnYouTubeDislikePatch.java index 9c8caa455b..5133283ffc 100644 --- a/app/src/main/java/app/revanced/integrations/patches/ReturnYouTubeDislikePatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/ReturnYouTubeDislikePatch.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import android.graphics.Rect; import android.graphics.drawable.ShapeDrawable; @@ -8,13 +8,14 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.revanced.integrations.patches.components.ReturnYouTubeDislikeFilterPatch; -import app.revanced.integrations.patches.spoof.SpoofAppVersionPatch; -import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.shared.PlayerType; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; + +import app.revanced.integrations.youtube.patches.components.ReturnYouTubeDislikeFilterPatch; +import app.revanced.integrations.youtube.patches.spoof.SpoofAppVersionPatch; +import app.revanced.integrations.youtube.returnyoutubedislike.ReturnYouTubeDislike; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.shared.PlayerType; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -22,7 +23,7 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; -import static app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike.Vote; +import static app.revanced.integrations.youtube.returnyoutubedislike.ReturnYouTubeDislike.Vote; /** * Handles all interaction of UI patch components. @@ -99,7 +100,7 @@ private static void clearData() { * Resource identifier of old UI dislike button. */ private static final int OLD_UI_DISLIKE_BUTTON_RESOURCE_ID - = ReVancedUtils.getResourceIdentifier("dislike_button", "id"); + = Utils.getResourceIdentifier("dislike_button", "id"); /** * Dislikes text label used by old UI. @@ -159,12 +160,12 @@ private static void updateOldUIDislikesTextView() { */ public static void setOldUILayoutDislikes(int buttonViewResourceId, @Nullable TextView textView) { try { - if (!SettingsEnum.RYD_ENABLED.getBoolean() + if (!Settings.RYD_ENABLED.get() || buttonViewResourceId != OLD_UI_DISLIKE_BUTTON_RESOURCE_ID || textView == null) { return; } - LogHelper.printDebug(() -> "setOldUILayoutDislikes"); + Logger.printDebug(() -> "setOldUILayoutDislikes"); if (oldUIOriginalSpan == null) { // Use value of the first instance, as it appears TextViews can be recycled @@ -185,7 +186,7 @@ public static void setOldUILayoutDislikes(int buttonViewResourceId, @Nullable Te updateOldUIDislikesTextView(); } catch (Exception ex) { - LogHelper.printException(() -> "setOldUILayoutDislikes failure", ex); + Logger.printException(() -> "setOldUILayoutDislikes failure", ex); } } @@ -201,9 +202,8 @@ public static void setOldUILayoutDislikes(int buttonViewResourceId, @Nullable Te */ @NonNull public static CharSequence onLithoTextLoaded(@NonNull Object conversionContext, - @Nullable AtomicReference textRef, @NonNull CharSequence original) { - return onLithoTextLoaded(conversionContext, textRef, original, false); + return onLithoTextLoaded(conversionContext, original, false); } /** @@ -213,20 +213,16 @@ public static CharSequence onLithoTextLoaded(@NonNull Object conversionContext, * This method is sometimes called on the main thread, but it usually is called _off_ the main thread. * This method can be called multiple times for the same UI element (including after dislikes was added). * - * @param textRef Optional cache reference to the like/dislike char sequence, - * which may or may not be the same as the original span parameter. - * If dislikes are added, the atomic reference must be set to the replacement span. * @param original Original char sequence was created or reused by Litho. * @param isRollingNumber If the span is for a Rolling Number. * @return The original char sequence (if nothing should change), or a replacement char sequence that contains dislikes. */ @NonNull private static CharSequence onLithoTextLoaded(@NonNull Object conversionContext, - @Nullable AtomicReference textRef, @NonNull CharSequence original, boolean isRollingNumber) { try { - if (!SettingsEnum.RYD_ENABLED.getBoolean()) { + if (!Settings.RYD_ENABLED.get()) { return original; } @@ -250,7 +246,7 @@ private static CharSequence onLithoTextLoaded(@NonNull Object conversionContext, // But spoofing to that range gives a broken UI layout so no point checking for that. } else if (!isRollingNumber && conversionContextString.contains("|shorts_dislike_button.eml|")) { // Litho Shorts player. - if (!SettingsEnum.RYD_SHORTS.getBoolean()) { + if (!Settings.RYD_SHORTS.get()) { // Must clear the current video here, otherwise if the user opens a regular video // then opens a litho short (while keeping the regular video on screen), then closes the short, // the original video may show the incorrect dislike value. @@ -261,7 +257,7 @@ private static CharSequence onLithoTextLoaded(@NonNull Object conversionContext, if (videoData == null) { // The Shorts litho video id filter did not detect the video id. // This is normal in incognito mode, but otherwise is abnormal. - LogHelper.printDebug(() -> "Cannot modify Shorts litho span, data is null"); + Logger.printDebug(() -> "Cannot modify Shorts litho span, data is null"); return original; } // Use the correct dislikes data after voting. @@ -269,20 +265,19 @@ private static CharSequence onLithoTextLoaded(@NonNull Object conversionContext, lithoShortsShouldUseCurrentData = false; videoData = currentVideoData; if (videoData == null) { - LogHelper.printException(() -> "currentVideoData is null"); // Should never happen + Logger.printException(() -> "currentVideoData is null"); // Should never happen return original; } - LogHelper.printDebug(() -> "Using current video data for litho span"); + Logger.printDebug(() -> "Using current video data for litho span"); } replacement = videoData.getDislikeSpanForShort((Spanned) original); } else { return original; } - if (textRef != null) textRef.set(replacement); return replacement; } catch (Exception ex) { - LogHelper.printException(() -> "onLithoTextLoaded failure", ex); + Logger.printException(() -> "onLithoTextLoaded failure", ex); } return original; } @@ -304,13 +299,13 @@ private static CharSequence onLithoTextLoaded(@NonNull Object conversionContext, public static String onRollingNumberLoaded(@NonNull Object conversionContext, @NonNull String original) { try { - CharSequence replacement = onLithoTextLoaded(conversionContext, null, original, true); + CharSequence replacement = onLithoTextLoaded(conversionContext, original, true); if (!replacement.toString().equals(original)) { rollingNumberSpan = replacement; return replacement.toString(); } // Else, the text was not a likes count but instead the view count or something else. } catch (Exception ex) { - LogHelper.printException(() -> "onRollingNumberLoaded failure", ex); + Logger.printException(() -> "onRollingNumberLoaded failure", ex); } return original; } @@ -323,7 +318,7 @@ public static String onRollingNumberLoaded(@NonNull Object conversionContext, */ public static float onRollingNumberMeasured(String text, float measuredTextWidth) { try { - if (SettingsEnum.RYD_ENABLED.getBoolean() && !SettingsEnum.RYD_COMPACT_LAYOUT.getBoolean()) { + if (Settings.RYD_ENABLED.get() && !Settings.RYD_COMPACT_LAYOUT.get()) { if (ReturnYouTubeDislike.isPreviouslyCreatedSegmentedSpan(text)) { // +1 pixel is needed for some foreign languages that measure // the text different from what is used for layout (Greek in particular). @@ -334,7 +329,7 @@ public static float onRollingNumberMeasured(String text, float measuredTextWidth } } } catch (Exception ex) { - LogHelper.printException(() -> "onRollingNumberMeasured failure", ex); + Logger.printException(() -> "onRollingNumberMeasured failure", ex); } return measuredTextWidth; } @@ -345,14 +340,19 @@ public static float onRollingNumberMeasured(String text, float measuredTextWidth private static void addRollingNumberPatchChanges(TextView view) { // YouTube Rolling Numbers do not use compound drawables or drawable padding. if (view.getCompoundDrawablePadding() == 0) { - LogHelper.printDebug(() -> "Adding rolling number TextView changes"); + Logger.printDebug(() -> "Adding rolling number TextView changes"); view.setCompoundDrawablePadding(ReturnYouTubeDislike.leftSeparatorShapePaddingPixels); ShapeDrawable separator = ReturnYouTubeDislike.getLeftSeparatorDrawable(); - if (ReVancedUtils.isRightToLeftTextLayout()) { + if (Utils.isRightToLeftTextLayout()) { view.setCompoundDrawables(null, null, separator, null); } else { view.setCompoundDrawables(separator, null, null, null); } + // Liking/disliking can cause the span to grow in size, + // which is ok and is laid out correctly, + // but if the user then undoes their action the layout will not remove the extra padding. + // Use a center alignment to take up any extra space. + view.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); // Single line mode does not clip words if the span is larger than the view bounds. // The styled span applied to the view should always have the same bounds, // but use this feature just in case the measurements are somehow off by a few pixels. @@ -366,9 +366,10 @@ private static void addRollingNumberPatchChanges(TextView view) { */ private static void removeRollingNumberPatchChanges(TextView view) { if (view.getCompoundDrawablePadding() != 0) { - LogHelper.printDebug(() -> "Removing rolling number TextView changes"); + Logger.printDebug(() -> "Removing rolling number TextView changes"); view.setCompoundDrawablePadding(0); view.setCompoundDrawables(null, null, null, null); + view.setTextAlignment(View.TEXT_ALIGNMENT_GRAVITY); // Default alignment view.setSingleLine(false); } } @@ -378,7 +379,7 @@ private static void removeRollingNumberPatchChanges(TextView view) { */ public static CharSequence updateRollingNumber(TextView view, CharSequence original) { try { - if (!SettingsEnum.RYD_ENABLED.getBoolean()) { + if (!Settings.RYD_ENABLED.get()) { removeRollingNumberPatchChanges(view); return original; } @@ -394,12 +395,12 @@ public static CharSequence updateRollingNumber(TextView view, CharSequence origi if (replacement == null) { // User enabled RYD while a video was open, // or user opened/closed a Short while a regular video was opened. - LogHelper.printDebug(() -> "Cannot update rolling number (field is null"); + Logger.printDebug(() -> "Cannot update rolling number (field is null"); removeRollingNumberPatchChanges(view); return original; } - if (SettingsEnum.RYD_COMPACT_LAYOUT.getBoolean()) { + if (Settings.RYD_COMPACT_LAYOUT.get()) { removeRollingNumberPatchChanges(view); } else { addRollingNumberPatchChanges(view); @@ -414,7 +415,7 @@ public static CharSequence updateRollingNumber(TextView view, CharSequence origi // and using only the modified segmented span prevents the animation from showing. return replacement; } catch (Exception ex) { - LogHelper.printException(() -> "updateRollingNumber failure", ex); + Logger.printException(() -> "updateRollingNumber failure", ex); return original; } } @@ -450,23 +451,23 @@ private static void clearRemovedShortsTextViews() { */ public static boolean setShortsDislikes(@NonNull View likeDislikeView) { try { - if (!SettingsEnum.RYD_ENABLED.getBoolean()) { + if (!Settings.RYD_ENABLED.get()) { return false; } - if (!SettingsEnum.RYD_SHORTS.getBoolean()) { + if (!Settings.RYD_SHORTS.get()) { // Must clear the data here, in case a new video was loaded while PlayerType // suggested the video was not a short (can happen when spoofing to an old app version). clearData(); return false; } - LogHelper.printDebug(() -> "setShortsDislikes"); + Logger.printDebug(() -> "setShortsDislikes"); TextView textView = (TextView) likeDislikeView; textView.setText(SHORTS_LOADING_SPAN); // Change 'Dislike' text to the loading text. shortsTextViewRefs.add(new WeakReference<>(textView)); if (likeDislikeView.isSelected() && isShortTextViewOnScreen(textView)) { - LogHelper.printDebug(() -> "Shorts dislike is already selected"); + Logger.printDebug(() -> "Shorts dislike is already selected"); ReturnYouTubeDislike videoData = currentVideoData; if (videoData != null) videoData.setUserVote(Vote.DISLIKE); } @@ -478,7 +479,7 @@ public static boolean setShortsDislikes(@NonNull View likeDislikeView) { return true; } catch (Exception ex) { - LogHelper.printException(() -> "setShortsDislikes failure", ex); + Logger.printException(() -> "setShortsDislikes failure", ex); return false; } } @@ -498,15 +499,15 @@ private static void updateOnScreenShortsTextViews(boolean forceUpdate) { return; } - LogHelper.printDebug(() -> "updateShortsTextViews"); + Logger.printDebug(() -> "updateShortsTextViews"); Runnable update = () -> { Spanned shortsDislikesSpan = videoData.getDislikeSpanForShort(SHORTS_LOADING_SPAN); - ReVancedUtils.runOnMainThreadNowOrLater(() -> { + Utils.runOnMainThreadNowOrLater(() -> { String videoId = videoData.getVideoId(); if (!videoId.equals(VideoInformation.getVideoId())) { // User swiped to new video before fetch completed - LogHelper.printDebug(() -> "Ignoring stale dislikes data for short: " + videoId); + Logger.printDebug(() -> "Ignoring stale dislikes data for short: " + videoId); return; } @@ -521,7 +522,7 @@ private static void updateOnScreenShortsTextViews(boolean forceUpdate) { } if (isShortTextViewOnScreen(textView) && (forceUpdate || textView.getText().toString().equals(SHORTS_LOADING_SPAN.toString()))) { - LogHelper.printDebug(() -> "Setting Shorts TextView to: " + shortsDislikesSpan); + Logger.printDebug(() -> "Setting Shorts TextView to: " + shortsDislikesSpan); textView.setText(shortsDislikesSpan); } } @@ -530,10 +531,10 @@ private static void updateOnScreenShortsTextViews(boolean forceUpdate) { if (videoData.fetchCompleted()) { update.run(); // Network call is completed, no need to wait on background thread. } else { - ReVancedUtils.runOnBackgroundThread(update); + Utils.runOnBackgroundThread(update); } } catch (Exception ex) { - LogHelper.printException(() -> "updateOnScreenShortsTextViews failure", ex); + Logger.printException(() -> "updateOnScreenShortsTextViews failure", ex); } } @@ -563,7 +564,7 @@ private static boolean isShortTextViewOnScreen(@NonNull View view) { */ public static void preloadVideoId(@NonNull String videoId, boolean isShortAndOpeningOrPlaying) { try { - if (!SettingsEnum.RYD_ENABLED.getBoolean()) { + if (!Settings.RYD_ENABLED.get()) { return; } if (videoId.equals(lastPrefetchedVideoId)) { @@ -574,13 +575,13 @@ public static void preloadVideoId(@NonNull String videoId, boolean isShortAndOpe // Shorts shelf in home and subscription feed causes player response hook to be called, // and the 'is opening/playing' parameter will be false. // This hook will be called again when the Short is actually opened. - if (videoIdIsShort && (!isShortAndOpeningOrPlaying || !SettingsEnum.RYD_SHORTS.getBoolean())) { + if (videoIdIsShort && (!isShortAndOpeningOrPlaying || !Settings.RYD_SHORTS.get())) { return; } final boolean waitForFetchToComplete = !IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER && videoIdIsShort && !lastPlayerResponseWasShort; - LogHelper.printDebug(() -> "Prefetching RYD for video: " + videoId); + Logger.printDebug(() -> "Prefetching RYD for video: " + videoId); ReturnYouTubeDislike fetch = ReturnYouTubeDislike.getFetchForVideoId(videoId); if (waitForFetchToComplete && !fetch.fetchCompleted()) { // This call is off the main thread, so wait until the RYD fetch completely finishes, @@ -591,14 +592,14 @@ public static void preloadVideoId(@NonNull String videoId, boolean isShortAndOpe // are preloaded in the background. // // If an asynchronous litho Shorts solution is found, then this blocking call should be removed. - LogHelper.printDebug(() -> "Waiting for prefetch to complete: " + videoId); + Logger.printDebug(() -> "Waiting for prefetch to complete: " + videoId); fetch.getFetchData(20000); // Any arbitrarily large max wait time. } // Set the fields after the fetch completes, so any concurrent calls will also wait. lastPlayerResponseWasShort = videoIdIsShort; lastPrefetchedVideoId = videoId; } catch (Exception ex) { - LogHelper.printException(() -> "preloadVideoId failure", ex); + Logger.printException(() -> "preloadVideoId failure", ex); } } @@ -607,12 +608,12 @@ public static void preloadVideoId(@NonNull String videoId, boolean isShortAndOpe */ public static void newVideoLoaded(@NonNull String videoId) { try { - if (!SettingsEnum.RYD_ENABLED.getBoolean()) return; + if (!Settings.RYD_ENABLED.get()) return; Objects.requireNonNull(videoId); PlayerType currentPlayerType = PlayerType.getCurrent(); final boolean isNoneHiddenOrSlidingMinimized = currentPlayerType.isNoneHiddenOrSlidingMinimized(); - if (isNoneHiddenOrSlidingMinimized && !SettingsEnum.RYD_SHORTS.getBoolean()) { + if (isNoneHiddenOrSlidingMinimized && !Settings.RYD_SHORTS.get()) { // Must clear here, otherwise the wrong data can be used for a minimized regular video. clearData(); return; @@ -621,7 +622,7 @@ public static void newVideoLoaded(@NonNull String videoId) { if (videoIdIsSame(currentVideoData, videoId)) { return; } - LogHelper.printDebug(() -> "New video id: " + videoId + " playerType: " + currentPlayerType); + Logger.printDebug(() -> "New video id: " + videoId + " playerType: " + currentPlayerType); ReturnYouTubeDislike data = ReturnYouTubeDislike.getFetchForVideoId(videoId); // Pre-emptively set the data to short status. @@ -637,7 +638,7 @@ public static void newVideoLoaded(@NonNull String videoId) { updateOnScreenShortsTextViews(true); } } catch (Exception ex) { - LogHelper.printException(() -> "newVideoLoaded failure", ex); + Logger.printException(() -> "newVideoLoaded failure", ex); } } @@ -650,11 +651,11 @@ public static void setLastLithoShortsVideoId(@Nullable String videoId) { // or the proto buffer structure was changed and the video id is no longer present. // Must clear both currently playing and last litho data otherwise the // next regular video may use the wrong data. - LogHelper.printDebug(() -> "Litho filter did not find any video ids"); + Logger.printDebug(() -> "Litho filter did not find any video ids"); clearData(); return; } - LogHelper.printDebug(() -> "New litho Shorts video id: " + videoId); + Logger.printDebug(() -> "New litho Shorts video id: " + videoId); ReturnYouTubeDislike videoData = ReturnYouTubeDislike.getFetchForVideoId(videoId); videoData.setVideoIdIsShort(true); lastLithoShortsVideoData = videoData; @@ -675,16 +676,16 @@ private static boolean videoIdIsSame(@Nullable ReturnYouTubeDislike fetch, @Null */ public static void sendVote(int vote) { try { - if (!SettingsEnum.RYD_ENABLED.getBoolean()) { + if (!Settings.RYD_ENABLED.get()) { return; } final boolean isNoneHiddenOrMinimized = PlayerType.getCurrent().isNoneHiddenOrMinimized(); - if (isNoneHiddenOrMinimized && !SettingsEnum.RYD_SHORTS.getBoolean()) { + if (isNoneHiddenOrMinimized && !Settings.RYD_SHORTS.get()) { return; } ReturnYouTubeDislike videoData = currentVideoData; if (videoData == null) { - LogHelper.printDebug(() -> "Cannot send vote, as current video data is null"); + Logger.printDebug(() -> "Cannot send vote, as current video data is null"); return; // User enabled RYD while a regular video was minimized. } @@ -702,9 +703,9 @@ public static void sendVote(int vote) { return; } } - LogHelper.printException(() -> "Unknown vote type: " + vote); + Logger.printException(() -> "Unknown vote type: " + vote); } catch (Exception ex) { - LogHelper.printException(() -> "sendVote failure", ex); + Logger.printException(() -> "sendVote failure", ex); } } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/SeekbarTappingPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/SeekbarTappingPatch.java new file mode 100644 index 0000000000..6f2d42dd06 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/SeekbarTappingPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public final class SeekbarTappingPatch { + public static boolean seekbarTappingEnabled() { + return Settings.SEEKBAR_TAPPING.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/SlideToSeekPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/SlideToSeekPatch.java new file mode 100644 index 0000000000..5a6f56290c --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/SlideToSeekPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public final class SlideToSeekPatch { + public static boolean isSlideToSeekDisabled() { + return !Settings.SLIDE_TO_SEEK.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/TabletMiniPlayerOverridePatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/TabletMiniPlayerOverridePatch.java new file mode 100644 index 0000000000..1a0515ae97 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/TabletMiniPlayerOverridePatch.java @@ -0,0 +1,13 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class TabletMiniPlayerOverridePatch { + + public static boolean getTabletMiniPlayerOverride(boolean original) { + if (Settings.USE_TABLET_MINIPLAYER.get()) + return true; + return original; + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/VideoAdsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoAdsPatch.java similarity index 50% rename from app/src/main/java/app/revanced/integrations/patches/VideoAdsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/VideoAdsPatch.java index 487817fdf2..1d1047a199 100644 --- a/app/src/main/java/app/revanced/integrations/patches/VideoAdsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoAdsPatch.java @@ -1,13 +1,14 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public class VideoAdsPatch { // Used by app.revanced.patches.youtube.ad.general.video.patch.VideoAdsPatch // depends on Whitelist patch (still needs to be written) public static boolean shouldShowAds() { - return !SettingsEnum.HIDE_VIDEO_ADS.getBoolean(); // TODO && Whitelist.shouldShowAds(); + return !Settings.HIDE_VIDEO_ADS.get(); // TODO && Whitelist.shouldShowAds(); } } diff --git a/app/src/main/java/app/revanced/integrations/patches/VideoInformation.java b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java similarity index 88% rename from app/src/main/java/app/revanced/integrations/patches/VideoInformation.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java index 15c97fb5ed..57751ff02a 100644 --- a/app/src/main/java/app/revanced/integrations/patches/VideoInformation.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/VideoInformation.java @@ -1,10 +1,10 @@ -package app.revanced.integrations.patches; +package app.revanced.integrations.youtube.patches; import androidx.annotation.NonNull; -import app.revanced.integrations.patches.playback.speed.RememberPlaybackSpeedPatch; -import app.revanced.integrations.shared.VideoState; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.youtube.patches.playback.speed.RememberPlaybackSpeedPatch; +import app.revanced.integrations.youtube.shared.VideoState; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; import java.lang.ref.WeakReference; import java.lang.reflect.Method; @@ -55,7 +55,7 @@ public static void initialize(@NonNull Object playerController) { seekMethod = playerController.getClass().getMethod(SEEK_METHOD_NAME, Long.TYPE); seekMethod.setAccessible(true); } catch (Exception ex) { - LogHelper.printException(() -> "Failed to initialize", ex); + Logger.printException(() -> "Failed to initialize", ex); } } @@ -66,7 +66,7 @@ public static void initialize(@NonNull Object playerController) { */ public static void setVideoId(@NonNull String newlyLoadedVideoId) { if (!videoId.equals(newlyLoadedVideoId)) { - LogHelper.printDebug(() -> "New video id: " + newlyLoadedVideoId); + Logger.printDebug(() -> "New video id: " + newlyLoadedVideoId); videoId = newlyLoadedVideoId; } } @@ -87,7 +87,7 @@ public static String newPlayerResponseSignature(@NonNull String signature, boole if (!isShort || isShortAndOpeningOrPlaying) { if (videoIdIsShort != isShort) { videoIdIsShort = isShort; - LogHelper.printDebug(() -> "videoIdIsShort: " + isShort); + Logger.printDebug(() -> "videoIdIsShort: " + isShort); } } return signature; // Return the original value since we are observing and not modifying. @@ -100,7 +100,7 @@ public static String newPlayerResponseSignature(@NonNull String signature, boole */ public static void setPlayerResponseVideoId(@NonNull String videoId, boolean isShortAndOpeningOrPlaying) { if (!playerResponseVideoId.equals(videoId)) { - LogHelper.printDebug(() -> "New player response video id: " + videoId); + Logger.printDebug(() -> "New player response video id: " + videoId); playerResponseVideoId = videoId; } } @@ -112,7 +112,7 @@ public static void setPlayerResponseVideoId(@NonNull String videoId, boolean isS * @param userSelectedPlaybackSpeed The playback speed the user selected */ public static void userSelectedPlaybackSpeed(float userSelectedPlaybackSpeed) { - LogHelper.printDebug(() -> "User selected playback speed: " + userSelectedPlaybackSpeed); + Logger.printDebug(() -> "User selected playback speed: " + userSelectedPlaybackSpeed); playbackSpeed = userSelectedPlaybackSpeed; } @@ -123,7 +123,7 @@ public static void userSelectedPlaybackSpeed(float userSelectedPlaybackSpeed) { */ public static void overridePlaybackSpeed(float speedOverride) { if (playbackSpeed != speedOverride) { - LogHelper.printDebug(() -> "Overriding playback speed to: " + speedOverride); + Logger.printDebug(() -> "Overriding playback speed to: " + speedOverride); playbackSpeed = speedOverride; } } @@ -135,7 +135,7 @@ public static void overridePlaybackSpeed(float speedOverride) { */ public static void setVideoLength(final long length) { if (videoLength != length) { - LogHelper.printDebug(() -> "Current video length: " + length); + Logger.printDebug(() -> "Current video length: " + length); videoLength = length; } } @@ -161,7 +161,7 @@ public static void setVideoTime(final long currentPlaybackTime) { * @return true if the seek was successful. */ public static boolean seekTo(final long seekTime) { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); try { final long videoTime = getVideoTime(); final long videoLength = getVideoLength(); @@ -172,16 +172,16 @@ public static boolean seekTo(final long seekTime) { // Both the current video time and the seekTo are in the last 250ms of the video. // Ignore this seek call, otherwise if a video ends with multiple closely timed segments // then seeking here can create an infinite loop of skip attempts. - LogHelper.printDebug(() -> "Ignoring seekTo call as video playback is almost finished. " + Logger.printDebug(() -> "Ignoring seekTo call as video playback is almost finished. " + " videoTime: " + videoTime + " videoLength: " + videoLength + " seekTo: " + seekTime); return false; } - LogHelper.printDebug(() -> "Seeking to " + adjustedSeekTime); + Logger.printDebug(() -> "Seeking to " + adjustedSeekTime); //noinspection DataFlowIssue return (Boolean) seekMethod.invoke(playerControllerRef.get(), adjustedSeekTime); } catch (Exception ex) { - LogHelper.printException(() -> "Failed to seek", ex); + Logger.printException(() -> "Failed to seek", ex); return false; } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/WideSearchbarPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/WideSearchbarPatch.java new file mode 100644 index 0000000000..4d63a25254 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/WideSearchbarPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public final class WideSearchbarPatch { + public static boolean enableWideSearchbar() { + return Settings.WIDE_SEARCHBAR.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/ZoomHapticsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/ZoomHapticsPatch.java new file mode 100644 index 0000000000..535e5af01e --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/ZoomHapticsPatch.java @@ -0,0 +1,10 @@ +package app.revanced.integrations.youtube.patches; + +import app.revanced.integrations.youtube.settings.Settings; + +@SuppressWarnings("unused") +public class ZoomHapticsPatch { + public static boolean shouldVibrate() { + return !Settings.DISABLE_ZOOM_HAPTICS.get(); + } +} diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java similarity index 69% rename from app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java index 81148c1f46..6f2c9e50ba 100644 --- a/app/src/main/java/app/revanced/integrations/patches/announcements/AnnouncementsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/AnnouncementsPatch.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.patches.announcements; +package app.revanced.integrations.youtube.patches.announcements; import android.app.Activity; import android.os.Build; @@ -6,22 +6,26 @@ import android.text.method.LinkMovementMethod; import android.widget.TextView; import androidx.annotation.RequiresApi; -import app.revanced.integrations.patches.announcements.requests.AnnouncementsRoutes; -import app.revanced.integrations.requests.Requester; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; + +import app.revanced.integrations.youtube.patches.announcements.requests.AnnouncementsRoutes; +import app.revanced.integrations.youtube.requests.Requester; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; import org.json.JSONObject; import java.io.IOException; import java.net.HttpURLConnection; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; +import java.util.Locale; import java.util.UUID; import static android.text.Html.FROM_HTML_MODE_COMPACT; -import static app.revanced.integrations.patches.announcements.requests.AnnouncementsRoutes.GET_LATEST_ANNOUNCEMENT; +import static app.revanced.integrations.shared.StringRef.str; +import static app.revanced.integrations.youtube.patches.announcements.requests.AnnouncementsRoutes.GET_LATEST_ANNOUNCEMENT; +@SuppressWarnings("unused") public final class AnnouncementsPatch { private final static String CONSUMER = getOrSetConsumer(); @@ -30,31 +34,32 @@ private AnnouncementsPatch() { @RequiresApi(api = Build.VERSION_CODES.O) public static void showAnnouncement(final Activity context) { - if (!SettingsEnum.ANNOUNCEMENTS.getBoolean()) return; + if (!Settings.ANNOUNCEMENTS.get()) return; // Check if there is internet connection - if (!ReVancedUtils.isNetworkConnected()) return; + if (!Utils.isNetworkConnected()) return; - ReVancedUtils.runOnBackgroundThread(() -> { + Utils.runOnBackgroundThread(() -> { try { - HttpURLConnection connection = AnnouncementsRoutes.getAnnouncementsConnectionFromRoute(GET_LATEST_ANNOUNCEMENT, CONSUMER); + HttpURLConnection connection = AnnouncementsRoutes.getAnnouncementsConnectionFromRoute( + GET_LATEST_ANNOUNCEMENT, CONSUMER, Locale.getDefault().toLanguageTag()); - LogHelper.printDebug(() -> "Get latest announcement route connection url: " + connection.getURL().toString()); + Logger.printDebug(() -> "Get latest announcement route connection url: " + connection.getURL()); try { // Do not show the announcement if the request failed. if (connection.getResponseCode() != 200) { - if (SettingsEnum.ANNOUNCEMENT_LAST_HASH.getString().isEmpty()) return; + if (Settings.ANNOUNCEMENT_LAST_HASH.get().isEmpty()) return; - SettingsEnum.ANNOUNCEMENT_LAST_HASH.resetToDefault(); - ReVancedUtils.showToastLong("Failed to get announcement"); + Settings.ANNOUNCEMENT_LAST_HASH.resetToDefault(); + Utils.showToastLong(str("revanced_announcements_connection_failed")); return; } } catch (IOException ex) { final var message = "Failed connecting to announcements provider"; - LogHelper.printException(() -> message, ex); + Logger.printException(() -> message, ex); return; } @@ -63,7 +68,7 @@ public static void showAnnouncement(final Activity context) { // Do not show the announcement if it is older or the same as the last one. final byte[] hashBytes = MessageDigest.getInstance("SHA-256").digest(jsonString.getBytes(StandardCharsets.UTF_8)); final var hash = java.util.Base64.getEncoder().encodeToString(hashBytes); - if (hash.equals(SettingsEnum.ANNOUNCEMENT_LAST_HASH.getString())) return; + if (hash.equals(Settings.ANNOUNCEMENT_LAST_HASH.get())) return; // Parse the announcement. Fall-back to raw string if it fails. String title; @@ -77,7 +82,7 @@ public static void showAnnouncement(final Activity context) { if (!announcement.isNull("level")) level = Level.fromInt(announcement.getInt("level")); } catch (Throwable ex) { - LogHelper.printException(() -> "Failed to parse announcement. Fall-backing to raw string", ex); + Logger.printException(() -> "Failed to parse announcement. Fall-backing to raw string", ex); title = "Announcement"; message = jsonString; @@ -87,14 +92,14 @@ public static void showAnnouncement(final Activity context) { final var finalMessage = Html.fromHtml(message, FROM_HTML_MODE_COMPACT); final Level finalLevel = level; - ReVancedUtils.runOnMainThread(() -> { + Utils.runOnMainThread(() -> { // Show the announcement. var alertDialog = new android.app.AlertDialog.Builder(context) .setTitle(finalTitle) .setMessage(finalMessage) .setIcon(finalLevel.icon) .setPositiveButton("Ok", (dialog, which) -> { - SettingsEnum.ANNOUNCEMENT_LAST_HASH.saveValue(hash); + Settings.ANNOUNCEMENT_LAST_HASH.save(hash); dialog.dismiss(); }).setNegativeButton("Dismiss", (dialog, which) -> { dialog.dismiss(); @@ -109,7 +114,7 @@ public static void showAnnouncement(final Activity context) { } catch (Exception e) { final var message = "Failed to get announcement"; - LogHelper.printException(() -> message, e); + Logger.printException(() -> message, e); } }); } @@ -120,18 +125,18 @@ public static void showAnnouncement(final Activity context) { * @return true if the last announcement hash was empty. */ private static boolean emptyLastAnnouncementHash() { - if (SettingsEnum.ANNOUNCEMENT_LAST_HASH.getString().isEmpty()) return true; - SettingsEnum.ANNOUNCEMENT_LAST_HASH.resetToDefault(); + if (Settings.ANNOUNCEMENT_LAST_HASH.get().isEmpty()) return true; + Settings.ANNOUNCEMENT_LAST_HASH.resetToDefault(); return false; } private static String getOrSetConsumer() { - final var consumer = SettingsEnum.ANNOUNCEMENT_CONSUMER.getString(); + final var consumer = Settings.ANNOUNCEMENT_CONSUMER.get(); if (!consumer.isEmpty()) return consumer; final var uuid = UUID.randomUUID().toString(); - SettingsEnum.ANNOUNCEMENT_CONSUMER.saveValue(uuid); + Settings.ANNOUNCEMENT_CONSUMER.save(uuid); return uuid; } diff --git a/app/src/main/java/app/revanced/integrations/patches/announcements/requests/AnnouncementsRoutes.java b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/requests/AnnouncementsRoutes.java similarity index 54% rename from app/src/main/java/app/revanced/integrations/patches/announcements/requests/AnnouncementsRoutes.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/announcements/requests/AnnouncementsRoutes.java index fc39090b2d..6fca530c2b 100644 --- a/app/src/main/java/app/revanced/integrations/patches/announcements/requests/AnnouncementsRoutes.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/announcements/requests/AnnouncementsRoutes.java @@ -1,18 +1,20 @@ -package app.revanced.integrations.patches.announcements.requests; +package app.revanced.integrations.youtube.patches.announcements.requests; -import app.revanced.integrations.requests.Requester; -import app.revanced.integrations.requests.Route; +import app.revanced.integrations.youtube.requests.Requester; +import app.revanced.integrations.youtube.requests.Route; import java.io.IOException; import java.net.HttpURLConnection; -import static app.revanced.integrations.requests.Route.Method.GET; +import static app.revanced.integrations.youtube.requests.Route.Method.GET; public class AnnouncementsRoutes { private static final String ANNOUNCEMENTS_PROVIDER = "https://api.revanced.app/v2"; - - public static final Route GET_LATEST_ANNOUNCEMENT = new Route(GET, "/announcements/youtube/latest?consumer={consumer}"); + /** + * 'language' parameter is IETF format (for USA it would be 'en-us'). + */ + public static final Route GET_LATEST_ANNOUNCEMENT = new Route(GET, "/announcements/youtube/latest?consumer={consumer}&language={language}"); private AnnouncementsRoutes() { } diff --git a/app/src/main/java/app/revanced/integrations/patches/components/AdsFilter.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/AdsFilter.java similarity index 79% rename from app/src/main/java/app/revanced/integrations/patches/components/AdsFilter.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/AdsFilter.java index 3b0cb0ec57..b1d38c6eb5 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/AdsFilter.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/AdsFilter.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import android.app.Instrumentation; import android.view.KeyEvent; @@ -6,10 +6,10 @@ import androidx.annotation.Nullable; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.StringTrieSearch; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.youtube.StringTrieSearch; @SuppressWarnings("unused") public final class AdsFilter extends Filter { @@ -36,7 +36,7 @@ public AdsFilter() { final var carouselAd = new StringFilterGroup( - SettingsEnum.HIDE_GENERAL_ADS, + Settings.HIDE_GENERAL_ADS, "carousel_ad" ); addIdentifierCallbacks(carouselAd); @@ -44,12 +44,12 @@ public AdsFilter() { // Paths. fullscreenAd = new StringFilterGroup( - SettingsEnum.HIDE_FULLSCREEN_ADS, + Settings.HIDE_FULLSCREEN_ADS, "_interstitial" ); final var buttonedAd = new StringFilterGroup( - SettingsEnum.HIDE_BUTTONED_ADS, + Settings.HIDE_BUTTONED_ADS, "_buttoned_layout", "full_width_square_image_layout", "_ad_with", @@ -60,7 +60,7 @@ public AdsFilter() { ); final var generalAds = new StringFilterGroup( - SettingsEnum.HIDE_GENERAL_ADS, + Settings.HIDE_GENERAL_ADS, "ads_video_with_context", "banner_text_icon", "square_image_layout", @@ -78,7 +78,7 @@ public AdsFilter() { ); final var movieAds = new StringFilterGroup( - SettingsEnum.HIDE_MOVIES_SECTION, + Settings.HIDE_MOVIES_SECTION, "browsy_bar", "compact_movie", "horizontal_movie_shelf", @@ -88,28 +88,28 @@ public AdsFilter() { ); final var viewProducts = new StringFilterGroup( - SettingsEnum.HIDE_PRODUCTS_BANNER, + Settings.HIDE_PRODUCTS_BANNER, "product_item", "products_in_video" ); shoppingLinks = new StringFilterGroup( - SettingsEnum.HIDE_SHOPPING_LINKS, + Settings.HIDE_SHOPPING_LINKS, "expandable_list" ); final var webLinkPanel = new StringFilterGroup( - SettingsEnum.HIDE_WEB_SEARCH_RESULTS, + Settings.HIDE_WEB_SEARCH_RESULTS, "web_link_panel" ); final var merchandise = new StringFilterGroup( - SettingsEnum.HIDE_MERCHANDISE_BANNERS, + Settings.HIDE_MERCHANDISE_BANNERS, "product_carousel" ); final var selfSponsor = new StringFilterGroup( - SettingsEnum.HIDE_SELF_SPONSOR, + Settings.HIDE_SELF_SPONSOR, "cta_shelf_card" ); @@ -132,8 +132,10 @@ public boolean isFiltered(@Nullable String identifier, String path, byte[] proto if (exceptions.matches(path)) return false; - if (matchedGroup == fullscreenAd && path.contains("|ImageType|")) { - closeFullscreenAd(); + if (matchedGroup == fullscreenAd) { + if (path.contains("|ImageType|")) closeFullscreenAd(); + + return false; // Do not actually filter the fullscreen ad otherwise it will leave a dimmed screen. } // Check for the index because of likelihood of false positives. @@ -149,7 +151,7 @@ public boolean isFiltered(@Nullable String identifier, String path, byte[] proto * @param view The view, which shows ads. */ public static void hideAdAttributionView(View view) { - ReVancedUtils.hideViewBy1dpUnderCondition(SettingsEnum.HIDE_GENERAL_ADS, view); + Utils.hideViewBy1dpUnderCondition(Settings.HIDE_GENERAL_ADS, view); } /** @@ -164,8 +166,8 @@ private static void closeFullscreenAd() { if (currentTime - lastTimeClosedFullscreenAd < 10000) return; lastTimeClosedFullscreenAd = currentTime; - LogHelper.printDebug(() -> "Closing fullscreen ad"); + Logger.printDebug(() -> "Closing fullscreen ad"); - ReVancedUtils.runOnMainThreadDelayed(() -> instrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK), 1000); + Utils.runOnMainThreadDelayed(() -> instrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK), 1000); } } diff --git a/app/src/main/java/app/revanced/integrations/patches/components/ButtonsFilter.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/ButtonsFilter.java similarity index 83% rename from app/src/main/java/app/revanced/integrations/patches/components/ButtonsFilter.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/ButtonsFilter.java index 123c58036b..5db9a8a841 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/ButtonsFilter.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/ButtonsFilter.java @@ -1,11 +1,11 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import android.os.Build; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; @SuppressWarnings("unused") @RequiresApi(api = Build.VERSION_CODES.N) @@ -30,19 +30,19 @@ public ButtonsFilter() { ); addPathCallbacks( new StringFilterGroup( - SettingsEnum.HIDE_LIKE_DISLIKE_BUTTON, + Settings.HIDE_LIKE_DISLIKE_BUTTON, "|segmented_like_dislike_button" ), new StringFilterGroup( - SettingsEnum.HIDE_DOWNLOAD_BUTTON, + Settings.HIDE_DOWNLOAD_BUTTON, "|download_button.eml|" ), new StringFilterGroup( - SettingsEnum.HIDE_PLAYLIST_BUTTON, + Settings.HIDE_PLAYLIST_BUTTON, "|save_to_playlist_button" ), new StringFilterGroup( - SettingsEnum.HIDE_CLIP_BUTTON, + Settings.HIDE_CLIP_BUTTON, "|clip_button.eml|" ), bufferFilterPathGroup @@ -50,33 +50,33 @@ public ButtonsFilter() { bufferButtonsGroupList.addAll( new ByteArrayFilterGroup( - SettingsEnum.HIDE_LIVE_CHAT_BUTTON, + Settings.HIDE_LIVE_CHAT_BUTTON, "yt_outline_message_bubble_overlap" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_REPORT_BUTTON, + Settings.HIDE_REPORT_BUTTON, "yt_outline_flag" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_SHARE_BUTTON, + Settings.HIDE_SHARE_BUTTON, "yt_outline_share" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_REMIX_BUTTON, + Settings.HIDE_REMIX_BUTTON, "yt_outline_youtube_shorts_plus" ), // Check for clip button both here and using a path filter, // as there's a chance the path is a generic action button and won't contain 'clip_button' new ByteArrayFilterGroup( - SettingsEnum.HIDE_CLIP_BUTTON, + Settings.HIDE_CLIP_BUTTON, "yt_outline_scissors" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_SHOP_BUTTON, + Settings.HIDE_SHOP_BUTTON, "yt_outline_bag" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_THANKS_BUTTON, + Settings.HIDE_THANKS_BUTTON, "yt_outline_dollar_sign_heart" ) ); diff --git a/app/src/main/java/app/revanced/integrations/patches/components/CommentsFilter.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/CommentsFilter.java similarity index 70% rename from app/src/main/java/app/revanced/integrations/patches/components/CommentsFilter.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/CommentsFilter.java index 6ae67f7c4b..3952797ecd 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/CommentsFilter.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/CommentsFilter.java @@ -1,19 +1,19 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; @SuppressWarnings("unused") final class CommentsFilter extends Filter { public CommentsFilter() { var comments = new StringFilterGroup( - SettingsEnum.HIDE_COMMENTS_SECTION, + Settings.HIDE_COMMENTS_SECTION, "video_metadata_carousel", "_comments" ); var previewComment = new StringFilterGroup( - SettingsEnum.HIDE_PREVIEW_COMMENT, + Settings.HIDE_PREVIEW_COMMENT, "|carousel_item", "comments_entry_point_teaser", "comments_entry_point_simplebox" diff --git a/app/src/main/java/app/revanced/integrations/patches/components/DescriptionComponentsFilter.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/DescriptionComponentsFilter.java similarity index 79% rename from app/src/main/java/app/revanced/integrations/patches/components/DescriptionComponentsFilter.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/DescriptionComponentsFilter.java index e786144ad8..0bf50b15aa 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/DescriptionComponentsFilter.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/DescriptionComponentsFilter.java @@ -1,8 +1,8 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import androidx.annotation.Nullable; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.StringTrieSearch; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.StringTrieSearch; @SuppressWarnings("unused") final class DescriptionComponentsFilter extends Filter { @@ -19,33 +19,33 @@ public DescriptionComponentsFilter() { ); final StringFilterGroup chapterSection = new StringFilterGroup( - SettingsEnum.HIDE_CHAPTERS, + Settings.HIDE_CHAPTERS, "macro_markers_carousel" ); final StringFilterGroup infoCardsSection = new StringFilterGroup( - SettingsEnum.HIDE_INFO_CARDS_SECTION, + Settings.HIDE_INFO_CARDS_SECTION, "infocards_section" ); final StringFilterGroup gameSection = new StringFilterGroup( - SettingsEnum.HIDE_GAME_SECTION, + Settings.HIDE_GAME_SECTION, "gaming_section" ); final StringFilterGroup musicSection = new StringFilterGroup( - SettingsEnum.HIDE_MUSIC_SECTION, + Settings.HIDE_MUSIC_SECTION, "music_section", "video_attributes_section" ); final StringFilterGroup podcastSection = new StringFilterGroup( - SettingsEnum.HIDE_PODCAST_SECTION, + Settings.HIDE_PODCAST_SECTION, "playlist_section" ); final StringFilterGroup transcriptSection = new StringFilterGroup( - SettingsEnum.HIDE_TRANSCIPT_SECTION, + Settings.HIDE_TRANSCIPT_SECTION, "transcript_section" ); diff --git a/app/src/main/java/app/revanced/integrations/patches/components/HideInfoCardsFilterPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/HideInfoCardsFilterPatch.java similarity index 63% rename from app/src/main/java/app/revanced/integrations/patches/components/HideInfoCardsFilterPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/HideInfoCardsFilterPatch.java index b1637b8353..959e83a4be 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/HideInfoCardsFilterPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/HideInfoCardsFilterPatch.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; @SuppressWarnings("unused") public final class HideInfoCardsFilterPatch extends Filter { @@ -8,7 +8,7 @@ public final class HideInfoCardsFilterPatch extends Filter { public HideInfoCardsFilterPatch() { addIdentifierCallbacks( new StringFilterGroup( - SettingsEnum.HIDE_INFO_CARDS, + Settings.HIDE_INFO_CARDS, "info_card_teaser_overlay.eml" ) ); diff --git a/app/src/main/java/app/revanced/integrations/patches/components/LayoutComponentsFilter.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/LayoutComponentsFilter.java similarity index 80% rename from app/src/main/java/app/revanced/integrations/patches/components/LayoutComponentsFilter.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/LayoutComponentsFilter.java index afc9b84572..368422a909 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/LayoutComponentsFilter.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/LayoutComponentsFilter.java @@ -1,13 +1,13 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import android.os.Build; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.StringTrieSearch; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.youtube.StringTrieSearch; @SuppressWarnings("unused") @RequiresApi(api = Build.VERSION_CODES.N) @@ -21,7 +21,7 @@ public final class LayoutComponentsFilter extends Filter { private final CustomFilterGroup custom; private static final ByteArrayFilterGroup mixPlaylists = new ByteArrayFilterGroup( - SettingsEnum.HIDE_MIX_PLAYLISTS, + Settings.HIDE_MIX_PLAYLISTS, "&list=" ); private final StringFilterGroup searchResultShelfHeader; @@ -52,12 +52,12 @@ public LayoutComponentsFilter() { // Identifiers. final var graySeparator = new StringFilterGroup( - SettingsEnum.HIDE_GRAY_SEPARATOR, + Settings.HIDE_GRAY_SEPARATOR, "cell_divider" // layout residue (gray line above the buttoned ad), ); final var chipsShelf = new StringFilterGroup( - SettingsEnum.HIDE_CHIPS_SHELF, + Settings.HIDE_CHIPS_SHELF, "chips_shelf" ); @@ -69,69 +69,69 @@ public LayoutComponentsFilter() { // Paths. custom = new CustomFilterGroup( - SettingsEnum.CUSTOM_FILTER, - SettingsEnum.CUSTOM_FILTER_STRINGS + Settings.CUSTOM_FILTER, + Settings.CUSTOM_FILTER_STRINGS ); final var communityPosts = new StringFilterGroup( - SettingsEnum.HIDE_COMMUNITY_POSTS, + Settings.HIDE_COMMUNITY_POSTS, "post_base_wrapper" ); final var communityGuidelines = new StringFilterGroup( - SettingsEnum.HIDE_COMMUNITY_GUIDELINES, + Settings.HIDE_COMMUNITY_GUIDELINES, "community_guidelines" ); final var subscribersCommunityGuidelines = new StringFilterGroup( - SettingsEnum.HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES, + Settings.HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES, "sponsorships_comments_upsell" ); final var channelMemberShelf = new StringFilterGroup( - SettingsEnum.HIDE_CHANNEL_MEMBER_SHELF, + Settings.HIDE_CHANNEL_MEMBER_SHELF, "member_recognition_shelf" ); final var compactBanner = new StringFilterGroup( - SettingsEnum.HIDE_COMPACT_BANNER, + Settings.HIDE_COMPACT_BANNER, "compact_banner" ); inFeedSurvey = new StringFilterGroup( - SettingsEnum.HIDE_FEED_SURVEY, + Settings.HIDE_FEED_SURVEY, "in_feed_survey", "slimline_survey" ); final var medicalPanel = new StringFilterGroup( - SettingsEnum.HIDE_MEDICAL_PANELS, + Settings.HIDE_MEDICAL_PANELS, "medical_panel" ); final var paidContent = new StringFilterGroup( - SettingsEnum.HIDE_PAID_CONTENT, + Settings.HIDE_PAID_CONTENT, "paid_content_overlay" ); final var infoPanel = new StringFilterGroup( - SettingsEnum.HIDE_HIDE_INFO_PANELS, + Settings.HIDE_HIDE_INFO_PANELS, "publisher_transparency_panel", "single_item_information_panel" ); final var latestPosts = new StringFilterGroup( - SettingsEnum.HIDE_HIDE_LATEST_POSTS, + Settings.HIDE_HIDE_LATEST_POSTS, "post_shelf" ); final var channelGuidelines = new StringFilterGroup( - SettingsEnum.HIDE_HIDE_CHANNEL_GUIDELINES, + Settings.HIDE_HIDE_CHANNEL_GUIDELINES, "channel_guidelines_entry_banner" ); final var emergencyBox = new StringFilterGroup( - SettingsEnum.HIDE_EMERGENCY_BOX, + Settings.HIDE_EMERGENCY_BOX, "emergency_onebox" ); @@ -149,79 +149,79 @@ public LayoutComponentsFilter() { ); final var artistCard = new StringFilterGroup( - SettingsEnum.HIDE_ARTIST_CARDS, + Settings.HIDE_ARTIST_CARDS, "official_card" ); expandableMetadata = new StringFilterGroup( - SettingsEnum.HIDE_EXPANDABLE_CHIP, + Settings.HIDE_EXPANDABLE_CHIP, "inline_expander" ); final var videoQualityMenuFooter = new StringFilterGroup( - SettingsEnum.HIDE_VIDEO_QUALITY_MENU_FOOTER, + Settings.HIDE_VIDEO_QUALITY_MENU_FOOTER, "quality_sheet_footer" ); final var channelBar = new StringFilterGroup( - SettingsEnum.HIDE_CHANNEL_BAR, + Settings.HIDE_CHANNEL_BAR, "channel_bar" ); final var relatedVideos = new StringFilterGroup( - SettingsEnum.HIDE_RELATED_VIDEOS, + Settings.HIDE_RELATED_VIDEOS, "fullscreen_related_videos" ); final var quickActions = new StringFilterGroup( - SettingsEnum.HIDE_QUICK_ACTIONS, + Settings.HIDE_QUICK_ACTIONS, "quick_actions" ); final var imageShelf = new StringFilterGroup( - SettingsEnum.HIDE_IMAGE_SHELF, + Settings.HIDE_IMAGE_SHELF, "image_shelf" ); final var timedReactions = new StringFilterGroup( - SettingsEnum.HIDE_TIMED_REACTIONS, + Settings.HIDE_TIMED_REACTIONS, "emoji_control_panel", "timed_reaction" ); searchResultShelfHeader = new StringFilterGroup( - SettingsEnum.HIDE_SEARCH_RESULT_SHELF_HEADER, + Settings.HIDE_SEARCH_RESULT_SHELF_HEADER, "shelf_header.eml" ); notifyMe = new StringFilterGroup( - SettingsEnum.HIDE_NOTIFY_ME_BUTTON, + Settings.HIDE_NOTIFY_ME_BUTTON, "set_reminder_button" ); final var joinMembership = new StringFilterGroup( - SettingsEnum.HIDE_JOIN_MEMBERSHIP_BUTTON, + Settings.HIDE_JOIN_MEMBERSHIP_BUTTON, "compact_sponsor_button" ); final var channelWatermark = new StringFilterGroup( - SettingsEnum.HIDE_VIDEO_CHANNEL_WATERMARK, + Settings.HIDE_VIDEO_CHANNEL_WATERMARK, "featured_channel_watermark_overlay" ); final var forYouShelf = new StringFilterGroup( - SettingsEnum.HIDE_FOR_YOU_SHELF, + Settings.HIDE_FOR_YOU_SHELF, "mixed_content_shelf" ); searchResultVideo = new StringFilterGroup( - SettingsEnum.HIDE_SEARCH_RESULT_RECOMMENDATIONS, + Settings.HIDE_SEARCH_RESULT_RECOMMENDATIONS, "search_video_with_context.eml" ); searchResultRecommendations = new ByteArrayFilterGroup( - SettingsEnum.HIDE_SEARCH_RESULT_RECOMMENDATIONS, + Settings.HIDE_SEARCH_RESULT_RECOMMENDATIONS, "endorsement_header_footer" ); @@ -285,7 +285,7 @@ public boolean isFiltered(@Nullable String identifier, String path, byte[] proto */ public static boolean filterMixPlaylists(final Object conversionContext, @Nullable final byte[] bytes) { if (bytes == null) { - LogHelper.printDebug(() -> "bytes is null"); + Logger.printDebug(() -> "bytes is null"); return false; } @@ -300,11 +300,11 @@ public static boolean filterMixPlaylists(final Object conversionContext, @Nullab if (mixPlaylistsExceptions2.check(bytes).isFiltered()) return false; - LogHelper.printDebug(() -> "Filtered mix playlist"); + Logger.printDebug(() -> "Filtered mix playlist"); return true; } public static boolean showWatermark() { - return !SettingsEnum.HIDE_VIDEO_CHANNEL_WATERMARK.getBoolean(); + return !Settings.HIDE_VIDEO_CHANNEL_WATERMARK.get(); } } diff --git a/app/src/main/java/app/revanced/integrations/patches/components/LithoFilterPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/LithoFilterPatch.java similarity index 88% rename from app/src/main/java/app/revanced/integrations/patches/components/LithoFilterPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/LithoFilterPatch.java index 26b31e64c5..4d9d370e6b 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/LithoFilterPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/LithoFilterPatch.java @@ -1,20 +1,32 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import android.os.Build; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.*; - import java.nio.ByteBuffer; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Spliterator; import java.util.function.Consumer; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.settings.BooleanSetting; +import app.revanced.integrations.shared.settings.BaseSettings; +import app.revanced.integrations.shared.settings.StringSetting; +import app.revanced.integrations.youtube.ByteTrieSearch; +import app.revanced.integrations.youtube.StringTrieSearch; +import app.revanced.integrations.youtube.TrieSearch; +import app.revanced.integrations.youtube.settings.Settings; + abstract class FilterGroup { final static class FilterGroupResult { - private SettingsEnum setting; + private BooleanSetting setting; private int matchedIndex; private int matchedLength; // In the future it might be useful to include which pattern matched, @@ -24,11 +36,11 @@ final static class FilterGroupResult { this(null, -1, 0); } - FilterGroupResult(SettingsEnum setting, int matchedIndex, int matchedLength) { + FilterGroupResult(BooleanSetting setting, int matchedIndex, int matchedLength) { setValues(setting, matchedIndex, matchedLength); } - public void setValues(SettingsEnum setting, int matchedIndex, int matchedLength) { + public void setValues(BooleanSetting setting, int matchedIndex, int matchedLength) { this.setting = setting; this.matchedIndex = matchedIndex; this.matchedLength = matchedLength; @@ -38,7 +50,7 @@ public void setValues(SettingsEnum setting, int matchedIndex, int matchedLength) * A null value if the group has no setting, * or if no match is returned from {@link FilterGroupList#check(Object)}. */ - public SettingsEnum getSetting() { + public BooleanSetting getSetting() { return setting; } @@ -61,7 +73,7 @@ public int getMatchedLength() { } } - protected final SettingsEnum setting; + protected final BooleanSetting setting; protected final T[] filters; /** @@ -71,7 +83,7 @@ public int getMatchedLength() { * @param filters The filters. */ @SafeVarargs - public FilterGroup(final SettingsEnum setting, final T... filters) { + public FilterGroup(final BooleanSetting setting, final T... filters) { this.setting = setting; this.filters = filters; if (filters.length == 0) { @@ -80,7 +92,7 @@ public FilterGroup(final SettingsEnum setting, final T... filters) { } public boolean isEnabled() { - return setting == null || setting.getBoolean(); + return setting == null || setting.get(); } /** @@ -102,7 +114,7 @@ public String toString() { class StringFilterGroup extends FilterGroup { - public StringFilterGroup(final SettingsEnum setting, final String... filters) { + public StringFilterGroup(final BooleanSetting setting, final String... filters) { super(setting, filters); } @@ -128,11 +140,11 @@ public FilterGroupResult check(final String string) { final class CustomFilterGroup extends StringFilterGroup { - private static String[] getFilterPatterns(SettingsEnum setting) { - String[] patterns = setting.getString().split("\\s+"); + private static String[] getFilterPatterns(StringSetting setting) { + String[] patterns = setting.get().split("\\s+"); for (String pattern : patterns) { if (!StringTrieSearch.isValidPattern(pattern)) { - ReVancedUtils.showToastLong("Invalid custom filter, resetting to default"); + Utils.showToastLong("Invalid custom filter, resetting to default"); setting.resetToDefault(); return getFilterPatterns(setting); } @@ -140,7 +152,7 @@ private static String[] getFilterPatterns(SettingsEnum setting) { return patterns; } - public CustomFilterGroup(SettingsEnum setting, SettingsEnum filter) { + public CustomFilterGroup(BooleanSetting setting, StringSetting filter) { super(setting, getFilterPatterns(filter)); } } @@ -191,7 +203,7 @@ private static int[] createFailurePattern(byte[] pattern) { return failure; } - public ByteArrayFilterGroup(SettingsEnum setting, byte[]... filters) { + public ByteArrayFilterGroup(BooleanSetting setting, byte[]... filters) { super(setting, filters); } @@ -199,13 +211,13 @@ public ByteArrayFilterGroup(SettingsEnum setting, byte[]... filters) { * Converts the Strings into byte arrays. Used to search for text in binary data. */ @RequiresApi(api = Build.VERSION_CODES.N) - public ByteArrayFilterGroup(SettingsEnum setting, String... filters) { + public ByteArrayFilterGroup(BooleanSetting setting, String... filters) { super(setting, Arrays.stream(filters).map(String::getBytes).toArray(byte[][]::new)); } private synchronized void buildFailurePatterns() { if (failurePatterns != null) return; // Thread race and another thread already initialized the search. - LogHelper.printDebug(() -> "Building failure array for: " + this); + Logger.printDebug(() -> "Building failure array for: " + this); int[][] failurePatterns = new int[filters.length][]; int i = 0; for (byte[] pattern : filters) { @@ -377,12 +389,12 @@ protected final void addPathCallbacks(StringFilterGroup... groups) { */ boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBufferArray, StringFilterGroup matchedGroup, FilterContentType contentType, int contentIndex) { - if (SettingsEnum.DEBUG.getBoolean()) { + if (BaseSettings.DEBUG.get()) { String filterSimpleName = getClass().getSimpleName(); if (contentType == FilterContentType.IDENTIFIER) { - LogHelper.printDebug(() -> filterSimpleName + " Filtered identifier: " + identifier); + Logger.printDebug(() -> filterSimpleName + " Filtered identifier: " + identifier); } else { - LogHelper.printDebug(() -> filterSimpleName + " Filtered path: " + path); + Logger.printDebug(() -> filterSimpleName + " Filtered path: " + path); } } return true; @@ -421,7 +433,7 @@ public String toString() { builder.append(identifier); builder.append(" Path: "); builder.append(path); - if (SettingsEnum.DEBUG_PROTOBUFFER.getBoolean()) { + if (Settings.DEBUG_PROTOBUFFER.get()) { builder.append(" BufferStrings: "); findAsciiStrings(builder, protoBuffer); } @@ -479,7 +491,7 @@ private static void findAsciiStrings(StringBuilder builder, byte[] buffer) { filter.pathCallbacks, Filter.FilterContentType.PATH); } - LogHelper.printDebug(() -> "Using: " + Logger.printDebug(() -> "Using: " + identifierSearchTree.numberOfPatterns() + " identifier filters" + " (" + identifierSearchTree.getEstimatedMemorySize() + " KB), " + pathSearchTree.numberOfPatterns() + " path filters" @@ -529,24 +541,24 @@ public static boolean filter(@Nullable String lithoIdentifier, @NonNull StringBu ByteBuffer protobufBuffer = bufferThreadLocal.get(); if (protobufBuffer == null) { - LogHelper.printException(() -> "Proto buffer is null"); // Should never happen. + Logger.printException(() -> "Proto buffer is null"); // Should never happen. return false; } if (!protobufBuffer.hasArray()) { - LogHelper.printDebug(() -> "Proto buffer does not have an array"); + Logger.printDebug(() -> "Proto buffer does not have an array"); return false; } LithoFilterParameters parameter = new LithoFilterParameters(lithoIdentifier, pathBuilder, protobufBuffer); - LogHelper.printDebug(() -> "Searching " + parameter); + Logger.printDebug(() -> "Searching " + parameter); if (parameter.identifier != null) { if (identifierSearchTree.matches(parameter.identifier, parameter)) return true; } if (pathSearchTree.matches(parameter.path, parameter)) return true; } catch (Exception ex) { - LogHelper.printException(() -> "Litho filter failure", ex); + Logger.printException(() -> "Litho filter failure", ex); } return false; diff --git a/app/src/main/java/app/revanced/integrations/patches/components/PlaybackSpeedMenuFilterPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/PlaybackSpeedMenuFilterPatch.java similarity index 84% rename from app/src/main/java/app/revanced/integrations/patches/components/PlaybackSpeedMenuFilterPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/PlaybackSpeedMenuFilterPatch.java index f609c43e2f..03319588d5 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/PlaybackSpeedMenuFilterPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/PlaybackSpeedMenuFilterPatch.java @@ -1,8 +1,8 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import androidx.annotation.Nullable; -import app.revanced.integrations.patches.playback.speed.CustomPlaybackSpeedPatch; +import app.revanced.integrations.youtube.patches.playback.speed.CustomPlaybackSpeedPatch; /** * Abuse LithoFilter for {@link CustomPlaybackSpeedPatch}. diff --git a/app/src/main/java/app/revanced/integrations/patches/components/PlayerFlyoutMenuItemsFilter.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java similarity index 77% rename from app/src/main/java/app/revanced/integrations/patches/components/PlayerFlyoutMenuItemsFilter.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java index 4f994dd9f5..19ccfac5ce 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/PlayerFlyoutMenuItemsFilter.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/PlayerFlyoutMenuItemsFilter.java @@ -1,12 +1,12 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import android.os.Build; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.shared.PlayerType; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.shared.PlayerType; @SuppressWarnings("unused") public class PlayerFlyoutMenuItemsFilter extends Filter { @@ -19,7 +19,7 @@ public class PlayerFlyoutMenuItemsFilter extends Filter { public PlayerFlyoutMenuItemsFilter() { exception = new ByteArrayFilterGroup( // Whitelist Quality menu item when "Hide Additional settings menu" is enabled - SettingsEnum.HIDE_ADDITIONAL_SETTINGS_MENU, + Settings.HIDE_ADDITIONAL_SETTINGS_MENU, "quality_sheet" ); @@ -30,43 +30,43 @@ public PlayerFlyoutMenuItemsFilter() { flyoutFilterGroupList.addAll( new ByteArrayFilterGroup( - SettingsEnum.HIDE_CAPTIONS_MENU, + Settings.HIDE_CAPTIONS_MENU, "closed_caption" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_ADDITIONAL_SETTINGS_MENU, + Settings.HIDE_ADDITIONAL_SETTINGS_MENU, "yt_outline_gear" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_LOOP_VIDEO_MENU, + Settings.HIDE_LOOP_VIDEO_MENU, "yt_outline_arrow_repeat_1_" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_AMBIENT_MODE_MENU, + Settings.HIDE_AMBIENT_MODE_MENU, "yt_outline_screen_light" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_REPORT_MENU, + Settings.HIDE_REPORT_MENU, "yt_outline_flag" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_HELP_MENU, + Settings.HIDE_HELP_MENU, "yt_outline_question_circle" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_MORE_INFO_MENU, + Settings.HIDE_MORE_INFO_MENU, "yt_outline_info_circle" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_SPEED_MENU, + Settings.HIDE_SPEED_MENU, "yt_outline_play_arrow_half_circle" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_AUDIO_TRACK_MENU, + Settings.HIDE_AUDIO_TRACK_MENU, "yt_outline_person_radar" ), new ByteArrayFilterGroup( - SettingsEnum.HIDE_WATCH_IN_VR_MENU, + Settings.HIDE_WATCH_IN_VR_MENU, "yt_outline_vr" ) ); diff --git a/app/src/main/java/app/revanced/integrations/patches/components/ReturnYouTubeDislikeFilterPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/ReturnYouTubeDislikeFilterPatch.java similarity index 87% rename from app/src/main/java/app/revanced/integrations/patches/components/ReturnYouTubeDislikeFilterPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/ReturnYouTubeDislikeFilterPatch.java index b0a4b4f973..f8ac724b74 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/ReturnYouTubeDislikeFilterPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/ReturnYouTubeDislikeFilterPatch.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import android.os.Build; @@ -11,11 +11,11 @@ import java.util.LinkedHashSet; import java.util.Map; -import app.revanced.integrations.patches.ReturnYouTubeDislikePatch; -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.TrieSearch; +import app.revanced.integrations.youtube.patches.ReturnYouTubeDislikePatch; +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.youtube.TrieSearch; /** * Searches for video id's in the proto buffer of Shorts dislike. @@ -55,16 +55,16 @@ protected boolean removeEldestEntry(Map.Entry eldest) { */ public static void newPlayerResponseVideoId(String videoId, boolean isShortAndOpeningOrPlaying) { try { - if (!isShortAndOpeningOrPlaying || !SettingsEnum.RYD_SHORTS.getBoolean()) { + if (!isShortAndOpeningOrPlaying || !Settings.RYD_SHORTS.get()) { return; } synchronized (lastVideoIds) { if (lastVideoIds.put(videoId, Boolean.TRUE) == null) { - LogHelper.printDebug(() -> "New Short video id: " + videoId); + Logger.printDebug(() -> "New Short video id: " + videoId); } } } catch (Exception ex) { - LogHelper.printException(() -> "newPlayerResponseVideoId failure", ex); + Logger.printException(() -> "newPlayerResponseVideoId failure", ex); } } @@ -72,7 +72,7 @@ public static void newPlayerResponseVideoId(String videoId, boolean isShortAndOp public ReturnYouTubeDislikeFilterPatch() { addPathCallbacks( - new StringFilterGroup(SettingsEnum.RYD_SHORTS, "|shorts_dislike_button.eml|") + new StringFilterGroup(Settings.RYD_SHORTS, "|shorts_dislike_button.eml|") ); // After the dislikes icon name is some binary data and then the video id for that specific short. videoIdFilterGroup.addAll( diff --git a/app/src/main/java/app/revanced/integrations/patches/components/ShortsFilter.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/ShortsFilter.java similarity index 79% rename from app/src/main/java/app/revanced/integrations/patches/components/ShortsFilter.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/ShortsFilter.java index 5e40f6e8e6..6782223c91 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/ShortsFilter.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/ShortsFilter.java @@ -1,14 +1,15 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import android.os.Build; import android.view.View; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; -import app.revanced.integrations.settings.SettingsEnum; + +import app.revanced.integrations.youtube.settings.Settings; import com.google.android.libraries.youtube.rendering.ui.pivotbar.PivotBar; -import static app.revanced.integrations.utils.ReVancedUtils.hideViewBy1dpUnderCondition; -import static app.revanced.integrations.utils.ReVancedUtils.hideViewUnderCondition; +import static app.revanced.integrations.shared.Utils.hideViewBy1dpUnderCondition; +import static app.revanced.integrations.shared.Utils.hideViewUnderCondition; @SuppressWarnings("unused") @RequiresApi(api = Build.VERSION_CODES.N) @@ -28,7 +29,7 @@ public final class ShortsFilter extends Filter { public ShortsFilter() { var shorts = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS, + Settings.HIDE_SHORTS, "shorts_shelf", "inline_shorts", "shorts_grid", @@ -39,13 +40,13 @@ public ShortsFilter() { // Feed Shorts shelf header. // Use a different filter group for this pattern, as it requires an additional check after matching. shelfHeader = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS, + Settings.HIDE_SHORTS, "shelf_header.eml" ); // Home / subscription feed components. var thanksButton = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS_THANKS_BUTTON, + Settings.HIDE_SHORTS_THANKS_BUTTON, "suggested_action" ); @@ -53,32 +54,32 @@ public ShortsFilter() { // Shorts player components. var joinButton = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS_JOIN_BUTTON, + Settings.HIDE_SHORTS_JOIN_BUTTON, "sponsor_button" ); subscribeButton = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS_SUBSCRIBE_BUTTON, + Settings.HIDE_SHORTS_SUBSCRIBE_BUTTON, "subscribe_button" ); subscribeButtonPaused = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS_SUBSCRIBE_BUTTON_PAUSED, + Settings.HIDE_SHORTS_SUBSCRIBE_BUTTON_PAUSED, "shorts_paused_state" ); channelBar = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS_CHANNEL_BAR, + Settings.HIDE_SHORTS_CHANNEL_BAR, REEL_CHANNEL_BAR_PATH ); soundButton = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS_SOUND_BUTTON, + Settings.HIDE_SHORTS_SOUND_BUTTON, "reel_pivot_button" ); infoPanel = new StringFilterGroup( - SettingsEnum.HIDE_SHORTS_INFO_PANEL, + Settings.HIDE_SHORTS_INFO_PANEL, "shorts_info_panel_overview" ); @@ -93,17 +94,17 @@ public ShortsFilter() { ); var shortsCommentButton = new ByteArrayFilterGroup( - SettingsEnum.HIDE_SHORTS_COMMENTS_BUTTON, + Settings.HIDE_SHORTS_COMMENTS_BUTTON, "reel_comment_button" ); var shortsShareButton = new ByteArrayFilterGroup( - SettingsEnum.HIDE_SHORTS_SHARE_BUTTON, + Settings.HIDE_SHORTS_SHARE_BUTTON, "reel_share_button" ); var shortsRemixButton = new ByteArrayFilterGroup( - SettingsEnum.HIDE_SHORTS_REMIX_BUTTON, + Settings.HIDE_SHORTS_REMIX_BUTTON, "reel_remix_button" ); @@ -148,34 +149,34 @@ boolean isFiltered(@Nullable String identifier, String path, byte[] protobufBuff } public static void hideShortsShelf(final View shortsShelfView) { - hideViewBy1dpUnderCondition(SettingsEnum.HIDE_SHORTS, shortsShelfView); + hideViewBy1dpUnderCondition(Settings.HIDE_SHORTS, shortsShelfView); } // region Hide the buttons in older versions of YouTube. New versions use Litho. public static void hideShortsCommentsButton(final View commentsButtonView) { - hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_COMMENTS_BUTTON, commentsButtonView); + hideViewUnderCondition(Settings.HIDE_SHORTS_COMMENTS_BUTTON, commentsButtonView); } public static void hideShortsRemixButton(final View remixButtonView) { - hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_REMIX_BUTTON, remixButtonView); + hideViewUnderCondition(Settings.HIDE_SHORTS_REMIX_BUTTON, remixButtonView); } public static void hideShortsShareButton(final View shareButtonView) { - hideViewUnderCondition(SettingsEnum.HIDE_SHORTS_SHARE_BUTTON, shareButtonView); + hideViewUnderCondition(Settings.HIDE_SHORTS_SHARE_BUTTON, shareButtonView); } // endregion public static void hideNavigationBar() { - if (!SettingsEnum.HIDE_SHORTS_NAVIGATION_BAR.getBoolean()) return; + if (!Settings.HIDE_SHORTS_NAVIGATION_BAR.get()) return; if (pivotBar == null) return; pivotBar.setVisibility(View.GONE); } public static View hideNavigationBar(final View navigationBarView) { - if (SettingsEnum.HIDE_SHORTS_NAVIGATION_BAR.getBoolean()) + if (Settings.HIDE_SHORTS_NAVIGATION_BAR.get()) return null; // Hides the navigation bar. return navigationBarView; diff --git a/app/src/main/java/app/revanced/integrations/patches/components/VideoQualityMenuFilterPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/components/VideoQualityMenuFilterPatch.java similarity index 74% rename from app/src/main/java/app/revanced/integrations/patches/components/VideoQualityMenuFilterPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/components/VideoQualityMenuFilterPatch.java index 2050cd3faa..e3d20e2d1e 100644 --- a/app/src/main/java/app/revanced/integrations/patches/components/VideoQualityMenuFilterPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/components/VideoQualityMenuFilterPatch.java @@ -1,9 +1,9 @@ -package app.revanced.integrations.patches.components; +package app.revanced.integrations.youtube.patches.components; import androidx.annotation.Nullable; -import app.revanced.integrations.patches.playback.quality.RestoreOldVideoQualityMenuPatch; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.patches.playback.quality.RestoreOldVideoQualityMenuPatch; +import app.revanced.integrations.youtube.settings.Settings; /** * Abuse LithoFilter for {@link RestoreOldVideoQualityMenuPatch}. @@ -15,7 +15,7 @@ public final class VideoQualityMenuFilterPatch extends Filter { public VideoQualityMenuFilterPatch() { addPathCallbacks(new StringFilterGroup( - SettingsEnum.RESTORE_OLD_VIDEO_QUALITY_MENU, + Settings.RESTORE_OLD_VIDEO_QUALITY_MENU, "quick_quality_sheet_content.eml-js" )); } diff --git a/app/src/main/java/app/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RememberVideoQualityPatch.java similarity index 71% rename from app/src/main/java/app/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RememberVideoQualityPatch.java index 04c19f7762..566792857f 100644 --- a/app/src/main/java/app/revanced/integrations/patches/playback/quality/RememberVideoQualityPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RememberVideoQualityPatch.java @@ -1,28 +1,31 @@ -package app.revanced.integrations.patches.playback.quality; - -import static app.revanced.integrations.utils.ReVancedUtils.NetworkType; +package app.revanced.integrations.youtube.patches.playback.quality; import androidx.annotation.Nullable; +import app.revanced.integrations.shared.settings.IntegerSetting; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; + import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import static app.revanced.integrations.shared.StringRef.str; +import static app.revanced.integrations.shared.Utils.NetworkType; +@SuppressWarnings("unused") public class RememberVideoQualityPatch { private static final int AUTOMATIC_VIDEO_QUALITY_VALUE = -2; - private static final SettingsEnum wifiQualitySetting = SettingsEnum.VIDEO_QUALITY_DEFAULT_WIFI; - private static final SettingsEnum mobileQualitySetting = SettingsEnum.VIDEO_QUALITY_DEFAULT_MOBILE; + private static final IntegerSetting wifiQualitySetting = Settings.VIDEO_QUALITY_DEFAULT_WIFI; + private static final IntegerSetting mobileQualitySetting = Settings.VIDEO_QUALITY_DEFAULT_MOBILE; private static boolean qualityNeedsUpdating; /** * If the user selected a new quality from the flyout menu, - * and {@link SettingsEnum#REMEMBER_VIDEO_QUALITY_LAST_SELECTED} is enabled. + * and {@link Settings#REMEMBER_VIDEO_QUALITY_LAST_SELECTED} is enabled. */ private static boolean userChangedDefaultQuality; @@ -39,15 +42,15 @@ public class RememberVideoQualityPatch { private static void changeDefaultQuality(int defaultQuality) { String networkTypeMessage; - if (ReVancedUtils.getNetworkType() == NetworkType.MOBILE) { - mobileQualitySetting.saveValue(defaultQuality); - networkTypeMessage = "mobile"; + if (Utils.getNetworkType() == NetworkType.MOBILE) { + mobileQualitySetting.save(defaultQuality); + networkTypeMessage = str("revanced_remember_video_quality_mobile"); } else { - wifiQualitySetting.saveValue(defaultQuality); - networkTypeMessage = "Wi-Fi"; + wifiQualitySetting.save(defaultQuality); + networkTypeMessage = str("revanced_remember_video_quality_wifi"); } - ReVancedUtils.showToastShort("Changed default " + networkTypeMessage - + " quality to: " + defaultQuality +"p"); + Utils.showToastShort( + str("revanced_remember_video_quality_toast", networkTypeMessage, (defaultQuality + "p"))); } /** @@ -64,10 +67,10 @@ public static int setVideoQuality(Object[] qualities, final int originalQualityI qualityNeedsUpdating = false; final int preferredQuality; - if (ReVancedUtils.getNetworkType() == NetworkType.MOBILE) { - preferredQuality = mobileQualitySetting.getInt(); + if (Utils.getNetworkType() == NetworkType.MOBILE) { + preferredQuality = mobileQualitySetting.get(); } else { - preferredQuality = wifiQualitySetting.getInt(); + preferredQuality = wifiQualitySetting.get(); } if (!userChangedDefaultQuality && preferredQuality == AUTOMATIC_VIDEO_QUALITY_VALUE) { return originalQualityIndex; // nothing to do @@ -83,13 +86,13 @@ public static int setVideoQuality(Object[] qualities, final int originalQualityI } } } - LogHelper.printDebug(() -> "videoQualities: " + videoQualities); + Logger.printDebug(() -> "videoQualities: " + videoQualities); } if (userChangedDefaultQuality) { userChangedDefaultQuality = false; final int quality = videoQualities.get(userSelectedQualityIndex); - LogHelper.printDebug(() -> "User changed default quality to: " + quality); + Logger.printDebug(() -> "User changed default quality to: " + quality); changeDefaultQuality(quality); return userSelectedQualityIndex; } @@ -117,10 +120,10 @@ public static int setVideoQuality(Object[] qualities, final int originalQualityI // To prevent confusion, set the video index anyways (even if it matches the existing index) // As that will force the UI picker to not display "Auto" which may confuse the user. if (qualityIndexToUse == originalQualityIndex) { - LogHelper.printDebug(() -> "Video is already preferred quality: " + preferredQuality); + Logger.printDebug(() -> "Video is already preferred quality: " + preferredQuality); } else { final int qualityToUseLog = qualityToUse; - LogHelper.printDebug(() -> "Quality changed from: " + Logger.printDebug(() -> "Quality changed from: " + videoQualities.get(originalQualityIndex) + " to: " + qualityToUseLog); } @@ -128,7 +131,7 @@ public static int setVideoQuality(Object[] qualities, final int originalQualityI m.invoke(qInterface, qualityToUse); return qualityIndexToUse; } catch (Exception ex) { - LogHelper.printException(() -> "Failed to set quality", ex); + Logger.printException(() -> "Failed to set quality", ex); return originalQualityIndex; } } @@ -137,7 +140,7 @@ public static int setVideoQuality(Object[] qualities, final int originalQualityI * Injection point. Old quality menu. */ public static void userChangedQuality(int selectedQualityIndex) { - if (!SettingsEnum.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.getBoolean()) return; + if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) return; userSelectedQualityIndex = selectedQualityIndex; userChangedDefaultQuality = true; @@ -147,7 +150,7 @@ public static void userChangedQuality(int selectedQualityIndex) { * Injection point. New quality menu. */ public static void userChangedQualityInNewFlyout(int selectedQuality) { - if (!SettingsEnum.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.getBoolean()) return; + if (!Settings.REMEMBER_VIDEO_QUALITY_LAST_SELECTED.get()) return; changeDefaultQuality(selectedQuality); // Quality is human readable resolution (ie: 1080). } @@ -156,7 +159,7 @@ public static void userChangedQualityInNewFlyout(int selectedQuality) { * Injection point. */ public static void newVideoStarted(Object ignoredPlayerController) { - LogHelper.printDebug(() -> "newVideoStarted"); + Logger.printDebug(() -> "newVideoStarted"); qualityNeedsUpdating = true; videoQualities = null; } diff --git a/app/src/main/java/app/revanced/integrations/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java similarity index 77% rename from app/src/main/java/app/revanced/integrations/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java index 0fee1039e6..d0a914232a 100644 --- a/app/src/main/java/app/revanced/integrations/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/quality/RestoreOldVideoQualityMenuPatch.java @@ -1,13 +1,13 @@ -package app.revanced.integrations.patches.playback.quality; +package app.revanced.integrations.youtube.patches.playback.quality; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; -import app.revanced.integrations.patches.components.VideoQualityMenuFilterPatch; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; +import app.revanced.integrations.youtube.patches.components.VideoQualityMenuFilterPatch; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; /** * This patch contains the logic to show the old video quality menu. @@ -21,7 +21,7 @@ public final class RestoreOldVideoQualityMenuPatch { * Injection point. */ public static void onFlyoutMenuCreate(RecyclerView recyclerView) { - if (!SettingsEnum.RESTORE_OLD_VIDEO_QUALITY_MENU.getBoolean()) return; + if (!Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get()) return; recyclerView.getViewTreeObserver().addOnDrawListener(() -> { try { @@ -38,7 +38,7 @@ public static void onFlyoutMenuCreate(RecyclerView recyclerView) { } } } catch (Exception ex) { - LogHelper.printException(() -> "onFlyoutMenuCreate failure", ex); + Logger.printException(() -> "onFlyoutMenuCreate failure", ex); } }); } @@ -47,19 +47,19 @@ public static void onFlyoutMenuCreate(RecyclerView recyclerView) { * Injection point. Only used if spoofing to an old app version. */ public static void showOldVideoQualityMenu(final ListView listView) { - if (!SettingsEnum.RESTORE_OLD_VIDEO_QUALITY_MENU.getBoolean()) return; + if (!Settings.RESTORE_OLD_VIDEO_QUALITY_MENU.get()) return; listView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { @Override public void onChildViewAdded(View parent, View child) { - LogHelper.printDebug(() -> "Added listener to old type of quality menu"); + Logger.printDebug(() -> "Added listener to old type of quality menu"); parent.setVisibility(View.GONE); final var indexOfAdvancedQualityMenuItem = 4; if (listView.indexOfChild(child) != indexOfAdvancedQualityMenuItem) return; - LogHelper.printDebug(() -> "Found advanced menu item in old type of quality menu"); + Logger.printDebug(() -> "Found advanced menu item in old type of quality menu"); final var qualityItemMenuPosition = 4; listView.performItemClick(null, qualityItemMenuPosition, 0); diff --git a/app/src/main/java/app/revanced/integrations/patches/playback/speed/CustomPlaybackSpeedPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/CustomPlaybackSpeedPatch.java similarity index 83% rename from app/src/main/java/app/revanced/integrations/patches/playback/speed/CustomPlaybackSpeedPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/CustomPlaybackSpeedPatch.java index 12e962d0b3..e863f8fdbc 100644 --- a/app/src/main/java/app/revanced/integrations/patches/playback/speed/CustomPlaybackSpeedPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/CustomPlaybackSpeedPatch.java @@ -1,17 +1,21 @@ -package app.revanced.integrations.patches.playback.speed; +package app.revanced.integrations.youtube.patches.playback.speed; + +import static app.revanced.integrations.shared.StringRef.str; import android.preference.ListPreference; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; -import app.revanced.integrations.patches.components.PlaybackSpeedMenuFilterPatch; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; + +import app.revanced.integrations.youtube.patches.components.PlaybackSpeedMenuFilterPatch; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; import java.util.Arrays; +@SuppressWarnings("unused") public class CustomPlaybackSpeedPatch { /** * Maximum playback speed, exclusive value. Custom speeds must be less than this value. @@ -42,13 +46,13 @@ public class CustomPlaybackSpeedPatch { } private static void resetCustomSpeeds(@NonNull String toastMessage) { - ReVancedUtils.showToastLong(toastMessage); - SettingsEnum.CUSTOM_PLAYBACK_SPEEDS.resetToDefault(); + Utils.showToastLong(toastMessage); + Settings.CUSTOM_PLAYBACK_SPEEDS.resetToDefault(); } private static void loadCustomSpeeds() { try { - String[] speedStrings = SettingsEnum.CUSTOM_PLAYBACK_SPEEDS.getString().split("\\s+"); + String[] speedStrings = Settings.CUSTOM_PLAYBACK_SPEEDS.get().split("\\s+"); Arrays.sort(speedStrings); if (speedStrings.length == 0) { throw new IllegalArgumentException(); @@ -60,16 +64,15 @@ private static void loadCustomSpeeds() { throw new IllegalArgumentException(); } if (speed >= MAXIMUM_PLAYBACK_SPEED) { - resetCustomSpeeds("Custom speeds must be less than " + MAXIMUM_PLAYBACK_SPEED - + ". Using default values."); + resetCustomSpeeds(str("revanced_custom_playback_speeds_invalid", MAXIMUM_PLAYBACK_SPEED)); loadCustomSpeeds(); return; } customPlaybackSpeeds[i] = speed; } } catch (Exception ex) { - LogHelper.printInfo(() -> "parse error", ex); - resetCustomSpeeds("Invalid custom playback speeds. Using default values."); + Logger.printInfo(() -> "parse error", ex); + resetCustomSpeeds(str("revanced_custom_playback_speeds_parse_exception")); loadCustomSpeeds(); } } @@ -137,7 +140,7 @@ public static void onFlyoutMenuCreate(RecyclerView recyclerView) { // Close the new Playback speed menu and show the old one. showOldPlaybackSpeedMenu(); } catch (Exception ex) { - LogHelper.printException(() -> "onFlyoutMenuCreate failure", ex); + Logger.printException(() -> "onFlyoutMenuCreate failure", ex); } }); } @@ -147,11 +150,11 @@ private static void showOldPlaybackSpeedMenu() { // To prevent this, ignore method reuse within 1 second. final long now = System.currentTimeMillis(); if (now - lastTimeOldPlaybackMenuInvoked < 1000) { - LogHelper.printDebug(() -> "Ignoring call to showOldPlaybackSpeedMenu"); + Logger.printDebug(() -> "Ignoring call to showOldPlaybackSpeedMenu"); return; } lastTimeOldPlaybackMenuInvoked = now; - LogHelper.printDebug(() -> "Old video quality menu shown"); + Logger.printDebug(() -> "Old video quality menu shown"); // Rest of the implementation added by patch. } diff --git a/app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/RememberPlaybackSpeedPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/RememberPlaybackSpeedPatch.java new file mode 100644 index 0000000000..1782ade6b3 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/playback/speed/RememberPlaybackSpeedPatch.java @@ -0,0 +1,42 @@ +package app.revanced.integrations.youtube.patches.playback.speed; + +import static app.revanced.integrations.shared.StringRef.str; + +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; + +@SuppressWarnings("unused") +public final class RememberPlaybackSpeedPatch { + + /** + * Injection point. + */ + public static void newVideoStarted(Object ignoredPlayerController) { + Logger.printDebug(() -> "newVideoStarted"); + VideoInformation.overridePlaybackSpeed(Settings.PLAYBACK_SPEED_DEFAULT.get()); + } + + /** + * Injection point. + * Called when user selects a playback speed. + * + * @param playbackSpeed The playback speed the user selected + */ + public static void userSelectedPlaybackSpeed(float playbackSpeed) { + if (Settings.REMEMBER_PLAYBACK_SPEED_LAST_SELECTED.get()) { + Settings.PLAYBACK_SPEED_DEFAULT.save(playbackSpeed); + Utils.showToastLong(str("revanced_remember_playback_speed_toast", (playbackSpeed + "x"))); + } + } + + /** + * Injection point. + * Overrides the video speed. Called after video loads, and immediately after user selects a different playback speed + */ + public static float getPlaybackSpeedOverride() { + return VideoInformation.getPlaybackSpeed(); + } + +} diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofAppVersionPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/SpoofAppVersionPatch.java similarity index 72% rename from app/src/main/java/app/revanced/integrations/patches/spoof/SpoofAppVersionPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/spoof/SpoofAppVersionPatch.java index a861708fda..c57bf0fc6f 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofAppVersionPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/SpoofAppVersionPatch.java @@ -1,11 +1,12 @@ -package app.revanced.integrations.patches.spoof; +package app.revanced.integrations.youtube.patches.spoof; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public class SpoofAppVersionPatch { - private static final boolean SPOOF_APP_VERSION_ENABLED = SettingsEnum.SPOOF_APP_VERSION.getBoolean(); - private static final String SPOOF_APP_VERSION_TARGET = SettingsEnum.SPOOF_APP_VERSION_TARGET.getString(); + private static final boolean SPOOF_APP_VERSION_ENABLED = Settings.SPOOF_APP_VERSION.get(); + private static final String SPOOF_APP_VERSION_TARGET = Settings.SPOOF_APP_VERSION_TARGET.get(); /** * Injection point diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofDeviceDimensionsPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/SpoofDeviceDimensionsPatch.java similarity index 55% rename from app/src/main/java/app/revanced/integrations/patches/spoof/SpoofDeviceDimensionsPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/spoof/SpoofDeviceDimensionsPatch.java index 5ac5355cf0..859a0841fd 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofDeviceDimensionsPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/SpoofDeviceDimensionsPatch.java @@ -1,9 +1,12 @@ -package app.revanced.integrations.patches.spoof; +package app.revanced.integrations.youtube.patches.spoof; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.settings.Settings; +@SuppressWarnings("unused") public class SpoofDeviceDimensionsPatch { - private static final boolean SPOOF = SettingsEnum.SPOOF_DEVICE_DIMENSIONS.getBoolean(); + private static final boolean SPOOF = Settings.SPOOF_DEVICE_DIMENSIONS.get(); + + public static int getMinHeightOrWidth(int minHeightOrWidth) { return SPOOF ? 64 : minHeightOrWidth; } diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofSignaturePatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/SpoofSignaturePatch.java similarity index 81% rename from app/src/main/java/app/revanced/integrations/patches/spoof/SpoofSignaturePatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/spoof/SpoofSignaturePatch.java index 58ef4675f7..e958f88461 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/SpoofSignaturePatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/SpoofSignaturePatch.java @@ -1,7 +1,7 @@ -package app.revanced.integrations.patches.spoof; +package app.revanced.integrations.youtube.patches.spoof; -import static app.revanced.integrations.patches.spoof.requests.StoryboardRendererRequester.getStoryboardRenderer; -import static app.revanced.integrations.utils.ReVancedUtils.containsAny; +import static app.revanced.integrations.youtube.patches.spoof.requests.StoryboardRendererRequester.getStoryboardRenderer; +import static app.revanced.integrations.shared.Utils.containsAny; import android.view.View; import android.view.ViewGroup; @@ -14,11 +14,11 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.shared.PlayerType; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.shared.PlayerType; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; /** @noinspection unused*/ public class SpoofSignaturePatch { @@ -70,10 +70,10 @@ private static StoryboardRenderer getRenderer(boolean waitForCompletion) { return future.get(20000, TimeUnit.MILLISECONDS); // Any arbitrarily large timeout. } // else, return null. } catch (TimeoutException ex) { - LogHelper.printDebug(() -> "Could not get renderer (get timed out)"); + Logger.printDebug(() -> "Could not get renderer (get timed out)"); } catch (ExecutionException | InterruptedException ex) { // Should never happen. - LogHelper.printException(() -> "Could not get renderer", ex); + Logger.printException(() -> "Could not get renderer", ex); } } return null; @@ -88,9 +88,9 @@ private static StoryboardRenderer getRenderer(boolean waitForCompletion) { */ public static String spoofParameter(String parameters, boolean isShortAndOpeningOrPlaying) { try { - LogHelper.printDebug(() -> "Original protobuf parameter value: " + parameters); + Logger.printDebug(() -> "Original protobuf parameter value: " + parameters); - if (!SettingsEnum.SPOOF_SIGNATURE.getBoolean()) { + if (!Settings.SPOOF_SIGNATURE.get()) { return parameters; } @@ -114,7 +114,7 @@ public static String spoofParameter(String parameters, boolean isShortAndOpening && containsAny(parameters, AUTOPLAY_PARAMETERS); if (isPlayingFeed) { //noinspection AssignmentUsedAsCondition - if (useOriginalStoryboardRenderer = !SettingsEnum.SPOOF_SIGNATURE_IN_FEED.getBoolean()) { + if (useOriginalStoryboardRenderer = !Settings.SPOOF_SIGNATURE_IN_FEED.get()) { // Don't spoof the feed video playback. This will cause video playback issues, // but only if user continues watching for more than 1 minute. return parameters; @@ -126,20 +126,20 @@ public static String spoofParameter(String parameters, boolean isShortAndOpening fetchStoryboardRenderer(); } catch (Exception ex) { - LogHelper.printException(() -> "spoofParameter failure", ex); + Logger.printException(() -> "spoofParameter failure", ex); } return INCOGNITO_PARAMETERS; } private static void fetchStoryboardRenderer() { - if (!SettingsEnum.SPOOF_STORYBOARD_RENDERER.getBoolean()) { + if (!Settings.SPOOF_STORYBOARD_RENDERER.get()) { lastPlayerResponseVideoId = null; rendererFuture = null; return; } String videoId = VideoInformation.getPlayerResponseVideoId(); if (!videoId.equals(lastPlayerResponseVideoId)) { - rendererFuture = ReVancedUtils.submitOnBackgroundThread(() -> getStoryboardRenderer(videoId)); + rendererFuture = Utils.submitOnBackgroundThread(() -> getStoryboardRenderer(videoId)); lastPlayerResponseVideoId = videoId; } // Block until the renderer fetch completes. @@ -150,7 +150,7 @@ private static void fetchStoryboardRenderer() { private static String getStoryboardRendererSpec(String originalStoryboardRendererSpec, boolean returnNullIfLiveStream) { - if (SettingsEnum.SPOOF_SIGNATURE.getBoolean() && !useOriginalStoryboardRenderer) { + if (Settings.SPOOF_SIGNATURE.get() && !useOriginalStoryboardRenderer) { StoryboardRenderer renderer = getRenderer(false); if (renderer != null) { if (returnNullIfLiveStream && renderer.isLiveStream()) { @@ -189,7 +189,7 @@ public static String getStoryboardDecoderRendererSpec(String originalStoryboardR * Injection point. */ public static int getRecommendedLevel(int originalLevel) { - if (SettingsEnum.SPOOF_SIGNATURE.getBoolean() && !useOriginalStoryboardRenderer) { + if (Settings.SPOOF_SIGNATURE.get() && !useOriginalStoryboardRenderer) { StoryboardRenderer renderer = getRenderer(false); if (renderer != null) { Integer recommendedLevel = renderer.getRecommendedLevel(); @@ -202,10 +202,10 @@ public static int getRecommendedLevel(int originalLevel) { /** * Injection point. Forces seekbar to be shown for paid videos or - * if {@link SettingsEnum#SPOOF_STORYBOARD_RENDERER} is not enabled. + * if {@link Settings#SPOOF_STORYBOARD_RENDERER} is not enabled. */ public static boolean getSeekbarThumbnailOverrideValue() { - if (!SettingsEnum.SPOOF_SIGNATURE.getBoolean()) { + if (!Settings.SPOOF_SIGNATURE.get()) { return false; } StoryboardRenderer renderer = getRenderer(false); @@ -225,8 +225,8 @@ public static boolean getSeekbarThumbnailOverrideValue() { */ public static void seekbarImageViewCreated(ImageView view) { try { - if (!SettingsEnum.SPOOF_SIGNATURE.getBoolean() - || SettingsEnum.SPOOF_STORYBOARD_RENDERER.getBoolean()) { + if (!Settings.SPOOF_SIGNATURE.get() + || Settings.SPOOF_STORYBOARD_RENDERER.get()) { return; } if (isPlayingShorts) return; @@ -236,7 +236,7 @@ public static void seekbarImageViewCreated(ImageView view) { ViewGroup parentLayout = (ViewGroup) view.getParent(); parentLayout.setPadding(0, 0, 0, 0); } catch (Exception ex) { - LogHelper.printException(() -> "seekbarImageViewCreated failure", ex); + Logger.printException(() -> "seekbarImageViewCreated failure", ex); } } } diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/StoryboardRenderer.java b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/StoryboardRenderer.java similarity index 95% rename from app/src/main/java/app/revanced/integrations/patches/spoof/StoryboardRenderer.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/spoof/StoryboardRenderer.java index 3adc5f6752..f2f69db7d8 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/StoryboardRenderer.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/StoryboardRenderer.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.patches.spoof; +package app.revanced.integrations.youtube.patches.spoof; import androidx.annotation.Nullable; diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/PlayerRoutes.java b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/requests/PlayerRoutes.java similarity index 84% rename from app/src/main/java/app/revanced/integrations/patches/spoof/requests/PlayerRoutes.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/spoof/requests/PlayerRoutes.java index 17fff6d1e1..c8f7741cbf 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/PlayerRoutes.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/requests/PlayerRoutes.java @@ -1,9 +1,9 @@ -package app.revanced.integrations.patches.spoof.requests; +package app.revanced.integrations.youtube.patches.spoof.requests; -import app.revanced.integrations.requests.Requester; -import app.revanced.integrations.requests.Route; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.youtube.requests.Requester; +import app.revanced.integrations.youtube.requests.Route; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; import org.json.JSONException; import org.json.JSONObject; @@ -36,7 +36,7 @@ final class PlayerRoutes { JSONObject client = new JSONObject(); client.put("clientName", "ANDROID"); - client.put("clientVersion", ReVancedUtils.getVersionName()); + client.put("clientVersion", Utils.getVersionName()); client.put("androidSdkVersion", 34); context.put("client", client); @@ -44,7 +44,7 @@ final class PlayerRoutes { innerTubeBody.put("context", context); innerTubeBody.put("videoId", "%s"); } catch (JSONException e) { - LogHelper.printException(() -> "Failed to create innerTubeBody", e); + Logger.printException(() -> "Failed to create innerTubeBody", e); } ANDROID_INNER_TUBE_BODY = innerTubeBody.toString(); @@ -69,7 +69,7 @@ final class PlayerRoutes { tvEmbedInnerTubeBody.put("context", context); tvEmbedInnerTubeBody.put("videoId", "%s"); } catch (JSONException e) { - LogHelper.printException(() -> "Failed to create tvEmbedInnerTubeBody", e); + Logger.printException(() -> "Failed to create tvEmbedInnerTubeBody", e); } TV_EMBED_INNER_TUBE_BODY = tvEmbedInnerTubeBody.toString(); @@ -84,7 +84,7 @@ static HttpURLConnection getPlayerResponseConnectionFromRoute(Route.CompiledRout connection.setRequestProperty( "User-Agent", "com.google.android.youtube/" + - ReVancedUtils.getVersionName() + + Utils.getVersionName() + " (Linux; U; Android 12; GB) gzip" ); connection.setRequestProperty("X-Goog-Api-Format-Version", "2"); diff --git a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryboardRendererRequester.java b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/requests/StoryboardRendererRequester.java similarity index 71% rename from app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryboardRendererRequester.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/spoof/requests/StoryboardRendererRequester.java index f5f7ce2740..aeb7fe251f 100644 --- a/app/src/main/java/app/revanced/integrations/patches/spoof/requests/StoryboardRendererRequester.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/spoof/requests/StoryboardRendererRequester.java @@ -1,12 +1,12 @@ -package app.revanced.integrations.patches.spoof.requests; - -import static app.revanced.integrations.patches.spoof.requests.PlayerRoutes.ANDROID_INNER_TUBE_BODY; -import static app.revanced.integrations.patches.spoof.requests.PlayerRoutes.GET_STORYBOARD_SPEC_RENDERER; -import static app.revanced.integrations.patches.spoof.requests.PlayerRoutes.TV_EMBED_INNER_TUBE_BODY; +package app.revanced.integrations.youtube.patches.spoof.requests; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - +import app.revanced.integrations.shared.settings.BaseSettings; +import app.revanced.integrations.youtube.patches.spoof.StoryboardRenderer; +import app.revanced.integrations.youtube.requests.Requester; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; import org.json.JSONException; import org.json.JSONObject; @@ -16,11 +16,8 @@ import java.nio.charset.StandardCharsets; import java.util.Objects; -import app.revanced.integrations.patches.spoof.StoryboardRenderer; -import app.revanced.integrations.requests.Requester; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import static app.revanced.integrations.shared.StringRef.str; +import static app.revanced.integrations.youtube.patches.spoof.requests.PlayerRoutes.*; public class StoryboardRendererRequester { @@ -39,21 +36,21 @@ private static void randomlyWaitIfLocallyDebugging() { final boolean randomlyWait = false; // Enable to simulate slow connection responses. if (randomlyWait) { final long maximumTimeToRandomlyWait = 10000; - ReVancedUtils.doNothingForDuration(maximumTimeToRandomlyWait); + Utils.doNothingForDuration(maximumTimeToRandomlyWait); } } private static void handleConnectionError(@NonNull String toastMessage, @Nullable Exception ex, boolean showToastOnIOException) { - if (showToastOnIOException) ReVancedUtils.showToastShort(toastMessage); - LogHelper.printInfo(() -> toastMessage, ex); + if (showToastOnIOException) Utils.showToastShort(toastMessage); + Logger.printInfo(() -> toastMessage, ex); } @Nullable private static JSONObject fetchPlayerResponse(@NonNull String requestBody, boolean showToastOnIOException) { final long startTime = System.currentTimeMillis(); try { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); Objects.requireNonNull(requestBody); final byte[] innerTubeBody = requestBody.getBytes(StandardCharsets.UTF_8); @@ -66,19 +63,19 @@ private static JSONObject fetchPlayerResponse(@NonNull String requestBody, boole if (responseCode == 200) return Requester.parseJSONObject(connection); // Always show a toast for this, as a non 200 response means something is broken. + // Not a normal code path and should not be reached, so no translations are needed. handleConnectionError("Spoof storyboard not available: " + responseCode, - null, showToastOnIOException || SettingsEnum.DEBUG_TOAST_ON_ERROR.getBoolean()); + null, showToastOnIOException || BaseSettings.DEBUG_TOAST_ON_ERROR.get()); connection.disconnect(); } catch (SocketTimeoutException ex) { - handleConnectionError("Spoof storyboard temporarily not available (API timed out)", - ex, showToastOnIOException); + handleConnectionError(str("revanced_spoof_storyboard_timeout"), ex, showToastOnIOException); } catch (IOException ex) { - handleConnectionError("Spoof storyboard temporarily not available: " + ex.getMessage(), + handleConnectionError(str("revanced_spoof_storyboard_io_exception", ex.getMessage()), ex, showToastOnIOException); } catch (Exception ex) { - LogHelper.printException(() -> "Spoof storyboard fetch failed", ex); // Should never happen. + Logger.printException(() -> "Spoof storyboard fetch failed", ex); // Should never happen. } finally { - LogHelper.printDebug(() -> "Request took: " + (System.currentTimeMillis() - startTime) + "ms"); + Logger.printDebug(() -> "Request took: " + (System.currentTimeMillis() - startTime) + "ms"); } return null; @@ -88,7 +85,7 @@ private static boolean isPlayabilityStatusOk(@NonNull JSONObject playerResponse) try { return playerResponse.getJSONObject("playabilityStatus").getString("status").equals("OK"); } catch (JSONException e) { - LogHelper.printDebug(() -> "Failed to get playabilityStatus for response: " + playerResponse); + Logger.printDebug(() -> "Failed to get playabilityStatus for response: " + playerResponse); } return false; @@ -112,9 +109,9 @@ private static StoryboardRenderer getStoryboardRendererUsingBody(@NonNull String @Nullable private static StoryboardRenderer getStoryboardRendererUsingResponse(@NonNull JSONObject playerResponse) { try { - LogHelper.printDebug(() -> "Parsing response: " + playerResponse); + Logger.printDebug(() -> "Parsing response: " + playerResponse); if (!playerResponse.has("storyboards")) { - LogHelper.printDebug(() -> "Using empty storyboard"); + Logger.printDebug(() -> "Using empty storyboard"); return emptyStoryboard; } final JSONObject storyboards = playerResponse.getJSONObject("storyboards"); @@ -132,11 +129,11 @@ private static StoryboardRenderer getStoryboardRendererUsingResponse(@NonNull JS : null ); - LogHelper.printDebug(() -> "Fetched: " + renderer); + Logger.printDebug(() -> "Fetched: " + renderer); return renderer; } catch (JSONException e) { - LogHelper.printException(() -> "Failed to get storyboardRenderer", e); + Logger.printException(() -> "Failed to get storyboardRenderer", e); } return null; @@ -149,11 +146,11 @@ public static StoryboardRenderer getStoryboardRenderer(@NonNull String videoId) var renderer = getStoryboardRendererUsingBody( String.format(ANDROID_INNER_TUBE_BODY, videoId), false); if (renderer == null) { - LogHelper.printDebug(() -> videoId + " not available using Android client"); + Logger.printDebug(() -> videoId + " not available using Android client"); renderer = getStoryboardRendererUsingBody( String.format(TV_EMBED_INNER_TUBE_BODY, videoId, videoId), true); if (renderer == null) { - LogHelper.printDebug(() -> videoId + " not available using TV embedded client"); + Logger.printDebug(() -> videoId + " not available using TV embedded client"); } } diff --git a/app/src/main/java/app/revanced/integrations/patches/theme/ProgressBarDrawable.java b/app/src/main/java/app/revanced/integrations/youtube/patches/theme/ProgressBarDrawable.java similarity index 79% rename from app/src/main/java/app/revanced/integrations/patches/theme/ProgressBarDrawable.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/theme/ProgressBarDrawable.java index 28df33604a..13ab20c6f0 100644 --- a/app/src/main/java/app/revanced/integrations/patches/theme/ProgressBarDrawable.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/theme/ProgressBarDrawable.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.patches.theme; +package app.revanced.integrations.youtube.patches.theme; import android.graphics.Canvas; import android.graphics.ColorFilter; @@ -9,21 +9,21 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.revanced.integrations.patches.HideSeekbarPatch; -import app.revanced.integrations.settings.SettingsEnum; +import app.revanced.integrations.youtube.patches.HideSeekbarPatch; +import app.revanced.integrations.youtube.settings.Settings; /** * Used by {@link SeekbarColorPatch} change the color of the seekbar. * and {@link HideSeekbarPatch} to hide the seekbar of the feed and watch history. */ +@SuppressWarnings("unused") public class ProgressBarDrawable extends Drawable { - private final Paint paint = new Paint(); @Override public void draw(@NonNull Canvas canvas) { - if (SettingsEnum.HIDE_SEEKBAR_THUMBNAIL.getBoolean()) { + if (Settings.HIDE_SEEKBAR_THUMBNAIL.get()) { return; } paint.setColor(SeekbarColorPatch.getSeekbarColor()); diff --git a/app/src/main/java/app/revanced/integrations/patches/theme/SeekbarColorPatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/theme/SeekbarColorPatch.java similarity index 78% rename from app/src/main/java/app/revanced/integrations/patches/theme/SeekbarColorPatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/theme/SeekbarColorPatch.java index 41fa877d2c..17caa5f6dc 100644 --- a/app/src/main/java/app/revanced/integrations/patches/theme/SeekbarColorPatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/theme/SeekbarColorPatch.java @@ -1,14 +1,17 @@ -package app.revanced.integrations.patches.theme; +package app.revanced.integrations.youtube.patches.theme; + +import static app.revanced.integrations.shared.StringRef.str; import android.graphics.Color; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +@SuppressWarnings("unused") public final class SeekbarColorPatch { - private static final boolean USE_SEEKBAR_CUSTOM_COLOR = SettingsEnum.SEEKBAR_CUSTOM_COLOR.getBoolean(); + private static final boolean USE_SEEKBAR_CUSTOM_COLOR = Settings.SEEKBAR_CUSTOM_COLOR.get(); /** * Default color of the seekbar. @@ -21,8 +24,8 @@ public final class SeekbarColorPatch { private static final float ORIGINAL_SEEKBAR_COLOR_BRIGHTNESS; /** - * If {@link SettingsEnum#SEEKBAR_CUSTOM_COLOR} is enabled, - * this is the color value of {@link SettingsEnum#SEEKBAR_CUSTOM_COLOR_VALUE}. + * If {@link Settings#SEEKBAR_CUSTOM_COLOR} is enabled, + * this is the color value of {@link Settings#SEEKBAR_CUSTOM_COLOR_VALUE}. * Otherwise this is {@link #ORIGINAL_SEEKBAR_COLOR}. */ private static int seekbarColor = ORIGINAL_SEEKBAR_COLOR; @@ -44,11 +47,11 @@ public final class SeekbarColorPatch { private static void loadCustomSeekbarColor() { try { - seekbarColor = Color.parseColor(SettingsEnum.SEEKBAR_CUSTOM_COLOR_VALUE.getString()); + seekbarColor = Color.parseColor(Settings.SEEKBAR_CUSTOM_COLOR_VALUE.get()); Color.colorToHSV(seekbarColor, customSeekbarColorHSV); } catch (Exception ex) { - ReVancedUtils.showToastShort("Invalid seekbar color value. Using default value."); - SettingsEnum.SEEKBAR_CUSTOM_COLOR_VALUE.resetToDefault(); + Utils.showToastShort(str("revanced_seekbar_custom_color_invalid")); + Settings.SEEKBAR_CUSTOM_COLOR_VALUE.resetToDefault(); loadCustomSeekbarColor(); } } @@ -64,11 +67,11 @@ public static int getSeekbarColor() { * Overrides all Litho components that use the YouTube seekbar color. * Used only for the video thumbnails seekbar. * - * If {@link SettingsEnum#HIDE_SEEKBAR_THUMBNAIL} is enabled, this returns a fully transparent color. + * If {@link Settings#HIDE_SEEKBAR_THUMBNAIL} is enabled, this returns a fully transparent color. */ public static int getLithoColor(int colorValue) { if (colorValue == ORIGINAL_SEEKBAR_COLOR) { - if (SettingsEnum.HIDE_SEEKBAR_THUMBNAIL.getBoolean()) { + if (Settings.HIDE_SEEKBAR_THUMBNAIL.get()) { return 0x00000000; } return getSeekbarColorValue(ORIGINAL_SEEKBAR_COLOR); @@ -119,11 +122,11 @@ private static int getSeekbarColorValue(int originalColor) { final int replacementAlpha = clamp(Color.alpha(seekbarColor) + alphaDifference, 0, 255); final int replacementColor = Color.HSVToColor(replacementAlpha, hsv); - LogHelper.printDebug(() -> String.format("Original color: #%08X replacement color: #%08X", + Logger.printDebug(() -> String.format("Original color: #%08X replacement color: #%08X", originalColor, replacementColor)); return replacementColor; } catch (Exception ex) { - LogHelper.printException(() -> "getSeekbarColorValue failure", ex); + Logger.printException(() -> "getSeekbarColorValue failure", ex); return originalColor; } } diff --git a/app/src/main/java/app/revanced/integrations/patches/theme/ThemePatch.java b/app/src/main/java/app/revanced/integrations/youtube/patches/theme/ThemePatch.java similarity index 79% rename from app/src/main/java/app/revanced/integrations/patches/theme/ThemePatch.java rename to app/src/main/java/app/revanced/integrations/youtube/patches/theme/ThemePatch.java index e9796db250..8cb0cded8e 100644 --- a/app/src/main/java/app/revanced/integrations/patches/theme/ThemePatch.java +++ b/app/src/main/java/app/revanced/integrations/youtube/patches/theme/ThemePatch.java @@ -1,9 +1,10 @@ -package app.revanced.integrations.patches.theme; +package app.revanced.integrations.youtube.patches.theme; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.ThemeHelper; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.youtube.ThemeHelper; +@SuppressWarnings("unused") public class ThemePatch { // color constants used in relation with litho components private static final int[] WHITE_VALUES = { @@ -42,16 +43,16 @@ public static int getValue(int originalValue) { } public static boolean gradientLoadingScreenEnabled() { - return SettingsEnum.GRADIENT_LOADING_SCREEN.getBoolean(); + return Settings.GRADIENT_LOADING_SCREEN.get(); } private static int getBlackColor() { - if (blackColor == 0) blackColor = ReVancedUtils.getResourceColor("yt_black1"); + if (blackColor == 0) blackColor = Utils.getResourceColor("yt_black1"); return blackColor; } private static int getWhiteColor() { - if (whiteColor == 0) whiteColor = ReVancedUtils.getResourceColor("yt_white1"); + if (whiteColor == 0) whiteColor = Utils.getResourceColor("yt_white1"); return whiteColor; } diff --git a/app/src/main/java/app/revanced/integrations/requests/Requester.java b/app/src/main/java/app/revanced/integrations/youtube/requests/Requester.java similarity index 96% rename from app/src/main/java/app/revanced/integrations/requests/Requester.java rename to app/src/main/java/app/revanced/integrations/youtube/requests/Requester.java index 0a49ecacb2..5c109f9880 100644 --- a/app/src/main/java/app/revanced/integrations/requests/Requester.java +++ b/app/src/main/java/app/revanced/integrations/youtube/requests/Requester.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.requests; +package app.revanced.integrations.youtube.requests; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.shared.Utils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -24,7 +24,7 @@ public static HttpURLConnection getConnectionFromCompiledRoute(String apiUrl, Ro String url = apiUrl + route.getCompiledRoute(); HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestMethod(route.getMethod().name()); - connection.setRequestProperty("User-Agent", System.getProperty("http.agent") + "; ReVanced/" + ReVancedUtils.getVersionName()); + connection.setRequestProperty("User-Agent", System.getProperty("http.agent") + "; ReVanced/" + Utils.getVersionName()); return connection; } diff --git a/app/src/main/java/app/revanced/integrations/requests/Route.java b/app/src/main/java/app/revanced/integrations/youtube/requests/Route.java similarity index 97% rename from app/src/main/java/app/revanced/integrations/requests/Route.java rename to app/src/main/java/app/revanced/integrations/youtube/requests/Route.java index 50182ea43a..877a364c90 100644 --- a/app/src/main/java/app/revanced/integrations/requests/Route.java +++ b/app/src/main/java/app/revanced/integrations/youtube/requests/Route.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.requests; +package app.revanced.integrations.youtube.requests; public class Route { private final String route; diff --git a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java b/app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/ReturnYouTubeDislike.java similarity index 86% rename from app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java rename to app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/ReturnYouTubeDislike.java index c049538438..7df275788e 100644 --- a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/ReturnYouTubeDislike.java +++ b/app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/ReturnYouTubeDislike.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.returnyoutubedislike; +package app.revanced.integrations.youtube.returnyoutubedislike; -import static app.revanced.integrations.utils.StringRef.str; +import static app.revanced.integrations.shared.StringRef.str; import android.graphics.Canvas; import android.graphics.Paint; @@ -37,13 +37,14 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import app.revanced.integrations.returnyoutubedislike.requests.RYDVoteData; -import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.shared.PlayerType; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.ThemeHelper; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.youtube.ThemeHelper; +import app.revanced.integrations.youtube.patches.spoof.SpoofAppVersionPatch; +import app.revanced.integrations.youtube.returnyoutubedislike.requests.RYDVoteData; +import app.revanced.integrations.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.shared.PlayerType; /** * Handles fetching and creation/replacing of RYD dislike text spans. @@ -89,6 +90,9 @@ public enum Vote { */ private static final char MIDDLE_SEPARATOR_CHARACTER = 'â—Ž'; // 'bullseye' + private static final boolean IS_SPOOFING_TO_OLD_SEPARATOR_COLOR + = SpoofAppVersionPatch.isSpoofingToEqualOrLessThan("18.09.39"); + /** * Cached lookup of all video ids. */ @@ -123,7 +127,7 @@ public enum Vote { private static final ShapeDrawable leftSeparatorShape; static { - DisplayMetrics dp = Objects.requireNonNull(ReVancedUtils.getContext()).getResources().getDisplayMetrics(); + DisplayMetrics dp = Objects.requireNonNull(Utils.getContext()).getResources().getDisplayMetrics(); leftSeparatorBounds = new Rect(0, 0, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1.2f, dp), @@ -179,10 +183,24 @@ public enum Vote { @GuardedBy("this") private SpannableString replacementLikeDislikeSpan; + /** + * Color of the left and middle separator, based on the color of the right separator. + * It's unknown where YT gets the color from, and the colors here are approximated by hand. + * Ideally, the color here would be the actual color YT uses at runtime. + * + * Older versions before the 'Me' library tab use a slightly different color. + * If spoofing was previously used and is now turned off, + * or an old version was recently upgraded then the old colors are sometimes used. + */ private static int getSeparatorColor() { + if (IS_SPOOFING_TO_OLD_SEPARATOR_COLOR) { + return ThemeHelper.isDarkTheme() + ? 0x29AAAAAA // transparent dark gray + : 0xFFD9D9D9; // light gray + } return ThemeHelper.isDarkTheme() - ? 0x33FFFFFF // transparent dark gray - : 0xFFD9D9D9; // light gray + ? 0x33FFFFFF + : 0xFFD9D9D9; } public static ShapeDrawable getLeftSeparatorDrawable() { @@ -225,10 +243,10 @@ private static SpannableString createDislikeSpan(@NonNull Spanned oldSpannable, } SpannableStringBuilder builder = new SpannableStringBuilder(); - final boolean compactLayout = SettingsEnum.RYD_COMPACT_LAYOUT.getBoolean(); + final boolean compactLayout = Settings.RYD_COMPACT_LAYOUT.get(); if (!compactLayout) { - String leftSeparatorString = ReVancedUtils.isRightToLeftTextLayout() + String leftSeparatorString = Utils.isRightToLeftTextLayout() ? "\u200F" // u200F = right to left character : "\u200E"; // u200E = left to right character final Spannable leftSeparatorSpan; @@ -318,7 +336,7 @@ private static boolean spansHaveEqualTextAndColor(@NonNull Spanned one, @NonNull private static SpannableString newSpannableWithDislikes(@NonNull Spanned sourceStyling, @NonNull RYDVoteData voteData) { return newSpanUsingStylingOfAnotherSpan(sourceStyling, - SettingsEnum.RYD_DISLIKE_PERCENTAGE.getBoolean() + Settings.RYD_DISLIKE_PERCENTAGE.get() ? formatDislikePercentage(voteData.getDislikePercentage()) : formatDislikeCount(voteData.getDislikeCount())); } @@ -340,8 +358,8 @@ private static String formatDislikeCount(long dislikeCount) { // such as Arabic which formats "1.234" into "Û±,Û²Û³Ù¤" // But YouTube disregards locale specific number characters // and instead shows english number characters everywhere. - Locale locale = Objects.requireNonNull(ReVancedUtils.getContext()).getResources().getConfiguration().locale; - LogHelper.printDebug(() -> "Locale: " + locale); + Locale locale = Objects.requireNonNull(Utils.getContext()).getResources().getConfiguration().locale; + Logger.printDebug(() -> "Locale: " + locale); dislikeCountFormatter = CompactDecimalFormat.getInstance(locale, CompactDecimalFormat.CompactStyle.SHORT); } return dislikeCountFormatter.format(dislikeCount); @@ -355,8 +373,8 @@ private static String formatDislikeCount(long dislikeCount) { private static String formatDislikePercentage(float dislikePercentage) { synchronized (ReturnYouTubeDislike.class) { // number formatter is not thread safe, must synchronize if (dislikePercentageFormatter == null) { - Locale locale = Objects.requireNonNull(ReVancedUtils.getContext()).getResources().getConfiguration().locale; - LogHelper.printDebug(() -> "Locale: " + locale); + Locale locale = Objects.requireNonNull(Utils.getContext()).getResources().getConfiguration().locale; + Logger.printDebug(() -> "Locale: " + locale); dislikePercentageFormatter = NumberFormat.getPercentInstance(locale); } if (dislikePercentage >= 0.01) { // at least 1% @@ -378,7 +396,7 @@ public static ReturnYouTubeDislike getFetchForVideoId(@Nullable String videoId) fetchCache.values().removeIf(value -> { final boolean expired = value.isExpired(now); if (expired) - LogHelper.printDebug(() -> "Removing expired fetch: " + value.videoId); + Logger.printDebug(() -> "Removing expired fetch: " + value.videoId); return expired; }); } @@ -406,7 +424,7 @@ public static void clearAllUICaches() { private ReturnYouTubeDislike(@NonNull String videoId) { this.videoId = Objects.requireNonNull(videoId); this.timeFetched = System.currentTimeMillis(); - this.future = ReVancedUtils.submitOnBackgroundThread(() -> ReturnYouTubeDislikeApi.fetchVotes(videoId)); + this.future = Utils.submitOnBackgroundThread(() -> ReturnYouTubeDislikeApi.fetchVotes(videoId)); } private boolean isExpired(long now) { @@ -426,9 +444,9 @@ public RYDVoteData getFetchData(long maxTimeToWait) { try { return future.get(maxTimeToWait, TimeUnit.MILLISECONDS); } catch (TimeoutException ex) { - LogHelper.printDebug(() -> "Waited but future was not complete after: " + maxTimeToWait + "ms"); + Logger.printDebug(() -> "Waited but future was not complete after: " + maxTimeToWait + "ms"); } catch (ExecutionException | InterruptedException ex) { - LogHelper.printException(() -> "Future failure ", ex); // will never happen + Logger.printException(() -> "Future failure ", ex); // will never happen } return null; } @@ -442,7 +460,7 @@ public boolean fetchCompleted() { private synchronized void clearUICache() { if (replacementLikeDislikeSpan != null) { - LogHelper.printDebug(() -> "Clearing replacement span for: " + videoId); + Logger.printDebug(() -> "Clearing replacement span for: " + videoId); } replacementLikeDislikeSpan = null; } @@ -485,7 +503,7 @@ private Spanned waitForFetchAndUpdateReplacementSpan(@NonNull Spanned original, try { RYDVoteData votingData = getFetchData(MAX_MILLISECONDS_TO_BLOCK_UI_WAITING_FOR_FETCH); if (votingData == null) { - LogHelper.printDebug(() -> "Cannot add dislike to UI (RYD data not available)"); + Logger.printDebug(() -> "Cannot add dislike to UI (RYD data not available)"); return original; } @@ -503,18 +521,18 @@ private Spanned waitForFetchAndUpdateReplacementSpan(@NonNull Spanned original, // 2. opened a short (without closing the regular video) // 3. closed the short // 4. regular video is now present, but the videoId and RYD data is still for the short - LogHelper.printDebug(() -> "Ignoring regular video dislike span," + Logger.printDebug(() -> "Ignoring regular video dislike span," + " as data loaded was previously used for a Short: " + videoId); return original; } if (originalDislikeSpan != null && replacementLikeDislikeSpan != null) { if (spansHaveEqualTextAndColor(original, replacementLikeDislikeSpan)) { - LogHelper.printDebug(() -> "Ignoring previously created dislikes span of data: " + videoId); + Logger.printDebug(() -> "Ignoring previously created dislikes span of data: " + videoId); return original; } if (spansHaveEqualTextAndColor(original, originalDislikeSpan)) { - LogHelper.printDebug(() -> "Replacing span with previously created dislike span of data: " + videoId); + Logger.printDebug(() -> "Replacing span with previously created dislike span of data: " + videoId); return replacementLikeDislikeSpan; } } @@ -522,7 +540,7 @@ private Spanned waitForFetchAndUpdateReplacementSpan(@NonNull Spanned original, // need to recreate using original, as original has prior outdated dislike values if (originalDislikeSpan == null) { // Should never happen. - LogHelper.printDebug(() -> "Cannot add dislikes - original span is null. videoId: " + videoId); + Logger.printDebug(() -> "Cannot add dislikes - original span is null. videoId: " + videoId); return original; } original = originalDislikeSpan; @@ -535,26 +553,26 @@ private Spanned waitForFetchAndUpdateReplacementSpan(@NonNull Spanned original, } originalDislikeSpan = original; replacementLikeDislikeSpan = createDislikeSpan(original, isSegmentedButton, isRollingNumber, votingData); - LogHelper.printDebug(() -> "Replaced: '" + originalDislikeSpan + "' with: '" + Logger.printDebug(() -> "Replaced: '" + originalDislikeSpan + "' with: '" + replacementLikeDislikeSpan + "'" + " using video: " + videoId); return replacementLikeDislikeSpan; } } catch (Exception e) { - LogHelper.printException(() -> "waitForFetchAndUpdateReplacementSpan failure", e); // should never happen + Logger.printException(() -> "waitForFetchAndUpdateReplacementSpan failure", e); // should never happen } return original; } public void sendVote(@NonNull Vote vote) { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); Objects.requireNonNull(vote); try { if (isShort != PlayerType.getCurrent().isNoneOrHidden()) { // Shorts was loaded with regular video present, then Shorts was closed. // and then user voted on the now visible original video. // Cannot send a vote, because this instance is for the wrong video. - ReVancedUtils.showToastLong(str("revanced_ryd_failure_ryd_enabled_while_playing_video_then_user_voted")); + Utils.showToastLong(str("revanced_ryd_failure_ryd_enabled_while_playing_video_then_user_voted")); return; } @@ -564,11 +582,11 @@ public void sendVote(@NonNull Vote vote) { try { // Must wrap in try/catch to properly log exceptions. ReturnYouTubeDislikeApi.sendVote(videoId, vote); } catch (Exception ex) { - LogHelper.printException(() -> "Failed to send vote", ex); + Logger.printException(() -> "Failed to send vote", ex); } }); } catch (Exception ex) { - LogHelper.printException(() -> "Error trying to send vote", ex); + Logger.printException(() -> "Error trying to send vote", ex); } } @@ -580,7 +598,7 @@ public void sendVote(@NonNull Vote vote) { public void setUserVote(@NonNull Vote vote) { Objects.requireNonNull(vote); try { - LogHelper.printDebug(() -> "setUserVote: " + vote); + Logger.printDebug(() -> "setUserVote: " + vote); synchronized (this) { userVote = vote; @@ -592,14 +610,14 @@ public void setUserVote(@NonNull Vote vote) { RYDVoteData voteData = getFetchData(MAX_MILLISECONDS_TO_BLOCK_UI_WAITING_FOR_FETCH); if (voteData == null) { // RYD fetch failed. - LogHelper.printDebug(() -> "Cannot update UI (vote data not available)"); + Logger.printDebug(() -> "Cannot update UI (vote data not available)"); return; } voteData.updateUsingVote(vote); } // Else, vote will be applied after fetch completes. } catch (Exception ex) { - LogHelper.printException(() -> "setUserVote failure", ex); + Logger.printException(() -> "setUserVote failure", ex); } } } diff --git a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/requests/RYDVoteData.java b/app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/requests/RYDVoteData.java similarity index 95% rename from app/src/main/java/app/revanced/integrations/returnyoutubedislike/requests/RYDVoteData.java rename to app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/requests/RYDVoteData.java index faf6161950..820c0492f3 100644 --- a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/requests/RYDVoteData.java +++ b/app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/requests/RYDVoteData.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.returnyoutubedislike.requests; +package app.revanced.integrations.youtube.returnyoutubedislike.requests; -import static app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike.Vote; +import static app.revanced.integrations.youtube.returnyoutubedislike.ReturnYouTubeDislike.Vote; import androidx.annotation.NonNull; diff --git a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/requests/ReturnYouTubeDislikeApi.java b/app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/requests/ReturnYouTubeDislikeApi.java similarity index 87% rename from app/src/main/java/app/revanced/integrations/returnyoutubedislike/requests/ReturnYouTubeDislikeApi.java rename to app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/requests/ReturnYouTubeDislikeApi.java index 1712d40a88..0b1c8e814b 100644 --- a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/requests/ReturnYouTubeDislikeApi.java +++ b/app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/requests/ReturnYouTubeDislikeApi.java @@ -1,7 +1,7 @@ -package app.revanced.integrations.returnyoutubedislike.requests; +package app.revanced.integrations.youtube.returnyoutubedislike.requests; -import static app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeRoutes.getRYDConnectionFromRoute; -import static app.revanced.integrations.utils.StringRef.str; +import static app.revanced.integrations.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeRoutes.getRYDConnectionFromRoute; +import static app.revanced.integrations.shared.StringRef.str; import android.util.Base64; @@ -22,11 +22,11 @@ import java.security.SecureRandom; import java.util.Objects; -import app.revanced.integrations.requests.Requester; -import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.youtube.requests.Requester; +import app.revanced.integrations.youtube.returnyoutubedislike.ReturnYouTubeDislike; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; public class ReturnYouTubeDislikeApi { /** @@ -144,7 +144,7 @@ private static void randomlyWaitIfLocallyDebugging() { if (DEBUG_RANDOMLY_DELAY_NETWORK_CALLS) { final long amountOfTimeToWaste = (long) (Math.random() * (API_GET_VOTES_TCP_TIMEOUT_MILLISECONDS + API_GET_VOTES_HTTP_TIMEOUT_MILLISECONDS)); - ReVancedUtils.doNothingForDuration(amountOfTimeToWaste); + Utils.doNothingForDuration(amountOfTimeToWaste); } } @@ -160,7 +160,7 @@ private static boolean checkIfRateLimitInEffect(String apiEndPointName) { timeToResumeAPICalls = 0; return false; } - LogHelper.printDebug(() -> "Ignoring api call " + apiEndPointName + " as rate limit is in effect"); + Logger.printDebug(() -> "Ignoring api call " + apiEndPointName + " as rate limit is in effect"); return true; } @@ -172,7 +172,7 @@ private static boolean checkIfRateLimitWasHit(int httpResponseCode) { if (DEBUG_RATE_LIMIT) { final double RANDOM_RATE_LIMIT_PERCENTAGE = 0.2; // 20% chance of a triggering a rate limit if (Math.random() < RANDOM_RATE_LIMIT_PERCENTAGE) { - LogHelper.printDebug(() -> "Artificially triggering rate limit for debug purposes"); + Logger.printDebug(() -> "Artificially triggering rate limit for debug purposes"); httpResponseCode = HTTP_STATUS_CODE_RATE_LIMIT; } } @@ -194,23 +194,23 @@ private static void updateRateLimitAndStats(long timeNetworkCallStarted, boolean fetchCallResponseTimeLast = responseTimeOfFetchCall; fetchCallNumberOfFailures++; } else if (rateLimitHit) { - LogHelper.printDebug(() -> "API rate limit was hit. Stopping API calls for the next " + Logger.printDebug(() -> "API rate limit was hit. Stopping API calls for the next " + BACKOFF_RATE_LIMIT_MILLISECONDS + " seconds"); timeToResumeAPICalls = System.currentTimeMillis() + BACKOFF_RATE_LIMIT_MILLISECONDS; numberOfRateLimitRequestsEncountered++; fetchCallResponseTimeLast = FETCH_CALL_RESPONSE_TIME_VALUE_RATE_LIMIT; - ReVancedUtils.showToastLong(str("revanced_ryd_failure_client_rate_limit_requested")); + Utils.showToastLong(str("revanced_ryd_failure_client_rate_limit_requested")); } else { fetchCallResponseTimeLast = responseTimeOfFetchCall; } } private static void handleConnectionError(@NonNull String toastMessage, @Nullable Exception ex) { - if (SettingsEnum.RYD_TOAST_ON_CONNECTION_ERROR.getBoolean()) { - ReVancedUtils.showToastShort(toastMessage); + if (Settings.RYD_TOAST_ON_CONNECTION_ERROR.get()) { + Utils.showToastShort(toastMessage); } if (ex != null) { - LogHelper.printInfo(() -> toastMessage, ex); + Logger.printInfo(() -> toastMessage, ex); } } @@ -219,13 +219,13 @@ private static void handleConnectionError(@NonNull String toastMessage, @Nullabl */ @Nullable public static RYDVoteData fetchVotes(String videoId) { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); Objects.requireNonNull(videoId); if (checkIfRateLimitInEffect("fetchVotes")) { return null; } - LogHelper.printDebug(() -> "Fetching votes for: " + videoId); + Logger.printDebug(() -> "Fetching votes for: " + videoId); final long timeNetworkCallStarted = System.currentTimeMillis(); try { @@ -255,10 +255,10 @@ public static RYDVoteData fetchVotes(String videoId) { try { RYDVoteData votingData = new RYDVoteData(json); updateRateLimitAndStats(timeNetworkCallStarted, false, false); - LogHelper.printDebug(() -> "Voting data fetched: " + votingData); + Logger.printDebug(() -> "Voting data fetched: " + votingData); return votingData; } catch (JSONException ex) { - LogHelper.printException(() -> "Failed to parse video: " + videoId + " json: " + json, ex); + Logger.printException(() -> "Failed to parse video: " + videoId + " json: " + json, ex); // fall thru to update statistics } } else { @@ -271,7 +271,7 @@ public static RYDVoteData fetchVotes(String videoId) { handleConnectionError((str("revanced_ryd_failure_generic", ex.getMessage())), ex); } catch (Exception ex) { // should never happen - LogHelper.printException(() -> "Failed to fetch votes", ex, str("revanced_ryd_failure_generic", ex.getMessage())); + Logger.printException(() -> "Failed to fetch votes", ex, str("revanced_ryd_failure_generic", ex.getMessage())); } updateRateLimitAndStats(timeNetworkCallStarted, true, false); @@ -283,13 +283,13 @@ public static RYDVoteData fetchVotes(String videoId) { */ @Nullable public static String registerAsNewUser() { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); try { if (checkIfRateLimitInEffect("registerAsNewUser")) { return null; } String userId = randomString(36); - LogHelper.printDebug(() -> "Trying to register new user"); + Logger.printDebug(() -> "Trying to register new user"); HttpURLConnection connection = getRYDConnectionFromRoute(ReturnYouTubeDislikeRoutes.GET_REGISTRATION, userId); connection.setRequestProperty("Accept", "application/json"); @@ -316,21 +316,21 @@ public static String registerAsNewUser() { } catch (IOException ex) { handleConnectionError(str("revanced_ryd_failure_generic", "registration failed"), ex); } catch (Exception ex) { - LogHelper.printException(() -> "Failed to register user", ex); // should never happen + Logger.printException(() -> "Failed to register user", ex); // should never happen } return null; } @Nullable private static String confirmRegistration(String userId, String solution) { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); Objects.requireNonNull(userId); Objects.requireNonNull(solution); try { if (checkIfRateLimitInEffect("confirmRegistration")) { return null; } - LogHelper.printDebug(() -> "Trying to confirm registration with solution: " + solution); + Logger.printDebug(() -> "Trying to confirm registration with solution: " + solution); HttpURLConnection connection = getRYDConnectionFromRoute(ReturnYouTubeDislikeRoutes.CONFIRM_REGISTRATION, userId); applyCommonPostRequestSettings(connection); @@ -349,12 +349,12 @@ private static String confirmRegistration(String userId, String solution) { if (responseCode == HTTP_STATUS_CODE_SUCCESS) { result = Requester.parseJson(connection); if (result.equalsIgnoreCase("true")) { - LogHelper.printDebug(() -> "Registration confirmation successful"); + Logger.printDebug(() -> "Registration confirmation successful"); return userId; } } final String resultLog = result == null ? "(no response)" : result; - LogHelper.printInfo(() -> "Failed to confirm registration for user: " + userId + Logger.printInfo(() -> "Failed to confirm registration for user: " + userId + " solution: " + solution + " responseCode: " + responseCode + " responseString: " + resultLog); handleConnectionError(str("revanced_ryd_failure_connection_status_code", responseCode), null); connection.disconnect(); // something went wrong, might as well disconnect @@ -363,7 +363,7 @@ private static String confirmRegistration(String userId, String solution) { } catch (IOException ex) { handleConnectionError(str("revanced_ryd_failure_generic", "confirm registration failed"), ex); } catch (Exception ex) { - LogHelper.printException(() -> "Failed to confirm registration for user: " + userId + Logger.printException(() -> "Failed to confirm registration for user: " + userId + "solution: " + solution, ex); } return null; @@ -377,22 +377,22 @@ private static String confirmRegistration(String userId, String solution) { */ @Nullable private static String getUserId() { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); - String userId = SettingsEnum.RYD_USER_ID.getString(); + String userId = Settings.RYD_USER_ID.get(); if (!userId.isEmpty()) { return userId; } userId = registerAsNewUser(); if (userId != null) { - SettingsEnum.RYD_USER_ID.saveValue(userId); + Settings.RYD_USER_ID.save(userId); } return userId; } public static boolean sendVote(String videoId, ReturnYouTubeDislike.Vote vote) { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); Objects.requireNonNull(videoId); Objects.requireNonNull(vote); @@ -403,7 +403,7 @@ public static boolean sendVote(String videoId, ReturnYouTubeDislike.Vote vote) { if (checkIfRateLimitInEffect("sendVote")) { return false; } - LogHelper.printDebug(() -> "Trying to vote for video: " + videoId + " with vote: " + vote); + Logger.printDebug(() -> "Trying to vote for video: " + videoId + " with vote: " + vote); HttpURLConnection connection = getRYDConnectionFromRoute(ReturnYouTubeDislikeRoutes.SEND_VOTE); applyCommonPostRequestSettings(connection); @@ -427,7 +427,7 @@ public static boolean sendVote(String videoId, ReturnYouTubeDislike.Vote vote) { String solution = solvePuzzle(challenge, difficulty); return confirmVote(videoId, userId, solution); } - LogHelper.printInfo(() -> "Failed to send vote for video: " + videoId + " vote: " + vote + Logger.printInfo(() -> "Failed to send vote for video: " + videoId + " vote: " + vote + " response code was: " + responseCode); handleConnectionError(str("revanced_ryd_failure_connection_status_code", responseCode), null); connection.disconnect(); // something went wrong, might as well disconnect @@ -437,13 +437,13 @@ public static boolean sendVote(String videoId, ReturnYouTubeDislike.Vote vote) { handleConnectionError(str("revanced_ryd_failure_generic", "send vote failed"), ex); } catch (Exception ex) { // should never happen - LogHelper.printException(() -> "Failed to send vote for video: " + videoId + " vote: " + vote, ex); + Logger.printException(() -> "Failed to send vote for video: " + videoId + " vote: " + vote, ex); } return false; } private static boolean confirmVote(String videoId, String userId, String solution) { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); Objects.requireNonNull(videoId); Objects.requireNonNull(userId); Objects.requireNonNull(solution); @@ -452,7 +452,7 @@ private static boolean confirmVote(String videoId, String userId, String solutio if (checkIfRateLimitInEffect("confirmVote")) { return false; } - LogHelper.printDebug(() -> "Trying to confirm vote for video: " + videoId + " solution: " + solution); + Logger.printDebug(() -> "Trying to confirm vote for video: " + videoId + " solution: " + solution); HttpURLConnection connection = getRYDConnectionFromRoute(ReturnYouTubeDislikeRoutes.CONFIRM_VOTE); applyCommonPostRequestSettings(connection); @@ -470,12 +470,12 @@ private static boolean confirmVote(String videoId, String userId, String solutio if (responseCode == HTTP_STATUS_CODE_SUCCESS) { result = Requester.parseJson(connection); if (result.equalsIgnoreCase("true")) { - LogHelper.printDebug(() -> "Vote confirm successful for video: " + videoId); + Logger.printDebug(() -> "Vote confirm successful for video: " + videoId); return true; } } final String resultLog = result == null ? "(no response)" : result; - LogHelper.printInfo(() -> "Failed to confirm vote for video: " + videoId + Logger.printInfo(() -> "Failed to confirm vote for video: " + videoId + " solution: " + solution + " responseCode: " + responseCode + " responseString: " + resultLog); handleConnectionError(str("revanced_ryd_failure_connection_status_code", responseCode), null); connection.disconnect(); // something went wrong, might as well disconnect @@ -484,7 +484,7 @@ private static boolean confirmVote(String videoId, String userId, String solutio } catch (IOException ex) { handleConnectionError(str("revanced_ryd_failure_generic", "confirm vote failed"), ex); } catch (Exception ex) { - LogHelper.printException(() -> "Failed to confirm vote for video: " + videoId + Logger.printException(() -> "Failed to confirm vote for video: " + videoId + " solution: " + solution, ex); // should never happen } return false; @@ -527,7 +527,7 @@ private static String solvePuzzle(String challenge, int difficulty) { if (countLeadingZeroes(messageDigest) >= difficulty) { String solution = Base64.encodeToString(new byte[]{buffer[0], buffer[1], buffer[2], buffer[3]}, Base64.NO_WRAP); - LogHelper.printDebug(() -> "Found puzzle solution: " + solution + " of difficulty: " + difficulty + Logger.printDebug(() -> "Found puzzle solution: " + solution + " of difficulty: " + difficulty + " in: " + (System.currentTimeMillis() - timeSolveStarted) + " ms"); return solution; } diff --git a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/requests/ReturnYouTubeDislikeRoutes.java b/app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/requests/ReturnYouTubeDislikeRoutes.java similarity index 71% rename from app/src/main/java/app/revanced/integrations/returnyoutubedislike/requests/ReturnYouTubeDislikeRoutes.java rename to app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/requests/ReturnYouTubeDislikeRoutes.java index dba0196b69..20a544883a 100644 --- a/app/src/main/java/app/revanced/integrations/returnyoutubedislike/requests/ReturnYouTubeDislikeRoutes.java +++ b/app/src/main/java/app/revanced/integrations/youtube/returnyoutubedislike/requests/ReturnYouTubeDislikeRoutes.java @@ -1,13 +1,13 @@ -package app.revanced.integrations.returnyoutubedislike.requests; +package app.revanced.integrations.youtube.returnyoutubedislike.requests; -import static app.revanced.integrations.requests.Route.Method.GET; -import static app.revanced.integrations.requests.Route.Method.POST; +import static app.revanced.integrations.youtube.requests.Route.Method.GET; +import static app.revanced.integrations.youtube.requests.Route.Method.POST; import java.io.IOException; import java.net.HttpURLConnection; -import app.revanced.integrations.requests.Requester; -import app.revanced.integrations.requests.Route; +import app.revanced.integrations.youtube.requests.Requester; +import app.revanced.integrations.youtube.requests.Route; class ReturnYouTubeDislikeRoutes { static final String RYD_API_URL = "https://returnyoutubedislikeapi.com/"; diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingActivity.java b/app/src/main/java/app/revanced/integrations/youtube/settings/LicenseActivityHook.java similarity index 64% rename from app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingActivity.java rename to app/src/main/java/app/revanced/integrations/youtube/settings/LicenseActivityHook.java index e7cba140cf..30d97a6724 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/ReVancedSettingActivity.java +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/LicenseActivityHook.java @@ -1,7 +1,4 @@ -package app.revanced.integrations.settingsmenu; - -import static app.revanced.integrations.utils.ReVancedUtils.getChildView; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceIdentifier; +package app.revanced.integrations.youtube.settings; import android.annotation.SuppressLint; import android.app.Activity; @@ -9,18 +6,31 @@ import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.TextView; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.youtube.ThemeHelper; +import app.revanced.integrations.youtube.settings.preference.ReVancedPreferenceFragment; +import app.revanced.integrations.youtube.settings.preference.ReturnYouTubeDislikePreferenceFragment; +import app.revanced.integrations.youtube.settings.preference.SponsorBlockPreferenceFragment; import java.util.Objects; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ThemeHelper; +import static app.revanced.integrations.shared.Utils.getChildView; +import static app.revanced.integrations.shared.Utils.getResourceIdentifier; -public class ReVancedSettingActivity { +/** + * Hooks LicenseActivity. + *

+ * This class is responsible for injecting our own fragment by replacing the LicenseActivity. + */ +@SuppressWarnings("unused") +public class LicenseActivityHook { /** * Injection point. + *

+ * Hooks LicenseActivity#onCreate in order to inject our own fragment. */ - public static void initializeSettings(Activity licenseActivity) { + public static void initialize(Activity licenseActivity) { try { ThemeHelper.setActivityTheme(licenseActivity); licenseActivity.setContentView( @@ -31,20 +41,20 @@ public static void initializeSettings(Activity licenseActivity) { String toolbarTitleResourceName; String dataString = licenseActivity.getIntent().getDataString(); switch (dataString) { - case "sponsorblock_settings": - toolbarTitleResourceName = "revanced_sponsorblock_settings_title"; - fragment = new SponsorBlockSettingsFragment(); + case "revanced_sb_settings_intent": + toolbarTitleResourceName = "revanced_sb_settings_title"; + fragment = new SponsorBlockPreferenceFragment(); break; - case "ryd_settings": + case "revanced_ryd_settings_intent": toolbarTitleResourceName = "revanced_ryd_settings_title"; - fragment = new ReturnYouTubeDislikeSettingsFragment(); + fragment = new ReturnYouTubeDislikePreferenceFragment(); break; - case "revanced_settings": + case "revanced_settings_intent": toolbarTitleResourceName = "revanced_settings_title"; - fragment = new ReVancedSettingsFragment(); + fragment = new ReVancedPreferenceFragment(); break; default: - LogHelper.printException(() -> "Unknown setting: " + dataString); + Logger.printException(() -> "Unknown setting: " + dataString); return; } @@ -54,7 +64,7 @@ public static void initializeSettings(Activity licenseActivity) { .replace(getResourceIdentifier("revanced_settings_fragments", "id"), fragment) .commit(); } catch (Exception ex) { - LogHelper.printException(() -> "onCreate failure", ex); + Logger.printException(() -> "onCreate failure", ex); } } diff --git a/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java new file mode 100644 index 0000000000..07b6ddf23a --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/Settings.java @@ -0,0 +1,361 @@ +package app.revanced.integrations.youtube.settings; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static app.revanced.integrations.shared.settings.Setting.migrateFromOldPreferences; +import static app.revanced.integrations.shared.settings.Setting.migrateOldSettingToNew; +import static app.revanced.integrations.shared.settings.Setting.parent; +import static app.revanced.integrations.shared.settings.Setting.parentsAny; +import static app.revanced.integrations.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE; +import static app.revanced.integrations.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP; +import static app.revanced.integrations.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY; +import static app.revanced.integrations.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.settings.BooleanSetting; +import app.revanced.integrations.shared.settings.FloatSetting; +import app.revanced.integrations.shared.settings.IntegerSetting; +import app.revanced.integrations.shared.settings.LongSetting; +import app.revanced.integrations.shared.settings.Setting; +import app.revanced.integrations.shared.settings.preference.SharedPrefCategory; +import app.revanced.integrations.shared.settings.BaseSettings; +import app.revanced.integrations.shared.settings.StringSetting; +import app.revanced.integrations.youtube.sponsorblock.SponsorBlockSettings; + +public class Settings extends BaseSettings { + // External downloader + public static final BooleanSetting EXTERNAL_DOWNLOADER = new BooleanSetting("revanced_external_downloader", FALSE); + public static final StringSetting EXTERNAL_DOWNLOADER_PACKAGE_NAME = new StringSetting("revanced_external_downloader_name", + "org.schabi.newpipe" /* NewPipe */, parent(EXTERNAL_DOWNLOADER)); + + // Copy video URL + public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE); + public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE); + + // Video + public static final BooleanSetting HDR_AUTO_BRIGHTNESS = new BooleanSetting("revanced_hdr_auto_brightness", TRUE); + public static final BooleanSetting RESTORE_OLD_VIDEO_QUALITY_MENU = new BooleanSetting("revanced_restore_old_video_quality_menu", TRUE); + public static final BooleanSetting REMEMBER_VIDEO_QUALITY_LAST_SELECTED = new BooleanSetting("revanced_remember_video_quality_last_selected", TRUE); + public static final IntegerSetting VIDEO_QUALITY_DEFAULT_WIFI = new IntegerSetting("revanced_video_quality_default_wifi", -2); + public static final IntegerSetting VIDEO_QUALITY_DEFAULT_MOBILE = new IntegerSetting("revanced_video_quality_default_mobile", -2); + public static final BooleanSetting REMEMBER_PLAYBACK_SPEED_LAST_SELECTED = new BooleanSetting("revanced_remember_playback_speed_last_selected", TRUE); + public static final FloatSetting PLAYBACK_SPEED_DEFAULT = new FloatSetting("revanced_playback_speed_default", 1.0f); + public static final StringSetting CUSTOM_PLAYBACK_SPEEDS = new StringSetting("revanced_custom_playback_speeds", + "0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true); + + // Ads + public static final BooleanSetting HIDE_FULLSCREEN_ADS = new BooleanSetting("revanced_hide_fullscreen_ads", TRUE); + public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE); + public static final BooleanSetting HIDE_GENERAL_ADS = new BooleanSetting("revanced_hide_general_ads", TRUE); + public static final BooleanSetting HIDE_GET_PREMIUM = new BooleanSetting("revanced_hide_get_premium", TRUE); + public static final BooleanSetting HIDE_HIDE_LATEST_POSTS = new BooleanSetting("revanced_hide_latest_posts_ads", TRUE); + public static final BooleanSetting HIDE_MERCHANDISE_BANNERS = new BooleanSetting("revanced_hide_merchandise_banners", TRUE); + public static final BooleanSetting HIDE_PAID_CONTENT = new BooleanSetting("revanced_hide_paid_content_ads", TRUE); + public static final BooleanSetting HIDE_PRODUCTS_BANNER = new BooleanSetting("revanced_hide_products_banner", TRUE); + public static final BooleanSetting HIDE_SHOPPING_LINKS = new BooleanSetting("revanced_hide_shopping_links", TRUE); + public static final BooleanSetting HIDE_SELF_SPONSOR = new BooleanSetting("revanced_hide_self_sponsor_ads", TRUE); + public static final BooleanSetting HIDE_VIDEO_ADS = new BooleanSetting("revanced_hide_video_ads", TRUE, true); + public static final BooleanSetting HIDE_WEB_SEARCH_RESULTS = new BooleanSetting("revanced_hide_web_search_results", TRUE); + // Layout + public static final BooleanSetting ALT_THUMBNAIL_STILLS = new BooleanSetting("revanced_alt_thumbnail_stills", FALSE); + public static final IntegerSetting ALT_THUMBNAIL_STILLS_TIME = new IntegerSetting("revanced_alt_thumbnail_stills_time", 2, parent(ALT_THUMBNAIL_STILLS)); + public static final BooleanSetting ALT_THUMBNAIL_STILLS_FAST = new BooleanSetting("revanced_alt_thumbnail_stills_fast", FALSE, parent(ALT_THUMBNAIL_STILLS)); + public static final BooleanSetting ALT_THUMBNAIL_DEARROW = new BooleanSetting("revanced_alt_thumbnail_dearrow", FALSE); + public static final StringSetting ALT_THUMBNAIL_DEARROW_API_URL = new StringSetting("revanced_alt_thumbnail_dearrow_api_url", + "https://dearrow-thumb.ajay.app/api/v1/getThumbnail", true, parent(ALT_THUMBNAIL_DEARROW)); + public static final BooleanSetting ALT_THUMBNAIL_DEARROW_CONNECTION_TOAST = new BooleanSetting("revanced_alt_thumbnail_dearrow_connection_toast", TRUE, parent(ALT_THUMBNAIL_DEARROW)); + public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE); + public static final StringSetting CUSTOM_FILTER_STRINGS = new StringSetting("revanced_custom_filter_strings", "", true, parent(CUSTOM_FILTER)); + public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true); + public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", FALSE); + public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE); + public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", TRUE); + public static final BooleanSetting GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_gradient_loading_screen", FALSE); + public static final BooleanSetting HIDE_ALBUM_CARDS = new BooleanSetting("revanced_hide_album_cards", FALSE, true); + public static final BooleanSetting HIDE_ARTIST_CARDS = new BooleanSetting("revanced_hide_artist_cards", FALSE); + public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true); + public static final BooleanSetting HIDE_BREAKING_NEWS = new BooleanSetting("revanced_hide_breaking_news", TRUE, true); + public static final BooleanSetting HIDE_CAPTIONS_BUTTON = new BooleanSetting("revanced_hide_captions_button", FALSE); + public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true); + public static final BooleanSetting HIDE_CHANNEL_BAR = new BooleanSetting("revanced_hide_channel_bar", FALSE); + public static final BooleanSetting HIDE_CHANNEL_MEMBER_SHELF = new BooleanSetting("revanced_hide_channel_member_shelf", TRUE); + public static final BooleanSetting HIDE_CHIPS_SHELF = new BooleanSetting("revanced_hide_chips_shelf", TRUE); + public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE, true); + public static final BooleanSetting HIDE_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_community_guidelines", TRUE); + public static final BooleanSetting HIDE_COMMUNITY_POSTS = new BooleanSetting("revanced_hide_community_posts", FALSE); + public static final BooleanSetting HIDE_COMPACT_BANNER = new BooleanSetting("revanced_hide_compact_banner", TRUE); + public static final BooleanSetting HIDE_CREATE_BUTTON = new BooleanSetting("revanced_hide_create_button", TRUE, true); + public static final BooleanSetting HIDE_CROWDFUNDING_BOX = new BooleanSetting("revanced_hide_crowdfunding_box", FALSE, true); + public static final BooleanSetting HIDE_EMAIL_ADDRESS = new BooleanSetting("revanced_hide_email_address", FALSE); + public static final BooleanSetting HIDE_EMERGENCY_BOX = new BooleanSetting("revanced_hide_emergency_box", TRUE); + public static final BooleanSetting HIDE_ENDSCREEN_CARDS = new BooleanSetting("revanced_hide_endscreen_cards", TRUE); + public static final BooleanSetting HIDE_EXPANDABLE_CHIP = new BooleanSetting("revanced_hide_expandable_chip", TRUE); + public static final BooleanSetting HIDE_FEED_SURVEY = new BooleanSetting("revanced_hide_feed_survey", TRUE); + public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_FEED = new BooleanSetting("revanced_hide_filter_bar_feed_in_feed", FALSE, true); + public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS = new BooleanSetting("revanced_hide_filter_bar_feed_in_related_videos", FALSE, true); + public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_SEARCH = new BooleanSetting("revanced_hide_filter_bar_feed_in_search", FALSE, true); + public static final BooleanSetting HIDE_FLOATING_MICROPHONE_BUTTON = new BooleanSetting("revanced_hide_floating_microphone_button", TRUE, true); + public static final BooleanSetting HIDE_FULLSCREEN_PANELS = new BooleanSetting("revanced_hide_fullscreen_panels", TRUE, true); + public static final BooleanSetting HIDE_GRAY_SEPARATOR = new BooleanSetting("revanced_hide_gray_separator", TRUE); + public static final BooleanSetting HIDE_HIDE_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_channel_guidelines", TRUE); + public static final BooleanSetting HIDE_HIDE_INFO_PANELS = new BooleanSetting("revanced_hide_info_panels", TRUE); + public static final BooleanSetting HIDE_HOME_BUTTON = new BooleanSetting("revanced_hide_home_button", FALSE, true); + public static final BooleanSetting HIDE_IMAGE_SHELF = new BooleanSetting("revanced_hide_image_shelf", TRUE); + public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("revanced_hide_info_cards", TRUE); + public static final BooleanSetting HIDE_JOIN_MEMBERSHIP_BUTTON = new BooleanSetting("revanced_hide_join_membership_button", TRUE); + public static final BooleanSetting HIDE_LOAD_MORE_BUTTON = new BooleanSetting("revanced_hide_load_more_button", TRUE, true); + public static final BooleanSetting HIDE_MEDICAL_PANELS = new BooleanSetting("revanced_hide_medical_panels", TRUE); + public static final BooleanSetting HIDE_MIX_PLAYLISTS = new BooleanSetting("revanced_hide_mix_playlists", TRUE); + public static final BooleanSetting HIDE_MOVIES_SECTION = new BooleanSetting("revanced_hide_movies_section", TRUE); + public static final BooleanSetting HIDE_NOTIFY_ME_BUTTON = new BooleanSetting("revanced_hide_notify_me_button", TRUE); + public static final BooleanSetting HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE); + public static final BooleanSetting HIDE_PREVIEW_COMMENT = new BooleanSetting("revanced_hide_preview_comment", FALSE, true); + public static final BooleanSetting HIDE_QUICK_ACTIONS = new BooleanSetting("revanced_hide_quick_actions", FALSE); + public static final BooleanSetting HIDE_RELATED_VIDEOS = new BooleanSetting("revanced_hide_related_videos", FALSE); + public static final BooleanSetting HIDE_SEARCH_RESULT_SHELF_HEADER = new BooleanSetting("revanced_hide_search_result_shelf_header", FALSE); + public static final BooleanSetting HIDE_SHORTS_BUTTON = new BooleanSetting("revanced_hide_shorts_button", TRUE, true); + public static final BooleanSetting HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_subscribers_community_guidelines", TRUE); + public static final BooleanSetting HIDE_SUBSCRIPTIONS_BUTTON = new BooleanSetting("revanced_hide_subscriptions_button", FALSE, true); + public static final BooleanSetting HIDE_TIMED_REACTIONS = new BooleanSetting("revanced_hide_timed_reactions", TRUE); + public static final BooleanSetting HIDE_TIMESTAMP = new BooleanSetting("revanced_hide_timestamp", FALSE); + public static final BooleanSetting HIDE_VIDEO_CHANNEL_WATERMARK = new BooleanSetting("revanced_hide_channel_watermark", TRUE); + public static final BooleanSetting HIDE_FOR_YOU_SHELF = new BooleanSetting("revanced_hide_for_you_shelf", TRUE); + public static final BooleanSetting HIDE_VIDEO_QUALITY_MENU_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", TRUE); + public static final BooleanSetting HIDE_SEARCH_RESULT_RECOMMENDATIONS = new BooleanSetting("revanced_hide_search_result_recommendations", TRUE); + public static final IntegerSetting PLAYER_OVERLAY_OPACITY = new IntegerSetting("revanced_player_overlay_opacity",100, true); + public static final BooleanSetting PLAYER_POPUP_PANELS = new BooleanSetting("revanced_hide_player_popup_panels", FALSE); + 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", "17.08.35", true, parent(SPOOF_APP_VERSION)); + public static final BooleanSetting SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON = new BooleanSetting("revanced_switch_create_with_notifications_button", TRUE, true); + public static final BooleanSetting TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_user_dialog_message"); + public static final BooleanSetting USE_TABLET_MINIPLAYER = new BooleanSetting("revanced_tablet_miniplayer", FALSE, true); + public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true); + public static final StringSetting START_PAGE = new StringSetting("revanced_start_page", ""); + + // Description + public static final BooleanSetting HIDE_CHAPTERS = new BooleanSetting("revanced_hide_chapters", TRUE); + public static final BooleanSetting HIDE_INFO_CARDS_SECTION = new BooleanSetting("revanced_hide_info_cards_section", TRUE); + public static final BooleanSetting HIDE_GAME_SECTION = new BooleanSetting("revanced_hide_game_section", TRUE); + public static final BooleanSetting HIDE_MUSIC_SECTION = new BooleanSetting("revanced_hide_music_section", TRUE); + public static final BooleanSetting HIDE_PODCAST_SECTION = new BooleanSetting("revanced_hide_podcast_section", TRUE); + public static final BooleanSetting HIDE_TRANSCIPT_SECTION = new BooleanSetting("revanced_hide_transcript_section", TRUE); + + // Shorts + public static final BooleanSetting HIDE_SHORTS = new BooleanSetting("revanced_hide_shorts", FALSE, true); + public static final BooleanSetting HIDE_SHORTS_JOIN_BUTTON = new BooleanSetting("revanced_hide_shorts_join_button", TRUE); + public static final BooleanSetting HIDE_SHORTS_SUBSCRIBE_BUTTON = new BooleanSetting("revanced_hide_shorts_subscribe_button", TRUE); + public static final BooleanSetting HIDE_SHORTS_SUBSCRIBE_BUTTON_PAUSED = new BooleanSetting("revanced_hide_shorts_subscribe_button_paused", FALSE); + public static final BooleanSetting HIDE_SHORTS_THANKS_BUTTON = new BooleanSetting("revanced_hide_shorts_thanks_button", TRUE); + public static final BooleanSetting HIDE_SHORTS_COMMENTS_BUTTON = new BooleanSetting("revanced_hide_shorts_comments_button", FALSE); + public static final BooleanSetting HIDE_SHORTS_REMIX_BUTTON = new BooleanSetting("revanced_hide_shorts_remix_button", TRUE); + public static final BooleanSetting HIDE_SHORTS_SHARE_BUTTON = new BooleanSetting("revanced_hide_shorts_share_button", FALSE); + public static final BooleanSetting HIDE_SHORTS_INFO_PANEL = new BooleanSetting("revanced_hide_shorts_info_panel", TRUE); + public static final BooleanSetting HIDE_SHORTS_SOUND_BUTTON = new BooleanSetting("revanced_hide_shorts_sound_button", FALSE); + public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE); + public static final BooleanSetting HIDE_SHORTS_NAVIGATION_BAR = new BooleanSetting("revanced_hide_shorts_navigation_bar", TRUE, true); + + // Seekbar + public static final BooleanSetting RESTORE_OLD_SEEKBAR_THUMBNAILS = new BooleanSetting("revanced_restore_old_seekbar_thumbnails", TRUE); + public static final BooleanSetting HIDE_SEEKBAR = new BooleanSetting("revanced_hide_seekbar", FALSE); + public static final BooleanSetting HIDE_SEEKBAR_THUMBNAIL = new BooleanSetting("revanced_hide_seekbar_thumbnail", FALSE); + public static final BooleanSetting SEEKBAR_CUSTOM_COLOR = new BooleanSetting("revanced_seekbar_custom_color", TRUE, true); + public static final StringSetting SEEKBAR_CUSTOM_COLOR_VALUE = new StringSetting("revanced_seekbar_custom_color_value", "#FF0000", true, parent(SEEKBAR_CUSTOM_COLOR)); + + // Action buttons + public static final BooleanSetting HIDE_LIKE_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_like_dislike_button", FALSE); + public static final BooleanSetting HIDE_LIVE_CHAT_BUTTON = new BooleanSetting("revanced_hide_live_chat_button", FALSE); + public static final BooleanSetting HIDE_SHARE_BUTTON = new BooleanSetting("revanced_hide_share_button", FALSE); + public static final BooleanSetting HIDE_REPORT_BUTTON = new BooleanSetting("revanced_hide_report_button", FALSE); + public static final BooleanSetting HIDE_REMIX_BUTTON = new BooleanSetting("revanced_hide_remix_button", TRUE); + public static final BooleanSetting HIDE_DOWNLOAD_BUTTON = new BooleanSetting("revanced_hide_download_button", FALSE); + public static final BooleanSetting HIDE_THANKS_BUTTON = new BooleanSetting("revanced_hide_thanks_button", TRUE); + public static final BooleanSetting HIDE_CLIP_BUTTON = new BooleanSetting("revanced_hide_clip_button", TRUE); + public static final BooleanSetting HIDE_PLAYLIST_BUTTON = new BooleanSetting("revanced_hide_playlist_button", FALSE); + public static final BooleanSetting HIDE_SHOP_BUTTON = new BooleanSetting("revanced_hide_shop_button", TRUE); + + // Player flyout menu items + public static final BooleanSetting HIDE_CAPTIONS_MENU = new BooleanSetting("revanced_hide_player_flyout_captions", FALSE); + public static final BooleanSetting HIDE_ADDITIONAL_SETTINGS_MENU = new BooleanSetting("revanced_hide_player_flyout_additional_settings", FALSE); + public static final BooleanSetting HIDE_LOOP_VIDEO_MENU = new BooleanSetting("revanced_hide_player_flyout_loop_video", FALSE); + public static final BooleanSetting HIDE_AMBIENT_MODE_MENU = new BooleanSetting("revanced_hide_player_flyout_ambient_mode", FALSE); + public static final BooleanSetting HIDE_REPORT_MENU = new BooleanSetting("revanced_hide_player_flyout_report", TRUE); + public static final BooleanSetting HIDE_HELP_MENU = new BooleanSetting("revanced_hide_player_flyout_help", TRUE); + public static final BooleanSetting HIDE_SPEED_MENU = new BooleanSetting("revanced_hide_player_flyout_speed", FALSE); + public static final BooleanSetting HIDE_MORE_INFO_MENU = new BooleanSetting("revanced_hide_player_flyout_more_info", TRUE); + public static final BooleanSetting HIDE_AUDIO_TRACK_MENU = new BooleanSetting("revanced_hide_player_flyout_audio_track", FALSE); + public static final BooleanSetting HIDE_WATCH_IN_VR_MENU = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE); + + // Misc + public static final BooleanSetting AUTO_CAPTIONS = new BooleanSetting("revanced_auto_captions", FALSE); + public static final BooleanSetting DISABLE_ZOOM_HAPTICS = new BooleanSetting("revanced_disable_zoom_haptics", TRUE); + public static final BooleanSetting EXTERNAL_BROWSER = new BooleanSetting("revanced_external_browser", TRUE, true); + public static final BooleanSetting AUTO_REPEAT = new BooleanSetting("revanced_auto_repeat", FALSE); + public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", TRUE); + public static final BooleanSetting SLIDE_TO_SEEK = new BooleanSetting("revanced_slide_to_seek", FALSE); + public static final BooleanSetting DISABLE_PRECISE_SEEKING_GESTURE = new BooleanSetting("revanced_disable_precise_seeking_gesture", TRUE); + public static final BooleanSetting SPOOF_SIGNATURE = new BooleanSetting("revanced_spoof_signature_verification_enabled", TRUE, true, + "revanced_spoof_signature_verification_enabled_user_dialog_message"); + public static final BooleanSetting SPOOF_SIGNATURE_IN_FEED = new BooleanSetting("revanced_spoof_signature_in_feed_enabled", FALSE, false, + parent(SPOOF_SIGNATURE)); + public static final BooleanSetting SPOOF_STORYBOARD_RENDERER = new BooleanSetting("revanced_spoof_storyboard", TRUE, true, + parent(SPOOF_SIGNATURE)); + public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true); + public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE); + public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE); + public static final StringSetting ANNOUNCEMENT_CONSUMER = new StringSetting("revanced_announcement_consumer", "", false, false); + public static final StringSetting ANNOUNCEMENT_LAST_HASH = new StringSetting("revanced_announcement_last_hash", ""); + public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE); + public static final BooleanSetting REMOVE_VIEWER_DISCRETION_DIALOG= new BooleanSetting("revanced_remove_viewer_discretion_dialog", FALSE, + "revanced_remove_viewer_discretion_dialog_user_dialog_message"); + + // Swipe controls + public static final BooleanSetting SWIPE_BRIGHTNESS = new BooleanSetting("revanced_swipe_brightness", TRUE); + public static final BooleanSetting SWIPE_VOLUME = new BooleanSetting("revanced_swipe_volume", TRUE); + public static final BooleanSetting SWIPE_PRESS_TO_ENGAGE = new BooleanSetting("revanced_swipe_press_to_engage", FALSE, true, + parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); + public static final BooleanSetting SWIPE_HAPTIC_FEEDBACK = new BooleanSetting("revanced_swipe_haptic_feedback", TRUE, true, + parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); + public static final IntegerSetting SWIPE_MAGNITUDE_THRESHOLD = new IntegerSetting("revanced_swipe_threshold", 30, true, + parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); + public static final IntegerSetting SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127, true, + parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); + public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_text_overlay_size", 22, true, + parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); + public static final LongSetting SWIPE_OVERLAY_TIMEOUT = new LongSetting("revanced_swipe_overlay_timeout", 500L, true, + parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); + public static final BooleanSetting SWIPE_SAVE_AND_RESTORE_BRIGHTNESS = new BooleanSetting("revanced_swipe_save_and_restore_brightness", TRUE, true, + parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME)); + + // Debugging + public static final BooleanSetting DEBUG_PROTOBUFFER = new BooleanSetting("revanced_debug_protobuffer", FALSE, parent(BaseSettings.DEBUG)); + + // ReturnYoutubeDislike + public static final BooleanSetting RYD_ENABLED = new BooleanSetting("ryd_enabled", TRUE); + public static final StringSetting RYD_USER_ID = new StringSetting("ryd_user_id", "", false, false); + public static final BooleanSetting RYD_SHORTS = new BooleanSetting("ryd_shorts", TRUE, parent(RYD_ENABLED)); + public static final BooleanSetting RYD_DISLIKE_PERCENTAGE = new BooleanSetting("ryd_dislike_percentage", FALSE, parent(RYD_ENABLED)); + public static final BooleanSetting RYD_COMPACT_LAYOUT = new BooleanSetting("ryd_compact_layout", FALSE, parent(RYD_ENABLED)); + public static final BooleanSetting RYD_TOAST_ON_CONNECTION_ERROR = new BooleanSetting("ryd_toast_on_connection_error", TRUE, parent(RYD_ENABLED)); + + // SponsorBlock + public static final BooleanSetting SB_ENABLED = new BooleanSetting("sb_enabled", TRUE); + /** + * Do not use directly, instead use {@link SponsorBlockSettings} + */ + public static final StringSetting SB_PRIVATE_USER_ID = new StringSetting("sb_private_user_id_Do_Not_Share", ""); + public static final StringSetting DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING = new StringSetting("uuid", ""); // Delete sometime in 2024 + public static final IntegerSetting SB_CREATE_NEW_SEGMENT_STEP = new IntegerSetting("sb_create_new_segment_step", 150, parent(SB_ENABLED)); + public static final BooleanSetting SB_VOTING_BUTTON = new BooleanSetting("sb_voting_button", FALSE, parent(SB_ENABLED)); + public static final BooleanSetting SB_CREATE_NEW_SEGMENT = new BooleanSetting("sb_create_new_segment", FALSE, parent(SB_ENABLED)); + public static final BooleanSetting SB_COMPACT_SKIP_BUTTON = new BooleanSetting("sb_compact_skip_button", FALSE, parent(SB_ENABLED)); + public static final BooleanSetting SB_AUTO_HIDE_SKIP_BUTTON = new BooleanSetting("sb_auto_hide_skip_button", TRUE, parent(SB_ENABLED)); + public static final BooleanSetting SB_TOAST_ON_SKIP = new BooleanSetting("sb_toast_on_skip", TRUE, parent(SB_ENABLED)); + public static final BooleanSetting SB_TOAST_ON_CONNECTION_ERROR = new BooleanSetting("sb_toast_on_connection_error", TRUE, parent(SB_ENABLED)); + public static final BooleanSetting SB_TRACK_SKIP_COUNT = new BooleanSetting("sb_track_skip_count", TRUE, parent(SB_ENABLED)); + public static final FloatSetting SB_SEGMENT_MIN_DURATION = new FloatSetting("sb_min_segment_duration", 0F, parent(SB_ENABLED)); + public static final BooleanSetting SB_VIDEO_LENGTH_WITHOUT_SEGMENTS = new BooleanSetting("sb_video_length_without_segments", TRUE, parent(SB_ENABLED)); + public static final StringSetting SB_API_URL = new StringSetting("sb_api_url","https://sponsor.ajay.app"); + public static final BooleanSetting SB_USER_IS_VIP = new BooleanSetting("sb_user_is_vip", FALSE); + public static final IntegerSetting SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS = new IntegerSetting("sb_local_time_saved_number_segments", 0); + public static final LongSetting SB_LOCAL_TIME_SAVED_MILLISECONDS = new LongSetting("sb_local_time_saved_milliseconds", 0L); + + public static final StringSetting SB_CATEGORY_SPONSOR = new StringSetting("sb_sponsor", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue); + public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color","#00D400"); + public static final StringSetting SB_CATEGORY_SELF_PROMO = new StringSetting("sb_selfpromo", MANUAL_SKIP.reVancedKeyValue); + public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color","#FFFF00"); + public static final StringSetting SB_CATEGORY_INTERACTION = new StringSetting("sb_interaction", MANUAL_SKIP.reVancedKeyValue); + public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color","#CC00FF"); + 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 StringSetting SB_CATEGORY_INTRO = new StringSetting("sb_intro", MANUAL_SKIP.reVancedKeyValue); + public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color","#00FFFF"); + public static final StringSetting SB_CATEGORY_OUTRO = new StringSetting("sb_outro", MANUAL_SKIP.reVancedKeyValue); + public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color","#0202ED"); + public static final StringSetting SB_CATEGORY_PREVIEW = new StringSetting("sb_preview", IGNORE.reVancedKeyValue); + public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color","#008FD6"); + public static final StringSetting SB_CATEGORY_FILLER = new StringSetting("sb_filler", IGNORE.reVancedKeyValue); + public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color","#7300FF"); + 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 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"); + + // SB Setting not exported + public static final LongSetting SB_LAST_VIP_CHECK = new LongSetting("sb_last_vip_check", 0L, false, false); + public static final BooleanSetting SB_HIDE_EXPORT_WARNING = new BooleanSetting("sb_hide_export_warning", FALSE, false, false); + public static final BooleanSetting SB_SEEN_GUIDELINES = new BooleanSetting("sb_seen_guidelines", FALSE, false, false); + + static { + // region Migration + + // region Migrate settings from old Preference categories into replacement "revanced_prefs" category. + // This region must run before all other migration code. + + // The YT and RYD migration portion of this can be removed anytime, + // but the SB migration should remain until late 2024 or early 2025 + // because it migrates the SB private user id which cannot be recovered if lost. + + // Categories were previously saved without a 'sb_' key prefix, so they need an additional adjustment. + Set> sbCategories = new HashSet<>(Arrays.asList( + SB_CATEGORY_SPONSOR, + SB_CATEGORY_SPONSOR_COLOR, + SB_CATEGORY_SELF_PROMO, + SB_CATEGORY_SELF_PROMO_COLOR, + SB_CATEGORY_INTERACTION, + SB_CATEGORY_INTERACTION_COLOR, + SB_CATEGORY_HIGHLIGHT, + SB_CATEGORY_HIGHLIGHT_COLOR, + SB_CATEGORY_INTRO, + SB_CATEGORY_INTRO_COLOR, + SB_CATEGORY_OUTRO, + SB_CATEGORY_OUTRO_COLOR, + SB_CATEGORY_PREVIEW, + SB_CATEGORY_PREVIEW_COLOR, + SB_CATEGORY_FILLER, + SB_CATEGORY_FILLER_COLOR, + SB_CATEGORY_MUSIC_OFFTOPIC, + SB_CATEGORY_MUSIC_OFFTOPIC_COLOR, + SB_CATEGORY_UNSUBMITTED, + SB_CATEGORY_UNSUBMITTED_COLOR)); + + SharedPrefCategory ytPrefs = new SharedPrefCategory("youtube"); + SharedPrefCategory rydPrefs = new SharedPrefCategory("ryd"); + SharedPrefCategory sbPrefs = new SharedPrefCategory("sponsor-block"); + for (Setting setting : Setting.allLoadedSettings()) { + String key = setting.key; + if (setting.key.startsWith("sb_")) { + if (sbCategories.contains(setting)) { + key = key.substring(3); // Remove the "sb_" prefix, as old categories are saved without it. + } + migrateFromOldPreferences(sbPrefs, setting, key); + } else if (setting.key.startsWith("ryd_")) { + migrateFromOldPreferences(rydPrefs, setting, key); + } else { + migrateFromOldPreferences(ytPrefs, setting, key); + } + } + // end region + + + // Do _not_ delete this SB private user id migration property until sometime in 2024. + // This is the only setting that cannot be reconfigured if lost, + // and more time should be given for users who rarely upgrade. + migrateOldSettingToNew(DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING, SB_PRIVATE_USER_ID); + + // This migration may need to remain here for a while. + // Older online guides will still reference using commas, + // and this code will automatically convert anything the user enters to newline format, + // and also migrate any imported older settings that using commas. + String componentsToFilter = Settings.CUSTOM_FILTER_STRINGS.get(); + if (componentsToFilter.contains(",")) { + Logger.printInfo(() -> "Migrating custom filter strings to new line format"); + Settings.CUSTOM_FILTER_STRINGS.save(componentsToFilter.replace(",", "\n")); + } + + // endregion + } +} diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/AlternativeThumbnailsAboutDeArrowPreference.java b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/AlternativeThumbnailsAboutDeArrowPreference.java similarity index 95% rename from app/src/main/java/app/revanced/integrations/settingsmenu/AlternativeThumbnailsAboutDeArrowPreference.java rename to app/src/main/java/app/revanced/integrations/youtube/settings/preference/AlternativeThumbnailsAboutDeArrowPreference.java index 353f40cc1e..b631e2e106 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/AlternativeThumbnailsAboutDeArrowPreference.java +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/AlternativeThumbnailsAboutDeArrowPreference.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.settingsmenu; +package app.revanced.integrations.youtube.settings.preference; import android.content.Context; import android.content.Intent; diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/AlternativeThumbnailsStatusPreference.java b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/AlternativeThumbnailsStatusPreference.java similarity index 71% rename from app/src/main/java/app/revanced/integrations/settingsmenu/AlternativeThumbnailsStatusPreference.java rename to app/src/main/java/app/revanced/integrations/youtube/settings/preference/AlternativeThumbnailsStatusPreference.java index 97dc6d532a..fc81cdc5bd 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/AlternativeThumbnailsStatusPreference.java +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/AlternativeThumbnailsStatusPreference.java @@ -1,17 +1,16 @@ -package app.revanced.integrations.settingsmenu; - -import static app.revanced.integrations.utils.StringRef.str; +package app.revanced.integrations.youtube.settings.preference; import android.content.Context; import android.content.SharedPreferences; import android.preference.Preference; import android.preference.PreferenceManager; import android.util.AttributeSet; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.settings.Setting; +import app.revanced.integrations.youtube.settings.Settings; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.settings.SharedPrefCategory; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import static app.revanced.integrations.shared.StringRef.str; /** * Shows what thumbnails will be used based on the current settings. @@ -25,7 +24,7 @@ public class AlternativeThumbnailsStatusPreference extends Preference { // // Push this call to the end of the main run queue, // so all other listeners are done and SettingsEnum is up to date. - ReVancedUtils.runOnMainThread(this::updateUI); + Utils.runOnMainThread(this::updateUI); }; public AlternativeThumbnailsStatusPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { @@ -42,13 +41,13 @@ public AlternativeThumbnailsStatusPreference(Context context) { } private void addChangeListener() { - LogHelper.printDebug(() -> "addChangeListener"); - SharedPrefCategory.YOUTUBE.preferences.registerOnSharedPreferenceChangeListener(listener); + Logger.printDebug(() -> "addChangeListener"); + Setting.preferences.preferences.registerOnSharedPreferenceChangeListener(listener); } private void removeChangeListener() { - LogHelper.printDebug(() -> "removeChangeListener"); - SharedPrefCategory.YOUTUBE.preferences.unregisterOnSharedPreferenceChangeListener(listener); + Logger.printDebug(() -> "removeChangeListener"); + Setting.preferences.preferences.unregisterOnSharedPreferenceChangeListener(listener); } @Override @@ -65,9 +64,9 @@ protected void onPrepareForRemoval() { } private void updateUI() { - LogHelper.printDebug(() -> "updateUI"); - final boolean usingDeArrow = SettingsEnum.ALT_THUMBNAIL_DEARROW.getBoolean(); - final boolean usingVideoStills = SettingsEnum.ALT_THUMBNAIL_STILLS.getBoolean(); + Logger.printDebug(() -> "updateUI"); + final boolean usingDeArrow = Settings.ALT_THUMBNAIL_DEARROW.get(); + final boolean usingVideoStills = Settings.ALT_THUMBNAIL_STILLS.get(); final String summaryTextKey; if (usingDeArrow && usingVideoStills) { diff --git a/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ReVancedPreferenceFragment.java b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ReVancedPreferenceFragment.java new file mode 100644 index 0000000000..5542d61a60 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ReVancedPreferenceFragment.java @@ -0,0 +1,25 @@ +package app.revanced.integrations.youtube.settings.preference; + +import android.preference.ListPreference; +import android.preference.Preference; +import app.revanced.integrations.shared.settings.preference.AbstractPreferenceFragment; +import app.revanced.integrations.youtube.patches.playback.speed.CustomPlaybackSpeedPatch; +import app.revanced.integrations.youtube.settings.Settings; + +/** + * Preference fragment for ReVanced settings. + * + * @noinspection deprecation + */ +public class ReVancedPreferenceFragment extends AbstractPreferenceFragment { + @Override + protected void initialize() { + super.initialize(); + + // If the preference was included, then initialize it based on the available playback speed + Preference defaultSpeedPreference = findPreference(Settings.PLAYBACK_SPEED_DEFAULT.key); + if (defaultSpeedPreference instanceof ListPreference) { + CustomPlaybackSpeedPatch.initializeListPreference((ListPreference) defaultSpeedPreference); + } + } +} diff --git a/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ReturnYouTubeDislikePreferenceFragment.java b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ReturnYouTubeDislikePreferenceFragment.java new file mode 100644 index 0000000000..50b0a78bb8 --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/ReturnYouTubeDislikePreferenceFragment.java @@ -0,0 +1,238 @@ +package app.revanced.integrations.youtube.settings.preference; + +import static app.revanced.integrations.shared.StringRef.str; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.PreferenceCategory; +import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; +import android.preference.PreferenceScreen; +import android.preference.SwitchPreference; + +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.settings.Setting; +import app.revanced.integrations.shared.settings.BaseSettings; +import app.revanced.integrations.youtube.patches.ReturnYouTubeDislikePatch; +import app.revanced.integrations.youtube.returnyoutubedislike.ReturnYouTubeDislike; +import app.revanced.integrations.youtube.returnyoutubedislike.requests.ReturnYouTubeDislikeApi; +import app.revanced.integrations.youtube.settings.Settings; + +/** @noinspection deprecation*/ +public class ReturnYouTubeDislikePreferenceFragment extends PreferenceFragment { + + /** + * If dislikes are shown on Shorts. + */ + private SwitchPreference shortsPreference; + + /** + * If dislikes are shown as percentage. + */ + private SwitchPreference percentagePreference; + + /** + * If segmented like/dislike button uses smaller compact layout. + */ + private SwitchPreference compactLayoutPreference; + + /** + * If segmented like/dislike button uses smaller compact layout. + */ + private SwitchPreference toastOnRYDNotAvailable; + + private void updateUIState() { + shortsPreference.setEnabled(Settings.RYD_SHORTS.isAvailable()); + percentagePreference.setEnabled(Settings.RYD_DISLIKE_PERCENTAGE.isAvailable()); + compactLayoutPreference.setEnabled(Settings.RYD_COMPACT_LAYOUT.isAvailable()); + toastOnRYDNotAvailable.setEnabled(Settings.RYD_TOAST_ON_CONNECTION_ERROR.isAvailable()); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + try { + Activity context = getActivity(); + PreferenceManager manager = getPreferenceManager(); + manager.setSharedPreferencesName(Setting.preferences.name); + PreferenceScreen preferenceScreen = manager.createPreferenceScreen(context); + setPreferenceScreen(preferenceScreen); + + SwitchPreference enabledPreference = new SwitchPreference(context); + enabledPreference.setChecked(Settings.RYD_ENABLED.get()); + enabledPreference.setTitle(str("revanced_ryd_enable_title")); + enabledPreference.setSummaryOn(str("revanced_ryd_enable_summary_on")); + enabledPreference.setSummaryOff(str("revanced_ryd_enable_summary_off")); + enabledPreference.setOnPreferenceChangeListener((pref, newValue) -> { + final Boolean rydIsEnabled = (Boolean) newValue; + Settings.RYD_ENABLED.save(rydIsEnabled); + ReturnYouTubeDislikePatch.onRYDStatusChange(rydIsEnabled); + + updateUIState(); + return true; + }); + preferenceScreen.addPreference(enabledPreference); + + shortsPreference = new SwitchPreference(context); + shortsPreference.setChecked(Settings.RYD_SHORTS.get()); + shortsPreference.setTitle(str("revanced_ryd_shorts_title")); + String shortsSummary = str("revanced_ryd_shorts_summary_on", + ReturnYouTubeDislikePatch.IS_SPOOFING_TO_NON_LITHO_SHORTS_PLAYER + ? "" + : "\n\n" + str("revanced_ryd_shorts_summary_disclaimer")); + shortsPreference.setSummaryOn(shortsSummary); + shortsPreference.setSummaryOff(str("revanced_ryd_shorts_summary_off")); + shortsPreference.setOnPreferenceChangeListener((pref, newValue) -> { + Settings.RYD_SHORTS.save((Boolean) newValue); + updateUIState(); + return true; + }); + preferenceScreen.addPreference(shortsPreference); + + percentagePreference = new SwitchPreference(context); + percentagePreference.setChecked(Settings.RYD_DISLIKE_PERCENTAGE.get()); + percentagePreference.setTitle(str("revanced_ryd_dislike_percentage_title")); + percentagePreference.setSummaryOn(str("revanced_ryd_dislike_percentage_summary_on")); + percentagePreference.setSummaryOff(str("revanced_ryd_dislike_percentage_summary_off")); + percentagePreference.setOnPreferenceChangeListener((pref, newValue) -> { + Settings.RYD_DISLIKE_PERCENTAGE.save((Boolean) newValue); + ReturnYouTubeDislike.clearAllUICaches(); + updateUIState(); + return true; + }); + preferenceScreen.addPreference(percentagePreference); + + compactLayoutPreference = new SwitchPreference(context); + compactLayoutPreference.setChecked(Settings.RYD_COMPACT_LAYOUT.get()); + compactLayoutPreference.setTitle(str("revanced_ryd_compact_layout_title")); + compactLayoutPreference.setSummaryOn(str("revanced_ryd_compact_layout_summary_on")); + compactLayoutPreference.setSummaryOff(str("revanced_ryd_compact_layout_summary_off")); + compactLayoutPreference.setOnPreferenceChangeListener((pref, newValue) -> { + Settings.RYD_COMPACT_LAYOUT.save((Boolean) newValue); + ReturnYouTubeDislike.clearAllUICaches(); + updateUIState(); + return true; + }); + preferenceScreen.addPreference(compactLayoutPreference); + + toastOnRYDNotAvailable = new SwitchPreference(context); + toastOnRYDNotAvailable.setChecked(Settings.RYD_TOAST_ON_CONNECTION_ERROR.get()); + toastOnRYDNotAvailable.setTitle(str("revanced_ryd_toast_on_connection_error_title")); + toastOnRYDNotAvailable.setSummaryOn(str("revanced_ryd_toast_on_connection_error_summary_on")); + toastOnRYDNotAvailable.setSummaryOff(str("revanced_ryd_toast_on_connection_error_summary_off")); + toastOnRYDNotAvailable.setOnPreferenceChangeListener((pref, newValue) -> { + Settings.RYD_TOAST_ON_CONNECTION_ERROR.save((Boolean) newValue); + updateUIState(); + return true; + }); + preferenceScreen.addPreference(toastOnRYDNotAvailable); + + updateUIState(); + + + // About category + + PreferenceCategory aboutCategory = new PreferenceCategory(context); + aboutCategory.setTitle(str("revanced_ryd_about")); + preferenceScreen.addPreference(aboutCategory); + + // ReturnYouTubeDislike Website + + Preference aboutWebsitePreference = new Preference(context); + aboutWebsitePreference.setTitle(str("revanced_ryd_attribution_title")); + aboutWebsitePreference.setSummary(str("revanced_ryd_attribution_summary")); + aboutWebsitePreference.setOnPreferenceClickListener(pref -> { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse("https://returnyoutubedislike.com")); + pref.getContext().startActivity(i); + return false; + }); + preferenceScreen.addPreference(aboutWebsitePreference); + + // RYD API connection statistics + + if (BaseSettings.DEBUG.get()) { + PreferenceCategory emptyCategory = new PreferenceCategory(context); // vertical padding + preferenceScreen.addPreference(emptyCategory); + + PreferenceCategory statisticsCategory = new PreferenceCategory(context); + statisticsCategory.setTitle(str("revanced_ryd_statistics_category_title")); + preferenceScreen.addPreference(statisticsCategory); + + Preference statisticPreference; + + statisticPreference = new Preference(context); + statisticPreference.setSelectable(false); + statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeAverage_title")); + statisticPreference.setSummary(createMillisecondStringFromNumber(ReturnYouTubeDislikeApi.getFetchCallResponseTimeAverage())); + preferenceScreen.addPreference(statisticPreference); + + statisticPreference = new Preference(context); + statisticPreference.setSelectable(false); + statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeMin_title")); + statisticPreference.setSummary(createMillisecondStringFromNumber(ReturnYouTubeDislikeApi.getFetchCallResponseTimeMin())); + preferenceScreen.addPreference(statisticPreference); + + statisticPreference = new Preference(context); + statisticPreference.setSelectable(false); + statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeMax_title")); + statisticPreference.setSummary(createMillisecondStringFromNumber(ReturnYouTubeDislikeApi.getFetchCallResponseTimeMax())); + preferenceScreen.addPreference(statisticPreference); + + String fetchCallTimeWaitingLastSummary; + final long fetchCallTimeWaitingLast = ReturnYouTubeDislikeApi.getFetchCallResponseTimeLast(); + if (fetchCallTimeWaitingLast == ReturnYouTubeDislikeApi.FETCH_CALL_RESPONSE_TIME_VALUE_RATE_LIMIT) { + fetchCallTimeWaitingLastSummary = str("revanced_ryd_statistics_getFetchCallResponseTimeLast_rate_limit_summary"); + } else { + fetchCallTimeWaitingLastSummary = createMillisecondStringFromNumber(fetchCallTimeWaitingLast); + } + statisticPreference = new Preference(context); + statisticPreference.setSelectable(false); + statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeLast_title")); + statisticPreference.setSummary(fetchCallTimeWaitingLastSummary); + preferenceScreen.addPreference(statisticPreference); + + statisticPreference = new Preference(context); + statisticPreference.setSelectable(false); + statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallCount_title")); + statisticPreference.setSummary(createSummaryText(ReturnYouTubeDislikeApi.getFetchCallCount(), + "revanced_ryd_statistics_getFetchCallCount_zero_summary", + "revanced_ryd_statistics_getFetchCallCount_non_zero_summary")); + preferenceScreen.addPreference(statisticPreference); + + statisticPreference = new Preference(context); + statisticPreference.setSelectable(false); + statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallNumberOfFailures_title")); + statisticPreference.setSummary(createSummaryText(ReturnYouTubeDislikeApi.getFetchCallNumberOfFailures(), + "revanced_ryd_statistics_getFetchCallNumberOfFailures_zero_summary", + "revanced_ryd_statistics_getFetchCallNumberOfFailures_non_zero_summary")); + preferenceScreen.addPreference(statisticPreference); + + statisticPreference = new Preference(context); + statisticPreference.setSelectable(false); + statisticPreference.setTitle(str("revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_title")); + statisticPreference.setSummary(createSummaryText(ReturnYouTubeDislikeApi.getNumberOfRateLimitRequestsEncountered(), + "revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_zero_summary", + "revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_non_zero_summary")); + preferenceScreen.addPreference(statisticPreference); + } + } catch (Exception ex) { + Logger.printException(() -> "onCreate failure", ex); + } + } + + private static String createSummaryText(int value, String summaryStringZeroKey, String summaryStringOneOrMoreKey) { + if (value == 0) { + return str(summaryStringZeroKey); + } + return String.format(str(summaryStringOneOrMoreKey), value); + } + + private static String createMillisecondStringFromNumber(long number) { + return String.format(str("revanced_ryd_statistics_millisecond_text"), number); + } + +} diff --git a/app/src/main/java/app/revanced/integrations/settingsmenu/SponsorBlockSettingsFragment.java b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/SponsorBlockPreferenceFragment.java similarity index 61% rename from app/src/main/java/app/revanced/integrations/settingsmenu/SponsorBlockSettingsFragment.java rename to app/src/main/java/app/revanced/integrations/youtube/settings/preference/SponsorBlockPreferenceFragment.java index 2257f82d13..137509d862 100644 --- a/app/src/main/java/app/revanced/integrations/settingsmenu/SponsorBlockSettingsFragment.java +++ b/app/src/main/java/app/revanced/integrations/youtube/settings/preference/SponsorBlockPreferenceFragment.java @@ -1,7 +1,4 @@ -package app.revanced.integrations.settingsmenu; - -import static android.text.Html.fromHtml; -import static app.revanced.integrations.utils.StringRef.str; +package app.revanced.integrations.youtube.settings.preference; import android.app.Activity; import android.app.AlertDialog; @@ -11,36 +8,31 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; -import android.preference.EditTextPreference; -import android.preference.Preference; -import android.preference.PreferenceCategory; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.preference.PreferenceScreen; -import android.preference.SwitchPreference; +import android.preference.*; import android.text.Html; import android.text.InputType; import android.util.TypedValue; import android.widget.EditText; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.settings.Setting; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.sponsorblock.SegmentPlaybackController; +import app.revanced.integrations.youtube.sponsorblock.SponsorBlockSettings; +import app.revanced.integrations.youtube.sponsorblock.SponsorBlockUtils; +import app.revanced.integrations.youtube.sponsorblock.objects.SegmentCategory; +import app.revanced.integrations.youtube.sponsorblock.objects.SegmentCategoryListPreference; +import app.revanced.integrations.youtube.sponsorblock.objects.UserStats; +import app.revanced.integrations.youtube.sponsorblock.requests.SBRequester; +import app.revanced.integrations.youtube.sponsorblock.ui.SponsorBlockViewController; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.settings.SharedPrefCategory; -import app.revanced.integrations.sponsorblock.SegmentPlaybackController; -import app.revanced.integrations.sponsorblock.SponsorBlockSettings; -import app.revanced.integrations.sponsorblock.SponsorBlockUtils; -import app.revanced.integrations.sponsorblock.objects.SegmentCategory; -import app.revanced.integrations.sponsorblock.objects.SegmentCategoryListPreference; -import app.revanced.integrations.sponsorblock.objects.UserStats; -import app.revanced.integrations.sponsorblock.requests.SBRequester; -import app.revanced.integrations.sponsorblock.ui.SponsorBlockViewController; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import static android.text.Html.fromHtml; +import static app.revanced.integrations.shared.StringRef.str; @SuppressWarnings("deprecation") -public class SponsorBlockSettingsFragment extends PreferenceFragment { +public class SponsorBlockPreferenceFragment extends PreferenceFragment { private SwitchPreference sbEnabled; private SwitchPreference addNewSegment; @@ -63,62 +55,62 @@ public class SponsorBlockSettingsFragment extends PreferenceFragment { private void updateUI() { try { - final boolean enabled = SettingsEnum.SB_ENABLED.getBoolean(); + final boolean enabled = Settings.SB_ENABLED.get(); if (!enabled) { SponsorBlockViewController.hideAll(); SegmentPlaybackController.setCurrentVideoId(null); - } else if (!SettingsEnum.SB_CREATE_NEW_SEGMENT.getBoolean()) { + } else if (!Settings.SB_CREATE_NEW_SEGMENT.get()) { SponsorBlockViewController.hideNewSegmentLayout(); } // Voting and add new segment buttons automatically shows/hide themselves. sbEnabled.setChecked(enabled); - addNewSegment.setChecked(SettingsEnum.SB_CREATE_NEW_SEGMENT.getBoolean()); + addNewSegment.setChecked(Settings.SB_CREATE_NEW_SEGMENT.get()); addNewSegment.setEnabled(enabled); - votingEnabled.setChecked(SettingsEnum.SB_VOTING_BUTTON.getBoolean()); + votingEnabled.setChecked(Settings.SB_VOTING_BUTTON.get()); votingEnabled.setEnabled(enabled); - compactSkipButton.setChecked(SettingsEnum.SB_COMPACT_SKIP_BUTTON.getBoolean()); + compactSkipButton.setChecked(Settings.SB_COMPACT_SKIP_BUTTON.get()); compactSkipButton.setEnabled(enabled); - autoHideSkipSegmentButton.setChecked(SettingsEnum.SB_AUTO_HIDE_SKIP_BUTTON.getBoolean()); + autoHideSkipSegmentButton.setChecked(Settings.SB_AUTO_HIDE_SKIP_BUTTON.get()); autoHideSkipSegmentButton.setEnabled(enabled); - showSkipToast.setChecked(SettingsEnum.SB_TOAST_ON_SKIP.getBoolean()); + showSkipToast.setChecked(Settings.SB_TOAST_ON_SKIP.get()); showSkipToast.setEnabled(enabled); - toastOnConnectionError.setChecked(SettingsEnum.SB_TOAST_ON_CONNECTION_ERROR.getBoolean()); + toastOnConnectionError.setChecked(Settings.SB_TOAST_ON_CONNECTION_ERROR.get()); toastOnConnectionError.setEnabled(enabled); - trackSkips.setChecked(SettingsEnum.SB_TRACK_SKIP_COUNT.getBoolean()); + trackSkips.setChecked(Settings.SB_TRACK_SKIP_COUNT.get()); trackSkips.setEnabled(enabled); - showTimeWithoutSegments.setChecked(SettingsEnum.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.getBoolean()); + showTimeWithoutSegments.setChecked(Settings.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.get()); showTimeWithoutSegments.setEnabled(enabled); - newSegmentStep.setText(SettingsEnum.SB_CREATE_NEW_SEGMENT_STEP.getObjectValue().toString()); + newSegmentStep.setText((Settings.SB_CREATE_NEW_SEGMENT_STEP.get()).toString()); newSegmentStep.setEnabled(enabled); - minSegmentDuration.setText(SettingsEnum.SB_SEGMENT_MIN_DURATION.getObjectValue().toString()); + minSegmentDuration.setText((Settings.SB_SEGMENT_MIN_DURATION.get()).toString()); minSegmentDuration.setEnabled(enabled); - privateUserId.setText(SettingsEnum.SB_PRIVATE_USER_ID.getString()); + privateUserId.setText(Settings.SB_PRIVATE_USER_ID.get()); privateUserId.setEnabled(enabled); // If the user has a private user id, then include a subtext that mentions not to share it. String exportSummarySubText = SponsorBlockSettings.userHasSBPrivateId() - ? str("sb_settings_ie_sum_warning") + ? str("revanced_sb_settings_ie_sum_warning") : ""; - importExport.setSummary(str("sb_settings_ie_sum", exportSummarySubText)); + importExport.setSummary(str("revanced_sb_settings_ie_sum", exportSummarySubText)); apiUrl.setEnabled(enabled); importExport.setEnabled(enabled); segmentCategory.setEnabled(enabled); statsCategory.setEnabled(enabled); } catch (Exception ex) { - LogHelper.printException(() -> "update settings UI failure", ex); + Logger.printException(() -> "update settings UI failure", ex); } } @@ -126,21 +118,20 @@ private void updateUI() { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { - PreferenceManager preferenceManager = getPreferenceManager(); - preferenceManager.setSharedPreferencesName(SharedPrefCategory.SPONSOR_BLOCK.prefName); - - Activity context = this.getActivity(); - PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(context); + Activity context = getActivity(); + PreferenceManager manager = getPreferenceManager(); + manager.setSharedPreferencesName(Setting.preferences.name); + PreferenceScreen preferenceScreen = manager.createPreferenceScreen(context); setPreferenceScreen(preferenceScreen); SponsorBlockSettings.initialize(); sbEnabled = new SwitchPreference(context); - sbEnabled.setTitle(str("sb_enable_sb")); - sbEnabled.setSummary(str("sb_enable_sb_sum")); + sbEnabled.setTitle(str("revanced_sb_enable_sb")); + sbEnabled.setSummary(str("revanced_sb_enable_sb_sum")); preferenceScreen.addPreference(sbEnabled); sbEnabled.setOnPreferenceChangeListener((preference1, newValue) -> { - SettingsEnum.SB_ENABLED.saveValue(newValue); + Settings.SB_ENABLED.save((Boolean) newValue); updateUI(); return true; }); @@ -148,7 +139,7 @@ public void onCreate(Bundle savedInstanceState) { addAppearanceCategory(context, preferenceScreen); segmentCategory = new PreferenceCategory(context); - segmentCategory.setTitle(str("sb_diff_segments")); + segmentCategory.setTitle(str("revanced_sb_diff_segments")); preferenceScreen.addPreference(segmentCategory); updateSegmentCategories(); @@ -157,7 +148,7 @@ public void onCreate(Bundle savedInstanceState) { addGeneralCategory(context, preferenceScreen); statsCategory = new PreferenceCategory(context); - statsCategory.setTitle(str("sb_stats")); + statsCategory.setTitle(str("revanced_sb_stats")); preferenceScreen.addPreference(statsCategory); fetchAndDisplayStats(); @@ -165,69 +156,69 @@ public void onCreate(Bundle savedInstanceState) { updateUI(); } catch (Exception ex) { - LogHelper.printException(() -> "onCreate failure", ex); + Logger.printException(() -> "onCreate failure", ex); } } private void addAppearanceCategory(Context context, PreferenceScreen screen) { PreferenceCategory category = new PreferenceCategory(context); screen.addPreference(category); - category.setTitle(str("sb_appearance_category")); + category.setTitle(str("revanced_sb_appearance_category")); votingEnabled = new SwitchPreference(context); - votingEnabled.setTitle(str("sb_enable_voting")); - votingEnabled.setSummaryOn(str("sb_enable_voting_sum_on")); - votingEnabled.setSummaryOff(str("sb_enable_voting_sum_off")); + votingEnabled.setTitle(str("revanced_sb_enable_voting")); + votingEnabled.setSummaryOn(str("revanced_sb_enable_voting_sum_on")); + votingEnabled.setSummaryOff(str("revanced_sb_enable_voting_sum_off")); category.addPreference(votingEnabled); votingEnabled.setOnPreferenceChangeListener((preference1, newValue) -> { - SettingsEnum.SB_VOTING_BUTTON.saveValue(newValue); + Settings.SB_VOTING_BUTTON.save((Boolean) newValue); updateUI(); return true; }); compactSkipButton = new SwitchPreference(context); - compactSkipButton.setTitle(str("sb_enable_compact_skip_button")); - compactSkipButton.setSummaryOn(str("sb_enable_compact_skip_button_sum_on")); - compactSkipButton.setSummaryOff(str("sb_enable_compact_skip_button_sum_off")); + compactSkipButton.setTitle(str("revanced_sb_enable_compact_skip_button")); + compactSkipButton.setSummaryOn(str("revanced_sb_enable_compact_skip_button_sum_on")); + compactSkipButton.setSummaryOff(str("revanced_sb_enable_compact_skip_button_sum_off")); category.addPreference(compactSkipButton); compactSkipButton.setOnPreferenceChangeListener((preference1, newValue) -> { - SettingsEnum.SB_COMPACT_SKIP_BUTTON.saveValue(newValue); + Settings.SB_COMPACT_SKIP_BUTTON.save((Boolean) newValue); updateUI(); return true; }); autoHideSkipSegmentButton = new SwitchPreference(context); - autoHideSkipSegmentButton.setTitle(str("sb_enable_auto_hide_skip_segment_button")); - autoHideSkipSegmentButton.setSummaryOn(str("sb_enable_auto_hide_skip_segment_button_sum_on")); - autoHideSkipSegmentButton.setSummaryOff(str("sb_enable_auto_hide_skip_segment_button_sum_off")); + autoHideSkipSegmentButton.setTitle(str("revanced_sb_enable_auto_hide_skip_segment_button")); + autoHideSkipSegmentButton.setSummaryOn(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_on")); + autoHideSkipSegmentButton.setSummaryOff(str("revanced_sb_enable_auto_hide_skip_segment_button_sum_off")); category.addPreference(autoHideSkipSegmentButton); autoHideSkipSegmentButton.setOnPreferenceChangeListener((preference1, newValue) -> { - SettingsEnum.SB_AUTO_HIDE_SKIP_BUTTON.saveValue(newValue); + Settings.SB_AUTO_HIDE_SKIP_BUTTON.save((Boolean) newValue); updateUI(); return true; }); showSkipToast = new SwitchPreference(context); - showSkipToast.setTitle(str("sb_general_skiptoast")); - showSkipToast.setSummaryOn(str("sb_general_skiptoast_sum_on")); - showSkipToast.setSummaryOff(str("sb_general_skiptoast_sum_off")); + showSkipToast.setTitle(str("revanced_sb_general_skiptoast")); + showSkipToast.setSummaryOn(str("revanced_sb_general_skiptoast_sum_on")); + showSkipToast.setSummaryOff(str("revanced_sb_general_skiptoast_sum_off")); showSkipToast.setOnPreferenceClickListener(preference1 -> { - ReVancedUtils.showToastShort(str("sb_skipped_sponsor")); + Utils.showToastShort(str("revanced_sb_skipped_sponsor")); return false; }); showSkipToast.setOnPreferenceChangeListener((preference1, newValue) -> { - SettingsEnum.SB_TOAST_ON_SKIP.saveValue(newValue); + Settings.SB_TOAST_ON_SKIP.save((Boolean) newValue); updateUI(); return true; }); category.addPreference(showSkipToast); showTimeWithoutSegments = new SwitchPreference(context); - showTimeWithoutSegments.setTitle(str("sb_general_time_without")); - showTimeWithoutSegments.setSummaryOn(str("sb_general_time_without_sum_on")); - showTimeWithoutSegments.setSummaryOff(str("sb_general_time_without_sum_off")); + showTimeWithoutSegments.setTitle(str("revanced_sb_general_time_without")); + showTimeWithoutSegments.setSummaryOn(str("revanced_sb_general_time_without_sum_on")); + showTimeWithoutSegments.setSummaryOff(str("revanced_sb_general_time_without_sum_off")); showTimeWithoutSegments.setOnPreferenceChangeListener((preference1, newValue) -> { - SettingsEnum.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.saveValue(newValue); + Settings.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.save((Boolean) newValue); updateUI(); return true; }); @@ -237,48 +228,48 @@ private void addAppearanceCategory(Context context, PreferenceScreen screen) { private void addCreateSegmentCategory(Context context, PreferenceScreen screen) { PreferenceCategory category = new PreferenceCategory(context); screen.addPreference(category); - category.setTitle(str("sb_create_segment_category")); + category.setTitle(str("revanced_sb_create_segment_category")); addNewSegment = new SwitchPreference(context); - addNewSegment.setTitle(str("sb_enable_create_segment")); - addNewSegment.setSummaryOn(str("sb_enable_create_segment_sum_on")); - addNewSegment.setSummaryOff(str("sb_enable_create_segment_sum_off")); + addNewSegment.setTitle(str("revanced_sb_enable_create_segment")); + addNewSegment.setSummaryOn(str("revanced_sb_enable_create_segment_sum_on")); + addNewSegment.setSummaryOff(str("revanced_sb_enable_create_segment_sum_off")); category.addPreference(addNewSegment); addNewSegment.setOnPreferenceChangeListener((preference1, o) -> { Boolean newValue = (Boolean) o; - if (newValue && !SettingsEnum.SB_SEEN_GUIDELINES.getBoolean()) { + if (newValue && !Settings.SB_SEEN_GUIDELINES.get()) { new AlertDialog.Builder(preference1.getContext()) - .setTitle(str("sb_guidelines_popup_title")) - .setMessage(str("sb_guidelines_popup_content")) - .setNegativeButton(str("sb_guidelines_popup_already_read"), null) - .setPositiveButton(str("sb_guidelines_popup_open"), (dialogInterface, i) -> openGuidelines()) - .setOnDismissListener(dialog -> SettingsEnum.SB_SEEN_GUIDELINES.saveValue(true)) + .setTitle(str("revanced_sb_guidelines_popup_title")) + .setMessage(str("revanced_sb_guidelines_popup_content")) + .setNegativeButton(str("revanced_sb_guidelines_popup_already_read"), null) + .setPositiveButton(str("revanced_sb_guidelines_popup_open"), (dialogInterface, i) -> openGuidelines()) + .setOnDismissListener(dialog -> Settings.SB_SEEN_GUIDELINES.save(true)) .setCancelable(false) .show(); } - SettingsEnum.SB_CREATE_NEW_SEGMENT.saveValue(newValue); + Settings.SB_CREATE_NEW_SEGMENT.save(newValue); updateUI(); return true; }); newSegmentStep = new EditTextPreference(context); - newSegmentStep.setTitle(str("sb_general_adjusting")); - newSegmentStep.setSummary(str("sb_general_adjusting_sum")); + newSegmentStep.setTitle(str("revanced_sb_general_adjusting")); + newSegmentStep.setSummary(str("revanced_sb_general_adjusting_sum")); newSegmentStep.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER); newSegmentStep.setOnPreferenceChangeListener((preference1, newValue) -> { final int newAdjustmentValue = Integer.parseInt(newValue.toString()); if (newAdjustmentValue == 0) { - ReVancedUtils.showToastLong(str("sb_general_adjusting_invalid")); + Utils.showToastLong(str("revanced_sb_general_adjusting_invalid")); return false; } - SettingsEnum.SB_CREATE_NEW_SEGMENT_STEP.saveValue(newAdjustmentValue); + Settings.SB_CREATE_NEW_SEGMENT_STEP.save(newAdjustmentValue); return true; }); category.addPreference(newSegmentStep); Preference guidelinePreferences = new Preference(context); - guidelinePreferences.setTitle(str("sb_guidelines_preference_title")); - guidelinePreferences.setSummary(str("sb_guidelines_preference_sum")); + guidelinePreferences.setTitle(str("revanced_sb_guidelines_preference_title")); + guidelinePreferences.setSummary(str("revanced_sb_guidelines_preference_sum")); guidelinePreferences.setOnPreferenceClickListener(preference1 -> { openGuidelines(); return true; @@ -289,50 +280,50 @@ private void addCreateSegmentCategory(Context context, PreferenceScreen screen) private void addGeneralCategory(final Context context, PreferenceScreen screen) { PreferenceCategory category = new PreferenceCategory(context); screen.addPreference(category); - category.setTitle(str("sb_general")); + category.setTitle(str("revanced_sb_general")); toastOnConnectionError = new SwitchPreference(context); - toastOnConnectionError.setTitle(str("sb_toast_on_connection_error_title")); - toastOnConnectionError.setSummaryOn(str("sb_toast_on_connection_error_summary_on")); - toastOnConnectionError.setSummaryOff(str("sb_toast_on_connection_error_summary_off")); + toastOnConnectionError.setTitle(str("revanced_sb_toast_on_connection_error_title")); + toastOnConnectionError.setSummaryOn(str("revanced_sb_toast_on_connection_error_summary_on")); + toastOnConnectionError.setSummaryOff(str("revanced_sb_toast_on_connection_error_summary_off")); toastOnConnectionError.setOnPreferenceChangeListener((preference1, newValue) -> { - SettingsEnum.SB_TOAST_ON_CONNECTION_ERROR.saveValue(newValue); + Settings.SB_TOAST_ON_CONNECTION_ERROR.save((Boolean) newValue); updateUI(); return true; }); category.addPreference(toastOnConnectionError); trackSkips = new SwitchPreference(context); - trackSkips.setTitle(str("sb_general_skipcount")); - trackSkips.setSummaryOn(str("sb_general_skipcount_sum_on")); - trackSkips.setSummaryOff(str("sb_general_skipcount_sum_off")); + trackSkips.setTitle(str("revanced_sb_general_skipcount")); + trackSkips.setSummaryOn(str("revanced_sb_general_skipcount_sum_on")); + trackSkips.setSummaryOff(str("revanced_sb_general_skipcount_sum_off")); trackSkips.setOnPreferenceChangeListener((preference1, newValue) -> { - SettingsEnum.SB_TRACK_SKIP_COUNT.saveValue(newValue); + Settings.SB_TRACK_SKIP_COUNT.save((Boolean) newValue); updateUI(); return true; }); category.addPreference(trackSkips); minSegmentDuration = new EditTextPreference(context); - minSegmentDuration.setTitle(str("sb_general_min_duration")); - minSegmentDuration.setSummary(str("sb_general_min_duration_sum")); + minSegmentDuration.setTitle(str("revanced_sb_general_min_duration")); + minSegmentDuration.setSummary(str("revanced_sb_general_min_duration_sum")); minSegmentDuration.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL); minSegmentDuration.setOnPreferenceChangeListener((preference1, newValue) -> { - SettingsEnum.SB_SEGMENT_MIN_DURATION.saveValue(Float.valueOf(newValue.toString())); + Settings.SB_SEGMENT_MIN_DURATION.save(Float.valueOf(newValue.toString())); return true; }); category.addPreference(minSegmentDuration); privateUserId = new EditTextPreference(context); - privateUserId.setTitle(str("sb_general_uuid")); - privateUserId.setSummary(str("sb_general_uuid_sum")); + privateUserId.setTitle(str("revanced_sb_general_uuid")); + privateUserId.setSummary(str("revanced_sb_general_uuid_sum")); privateUserId.setOnPreferenceChangeListener((preference1, newValue) -> { String newUUID = newValue.toString(); if (!SponsorBlockSettings.isValidSBUserId(newUUID)) { - ReVancedUtils.showToastLong(str("sb_general_uuid_invalid")); + Utils.showToastLong(str("revanced_sb_general_uuid_invalid")); return false; } - SettingsEnum.SB_PRIVATE_USER_ID.saveValue(newUUID); + Settings.SB_PRIVATE_USER_ID.save(newUUID); updateUI(); fetchAndDisplayStats(); return true; @@ -340,24 +331,24 @@ private void addGeneralCategory(final Context context, PreferenceScreen screen) category.addPreference(privateUserId); apiUrl = new Preference(context); - apiUrl.setTitle(str("sb_general_api_url")); - apiUrl.setSummary(Html.fromHtml(str("sb_general_api_url_sum"))); + apiUrl.setTitle(str("revanced_sb_general_api_url")); + apiUrl.setSummary(Html.fromHtml(str("revanced_sb_general_api_url_sum"))); apiUrl.setOnPreferenceClickListener(preference1 -> { EditText editText = new EditText(context); editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI); - editText.setText(SettingsEnum.SB_API_URL.getString()); + editText.setText(Settings.SB_API_URL.get()); DialogInterface.OnClickListener urlChangeListener = (dialog, buttonPressed) -> { if (buttonPressed == DialogInterface.BUTTON_NEUTRAL) { - SettingsEnum.SB_API_URL.resetToDefault(); - ReVancedUtils.showToastLong(str("sb_api_url_reset")); + Settings.SB_API_URL.resetToDefault(); + Utils.showToastLong(str("revanced_sb_api_url_reset")); } else if (buttonPressed == DialogInterface.BUTTON_POSITIVE) { String serverAddress = editText.getText().toString(); if (!SponsorBlockSettings.isValidSBServerAddress(serverAddress)) { - ReVancedUtils.showToastLong(str("sb_api_url_invalid")); - } else if (!serverAddress.equals(SettingsEnum.SB_API_URL.getString())) { - SettingsEnum.SB_API_URL.saveValue(serverAddress); - ReVancedUtils.showToastLong(str("sb_api_url_changed")); + Utils.showToastLong(str("revanced_sb_api_url_invalid")); + } else if (!serverAddress.equals(Settings.SB_API_URL.get())) { + Settings.SB_API_URL.save(serverAddress); + Utils.showToastLong(str("revanced_sb_api_url_changed")); } } }; @@ -365,7 +356,7 @@ private void addGeneralCategory(final Context context, PreferenceScreen screen) .setTitle(apiUrl.getTitle()) .setView(editText) .setNegativeButton(android.R.string.cancel, null) - .setNeutralButton(str("sb_reset"), urlChangeListener) + .setNeutralButton(str("revanced_sb_reset"), urlChangeListener) .setPositiveButton(android.R.string.ok, urlChangeListener) .show(); return true; @@ -374,12 +365,12 @@ private void addGeneralCategory(final Context context, PreferenceScreen screen) importExport = new EditTextPreference(context) { protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { - builder.setNeutralButton(str("sb_settings_copy"), (dialog, which) -> { - ReVancedUtils.setClipboard(getEditText().getText().toString()); + builder.setNeutralButton(str("revanced_sb_settings_copy"), (dialog, which) -> { + Utils.setClipboard(getEditText().getText().toString()); }); } }; - importExport.setTitle(str("sb_settings_ie")); + importExport.setTitle(str("revanced_sb_settings_ie")); // Summary is set in updateUI() importExport.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE @@ -389,11 +380,11 @@ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { } importExport.getEditText().setTextSize(TypedValue.COMPLEX_UNIT_PT, 8); importExport.setOnPreferenceClickListener(preference1 -> { - importExport.getEditText().setText(SponsorBlockSettings.exportSettings()); + importExport.getEditText().setText(SponsorBlockSettings.exportDesktopSettings()); return true; }); importExport.setOnPreferenceChangeListener((preference1, newValue) -> { - SponsorBlockSettings.importSettings((String) newValue); + SponsorBlockSettings.importDesktopSettings((String) newValue); updateSegmentCategories(); fetchAndDisplayStats(); updateUI(); @@ -411,20 +402,20 @@ private void updateSegmentCategories() { segmentCategory.addPreference(new SegmentCategoryListPreference(activity, category)); } } catch (Exception ex) { - LogHelper.printException(() -> "updateSegmentCategories failure", ex); + Logger.printException(() -> "updateSegmentCategories failure", ex); } } private void addAboutCategory(Context context, PreferenceScreen screen) { PreferenceCategory category = new PreferenceCategory(context); screen.addPreference(category); - category.setTitle(str("sb_about")); + category.setTitle(str("revanced_sb_about")); { Preference preference = new Preference(context); category.addPreference(preference); - preference.setTitle(str("sb_about_api")); - preference.setSummary(str("sb_about_api_sum")); + preference.setTitle(str("revanced_sb_about_api")); + preference.setSummary(str("revanced_sb_about_api_sum")); preference.setOnPreferenceClickListener(preference1 -> { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse("https://sponsor.ajay.app")); @@ -452,28 +443,28 @@ private void fetchAndDisplayStats() { Preference loadingPlaceholderPreference = new Preference(this.getActivity()); loadingPlaceholderPreference.setEnabled(false); statsCategory.addPreference(loadingPlaceholderPreference); - if (SettingsEnum.SB_ENABLED.getBoolean()) { - loadingPlaceholderPreference.setTitle(str("sb_stats_loading")); - ReVancedUtils.runOnBackgroundThread(() -> { + if (Settings.SB_ENABLED.get()) { + loadingPlaceholderPreference.setTitle(str("revanced_sb_stats_loading")); + Utils.runOnBackgroundThread(() -> { UserStats stats = SBRequester.retrieveUserStats(); - ReVancedUtils.runOnMainThread(() -> { // get back on main thread to modify UI elements + Utils.runOnMainThread(() -> { // get back on main thread to modify UI elements addUserStats(loadingPlaceholderPreference, stats); addLocalUserStats(); }); }); } else { - loadingPlaceholderPreference.setTitle(str("sb_stats_sb_disabled")); + loadingPlaceholderPreference.setTitle(str("revanced_sb_stats_sb_disabled")); } } catch (Exception ex) { - LogHelper.printException(() -> "fetchAndDisplayStats failure", ex); + Logger.printException(() -> "fetchAndDisplayStats failure", ex); } } private void addUserStats(@NonNull Preference loadingPlaceholder, @Nullable UserStats stats) { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); try { if (stats == null) { - loadingPlaceholder.setTitle(str("sb_stats_connection_failure")); + loadingPlaceholder.setTitle(str("revanced_sb_stats_connection_failure")); return; } statsCategory.removeAll(); @@ -484,21 +475,21 @@ private void addUserStats(@NonNull Preference loadingPlaceholder, @Nullable User EditTextPreference preference = new EditTextPreference(context); statsCategory.addPreference(preference); String userName = stats.userName; - preference.setTitle(fromHtml(str("sb_stats_username", userName))); - preference.setSummary(str("sb_stats_username_change")); + preference.setTitle(fromHtml(str("revanced_sb_stats_username", userName))); + preference.setSummary(str("revanced_sb_stats_username_change")); preference.setText(userName); preference.setOnPreferenceChangeListener((preference1, value) -> { - ReVancedUtils.runOnBackgroundThread(() -> { + Utils.runOnBackgroundThread(() -> { String newUserName = (String) value; String errorMessage = SBRequester.setUsername(newUserName); - ReVancedUtils.runOnMainThread(() -> { + Utils.runOnMainThread(() -> { if (errorMessage == null) { - preference.setTitle(fromHtml(str("sb_stats_username", newUserName))); + preference.setTitle(fromHtml(str("revanced_sb_stats_username", newUserName))); preference.setText(newUserName); - ReVancedUtils.showToastLong(str("sb_stats_username_changed")); + Utils.showToastLong(str("revanced_sb_stats_username_changed")); } else { preference.setText(userName); // revert to previous - ReVancedUtils.showToastLong(errorMessage); + Utils.showToastLong(errorMessage); } }); }); @@ -511,7 +502,7 @@ private void addUserStats(@NonNull Preference loadingPlaceholder, @Nullable User Preference preference = new Preference(context); statsCategory.addPreference(preference); String formatted = SponsorBlockUtils.getNumberOfSkipsString(stats.segmentCount); - preference.setTitle(fromHtml(str("sb_stats_submissions", formatted))); + preference.setTitle(fromHtml(str("revanced_sb_stats_submissions", formatted))); if (stats.totalSegmentCountIncludingIgnored == 0) { preference.setSelectable(false); } else { @@ -528,7 +519,7 @@ private void addUserStats(@NonNull Preference loadingPlaceholder, @Nullable User // "user reputation". Usually not useful, since it appears most users have zero reputation. // But if there is a reputation, then show it here Preference preference = new Preference(context); - preference.setTitle(fromHtml(str("sb_stats_reputation", stats.reputation))); + preference.setTitle(fromHtml(str("revanced_sb_stats_reputation", stats.reputation))); preference.setSelectable(false); if (stats.reputation != 0) { statsCategory.addPreference(preference); @@ -543,12 +534,12 @@ private void addUserStats(@NonNull Preference loadingPlaceholder, @Nullable User String stats_saved; String stats_saved_sum; if (stats.totalSegmentCountIncludingIgnored == 0) { - stats_saved = str("sb_stats_saved_zero"); - stats_saved_sum = str("sb_stats_saved_sum_zero"); + stats_saved = str("revanced_sb_stats_saved_zero"); + stats_saved_sum = str("revanced_sb_stats_saved_sum_zero"); } else { - stats_saved = str("sb_stats_saved", + stats_saved = str("revanced_sb_stats_saved", SponsorBlockUtils.getNumberOfSkipsString(stats.viewCount)); - stats_saved_sum = str("sb_stats_saved_sum", SponsorBlockUtils.getTimeSavedString((long) (60 * stats.minutesSaved))); + stats_saved_sum = str("revanced_sb_stats_saved_sum", SponsorBlockUtils.getTimeSavedString((long) (60 * stats.minutesSaved))); } preference.setTitle(fromHtml(stats_saved)); preference.setSummary(fromHtml(stats_saved_sum)); @@ -560,7 +551,7 @@ private void addUserStats(@NonNull Preference loadingPlaceholder, @Nullable User }); } } catch (Exception ex) { - LogHelper.printException(() -> "addUserStats failure", ex); + Logger.printException(() -> "addUserStats failure", ex); } } @@ -570,18 +561,18 @@ private void addLocalUserStats() { statsCategory.addPreference(preference); Runnable updateStatsSelfSaved = () -> { - String formatted = SponsorBlockUtils.getNumberOfSkipsString(SettingsEnum.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.getInt()); - preference.setTitle(fromHtml(str("sb_stats_self_saved", formatted))); - String formattedSaved = SponsorBlockUtils.getTimeSavedString(SettingsEnum.SB_LOCAL_TIME_SAVED_MILLISECONDS.getLong() / 1000); - preference.setSummary(fromHtml(str("sb_stats_self_saved_sum", formattedSaved))); + String formatted = SponsorBlockUtils.getNumberOfSkipsString(Settings.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.get()); + preference.setTitle(fromHtml(str("revanced_sb_stats_self_saved", formatted))); + String formattedSaved = SponsorBlockUtils.getTimeSavedString(Settings.SB_LOCAL_TIME_SAVED_MILLISECONDS.get() / 1000); + preference.setSummary(fromHtml(str("revanced_sb_stats_self_saved_sum", formattedSaved))); }; updateStatsSelfSaved.run(); preference.setOnPreferenceClickListener(preference1 -> { new AlertDialog.Builder(preference1.getContext()) - .setTitle(str("sb_stats_self_saved_reset_title")) + .setTitle(str("revanced_sb_stats_self_saved_reset_title")) .setPositiveButton(android.R.string.yes, (dialog, whichButton) -> { - SettingsEnum.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.resetToDefault(); - SettingsEnum.SB_LOCAL_TIME_SAVED_MILLISECONDS.resetToDefault(); + Settings.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.resetToDefault(); + Settings.SB_LOCAL_TIME_SAVED_MILLISECONDS.resetToDefault(); updateStatsSelfSaved.run(); }) .setNegativeButton(android.R.string.no, null).show(); diff --git a/app/src/main/java/app/revanced/integrations/shared/PlayerControlsVisibilityObserver.kt b/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerControlsVisibilityObserver.kt similarity index 89% rename from app/src/main/java/app/revanced/integrations/shared/PlayerControlsVisibilityObserver.kt rename to app/src/main/java/app/revanced/integrations/youtube/shared/PlayerControlsVisibilityObserver.kt index 1db019e1c0..912f369ecd 100644 --- a/app/src/main/java/app/revanced/integrations/shared/PlayerControlsVisibilityObserver.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerControlsVisibilityObserver.kt @@ -1,9 +1,9 @@ -package app.revanced.integrations.shared +package app.revanced.integrations.youtube.shared import android.app.Activity import android.view.View import android.view.ViewGroup -import app.revanced.integrations.utils.ReVancedUtils +import app.revanced.integrations.shared.Utils import java.lang.ref.WeakReference /** @@ -19,13 +19,13 @@ class PlayerControlsVisibilityObserverImpl( * id of the direct parent of controls_layout, R.id.youtube_controls_overlay */ private val controlsLayoutParentId = - ReVancedUtils.getResourceIdentifier(activity, "youtube_controls_overlay", "id") + Utils.getResourceIdentifier(activity, "youtube_controls_overlay", "id") /** * id of R.id.controls_layout */ private val controlsLayoutId = - ReVancedUtils.getResourceIdentifier(activity, "controls_layout", "id") + Utils.getResourceIdentifier(activity, "controls_layout", "id") /** * reference to the controls layout view diff --git a/app/src/main/java/app/revanced/integrations/shared/PlayerOverlays.kt b/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerOverlays.kt similarity index 94% rename from app/src/main/java/app/revanced/integrations/shared/PlayerOverlays.kt rename to app/src/main/java/app/revanced/integrations/youtube/shared/PlayerOverlays.kt index 9c4c607b15..3b15f043eb 100644 --- a/app/src/main/java/app/revanced/integrations/shared/PlayerOverlays.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerOverlays.kt @@ -1,9 +1,9 @@ -package app.revanced.integrations.shared +package app.revanced.integrations.youtube.shared import android.view.View import android.view.ViewGroup -import app.revanced.integrations.swipecontrols.misc.Rectangle -import app.revanced.integrations.utils.Event +import app.revanced.integrations.youtube.swipecontrols.misc.Rectangle +import app.revanced.integrations.youtube.Event /** * hooking class for player overlays diff --git a/app/src/main/java/app/revanced/integrations/shared/PlayerType.kt b/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerType.kt similarity index 91% rename from app/src/main/java/app/revanced/integrations/shared/PlayerType.kt rename to app/src/main/java/app/revanced/integrations/youtube/shared/PlayerType.kt index b74a4d6329..64634cebc3 100644 --- a/app/src/main/java/app/revanced/integrations/shared/PlayerType.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/shared/PlayerType.kt @@ -1,11 +1,11 @@ -package app.revanced.integrations.shared +package app.revanced.integrations.youtube.shared -import app.revanced.integrations.patches.VideoInformation -import app.revanced.integrations.utils.Event -import app.revanced.integrations.utils.LogHelper +import app.revanced.integrations.youtube.patches.VideoInformation +import app.revanced.integrations.youtube.Event +import app.revanced.integrations.shared.Logger /** - * WatchWhile player type. + * Main player type. */ enum class PlayerType { /** @@ -50,9 +50,9 @@ enum class PlayerType { fun setFromString(enumName: String) { val newType = nameToPlayerType[enumName] if (newType == null) { - LogHelper.printException { "Unknown PlayerType encountered: $enumName" } + Logger.printException { "Unknown PlayerType encountered: $enumName" } } else if (current != newType) { - LogHelper.printDebug { "PlayerType changed to: $newType" } + Logger.printDebug { "PlayerType changed to: $newType" } current = newType } } diff --git a/app/src/main/java/app/revanced/integrations/shared/VideoState.kt b/app/src/main/java/app/revanced/integrations/youtube/shared/VideoState.kt similarity index 75% rename from app/src/main/java/app/revanced/integrations/shared/VideoState.kt rename to app/src/main/java/app/revanced/integrations/youtube/shared/VideoState.kt index 977b9181dd..dfae41336a 100644 --- a/app/src/main/java/app/revanced/integrations/shared/VideoState.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/shared/VideoState.kt @@ -1,7 +1,7 @@ -package app.revanced.integrations.shared +package app.revanced.integrations.youtube.shared -import app.revanced.integrations.utils.LogHelper -import app.revanced.integrations.patches.VideoInformation +import app.revanced.integrations.shared.Logger +import app.revanced.integrations.youtube.patches.VideoInformation /** * VideoState playback state. @@ -25,9 +25,9 @@ enum class VideoState { fun setFromString(enumName: String) { val state = nameToVideoState[enumName] if (state == null) { - LogHelper.printException { "Unknown VideoState encountered: $enumName" } + Logger.printException { "Unknown VideoState encountered: $enumName" } } else if (currentVideoState != state) { - LogHelper.printDebug { "VideoState changed to: $state" } + Logger.printDebug { "VideoState changed to: $state" } currentVideoState = state } } diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/SegmentPlaybackController.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController.java similarity index 81% rename from app/src/main/java/app/revanced/integrations/sponsorblock/SegmentPlaybackController.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController.java index c8edbdfcaa..9a35adceda 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/SegmentPlaybackController.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController.java @@ -1,27 +1,33 @@ -package app.revanced.integrations.sponsorblock; +package app.revanced.integrations.youtube.sponsorblock; + +import static app.revanced.integrations.shared.StringRef.str; import android.graphics.Canvas; import android.graphics.Rect; import android.text.TextUtils; import android.util.TypedValue; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.shared.PlayerType; -import app.revanced.integrations.shared.VideoState; -import app.revanced.integrations.sponsorblock.objects.CategoryBehaviour; -import app.revanced.integrations.sponsorblock.objects.SegmentCategory; -import app.revanced.integrations.sponsorblock.objects.SponsorSegment; -import app.revanced.integrations.sponsorblock.requests.SBRequester; -import app.revanced.integrations.sponsorblock.ui.SponsorBlockViewController; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; import java.lang.reflect.Field; -import java.util.*; - -import static app.revanced.integrations.utils.StringRef.str; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.shared.PlayerType; +import app.revanced.integrations.youtube.shared.VideoState; +import app.revanced.integrations.youtube.sponsorblock.objects.CategoryBehaviour; +import app.revanced.integrations.youtube.sponsorblock.objects.SegmentCategory; +import app.revanced.integrations.youtube.sponsorblock.objects.SponsorSegment; +import app.revanced.integrations.youtube.sponsorblock.requests.SBRequester; +import app.revanced.integrations.youtube.sponsorblock.ui.SponsorBlockViewController; /** * Handles showing, scheduling, and skipping of all {@link SponsorSegment} for the current video. @@ -31,7 +37,7 @@ public class SegmentPlaybackController { /** * Length of time to show a skip button for a highlight segment, - * or a regular segment if {@link SettingsEnum#SB_AUTO_HIDE_SKIP_BUTTON} is enabled. + * or a regular segment if {@link Settings#SB_AUTO_HIDE_SKIP_BUTTON} is enabled. * * Effectively this value is rounded up to the next second. */ @@ -81,7 +87,7 @@ public class SegmentPlaybackController { /** * Used to prevent re-showing a previously hidden skip button when exiting an embedded segment. - * Only used when {@link SettingsEnum#SB_AUTO_HIDE_SKIP_BUTTON} is enabled. + * Only used when {@link Settings#SB_AUTO_HIDE_SKIP_BUTTON} is enabled. * * A collection of segments that have automatically hidden the skip button for, and all segments in this list * contain the current video time. Segment are removed when playback exits the segment. @@ -91,7 +97,7 @@ public class SegmentPlaybackController { /** * System time (in milliseconds) of when to hide the skip button of {@link #segmentCurrentlyPlaying}. * Value is zero if playback is not inside a segment ({@link #segmentCurrentlyPlaying} is null), - * or if {@link SettingsEnum#SB_AUTO_HIDE_SKIP_BUTTON} is not enabled. + * or if {@link Settings#SB_AUTO_HIDE_SKIP_BUTTON} is not enabled. */ private static long skipSegmentButtonEndTime; @@ -178,14 +184,14 @@ private static void clearData() { */ public static void initialize(Object ignoredPlayerController) { try { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); SponsorBlockSettings.initialize(); clearData(); SponsorBlockViewController.hideAll(); SponsorBlockUtils.clearUnsubmittedSegmentTimes(); - LogHelper.printDebug(() -> "Initialized SponsorBlock"); + Logger.printDebug(() -> "Initialized SponsorBlock"); } catch (Exception ex) { - LogHelper.printException(() -> "Failed to initialize SponsorBlock", ex); + Logger.printException(() -> "Failed to initialize SponsorBlock", ex); } } @@ -198,30 +204,30 @@ public static void setCurrentVideoId(@Nullable String videoId) { return; } clearData(); - if (videoId == null || !SettingsEnum.SB_ENABLED.getBoolean()) { + if (videoId == null || !Settings.SB_ENABLED.get()) { return; } if (PlayerType.getCurrent().isNoneOrHidden()) { - LogHelper.printDebug(() -> "ignoring Short"); + Logger.printDebug(() -> "ignoring Short"); return; } - if (!ReVancedUtils.isNetworkConnected()) { - LogHelper.printDebug(() -> "Network not connected, ignoring video"); + if (!Utils.isNetworkConnected()) { + Logger.printDebug(() -> "Network not connected, ignoring video"); return; } currentVideoId = videoId; - LogHelper.printDebug(() -> "setCurrentVideoId: " + videoId); + Logger.printDebug(() -> "setCurrentVideoId: " + videoId); - ReVancedUtils.runOnBackgroundThread(() -> { + Utils.runOnBackgroundThread(() -> { try { executeDownloadSegments(videoId); } catch (Exception e) { - LogHelper.printException(() -> "Failed to download segments", e); + Logger.printException(() -> "Failed to download segments", e); } }); } catch (Exception ex) { - LogHelper.printException(() -> "setCurrentVideoId failure", ex); + Logger.printException(() -> "setCurrentVideoId failure", ex); } } @@ -233,10 +239,10 @@ static void executeDownloadSegments(@NonNull String videoId) { try { SponsorSegment[] segments = SBRequester.getSegments(videoId); - ReVancedUtils.runOnMainThread(()-> { + Utils.runOnMainThread(()-> { if (!videoId.equals(currentVideoId)) { // user changed videos before get segments network call could complete - LogHelper.printDebug(() -> "Ignoring segments for prior video: " + videoId); + Logger.printDebug(() -> "Ignoring segments for prior video: " + videoId); return; } setSegments(segments); @@ -260,7 +266,7 @@ static void executeDownloadSegments(@NonNull String videoId) { setVideoTime(videoTime); }); } catch (Exception ex) { - LogHelper.printException(() -> "executeDownloadSegments failure", ex); + Logger.printException(() -> "executeDownloadSegments failure", ex); } } @@ -271,12 +277,12 @@ static void executeDownloadSegments(@NonNull String videoId) { */ public static void setVideoTime(long millis) { try { - if (!SettingsEnum.SB_ENABLED.getBoolean() + if (!Settings.SB_ENABLED.get() || PlayerType.getCurrent().isNoneOrHidden() // Shorts playback. || segments == null || segments.length == 0) { return; } - LogHelper.printDebug(() -> "setVideoTime: " + millis); + Logger.printDebug(() -> "setVideoTime: " + millis); updateHiddenSegments(millis); @@ -322,7 +328,7 @@ public static void setVideoTime(long millis) { || !segment.endIsNear(millis, minMillisOfSegmentRemainingThreshold)) { foundSegmentCurrentlyPlaying = segment; } else { - LogHelper.printDebug(() -> "Ignoring segment that ends very soon: " + segment); + Logger.printDebug(() -> "Ignoring segment that ends very soon: " + segment); } } // Keep iterating and looking. There may be an upcoming autoskip, @@ -354,7 +360,7 @@ public static void setVideoTime(long millis) { || !foundSegmentCurrentlyPlaying.endIsNear(segment.start, minTimeBetweenStartEndOfSegments)) { foundUpcomingSegment = segment; } else { - LogHelper.printDebug(() -> "Not scheduling segment (start time is near end of current segment): " + segment); + Logger.printDebug(() -> "Not scheduling segment (start time is near end of current segment): " + segment); } } } @@ -373,7 +379,7 @@ public static void setVideoTime(long millis) { setSegmentCurrentlyPlaying(foundSegmentCurrentlyPlaying); } else if (foundSegmentCurrentlyPlaying != null && skipSegmentButtonEndTime != 0 && skipSegmentButtonEndTime <= System.currentTimeMillis()) { - LogHelper.printDebug(() -> "Auto hiding skip button for segment: " + segmentCurrentlyPlaying); + Logger.printDebug(() -> "Auto hiding skip button for segment: " + segmentCurrentlyPlaying); skipSegmentButtonEndTime = 0; hiddenSkipSegmentsForCurrentVideoTime.add(foundSegmentCurrentlyPlaying); SponsorBlockViewController.hideSkipSegmentButton(); @@ -387,31 +393,31 @@ public static void setVideoTime(long millis) { if (scheduledHideSegment != segmentToHide) { if (segmentToHide == null) { - LogHelper.printDebug(() -> "Clearing scheduled hide: " + scheduledHideSegment); + Logger.printDebug(() -> "Clearing scheduled hide: " + scheduledHideSegment); scheduledHideSegment = null; } else { scheduledHideSegment = segmentToHide; - LogHelper.printDebug(() -> "Scheduling hide segment: " + segmentToHide + " playbackSpeed: " + playbackSpeed); + Logger.printDebug(() -> "Scheduling hide segment: " + segmentToHide + " playbackSpeed: " + playbackSpeed); final long delayUntilHide = (long) ((segmentToHide.end - millis) / playbackSpeed); - ReVancedUtils.runOnMainThreadDelayed(() -> { + Utils.runOnMainThreadDelayed(() -> { if (scheduledHideSegment != segmentToHide) { - LogHelper.printDebug(() -> "Ignoring old scheduled hide segment: " + segmentToHide); + Logger.printDebug(() -> "Ignoring old scheduled hide segment: " + segmentToHide); return; } scheduledHideSegment = null; if (VideoState.getCurrent() != VideoState.PLAYING) { - LogHelper.printDebug(() -> "Ignoring scheduled hide segment as video is paused: " + segmentToHide); + Logger.printDebug(() -> "Ignoring scheduled hide segment as video is paused: " + segmentToHide); return; } final long videoTime = VideoInformation.getVideoTime(); if (!segmentToHide.endIsNear(videoTime, speedAdjustedTimeThreshold)) { // current video time is not what's expected. User paused playback - LogHelper.printDebug(() -> "Ignoring outdated scheduled hide: " + segmentToHide + Logger.printDebug(() -> "Ignoring outdated scheduled hide: " + segmentToHide + " videoInformation time: " + videoTime); return; } - LogHelper.printDebug(() -> "Running scheduled hide segment: " + segmentToHide); + Logger.printDebug(() -> "Running scheduled hide segment: " + segmentToHide); // Need more than just hide the skip button, as this may have been an embedded segment // Instead call back into setVideoTime to check everything again. // Should not use VideoInformation time as it is less accurate, @@ -424,44 +430,44 @@ public static void setVideoTime(long millis) { if (scheduledUpcomingSegment != foundUpcomingSegment) { if (foundUpcomingSegment == null) { - LogHelper.printDebug(() -> "Clearing scheduled segment: " + scheduledUpcomingSegment); + Logger.printDebug(() -> "Clearing scheduled segment: " + scheduledUpcomingSegment); scheduledUpcomingSegment = null; } else { scheduledUpcomingSegment = foundUpcomingSegment; final SponsorSegment segmentToSkip = foundUpcomingSegment; - LogHelper.printDebug(() -> "Scheduling segment: " + segmentToSkip + " playbackSpeed: " + playbackSpeed); + Logger.printDebug(() -> "Scheduling segment: " + segmentToSkip + " playbackSpeed: " + playbackSpeed); final long delayUntilSkip = (long) ((segmentToSkip.start - millis) / playbackSpeed); - ReVancedUtils.runOnMainThreadDelayed(() -> { + Utils.runOnMainThreadDelayed(() -> { if (scheduledUpcomingSegment != segmentToSkip) { - LogHelper.printDebug(() -> "Ignoring old scheduled segment: " + segmentToSkip); + Logger.printDebug(() -> "Ignoring old scheduled segment: " + segmentToSkip); return; } scheduledUpcomingSegment = null; if (VideoState.getCurrent() != VideoState.PLAYING) { - LogHelper.printDebug(() -> "Ignoring scheduled hide segment as video is paused: " + segmentToSkip); + Logger.printDebug(() -> "Ignoring scheduled hide segment as video is paused: " + segmentToSkip); return; } final long videoTime = VideoInformation.getVideoTime(); if (!segmentToSkip.startIsNear(videoTime, speedAdjustedTimeThreshold)) { // current video time is not what's expected. User paused playback - LogHelper.printDebug(() -> "Ignoring outdated scheduled segment: " + segmentToSkip + Logger.printDebug(() -> "Ignoring outdated scheduled segment: " + segmentToSkip + " videoInformation time: " + videoTime); return; } if (segmentToSkip.shouldAutoSkip()) { - LogHelper.printDebug(() -> "Running scheduled skip segment: " + segmentToSkip); + Logger.printDebug(() -> "Running scheduled skip segment: " + segmentToSkip); skipSegment(segmentToSkip, false); } else { - LogHelper.printDebug(() -> "Running scheduled show segment: " + segmentToSkip); + Logger.printDebug(() -> "Running scheduled show segment: " + segmentToSkip); setSegmentCurrentlyPlaying(segmentToSkip); } }, delayUntilSkip); } } } catch (Exception e) { - LogHelper.printException(() -> "setVideoTime failure", e); + Logger.printException(() -> "setVideoTime failure", e); } } @@ -473,7 +479,7 @@ private static void updateHiddenSegments(long currentVideoTime) { while (i.hasNext()) { SponsorSegment hiddenSegment = i.next(); if (!hiddenSegment.containsTime(currentVideoTime)) { - LogHelper.printDebug(() -> "Resetting hide skip button: " + hiddenSegment); + Logger.printDebug(() -> "Resetting hide skip button: " + hiddenSegment); i.remove(); } } @@ -481,7 +487,7 @@ private static void updateHiddenSegments(long currentVideoTime) { private static void setSegmentCurrentlyPlaying(@Nullable SponsorSegment segment) { if (segment == null) { - if (segmentCurrentlyPlaying != null) LogHelper.printDebug(() -> "Hiding segment: " + segmentCurrentlyPlaying); + if (segmentCurrentlyPlaying != null) Logger.printDebug(() -> "Hiding segment: " + segmentCurrentlyPlaying); segmentCurrentlyPlaying = null; skipSegmentButtonEndTime = 0; SponsorBlockViewController.hideSkipSegmentButton(); @@ -489,16 +495,16 @@ private static void setSegmentCurrentlyPlaying(@Nullable SponsorSegment segment) } segmentCurrentlyPlaying = segment; skipSegmentButtonEndTime = 0; - if (SettingsEnum.SB_AUTO_HIDE_SKIP_BUTTON.getBoolean()) { + if (Settings.SB_AUTO_HIDE_SKIP_BUTTON.get()) { if (hiddenSkipSegmentsForCurrentVideoTime.contains(segment)) { // Playback exited a nested segment and the outer segment skip button was previously hidden. - LogHelper.printDebug(() -> "Ignoring previously auto-hidden segment: " + segment); + Logger.printDebug(() -> "Ignoring previously auto-hidden segment: " + segment); SponsorBlockViewController.hideSkipSegmentButton(); return; } skipSegmentButtonEndTime = System.currentTimeMillis() + DURATION_TO_SHOW_SKIP_BUTTON; } - LogHelper.printDebug(() -> "Showing segment: " + segment); + Logger.printDebug(() -> "Showing segment: " + segment); SponsorBlockViewController.showSkipSegmentButton(segment); } @@ -519,12 +525,12 @@ private static void skipSegment(@NonNull SponsorSegment segmentToSkip, boolean u final long minTimeBetweenSkippingSameSegment = Math.max(500, (long) (500 / VideoInformation.getPlaybackSpeed())); if (now - lastSegmentSkippedTime < minTimeBetweenSkippingSameSegment) { - LogHelper.printDebug(() -> "Ignoring skip segment request (already skipped as close as possible): " + segmentToSkip); + Logger.printDebug(() -> "Ignoring skip segment request (already skipped as close as possible): " + segmentToSkip); return; } } - LogHelper.printDebug(() -> "Skipping segment: " + segmentToSkip); + Logger.printDebug(() -> "Skipping segment: " + segmentToSkip); lastSegmentSkipped = segmentToSkip; lastSegmentSkippedTime = now; setSegmentCurrentlyPlaying(null); @@ -538,14 +544,14 @@ private static void skipSegment(@NonNull SponsorSegment segmentToSkip, boolean u final boolean seekSuccessful = VideoInformation.seekTo(segmentToSkip.end); if (!seekSuccessful) { // can happen when switching videos and is normal - LogHelper.printDebug(() -> "Could not skip segment (seek unsuccessful): " + segmentToSkip); + Logger.printDebug(() -> "Could not skip segment (seek unsuccessful): " + segmentToSkip); return; } final boolean videoIsPaused = VideoState.getCurrent() == VideoState.PAUSED; if (!userManuallySkipped) { // check for any smaller embedded segments, and count those as autoskipped - final boolean showSkipToast = SettingsEnum.SB_TOAST_ON_SKIP.getBoolean(); + final boolean showSkipToast = Settings.SB_TOAST_ON_SKIP.get(); for (final SponsorSegment otherSegment : Objects.requireNonNull(segments)) { if (segmentToSkip.end < otherSegment.start) { break; // no other segments can be contained @@ -570,7 +576,7 @@ private static void skipSegment(@NonNull SponsorSegment segmentToSkip, boolean u SponsorBlockUtils.sendViewRequestAsync(segmentToSkip); } } catch (Exception ex) { - LogHelper.printException(() -> "skipSegment failure", ex); + Logger.printException(() -> "skipSegment failure", ex); } } @@ -580,7 +586,7 @@ private static void skipSegment(@NonNull SponsorSegment segmentToSkip, boolean u private static SponsorSegment toastSegmentSkipped; private static void showSkippedSegmentToast(@NonNull SponsorSegment segment) { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); toastNumberOfSegmentsSkipped++; if (toastNumberOfSegmentsSkipped > 1) { return; // toast already scheduled @@ -588,17 +594,17 @@ private static void showSkippedSegmentToast(@NonNull SponsorSegment segment) { toastSegmentSkipped = segment; final long delayToToastMilliseconds = 250; // also the maximum time between skips to be considered skipping multiple segments - ReVancedUtils.runOnMainThreadDelayed(() -> { + Utils.runOnMainThreadDelayed(() -> { try { if (toastSegmentSkipped == null) { // video was changed just after skipping segment - LogHelper.printDebug(() -> "Ignoring old scheduled show toast"); + Logger.printDebug(() -> "Ignoring old scheduled show toast"); return; } - ReVancedUtils.showToastShort(toastNumberOfSegmentsSkipped == 1 + Utils.showToastShort(toastNumberOfSegmentsSkipped == 1 ? toastSegmentSkipped.getSkippedToastText() - : str("sb_skipped_multiple_segments")); + : str("revanced_sb_skipped_multiple_segments")); } catch (Exception ex) { - LogHelper.printException(() -> "showSkippedSegmentToast failure", ex); + Logger.printException(() -> "showSkippedSegmentToast failure", ex); } finally { toastNumberOfSegmentsSkipped = 0; toastSegmentSkipped = null; @@ -612,14 +618,14 @@ private static void showSkippedSegmentToast(@NonNull SponsorSegment segment) { public static void onSkipSegmentClicked(@NonNull SponsorSegment segment) { try { if (segment != highlightSegment && segment != segmentCurrentlyPlaying) { - LogHelper.printException(() -> "error: segment not available to skip"); // should never happen + Logger.printException(() -> "error: segment not available to skip"); // should never happen SponsorBlockViewController.hideSkipSegmentButton(); SponsorBlockViewController.hideSkipHighlightButton(); return; } skipSegment(segment, true); } catch (Exception ex) { - LogHelper.printException(() -> "onSkipSegmentClicked failure", ex); + Logger.printException(() -> "onSkipSegmentClicked failure", ex); } } @@ -634,14 +640,14 @@ public static void setSponsorBarRect(final Object self) { setSponsorBarAbsoluteLeft(rect); setSponsorBarAbsoluteRight(rect); } catch (Exception ex) { - LogHelper.printException(() -> "setSponsorBarRect failure", ex); + Logger.printException(() -> "setSponsorBarRect failure", ex); } } private static void setSponsorBarAbsoluteLeft(Rect rect) { final int left = rect.left; if (sponsorBarAbsoluteLeft != left) { - LogHelper.printDebug(() -> "setSponsorBarAbsoluteLeft: " + left); + Logger.printDebug(() -> "setSponsorBarAbsoluteLeft: " + left); sponsorBarAbsoluteLeft = left; } } @@ -649,7 +655,7 @@ private static void setSponsorBarAbsoluteLeft(Rect rect) { private static void setSponsorBarAbsoluteRight(Rect rect) { final int right = rect.right; if (sponsorAbsoluteBarRight != right) { - LogHelper.printDebug(() -> "setSponsorBarAbsoluteRight: " + right); + Logger.printDebug(() -> "setSponsorBarAbsoluteRight: " + right); sponsorAbsoluteBarRight = right; } } @@ -659,7 +665,7 @@ private static void setSponsorBarAbsoluteRight(Rect rect) { */ public static void setSponsorBarThickness(int thickness) { if (sponsorBarThickness != thickness) { - LogHelper.printDebug(() -> "setSponsorBarThickness: " + thickness); + Logger.printDebug(() -> "setSponsorBarThickness: " + thickness); sponsorBarThickness = thickness; } } @@ -669,13 +675,13 @@ public static void setSponsorBarThickness(int thickness) { */ public static String appendTimeWithoutSegments(String totalTime) { try { - if (SettingsEnum.SB_ENABLED.getBoolean() && SettingsEnum.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.getBoolean() + if (Settings.SB_ENABLED.get() && Settings.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.get() && !TextUtils.isEmpty(totalTime) && !TextUtils.isEmpty(timeWithoutSegments)) { // Force LTR layout, to match the same LTR video time/length layout YouTube uses for all languages return "\u202D" + totalTime + timeWithoutSegments; // u202D = left to right override } } catch (Exception ex) { - LogHelper.printException(() -> "appendTimeWithoutSegments failure", ex); + Logger.printException(() -> "appendTimeWithoutSegments failure", ex); } return totalTime; @@ -683,7 +689,7 @@ public static String appendTimeWithoutSegments(String totalTime) { private static void calculateTimeWithoutSegments() { final long currentVideoLength = VideoInformation.getVideoLength(); - if (!SettingsEnum.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.getBoolean() || currentVideoLength <= 0 + if (!Settings.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.get() || currentVideoLength <= 0 || segments == null || segments.length == 0) { timeWithoutSegments = null; return; @@ -730,7 +736,7 @@ private static int getHighlightSegmentTimeBarScreenWidth() { if (highlightSegmentTimeBarScreenWidth == -1) { highlightSegmentTimeBarScreenWidth = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, HIGHLIGHT_SEGMENT_DRAW_BAR_WIDTH, - Objects.requireNonNull(ReVancedUtils.getContext()).getResources().getDisplayMetrics()); + Objects.requireNonNull(Utils.getContext()).getResources().getDisplayMetrics()); } return highlightSegmentTimeBarScreenWidth; } @@ -761,7 +767,7 @@ public static void drawSponsorTimeBars(final Canvas canvas, final float posY) { canvas.drawRect(left, top, right, bottom, segment.category.paint); } } catch (Exception ex) { - LogHelper.printException(() -> "drawSponsorTimeBars failure", ex); + Logger.printException(() -> "drawSponsorTimeBars failure", ex); } } diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockSettings.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockSettings.java similarity index 55% rename from app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockSettings.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockSettings.java index 595a037ee3..084bbf5254 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockSettings.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockSettings.java @@ -1,27 +1,25 @@ -package app.revanced.integrations.sponsorblock; +package app.revanced.integrations.youtube.sponsorblock; -import static app.revanced.integrations.utils.StringRef.str; +import static app.revanced.integrations.shared.StringRef.str; import android.app.AlertDialog; import android.content.Context; -import android.content.SharedPreferences; import android.util.Patterns; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; import java.util.UUID; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.settings.SharedPrefCategory; -import app.revanced.integrations.sponsorblock.objects.CategoryBehaviour; -import app.revanced.integrations.sponsorblock.objects.SegmentCategory; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.settings.Setting; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.sponsorblock.objects.CategoryBehaviour; +import app.revanced.integrations.youtube.sponsorblock.objects.SegmentCategory; public class SponsorBlockSettings { /** @@ -29,8 +27,8 @@ public class SponsorBlockSettings { */ private static final int SB_PRIVATE_USER_ID_MINIMUM_LENGTH = 30; - public static void importSettings(@NonNull String json) { - ReVancedUtils.verifyOnMainThread(); + public static void importDesktopSettings(@NonNull String json) { + Utils.verifyOnMainThread(); try { JSONObject settingsJson = new JSONObject(json); JSONObject barTypesObject = settingsJson.getJSONObject("barTypes"); @@ -38,9 +36,9 @@ public static void importSettings(@NonNull String json) { for (SegmentCategory category : SegmentCategory.categoriesWithoutUnsubmitted()) { // clear existing behavior, as browser plugin exports no behavior for ignored categories - category.behaviour = CategoryBehaviour.IGNORE; - if (barTypesObject.has(category.key)) { - JSONObject categoryObject = barTypesObject.getJSONObject(category.key); + category.setBehaviour(CategoryBehaviour.IGNORE); + if (barTypesObject.has(category.keyValue)) { + JSONObject categoryObject = barTypesObject.getJSONObject(category.keyValue); category.setColor(categoryObject.getString("color")); } } @@ -54,54 +52,48 @@ public static void importSettings(@NonNull String json) { continue; // unsupported category, ignore } - final int desktopKey = categorySelectionObject.getInt("option"); - CategoryBehaviour behaviour = CategoryBehaviour.byDesktopKey(desktopKey); + final int desktopValue = categorySelectionObject.getInt("option"); + CategoryBehaviour behaviour = CategoryBehaviour.byDesktopKeyValue(desktopValue); if (behaviour == null) { - ReVancedUtils.showToastLong(categoryKey + " unknown behavior key: " + desktopKey); + Utils.showToastLong(categoryKey + " unknown behavior key: " + categoryKey); } else if (category == SegmentCategory.HIGHLIGHT && behaviour == CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE) { - ReVancedUtils.showToastLong("Skip-once behavior not allowed for " + category.key); - category.behaviour = CategoryBehaviour.SKIP_AUTOMATICALLY; // use closest match + Utils.showToastLong("Skip-once behavior not allowed for " + category.keyValue); + category.setBehaviour(CategoryBehaviour.SKIP_AUTOMATICALLY); // use closest match } else { - category.behaviour = behaviour; + category.setBehaviour(behaviour); } } SegmentCategory.updateEnabledCategories(); - SharedPreferences.Editor editor = SharedPrefCategory.SPONSOR_BLOCK.preferences.edit(); - for (SegmentCategory category : SegmentCategory.categoriesWithoutUnsubmitted()) { - category.save(editor); - } - editor.apply(); - if (settingsJson.has("userID")) { // User id does not exist if user never voted or created any segments. String userID = settingsJson.getString("userID"); if (isValidSBUserId(userID)) { - SettingsEnum.SB_PRIVATE_USER_ID.saveValue(userID); + Settings.SB_PRIVATE_USER_ID.save(userID); } } - SettingsEnum.SB_USER_IS_VIP.saveValue(settingsJson.getBoolean("isVip")); - SettingsEnum.SB_TOAST_ON_SKIP.saveValue(!settingsJson.getBoolean("dontShowNotice")); - SettingsEnum.SB_TRACK_SKIP_COUNT.saveValue(settingsJson.getBoolean("trackViewCount")); - SettingsEnum.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.saveValue(settingsJson.getBoolean("showTimeWithSkips")); + Settings.SB_USER_IS_VIP.save(settingsJson.getBoolean("isVip")); + Settings.SB_TOAST_ON_SKIP.save(!settingsJson.getBoolean("dontShowNotice")); + Settings.SB_TRACK_SKIP_COUNT.save(settingsJson.getBoolean("trackViewCount")); + Settings.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.save(settingsJson.getBoolean("showTimeWithSkips")); String serverAddress = settingsJson.getString("serverAddress"); if (isValidSBServerAddress(serverAddress)) { // Old versions of ReVanced exported wrong url format - SettingsEnum.SB_API_URL.saveValue(serverAddress); + Settings.SB_API_URL.save(serverAddress); } final float minDuration = (float) settingsJson.getDouble("minDuration"); if (minDuration < 0) { throw new IllegalArgumentException("invalid minDuration: " + minDuration); } - SettingsEnum.SB_SEGMENT_MIN_DURATION.saveValue(minDuration); + Settings.SB_SEGMENT_MIN_DURATION.save(minDuration); if (settingsJson.has("skipCount")) { // Value not exported in old versions of ReVanced int skipCount = settingsJson.getInt("skipCount"); if (skipCount < 0) { throw new IllegalArgumentException("invalid skipCount: " + skipCount); } - SettingsEnum.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.saveValue(skipCount); + Settings.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.save(skipCount); } if (settingsJson.has("minutesSaved")) { @@ -109,21 +101,21 @@ public static void importSettings(@NonNull String json) { if (minutesSaved < 0) { throw new IllegalArgumentException("invalid minutesSaved: " + minutesSaved); } - SettingsEnum.SB_LOCAL_TIME_SAVED_MILLISECONDS.saveValue((long) (minutesSaved * 60 * 1000)); + Settings.SB_LOCAL_TIME_SAVED_MILLISECONDS.save((long) (minutesSaved * 60 * 1000)); } - ReVancedUtils.showToastLong(str("sb_settings_import_successful")); + Utils.showToastLong(str("revanced_sb_settings_import_successful")); } catch (Exception ex) { - LogHelper.printInfo(() -> "failed to import settings", ex); // use info level, as we are showing our own toast - ReVancedUtils.showToastLong(str("sb_settings_import_failed", ex.getMessage())); + Logger.printInfo(() -> "failed to import settings", ex); // use info level, as we are showing our own toast + Utils.showToastLong(str("revanced_sb_settings_import_failed", ex.getMessage())); } } @NonNull - public static String exportSettings() { - ReVancedUtils.verifyOnMainThread(); + public static String exportDesktopSettings() { + Utils.verifyOnMainThread(); try { - LogHelper.printDebug(() -> "Creating SponsorBlock export settings string"); + Logger.printDebug(() -> "Creating SponsorBlock export settings string"); JSONObject json = new JSONObject(); JSONObject barTypesObject = new JSONObject(); // categories' colors @@ -132,36 +124,36 @@ public static String exportSettings() { SegmentCategory[] categories = SegmentCategory.categoriesWithoutUnsubmitted(); for (SegmentCategory category : categories) { JSONObject categoryObject = new JSONObject(); - String categoryKey = category.key; + String categoryKey = category.keyValue; categoryObject.put("color", category.colorString()); barTypesObject.put(categoryKey, categoryObject); if (category.behaviour != CategoryBehaviour.IGNORE) { JSONObject behaviorObject = new JSONObject(); behaviorObject.put("name", categoryKey); - behaviorObject.put("option", category.behaviour.desktopKey); + behaviorObject.put("option", category.behaviour.desktopKeyValue); categorySelectionsArray.put(behaviorObject); } } if (SponsorBlockSettings.userHasSBPrivateId()) { - json.put("userID", SettingsEnum.SB_PRIVATE_USER_ID.getString()); + json.put("userID", Settings.SB_PRIVATE_USER_ID.get()); } - json.put("isVip", SettingsEnum.SB_USER_IS_VIP.getBoolean()); - json.put("serverAddress", SettingsEnum.SB_API_URL.getString()); - json.put("dontShowNotice", !SettingsEnum.SB_TOAST_ON_SKIP.getBoolean()); - json.put("showTimeWithSkips", SettingsEnum.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.getBoolean()); - json.put("minDuration", SettingsEnum.SB_SEGMENT_MIN_DURATION.getFloat()); - json.put("trackViewCount", SettingsEnum.SB_TRACK_SKIP_COUNT.getBoolean()); - json.put("skipCount", SettingsEnum.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.getInt()); - json.put("minutesSaved", SettingsEnum.SB_LOCAL_TIME_SAVED_MILLISECONDS.getLong() / (60f * 1000)); + json.put("isVip", Settings.SB_USER_IS_VIP.get()); + json.put("serverAddress", Settings.SB_API_URL.get()); + json.put("dontShowNotice", !Settings.SB_TOAST_ON_SKIP.get()); + json.put("showTimeWithSkips", Settings.SB_VIDEO_LENGTH_WITHOUT_SEGMENTS.get()); + json.put("minDuration", Settings.SB_SEGMENT_MIN_DURATION.get()); + json.put("trackViewCount", Settings.SB_TRACK_SKIP_COUNT.get()); + json.put("skipCount", Settings.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.get()); + json.put("minutesSaved", Settings.SB_LOCAL_TIME_SAVED_MILLISECONDS.get() / (60f * 1000)); json.put("categorySelections", categorySelectionsArray); json.put("barTypes", barTypesObject); return json.toString(2); } catch (Exception ex) { - LogHelper.printInfo(() -> "failed to export settings", ex); // use info level, as we are showing our own toast - ReVancedUtils.showToastLong(str("sb_settings_export_failed", ex)); + Logger.printInfo(() -> "failed to export settings", ex); // use info level, as we are showing our own toast + Utils.showToastLong(str("revanced_sb_settings_export_failed", ex)); return ""; } } @@ -169,47 +161,21 @@ public static String exportSettings() { /** * Export the categories using flatten json (no embedded dictionaries or arrays). */ - public static void exportCategoriesToFlatJson(@Nullable Context dialogContext, - @NonNull JSONObject json) throws JSONException { - ReVancedUtils.verifyOnMainThread(); + public static void showExportWarningIfNeeded(@Nullable Context dialogContext) { + Utils.verifyOnMainThread(); initialize(); // If user has a SponsorBlock user id then show a warning. if (dialogContext != null && SponsorBlockSettings.userHasSBPrivateId() - && !SettingsEnum.SB_HIDE_EXPORT_WARNING.getBoolean()) { + && !Settings.SB_HIDE_EXPORT_WARNING.get()) { new AlertDialog.Builder(dialogContext) - .setMessage(str("sb_settings_revanced_export_user_id_warning")) - .setNeutralButton(str("sb_settings_revanced_export_user_id_warning_dismiss"), - (dialog, which) -> SettingsEnum.SB_HIDE_EXPORT_WARNING.saveValue(true)) + .setMessage(str("revanced_sb_settings_revanced_export_user_id_warning")) + .setNeutralButton(str("revanced_sb_settings_revanced_export_user_id_warning_dismiss"), + (dialog, which) -> Settings.SB_HIDE_EXPORT_WARNING.save(true)) .setPositiveButton(android.R.string.ok, null) .setCancelable(false) .show(); } - - for (SegmentCategory category : SegmentCategory.categoriesWithoutUnsubmitted()) { - category.exportToFlatJSON(json); - } - } - - /** - * Import the categories using flatten json (no embedded dictionaries or arrays). - * - * @return the number of settings imported - */ - public static int importCategoriesFromFlatJson(JSONObject json) throws JSONException { - ReVancedUtils.verifyOnMainThread(); - initialize(); - - int numberOfImportedSettings = 0; - SharedPreferences.Editor editor = SharedPrefCategory.SPONSOR_BLOCK.preferences.edit(); - for (SegmentCategory category : SegmentCategory.categoriesWithoutUnsubmitted()) { - numberOfImportedSettings += category.importFromFlatJSON(json, editor); - } - editor.apply(); - - SegmentCategory.updateEnabledCategories(); - - return numberOfImportedSettings; } public static boolean isValidSBUserId(@NonNull String userId) { @@ -239,7 +205,7 @@ public static boolean isValidSBServerAddress(@NonNull String serverAddress) { * @return if the user has ever voted, created a segment, or imported existing SB settings. */ public static boolean userHasSBPrivateId() { - return !SettingsEnum.SB_PRIVATE_USER_ID.getString().isEmpty(); + return !Settings.SB_PRIVATE_USER_ID.get().isEmpty(); } /** @@ -247,13 +213,13 @@ public static boolean userHasSBPrivateId() { */ @NonNull public static String getSBPrivateUserID() { - String uuid = SettingsEnum.SB_PRIVATE_USER_ID.getString(); + String uuid = Settings.SB_PRIVATE_USER_ID.get(); if (uuid.isEmpty()) { uuid = (UUID.randomUUID().toString() + UUID.randomUUID().toString() + UUID.randomUUID().toString()) .replace("-", ""); - SettingsEnum.SB_PRIVATE_USER_ID.saveValue(uuid); + Settings.SB_PRIVATE_USER_ID.save(uuid); } return uuid; } @@ -266,6 +232,13 @@ public static void initialize() { } initialized = true; - SegmentCategory.loadFromPreferences(); + SegmentCategory.updateEnabledCategories(); + } + + /** + * Updates internal data based on {@link Setting} values. + */ + public static void updateFromImportedSettings() { + SegmentCategory.loadAllCategoriesFromSettings(); } } diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockUtils.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockUtils.java similarity index 77% rename from app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockUtils.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockUtils.java index ef30eb247f..a8ec384fc0 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/SponsorBlockUtils.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/SponsorBlockUtils.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.sponsorblock; +package app.revanced.integrations.youtube.sponsorblock; -import static app.revanced.integrations.utils.StringRef.str; +import static app.revanced.integrations.shared.StringRef.str; import android.annotation.SuppressLint; import android.app.AlertDialog; @@ -20,16 +20,16 @@ import java.util.Objects; import java.util.TimeZone; -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.sponsorblock.objects.CategoryBehaviour; -import app.revanced.integrations.sponsorblock.objects.SegmentCategory; -import app.revanced.integrations.sponsorblock.objects.SponsorSegment; -import app.revanced.integrations.sponsorblock.objects.SponsorSegment.SegmentVote; -import app.revanced.integrations.sponsorblock.requests.SBRequester; -import app.revanced.integrations.sponsorblock.ui.SponsorBlockViewController; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.sponsorblock.objects.CategoryBehaviour; +import app.revanced.integrations.youtube.sponsorblock.objects.SegmentCategory; +import app.revanced.integrations.youtube.sponsorblock.objects.SponsorSegment; +import app.revanced.integrations.youtube.sponsorblock.objects.SponsorSegment.SegmentVote; +import app.revanced.integrations.youtube.sponsorblock.requests.SBRequester; +import app.revanced.integrations.youtube.sponsorblock.ui.SponsorBlockViewController; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; /** * Not thread safe. All fields/methods must be accessed from the main thread. @@ -76,7 +76,7 @@ public void onClick(DialogInterface dialog, int which) { SegmentCategory category = SegmentCategory.categoriesWithoutHighlights()[which]; final boolean enableButton; if (category.behaviour == CategoryBehaviour.IGNORE) { - ReVancedUtils.showToastLong(str("sb_new_segment_disabled_category")); + Utils.showToastLong(str("revanced_sb_new_segment_disabled_category")); enableButton = false; } else { newUserCreatedSegmentCategory = category; @@ -87,7 +87,7 @@ public void onClick(DialogInterface dialog, int which) { .getButton(DialogInterface.BUTTON_POSITIVE) .setEnabled(enableButton); } catch (Exception ex) { - LogHelper.printException(() -> "segmentTypeListener failure", ex); + Logger.printException(() -> "segmentTypeListener failure", ex); } } }; @@ -107,7 +107,7 @@ public void onClick(DialogInterface dialog, int which) { newUserCreatedSegmentCategory = null; new AlertDialog.Builder(context) - .setTitle(str("sb_new_segment_choose_category")) + .setTitle(str("revanced_sb_new_segment_choose_category")) .setSingleChoiceItems(titles, -1, segmentTypeListener) .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(android.R.string.ok, segmentCategorySelectedDialogListener) @@ -115,7 +115,7 @@ public void onClick(DialogInterface dialog, int which) { .getButton(DialogInterface.BUTTON_POSITIVE) .setEnabled(false); } catch (Exception ex) { - LogHelper.printException(() -> "segmentReadyDialogButtonListener failure", ex); + Logger.printException(() -> "segmentReadyDialogButtonListener failure", ex); } } }; @@ -143,16 +143,16 @@ public void onClick(DialogInterface dialog, int which) { editByHandSaveDialogListener.settingStart = isStart; editByHandSaveDialogListener.editText = new WeakReference<>(textView); new AlertDialog.Builder(context) - .setTitle(str(isStart ? "sb_new_segment_time_start" : "sb_new_segment_time_end")) + .setTitle(str(isStart ? "revanced_sb_new_segment_time_start" : "revanced_sb_new_segment_time_end")) .setView(textView) .setNegativeButton(android.R.string.cancel, null) - .setNeutralButton(str("sb_new_segment_now"), editByHandSaveDialogListener) + .setNeutralButton(str("revanced_sb_new_segment_now"), editByHandSaveDialogListener) .setPositiveButton(android.R.string.ok, editByHandSaveDialogListener) .show(); dialog.dismiss(); } catch (Exception ex) { - LogHelper.printException(() -> "editByHandDialogListener failure", ex); + Logger.printException(() -> "editByHandDialogListener failure", ex); } }; private static final DialogInterface.OnClickListener segmentVoteClickListener = (dialog, which) -> { @@ -161,7 +161,7 @@ public void onClick(DialogInterface dialog, int which) { SponsorSegment[] segments = SegmentPlaybackController.getSegments(); if (segments == null || segments.length == 0) { // should never be reached - LogHelper.printException(() -> "Segment is no longer available on the client"); + Logger.printException(() -> "Segment is no longer available on the client"); return; } SponsorSegment segment = segments[which]; @@ -174,7 +174,7 @@ public void onClick(DialogInterface dialog, int which) { for (int i = 0; i < voteOptions.length; i++) { SegmentVote voteOption = voteOptions[i]; String title = voteOption.title.toString(); - if (SettingsEnum.SB_USER_IS_VIP.getBoolean() && segment.isLocked && voteOption.shouldHighlight) { + if (Settings.SB_USER_IS_VIP.get() && segment.isLocked && voteOption.shouldHighlight) { items[i] = Html.fromHtml(String.format("%s", LOCKED_COLOR, title)); } else { items[i] = title; @@ -196,7 +196,7 @@ public void onClick(DialogInterface dialog, int which) { }) .show(); } catch (Exception ex) { - LogHelper.printException(() -> "segmentVoteClickListener failure", ex); + Logger.printException(() -> "segmentVoteClickListener failure", ex); } }; @@ -215,62 +215,62 @@ static void clearUnsubmittedSegmentTimes() { private static void submitNewSegment() { try { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); final long start = newSponsorSegmentStartMillis; final long end = newSponsorSegmentEndMillis; final String videoId = VideoInformation.getVideoId(); final long videoLength = VideoInformation.getVideoLength(); final SegmentCategory segmentCategory = newUserCreatedSegmentCategory; if (start < 0 || end < 0 || start >= end || videoLength <= 0 || videoId.isEmpty() || segmentCategory == null) { - LogHelper.printException(() -> "invalid parameters"); + Logger.printException(() -> "invalid parameters"); return; } clearUnsubmittedSegmentTimes(); - ReVancedUtils.runOnBackgroundThread(() -> { - SBRequester.submitSegments(videoId, segmentCategory.key, start, end, videoLength); + Utils.runOnBackgroundThread(() -> { + SBRequester.submitSegments(videoId, segmentCategory.keyValue, start, end, videoLength); SegmentPlaybackController.executeDownloadSegments(videoId); }); } catch (Exception e) { - LogHelper.printException(() -> "Unable to submit segment", e); + Logger.printException(() -> "Unable to submit segment", e); } } public static void onMarkLocationClicked() { try { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); newSponsorSegmentDialogShownMillis = VideoInformation.getVideoTime(); new AlertDialog.Builder(SponsorBlockViewController.getOverLaysViewGroupContext()) - .setTitle(str("sb_new_segment_title")) - .setMessage(str("sb_new_segment_mark_time_as_question", + .setTitle(str("revanced_sb_new_segment_title")) + .setMessage(str("revanced_sb_new_segment_mark_time_as_question", newSponsorSegmentDialogShownMillis / 60000, newSponsorSegmentDialogShownMillis / 1000 % 60, newSponsorSegmentDialogShownMillis % 1000)) .setNeutralButton(android.R.string.cancel, null) - .setNegativeButton(str("sb_new_segment_mark_start"), newSponsorSegmentDialogListener) - .setPositiveButton(str("sb_new_segment_mark_end"), newSponsorSegmentDialogListener) + .setNegativeButton(str("revanced_sb_new_segment_mark_start"), newSponsorSegmentDialogListener) + .setPositiveButton(str("revanced_sb_new_segment_mark_end"), newSponsorSegmentDialogListener) .show(); } catch (Exception ex) { - LogHelper.printException(() -> "onMarkLocationClicked failure", ex); + Logger.printException(() -> "onMarkLocationClicked failure", ex); } } public static void onPublishClicked() { try { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); if (newSponsorSegmentStartMillis < 0 || newSponsorSegmentEndMillis < 0) { - ReVancedUtils.showToastShort(str("sb_new_segment_mark_locations_first")); + Utils.showToastShort(str("revanced_sb_new_segment_mark_locations_first")); } else if (newSponsorSegmentStartMillis >= newSponsorSegmentEndMillis) { - ReVancedUtils.showToastShort(str("sb_new_segment_start_is_before_end")); + Utils.showToastShort(str("revanced_sb_new_segment_start_is_before_end")); } else if (!newSponsorSegmentPreviewed && newSponsorSegmentStartMillis != 0) { - ReVancedUtils.showToastLong(str("sb_new_segment_preview_segment_first")); + Utils.showToastLong(str("revanced_sb_new_segment_preview_segment_first")); } else { long length = (newSponsorSegmentEndMillis - newSponsorSegmentStartMillis) / 1000; long start = (newSponsorSegmentStartMillis) / 1000; long end = (newSponsorSegmentEndMillis) / 1000; new AlertDialog.Builder(SponsorBlockViewController.getOverLaysViewGroupContext()) - .setTitle(str("sb_new_segment_confirm_title")) - .setMessage(str("sb_new_segment_confirm_content", + .setTitle(str("revanced_sb_new_segment_confirm_title")) + .setMessage(str("revanced_sb_new_segment_confirm_content", start / 60, start % 60, end / 60, end % 60, length / 60, length % 60)) @@ -279,19 +279,19 @@ public static void onPublishClicked() { .show(); } } catch (Exception ex) { - LogHelper.printException(() -> "onPublishClicked failure", ex); + Logger.printException(() -> "onPublishClicked failure", ex); } } public static void onVotingClicked(@NonNull Context context) { try { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); SponsorSegment[] segments = SegmentPlaybackController.getSegments(); if (segments == null || segments.length == 0) { // Button is hidden if no segments exist. // But if prior video had segments, and current video does not, // then the button persists until the overlay fades out (this is intentional, as abruptly hiding the button is jarring). - ReVancedUtils.showToastShort(str("sb_vote_no_segments")); + Utils.showToastShort(str("revanced_sb_vote_no_segments")); return; } @@ -333,13 +333,13 @@ public static void onVotingClicked(@NonNull Context context) { .setItems(titles, segmentVoteClickListener) .show(); } catch (Exception ex) { - LogHelper.printException(() -> "onVotingClicked failure", ex); + Logger.printException(() -> "onVotingClicked failure", ex); } } private static void onNewCategorySelect(@NonNull SponsorSegment segment, @NonNull Context context) { try { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); final SegmentCategory[] values = SegmentCategory.categoriesWithoutHighlights(); CharSequence[] titles = new CharSequence[values.length]; for (int i = 0; i < values.length; i++) { @@ -347,21 +347,21 @@ private static void onNewCategorySelect(@NonNull SponsorSegment segment, @NonNul } new AlertDialog.Builder(context) - .setTitle(str("sb_new_segment_choose_category")) + .setTitle(str("revanced_sb_new_segment_choose_category")) .setItems(titles, (dialog, which) -> SBRequester.voteToChangeCategoryOnBackgroundThread(segment, values[which])) .show(); } catch (Exception ex) { - LogHelper.printException(() -> "onNewCategorySelect failure", ex); + Logger.printException(() -> "onNewCategorySelect failure", ex); } } public static void onPreviewClicked() { try { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); if (newSponsorSegmentStartMillis < 0 || newSponsorSegmentEndMillis < 0) { - ReVancedUtils.showToastShort(str("sb_new_segment_mark_locations_first")); + Utils.showToastShort(str("revanced_sb_new_segment_mark_locations_first")); } else if (newSponsorSegmentStartMillis >= newSponsorSegmentEndMillis) { - ReVancedUtils.showToastShort(str("sb_new_segment_start_is_before_end")); + Utils.showToastShort(str("revanced_sb_new_segment_start_is_before_end")); } else { SegmentPlaybackController.removeUnsubmittedSegments(); // If user hits preview more than once before playing. SegmentPlaybackController.addUnsubmittedSegment( @@ -370,7 +370,7 @@ public static void onPreviewClicked() { VideoInformation.seekTo(newSponsorSegmentStartMillis - 2500); } } catch (Exception ex) { - LogHelper.printException(() -> "onPreviewClicked failure", ex); + Logger.printException(() -> "onPreviewClicked failure", ex); } } @@ -380,27 +380,27 @@ static void sendViewRequestAsync(@NonNull SponsorSegment segment) { return; } segment.recordedAsSkipped = true; - final long totalTimeSkipped = SettingsEnum.SB_LOCAL_TIME_SAVED_MILLISECONDS.getLong() + segment.length(); - SettingsEnum.SB_LOCAL_TIME_SAVED_MILLISECONDS.saveValue(totalTimeSkipped); - SettingsEnum.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.saveValue(SettingsEnum.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.getInt() + 1); + final long totalTimeSkipped = Settings.SB_LOCAL_TIME_SAVED_MILLISECONDS.get() + segment.length(); + Settings.SB_LOCAL_TIME_SAVED_MILLISECONDS.save(totalTimeSkipped); + Settings.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.save(Settings.SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS.get() + 1); - if (SettingsEnum.SB_TRACK_SKIP_COUNT.getBoolean()) { - ReVancedUtils.runOnBackgroundThread(() -> SBRequester.sendSegmentSkippedViewedRequest(segment)); + if (Settings.SB_TRACK_SKIP_COUNT.get()) { + Utils.runOnBackgroundThread(() -> SBRequester.sendSegmentSkippedViewedRequest(segment)); } } public static void onEditByHandClicked() { try { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); new AlertDialog.Builder(SponsorBlockViewController.getOverLaysViewGroupContext()) - .setTitle(str("sb_new_segment_edit_by_hand_title")) - .setMessage(str("sb_new_segment_edit_by_hand_content")) + .setTitle(str("revanced_sb_new_segment_edit_by_hand_title")) + .setMessage(str("revanced_sb_new_segment_edit_by_hand_content")) .setNeutralButton(android.R.string.cancel, null) - .setNegativeButton(str("sb_new_segment_mark_start"), editByHandDialogListener) - .setPositiveButton(str("sb_new_segment_mark_end"), editByHandDialogListener) + .setNegativeButton(str("revanced_sb_new_segment_mark_start"), editByHandDialogListener) + .setPositiveButton(str("revanced_sb_new_segment_mark_end"), editByHandDialogListener) .show(); } catch (Exception ex) { - LogHelper.printException(() -> "onEditByHandClicked failure", ex); + Logger.printException(() -> "onEditByHandClicked failure", ex); } } @@ -417,14 +417,14 @@ public static String getTimeSavedString(long totalSecondsSaved) { String minutesFormatted = statsNumberFormatter.format(minutes); if (hours > 0) { String hoursFormatted = statsNumberFormatter.format(hours); - return str("sb_stats_saved_hour_format", hoursFormatted, minutesFormatted); + return str("revanced_sb_stats_saved_hour_format", hoursFormatted, minutesFormatted); } final long seconds = duration.getSeconds() % 60; String secondsFormatted = statsNumberFormatter.format(seconds); if (minutes > 0) { - return str("sb_stats_saved_minute_format", minutesFormatted, secondsFormatted); + return str("revanced_sb_stats_saved_minute_format", minutesFormatted, secondsFormatted); } - return str("sb_stats_saved_second_format", secondsFormatted); + return str("revanced_sb_stats_saved_second_format", secondsFormatted); } return "error"; // will never be reached. YouTube requires Android O or greater } @@ -453,9 +453,9 @@ public void onClick(DialogInterface dialog, int which) { DialogInterface.BUTTON_NEGATIVE : DialogInterface.BUTTON_POSITIVE); } catch (ParseException e) { - ReVancedUtils.showToastLong(str("sb_new_segment_edit_by_hand_parse_error")); + Utils.showToastLong(str("revanced_sb_new_segment_edit_by_hand_parse_error")); } catch (Exception ex) { - LogHelper.printException(() -> "EditByHandSaveDialogListener failure", ex); + Logger.printException(() -> "EditByHandSaveDialogListener failure", ex); } } } diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/CategoryBehaviour.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/CategoryBehaviour.java similarity index 53% rename from app/src/main/java/app/revanced/integrations/sponsorblock/objects/CategoryBehaviour.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/CategoryBehaviour.java index 9b15d086f6..d34a8e6417 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/CategoryBehaviour.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/CategoryBehaviour.java @@ -1,27 +1,33 @@ -package app.revanced.integrations.sponsorblock.objects; +package app.revanced.integrations.youtube.sponsorblock.objects; -import static app.revanced.integrations.utils.StringRef.sf; +import static app.revanced.integrations.shared.StringRef.sf; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.Objects; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.StringRef; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.StringRef; public enum CategoryBehaviour { - SKIP_AUTOMATICALLY("skip", 2, true, sf("sb_skip_automatically")), + SKIP_AUTOMATICALLY("skip", 2, true, sf("revanced_sb_skip_automatically")), // desktop does not have skip-once behavior. Key is unique to ReVanced - SKIP_AUTOMATICALLY_ONCE("skip-once", 3, true, sf("sb_skip_automatically_once")), - MANUAL_SKIP("manual-skip", 1, false, sf("sb_skip_showbutton")), - SHOW_IN_SEEKBAR("seekbar-only", 0, false, sf("sb_skip_seekbaronly")), + SKIP_AUTOMATICALLY_ONCE("skip-once", 3, true, sf("revanced_sb_skip_automatically_once")), + MANUAL_SKIP("manual-skip", 1, false, sf("revanced_sb_skip_showbutton")), + SHOW_IN_SEEKBAR("seekbar-only", 0, false, sf("revanced_sb_skip_seekbaronly")), // ignored categories are not exported to json, and ignore is the default behavior when importing - IGNORE("ignore", -1, false, sf("sb_skip_ignore")); + IGNORE("ignore", -1, false, sf("revanced_sb_skip_ignore")); + /** + * ReVanced specific value. + */ @NonNull - public final String key; - public final int desktopKey; + public final String reVancedKeyValue; + /** + * Desktop specific value. + */ + public final int desktopKeyValue; /** * If the segment should skip automatically */ @@ -29,17 +35,17 @@ public enum CategoryBehaviour { @NonNull public final StringRef description; - CategoryBehaviour(String key, int desktopKey, boolean skipAutomatically, StringRef description) { - this.key = Objects.requireNonNull(key); - this.desktopKey = desktopKey; + CategoryBehaviour(String reVancedKeyValue, int desktopKeyValue, boolean skipAutomatically, StringRef description) { + this.reVancedKeyValue = Objects.requireNonNull(reVancedKeyValue); + this.desktopKeyValue = desktopKeyValue; this.skipAutomatically = skipAutomatically; this.description = Objects.requireNonNull(description); } @Nullable - public static CategoryBehaviour byStringKey(@NonNull String key) { + public static CategoryBehaviour byReVancedKeyValue(@NonNull String keyValue) { for (CategoryBehaviour behaviour : values()){ - if (behaviour.key.equals(key)) { + if (behaviour.reVancedKeyValue.equals(keyValue)) { return behaviour; } } @@ -47,58 +53,58 @@ public static CategoryBehaviour byStringKey(@NonNull String key) { } @Nullable - public static CategoryBehaviour byDesktopKey(int desktopKey) { + public static CategoryBehaviour byDesktopKeyValue(int desktopKeyValue) { for (CategoryBehaviour behaviour : values()) { - if (behaviour.desktopKey == desktopKey) { + if (behaviour.desktopKeyValue == desktopKeyValue) { return behaviour; } } return null; } - private static String[] behaviorKeys; + private static String[] behaviorKeyValues; private static String[] behaviorDescriptions; - private static String[] behaviorKeysWithoutSkipOnce; + private static String[] behaviorKeyValuesWithoutSkipOnce; private static String[] behaviorDescriptionsWithoutSkipOnce; private static void createNameAndKeyArrays() { - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); CategoryBehaviour[] behaviours = values(); final int behaviorLength = behaviours.length; - behaviorKeys = new String[behaviorLength]; + behaviorKeyValues = new String[behaviorLength]; behaviorDescriptions = new String[behaviorLength]; - behaviorKeysWithoutSkipOnce = new String[behaviorLength - 1]; + behaviorKeyValuesWithoutSkipOnce = new String[behaviorLength - 1]; behaviorDescriptionsWithoutSkipOnce = new String[behaviorLength - 1]; int behaviorIndex = 0, behaviorHighlightIndex = 0; while (behaviorIndex < behaviorLength) { CategoryBehaviour behaviour = behaviours[behaviorIndex]; - String key = behaviour.key; + String value = behaviour.reVancedKeyValue; String description = behaviour.description.toString(); - behaviorKeys[behaviorIndex] = key; + behaviorKeyValues[behaviorIndex] = value; behaviorDescriptions[behaviorIndex] = description; behaviorIndex++; if (behaviour != SKIP_AUTOMATICALLY_ONCE) { - behaviorKeysWithoutSkipOnce[behaviorHighlightIndex] = key; + behaviorKeyValuesWithoutSkipOnce[behaviorHighlightIndex] = value; behaviorDescriptionsWithoutSkipOnce[behaviorHighlightIndex] = description; behaviorHighlightIndex++; } } } - static String[] getBehaviorKeys() { - if (behaviorKeys == null) { + static String[] getBehaviorKeyValues() { + if (behaviorKeyValues == null) { createNameAndKeyArrays(); } - return behaviorKeys; + return behaviorKeyValues; } - static String[] getBehaviorKeysWithoutSkipOnce() { - if (behaviorKeysWithoutSkipOnce == null) { + static String[] getBehaviorKeyValuesWithoutSkipOnce() { + if (behaviorKeyValuesWithoutSkipOnce == null) { createNameAndKeyArrays(); } - return behaviorKeysWithoutSkipOnce; + return behaviorKeyValuesWithoutSkipOnce; } static String[] getBehaviorDescriptions() { diff --git a/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategory.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategory.java new file mode 100644 index 0000000000..03d74b3b7a --- /dev/null +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategory.java @@ -0,0 +1,332 @@ +package app.revanced.integrations.youtube.sponsorblock.objects; + +import static app.revanced.integrations.youtube.settings.Settings.*; +import static app.revanced.integrations.shared.StringRef.sf; + +import android.graphics.Color; +import android.graphics.Paint; +import android.text.Html; +import android.text.Spanned; +import android.text.TextUtils; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.settings.StringSetting; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.StringRef; + +public enum SegmentCategory { + SPONSOR("sponsor", sf("revanced_sb_segments_sponsor"), sf("revanced_sb_segments_sponsor_sum"), sf("revanced_sb_skip_button_sponsor"), sf("revanced_sb_skipped_sponsor"), + SB_CATEGORY_SPONSOR, SB_CATEGORY_SPONSOR_COLOR), + SELF_PROMO("selfpromo", sf("revanced_sb_segments_selfpromo"), sf("revanced_sb_segments_selfpromo_sum"), sf("revanced_sb_skip_button_selfpromo"), sf("revanced_sb_skipped_selfpromo"), + SB_CATEGORY_SELF_PROMO, SB_CATEGORY_SELF_PROMO_COLOR), + INTERACTION("interaction", sf("revanced_sb_segments_interaction"), sf("revanced_sb_segments_interaction_sum"), sf("revanced_sb_skip_button_interaction"), sf("revanced_sb_skipped_interaction"), + SB_CATEGORY_INTERACTION, SB_CATEGORY_INTERACTION_COLOR), + /** + * Unique category that is treated differently than the rest. + */ + HIGHLIGHT("poi_highlight", sf("revanced_sb_segments_highlight"), sf("revanced_sb_segments_highlight_sum"), sf("revanced_sb_skip_button_highlight"), sf("revanced_sb_skipped_highlight"), + SB_CATEGORY_HIGHLIGHT, SB_CATEGORY_HIGHLIGHT_COLOR), + INTRO("intro", sf("revanced_sb_segments_intro"), sf("revanced_sb_segments_intro_sum"), + sf("revanced_sb_skip_button_intro_beginning"), sf("revanced_sb_skip_button_intro_middle"), sf("revanced_sb_skip_button_intro_end"), + sf("revanced_sb_skipped_intro_beginning"), sf("revanced_sb_skipped_intro_middle"), sf("revanced_sb_skipped_intro_end"), + SB_CATEGORY_INTRO, SB_CATEGORY_INTRO_COLOR), + OUTRO("outro", sf("revanced_sb_segments_outro"), sf("revanced_sb_segments_outro_sum"), sf("revanced_sb_skip_button_outro"), sf("revanced_sb_skipped_outro"), + SB_CATEGORY_OUTRO, SB_CATEGORY_OUTRO_COLOR), + PREVIEW("preview", sf("revanced_sb_segments_preview"), sf("revanced_sb_segments_preview_sum"), + sf("revanced_sb_skip_button_preview_beginning"), sf("revanced_sb_skip_button_preview_middle"), sf("revanced_sb_skip_button_preview_end"), + sf("revanced_sb_skipped_preview_beginning"), sf("revanced_sb_skipped_preview_middle"), sf("revanced_sb_skipped_preview_end"), + SB_CATEGORY_PREVIEW, SB_CATEGORY_PREVIEW_COLOR), + FILLER("filler", sf("revanced_sb_segments_filler"), sf("revanced_sb_segments_filler_sum"), sf("revanced_sb_skip_button_filler"), sf("revanced_sb_skipped_filler"), + SB_CATEGORY_FILLER, SB_CATEGORY_FILLER_COLOR), + MUSIC_OFFTOPIC("music_offtopic", sf("revanced_sb_segments_nomusic"), sf("revanced_sb_segments_nomusic_sum"), sf("revanced_sb_skip_button_nomusic"), sf("revanced_sb_skipped_nomusic"), + SB_CATEGORY_MUSIC_OFFTOPIC, SB_CATEGORY_MUSIC_OFFTOPIC_COLOR), + UNSUBMITTED("unsubmitted", StringRef.empty, StringRef.empty, sf("revanced_sb_skip_button_unsubmitted"), sf("revanced_sb_skipped_unsubmitted"), + SB_CATEGORY_UNSUBMITTED, SB_CATEGORY_UNSUBMITTED_COLOR),; + + private static final StringRef skipSponsorTextCompact = sf("revanced_sb_skip_button_compact"); + private static final StringRef skipSponsorTextCompactHighlight = sf("revanced_sb_skip_button_compact_highlight"); + + private static final SegmentCategory[] categoriesWithoutHighlights = new SegmentCategory[]{ + SPONSOR, + SELF_PROMO, + INTERACTION, + INTRO, + OUTRO, + PREVIEW, + FILLER, + MUSIC_OFFTOPIC, + }; + + private static final SegmentCategory[] categoriesWithoutUnsubmitted = new SegmentCategory[]{ + SPONSOR, + SELF_PROMO, + INTERACTION, + HIGHLIGHT, + INTRO, + OUTRO, + PREVIEW, + FILLER, + MUSIC_OFFTOPIC, + }; + private static final Map mValuesMap = new HashMap<>(2 * categoriesWithoutUnsubmitted.length); + + /** + * Categories currently enabled, formatted for an API call + */ + public static String sponsorBlockAPIFetchCategories = "[]"; + + static { + for (SegmentCategory value : categoriesWithoutUnsubmitted) + mValuesMap.put(value.keyValue, value); + } + + @NonNull + public static SegmentCategory[] categoriesWithoutUnsubmitted() { + return categoriesWithoutUnsubmitted; + } + + @NonNull + public static SegmentCategory[] categoriesWithoutHighlights() { + return categoriesWithoutHighlights; + } + + @Nullable + public static SegmentCategory byCategoryKey(@NonNull String key) { + return mValuesMap.get(key); + } + + /** + * Must be called if behavior of any category is changed + */ + public static void updateEnabledCategories() { + Utils.verifyOnMainThread(); + Logger.printDebug(() -> "updateEnabledCategories"); + SegmentCategory[] categories = categoriesWithoutUnsubmitted(); + List enabledCategories = new ArrayList<>(categories.length); + for (SegmentCategory category : categories) { + if (category.behaviour != CategoryBehaviour.IGNORE) { + enabledCategories.add(category.keyValue); + } + } + + //"[%22sponsor%22,%22outro%22,%22music_offtopic%22,%22intro%22,%22selfpromo%22,%22interaction%22,%22preview%22]"; + if (enabledCategories.isEmpty()) + sponsorBlockAPIFetchCategories = "[]"; + else + sponsorBlockAPIFetchCategories = "[%22" + TextUtils.join("%22,%22", enabledCategories) + "%22]"; + } + + public static void loadAllCategoriesFromSettings() { + for (SegmentCategory category : values()) { + category.loadFromSettings(); + } + updateEnabledCategories(); + } + + @NonNull + public final String keyValue; + @NonNull + private final StringSetting behaviorSetting; + @NonNull + private final StringSetting colorSetting; + + @NonNull + public final StringRef title; + @NonNull + public final StringRef description; + + /** + * Skip button text, if the skip occurs in the first quarter of the video + */ + @NonNull + public final StringRef skipButtonTextBeginning; + /** + * Skip button text, if the skip occurs in the middle half of the video + */ + @NonNull + public final StringRef skipButtonTextMiddle; + /** + * Skip button text, if the skip occurs in the last quarter of the video + */ + @NonNull + public final StringRef skipButtonTextEnd; + /** + * Skipped segment toast, if the skip occurred in the first quarter of the video + */ + @NonNull + public final StringRef skippedToastBeginning; + /** + * Skipped segment toast, if the skip occurred in the middle half of the video + */ + @NonNull + public final StringRef skippedToastMiddle; + /** + * Skipped segment toast, if the skip occurred in the last quarter of the video + */ + @NonNull + public final StringRef skippedToastEnd; + + @NonNull + public final Paint paint; + + /** + * Value must be changed using {@link #setColor(String)}. + */ + public int color; + + /** + * Value must be changed using {@link #setBehaviour(CategoryBehaviour)}. + * Caller must also {@link #updateEnabledCategories()}. + */ + @NonNull + public CategoryBehaviour behaviour = CategoryBehaviour.IGNORE; + + SegmentCategory(String keyValue, StringRef title, StringRef description, + StringRef skipButtonText, + StringRef skippedToastText, + StringSetting behavior, StringSetting color) { + this(keyValue, title, description, + skipButtonText, skipButtonText, skipButtonText, + skippedToastText, skippedToastText, skippedToastText, + behavior, color); + } + + SegmentCategory(String keyValue, StringRef title, StringRef description, + StringRef skipButtonTextBeginning, StringRef skipButtonTextMiddle, StringRef skipButtonTextEnd, + StringRef skippedToastBeginning, StringRef skippedToastMiddle, StringRef skippedToastEnd, + StringSetting behavior, StringSetting color) { + this.keyValue = Objects.requireNonNull(keyValue); + this.title = Objects.requireNonNull(title); + this.description = Objects.requireNonNull(description); + this.skipButtonTextBeginning = Objects.requireNonNull(skipButtonTextBeginning); + this.skipButtonTextMiddle = Objects.requireNonNull(skipButtonTextMiddle); + this.skipButtonTextEnd = Objects.requireNonNull(skipButtonTextEnd); + this.skippedToastBeginning = Objects.requireNonNull(skippedToastBeginning); + this.skippedToastMiddle = Objects.requireNonNull(skippedToastMiddle); + this.skippedToastEnd = Objects.requireNonNull(skippedToastEnd); + this.behaviorSetting = Objects.requireNonNull(behavior); + this.colorSetting = Objects.requireNonNull(color); + this.paint = new Paint(); + loadFromSettings(); + } + + private void loadFromSettings() { + String behaviorString = behaviorSetting.get(); + CategoryBehaviour savedBehavior = CategoryBehaviour.byReVancedKeyValue(behaviorString); + if (savedBehavior == null) { + Logger.printException(() -> "Invalid behavior: " + behaviorString); + behaviorSetting.resetToDefault(); + loadFromSettings(); + return; + } + this.behaviour = savedBehavior; + + String colorString = colorSetting.get(); + try { + setColor(colorString); + } catch (Exception ex) { + Logger.printException(() -> "Invalid color: " + colorString, ex); + colorSetting.resetToDefault(); + loadFromSettings(); + } + } + + public void setBehaviour(@NonNull CategoryBehaviour behaviour) { + this.behaviour = Objects.requireNonNull(behaviour); + this.behaviorSetting.save(behaviour.reVancedKeyValue); + } + /** + * @return HTML color format string + */ + @NonNull + public String colorString() { + return String.format("#%06X", color); + } + + public void setColor(@NonNull String colorString) throws IllegalArgumentException { + final int color = Color.parseColor(colorString) & 0xFFFFFF; + this.color = color; + paint.setColor(color); + paint.setAlpha(255); + colorSetting.save(colorString); // Save after parsing. + } + + public void resetColor() { + setColor(colorSetting.defaultValue); + } + + @NonNull + private static String getCategoryColorDotHTML(int color) { + color &= 0xFFFFFF; + return String.format("⬤", color); + } + + @NonNull + public static Spanned getCategoryColorDot(int color) { + return Html.fromHtml(getCategoryColorDotHTML(color)); + } + + @NonNull + public Spanned getCategoryColorDot() { + return getCategoryColorDot(color); + } + + @NonNull + public Spanned getTitleWithColorDot() { + return Html.fromHtml(getCategoryColorDotHTML(color) + " " + title); + } + + /** + * @param segmentStartTime video time the segment category started + * @param videoLength length of the video + * @return the skip button text + */ + @NonNull + StringRef getSkipButtonText(long segmentStartTime, long videoLength) { + if (Settings.SB_COMPACT_SKIP_BUTTON.get()) { + return (this == SegmentCategory.HIGHLIGHT) + ? skipSponsorTextCompactHighlight + : skipSponsorTextCompact; + } + + if (videoLength == 0) { + return skipButtonTextBeginning; // video is still loading. Assume it's the beginning + } + final float position = segmentStartTime / (float) videoLength; + if (position < 0.25f) { + return skipButtonTextBeginning; + } else if (position < 0.75f) { + return skipButtonTextMiddle; + } + return skipButtonTextEnd; + } + + /** + * @param segmentStartTime video time the segment category started + * @param videoLength length of the video + * @return 'skipped segment' toast message + */ + @NonNull + StringRef getSkippedToastText(long segmentStartTime, long videoLength) { + if (videoLength == 0) { + return skippedToastBeginning; // video is still loading. Assume it's the beginning + } + final float position = segmentStartTime / (float) videoLength; + if (position < 0.25f) { + return skippedToastBeginning; + } else if (position < 0.75f) { + return skippedToastMiddle; + } + return skippedToastEnd; + } +} diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategoryListPreference.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategoryListPreference.java similarity index 73% rename from app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategoryListPreference.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategoryListPreference.java index b2e9e2c9b7..09235e8504 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SegmentCategoryListPreference.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SegmentCategoryListPreference.java @@ -1,11 +1,10 @@ -package app.revanced.integrations.sponsorblock.objects; +package app.revanced.integrations.youtube.sponsorblock.objects; -import static app.revanced.integrations.utils.StringRef.str; +import static app.revanced.integrations.shared.StringRef.str; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.content.SharedPreferences; import android.graphics.Color; import android.preference.ListPreference; import android.text.Editable; @@ -19,8 +18,8 @@ import java.util.Objects; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; public class SegmentCategoryListPreference extends ListPreference { private final SegmentCategory category; @@ -31,14 +30,14 @@ public SegmentCategoryListPreference(Context context, SegmentCategory category) super(context); final boolean isHighlightCategory = category == SegmentCategory.HIGHLIGHT; this.category = Objects.requireNonNull(category); - setKey(category.key); - setDefaultValue(category.behaviour.key); + setKey(category.keyValue); + setDefaultValue(category.behaviour.reVancedKeyValue); setEntries(isHighlightCategory ? CategoryBehaviour.getBehaviorDescriptionsWithoutSkipOnce() : CategoryBehaviour.getBehaviorDescriptions()); setEntryValues(isHighlightCategory - ? CategoryBehaviour.getBehaviorKeysWithoutSkipOnce() - : CategoryBehaviour.getBehaviorKeys()); + ? CategoryBehaviour.getBehaviorKeyValuesWithoutSkipOnce() + : CategoryBehaviour.getBehaviorKeyValues()); setSummary(category.description.toString()); updateTitle(); } @@ -54,7 +53,7 @@ protected void onPrepareDialogBuilder(AlertDialog.Builder builder) { TableRow row = new TableRow(context); TextView colorTextLabel = new TextView(context); - colorTextLabel.setText(str("sb_color_dot_label")); + colorTextLabel.setText(str("revanced_sb_color_dot_label")); row.addView(colorTextLabel); TextView colorDotView = new TextView(context); @@ -103,16 +102,13 @@ public void afterTextChanged(Editable s) { builder.setPositiveButton(android.R.string.ok, (dialog, which) -> { onClick(dialog, DialogInterface.BUTTON_POSITIVE); }); - builder.setNeutralButton(str("sb_reset_color"), (dialog, which) -> { + builder.setNeutralButton(str("revanced_sb_reset_color"), (dialog, which) -> { try { - SharedPreferences.Editor editor = getSharedPreferences().edit(); - category.setColor(category.defaultColor); - category.save(editor); - editor.apply(); + category.resetColor(); updateTitle(); - ReVancedUtils.showToastShort(str("sb_color_reset")); + Utils.showToastShort(str("revanced_sb_color_reset")); } catch (Exception ex) { - LogHelper.printException(() -> "setNeutralButton failure", ex); + Logger.printException(() -> "setNeutralButton failure", ex); } }); builder.setNegativeButton(android.R.string.cancel, null); @@ -120,7 +116,7 @@ public void afterTextChanged(Editable s) { mClickedDialogEntryIndex = findIndexOfValue(getValue()); builder.setSingleChoiceItems(getEntries(), mClickedDialogEntryIndex, (dialog, which) -> mClickedDialogEntryIndex = which); } catch (Exception ex) { - LogHelper.printException(() -> "onPrepareDialogBuilder failure", ex); + Logger.printException(() -> "onPrepareDialogBuilder failure", ex); } } @@ -131,27 +127,22 @@ protected void onDialogClosed(boolean positiveResult) { String value = getEntryValues()[mClickedDialogEntryIndex].toString(); if (callChangeListener(value)) { setValue(value); - category.behaviour = Objects.requireNonNull(CategoryBehaviour.byStringKey(value)); + category.setBehaviour(Objects.requireNonNull(CategoryBehaviour.byReVancedKeyValue(value))); SegmentCategory.updateEnabledCategories(); } String colorString = mEditText.getText().toString(); try { - final int color = Color.parseColor(colorString) & 0xFFFFFF; - if (color != category.color) { - category.setColor(color); - ReVancedUtils.showToastShort(str("sb_color_changed")); + if (!colorString.equals(category.colorString())) { + category.setColor(colorString); + Utils.showToastShort(str("revanced_sb_color_changed")); } } catch (IllegalArgumentException ex) { - ReVancedUtils.showToastShort(str("sb_color_invalid")); + Utils.showToastShort(str("revanced_sb_color_invalid")); } - // behavior is already saved, but color needs to be saved - SharedPreferences.Editor editor = getSharedPreferences().edit(); - category.save(editor); - editor.apply(); updateTitle(); } } catch (Exception ex) { - LogHelper.printException(() -> "onDialogClosed failure", ex); + Logger.printException(() -> "onDialogClosed failure", ex); } } diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SponsorSegment.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SponsorSegment.java similarity index 89% rename from app/src/main/java/app/revanced/integrations/sponsorblock/objects/SponsorSegment.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SponsorSegment.java index 60c6059867..7e8d529e59 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/SponsorSegment.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/SponsorSegment.java @@ -1,19 +1,19 @@ -package app.revanced.integrations.sponsorblock.objects; +package app.revanced.integrations.youtube.sponsorblock.objects; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.utils.StringRef; +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.shared.StringRef; import java.util.Objects; -import static app.revanced.integrations.utils.StringRef.sf; +import static app.revanced.integrations.shared.StringRef.sf; public class SponsorSegment implements Comparable { public enum SegmentVote { - UPVOTE(sf("sb_vote_upvote"), 1,false), - DOWNVOTE(sf("sb_vote_downvote"), 0, true), - CATEGORY_CHANGE(sf("sb_vote_category"), -1, true); // apiVoteType is not used for category change + UPVOTE(sf("revanced_sb_vote_upvote"), 1,false), + DOWNVOTE(sf("revanced_sb_vote_downvote"), 0, true), + CATEGORY_CHANGE(sf("revanced_sb_vote_category"), -1, true); // apiVoteType is not used for category change public static final SegmentVote[] voteTypesWithoutCategoryChange = { UPVOTE, diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/UserStats.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/UserStats.java similarity index 96% rename from app/src/main/java/app/revanced/integrations/sponsorblock/objects/UserStats.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/UserStats.java index ae5bdbc4f6..f74b22e525 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/objects/UserStats.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/objects/UserStats.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.sponsorblock.objects; +package app.revanced.integrations.youtube.sponsorblock.objects; import androidx.annotation.NonNull; diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/requests/SBRequester.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/requests/SBRequester.java similarity index 67% rename from app/src/main/java/app/revanced/integrations/sponsorblock/requests/SBRequester.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/requests/SBRequester.java index 6bb699173a..020fd03849 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/requests/SBRequester.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/requests/SBRequester.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.sponsorblock.requests; +package app.revanced.integrations.youtube.sponsorblock.requests; -import static app.revanced.integrations.utils.StringRef.str; +import static app.revanced.integrations.shared.StringRef.str; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -17,16 +17,16 @@ import java.util.Locale; import java.util.concurrent.TimeUnit; -import app.revanced.integrations.requests.Requester; -import app.revanced.integrations.requests.Route; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.sponsorblock.SponsorBlockSettings; -import app.revanced.integrations.sponsorblock.objects.SegmentCategory; -import app.revanced.integrations.sponsorblock.objects.SponsorSegment; -import app.revanced.integrations.sponsorblock.objects.SponsorSegment.SegmentVote; -import app.revanced.integrations.sponsorblock.objects.UserStats; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.youtube.requests.Requester; +import app.revanced.integrations.youtube.requests.Route; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.sponsorblock.SponsorBlockSettings; +import app.revanced.integrations.youtube.sponsorblock.objects.SegmentCategory; +import app.revanced.integrations.youtube.sponsorblock.objects.SponsorSegment; +import app.revanced.integrations.youtube.sponsorblock.objects.SponsorSegment.SegmentVote; +import app.revanced.integrations.youtube.sponsorblock.objects.UserStats; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; public class SBRequester { private static final String TIME_TEMPLATE = "%.3f"; @@ -50,17 +50,17 @@ private SBRequester() { } private static void handleConnectionError(@NonNull String toastMessage, @Nullable Exception ex) { - if (SettingsEnum.SB_TOAST_ON_CONNECTION_ERROR.getBoolean()) { - ReVancedUtils.showToastShort(toastMessage); + if (Settings.SB_TOAST_ON_CONNECTION_ERROR.get()) { + Utils.showToastShort(toastMessage); } if (ex != null) { - LogHelper.printInfo(() -> toastMessage, ex); + Logger.printInfo(() -> toastMessage, ex); } } @NonNull public static SponsorSegment[] getSegments(@NonNull String videoId) { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); List segments = new ArrayList<>(); try { HttpURLConnection connection = getConnectionFromRoute(SBRoutes.GET_SEGMENTS, videoId, SegmentCategory.sponsorBlockAPIFetchCategories); @@ -68,7 +68,7 @@ public static SponsorSegment[] getSegments(@NonNull String videoId) { if (responseCode == HTTP_STATUS_CODE_SUCCESS) { JSONArray responseArray = Requester.parseJSONArray(connection); - final long minSegmentDuration = (long) (SettingsEnum.SB_SEGMENT_MIN_DURATION.getFloat() * 1000); + final long minSegmentDuration = (long) (Settings.SB_SEGMENT_MIN_DURATION.get() * 1000); for (int i = 0, length = responseArray.length(); i < length; i++) { JSONObject obj = (JSONObject) responseArray.get(i); JSONArray segment = obj.getJSONArray("segment"); @@ -80,12 +80,12 @@ public static SponsorSegment[] getSegments(@NonNull String videoId) { String categoryKey = obj.getString("category"); SegmentCategory category = SegmentCategory.byCategoryKey(categoryKey); if (category == null) { - LogHelper.printException(() -> "Received unknown category: " + categoryKey); // should never happen + Logger.printException(() -> "Received unknown category: " + categoryKey); // should never happen } else if ((end - start) >= minSegmentDuration || category == SegmentCategory.HIGHLIGHT) { segments.add(new SponsorSegment(category, uuid, start, end, locked)); } } - LogHelper.printDebug(() -> { + Logger.printDebug(() -> { StringBuilder builder = new StringBuilder("Downloaded segments:"); for (SponsorSegment segment : segments) { builder.append('\n').append(segment); @@ -95,18 +95,18 @@ public static SponsorSegment[] getSegments(@NonNull String videoId) { runVipCheckInBackgroundIfNeeded(); } else if (responseCode == 404) { // no segments are found. a normal response - LogHelper.printDebug(() -> "No segments found for video: " + videoId); + Logger.printDebug(() -> "No segments found for video: " + videoId); } else { - handleConnectionError(str("sb_sponsorblock_connection_failure_status", responseCode), null); + handleConnectionError(str("revanced_sb_sponsorblock_connection_failure_status", responseCode), null); connection.disconnect(); // something went wrong, might as well disconnect } } catch (SocketTimeoutException ex) { - handleConnectionError(str("sb_sponsorblock_connection_failure_timeout"), ex); + handleConnectionError(str("revanced_sb_sponsorblock_connection_failure_timeout"), ex); } catch (IOException ex) { - handleConnectionError(str("sb_sponsorblock_connection_failure_generic"), ex); + handleConnectionError(str("revanced_sb_sponsorblock_connection_failure_generic"), ex); } catch (Exception ex) { // Should never happen - LogHelper.printException(() -> "getSegments failure", ex); + Logger.printException(() -> "getSegments failure", ex); } // Crude debug tests to verify random features @@ -140,7 +140,7 @@ public static SponsorSegment[] getSegments(@NonNull String videoId) { public static void submitSegments(@NonNull String videoId, @NonNull String category, long startTime, long endTime, long videoLength) { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); try { String privateUserId = SponsorBlockSettings.getSBPrivateUserID(); String start = String.format(Locale.US, TIME_TEMPLATE, startTime / 1000f); @@ -153,51 +153,51 @@ public static void submitSegments(@NonNull String videoId, @NonNull String categ final String messageToToast; switch (responseCode) { case HTTP_STATUS_CODE_SUCCESS: - messageToToast = str("sb_submit_succeeded"); + messageToToast = str("revanced_sb_submit_succeeded"); break; case 409: - messageToToast = str("sb_submit_failed_duplicate"); + messageToToast = str("revanced_sb_submit_failed_duplicate"); break; case 403: - messageToToast = str("sb_submit_failed_forbidden", Requester.parseErrorJsonAndDisconnect(connection)); + messageToToast = str("revanced_sb_submit_failed_forbidden", Requester.parseErrorJsonAndDisconnect(connection)); break; case 429: - messageToToast = str("sb_submit_failed_rate_limit"); + messageToToast = str("revanced_sb_submit_failed_rate_limit"); break; case 400: - messageToToast = str("sb_submit_failed_invalid", Requester.parseErrorJsonAndDisconnect(connection)); + messageToToast = str("revanced_sb_submit_failed_invalid", Requester.parseErrorJsonAndDisconnect(connection)); break; default: - messageToToast = str("sb_submit_failed_unknown_error", responseCode, connection.getResponseMessage()); + messageToToast = str("revanced_sb_submit_failed_unknown_error", responseCode, connection.getResponseMessage()); break; } - ReVancedUtils.showToastLong(messageToToast); + Utils.showToastLong(messageToToast); } catch (SocketTimeoutException ex) { // Always show, even if show connection toasts is turned off - ReVancedUtils.showToastLong(str("sb_submit_failed_timeout")); + Utils.showToastLong(str("revanced_sb_submit_failed_timeout")); } catch (IOException ex) { - ReVancedUtils.showToastLong(str("sb_submit_failed_unknown_error", 0, ex.getMessage())); + Utils.showToastLong(str("revanced_sb_submit_failed_unknown_error", 0, ex.getMessage())); } catch (Exception ex) { - LogHelper.printException(() -> "failed to submit segments", ex); + Logger.printException(() -> "failed to submit segments", ex); } } public static void sendSegmentSkippedViewedRequest(@NonNull SponsorSegment segment) { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); try { HttpURLConnection connection = getConnectionFromRoute(SBRoutes.VIEWED_SEGMENT, segment.UUID); final int responseCode = connection.getResponseCode(); if (responseCode == HTTP_STATUS_CODE_SUCCESS) { - LogHelper.printDebug(() -> "Successfully sent view count for segment: " + segment); + Logger.printDebug(() -> "Successfully sent view count for segment: " + segment); } else { - LogHelper.printDebug(() -> "Failed to sent view count for segment: " + segment.UUID + Logger.printDebug(() -> "Failed to sent view count for segment: " + segment.UUID + " responseCode: " + responseCode); // debug level, no toast is shown } } catch (IOException ex) { - LogHelper.printInfo(() -> "Failed to send view count", ex); // do not show a toast + Logger.printInfo(() -> "Failed to send view count", ex); // do not show a toast } catch (Exception ex) { - LogHelper.printException(() -> "Failed to send view count request", ex); // should never happen + Logger.printException(() -> "Failed to send view count request", ex); // should never happen } } @@ -208,34 +208,34 @@ public static void voteToChangeCategoryOnBackgroundThread(@NonNull SponsorSegmen voteOrRequestCategoryChange(segment, SegmentVote.CATEGORY_CHANGE, categoryToVoteFor); } private static void voteOrRequestCategoryChange(@NonNull SponsorSegment segment, @NonNull SegmentVote voteOption, SegmentCategory categoryToVoteFor) { - ReVancedUtils.runOnBackgroundThread(() -> { + Utils.runOnBackgroundThread(() -> { try { String segmentUuid = segment.UUID; String uuid = SponsorBlockSettings.getSBPrivateUserID(); HttpURLConnection connection = (voteOption == SegmentVote.CATEGORY_CHANGE) - ? getConnectionFromRoute(SBRoutes.VOTE_ON_SEGMENT_CATEGORY, uuid, segmentUuid, categoryToVoteFor.key) + ? getConnectionFromRoute(SBRoutes.VOTE_ON_SEGMENT_CATEGORY, uuid, segmentUuid, categoryToVoteFor.keyValue) : getConnectionFromRoute(SBRoutes.VOTE_ON_SEGMENT_QUALITY, uuid, segmentUuid, String.valueOf(voteOption.apiVoteType)); final int responseCode = connection.getResponseCode(); switch (responseCode) { case HTTP_STATUS_CODE_SUCCESS: - LogHelper.printDebug(() -> "Vote success for segment: " + segment); + Logger.printDebug(() -> "Vote success for segment: " + segment); break; case 403: - ReVancedUtils.showToastLong( - str("sb_vote_failed_forbidden", Requester.parseErrorJsonAndDisconnect(connection))); + Utils.showToastLong( + str("revanced_sb_vote_failed_forbidden", Requester.parseErrorJsonAndDisconnect(connection))); break; default: - ReVancedUtils.showToastLong( - str("sb_vote_failed_unknown_error", responseCode, connection.getResponseMessage())); + Utils.showToastLong( + str("revanced_sb_vote_failed_unknown_error", responseCode, connection.getResponseMessage())); break; } } catch (SocketTimeoutException ex) { - ReVancedUtils.showToastShort(str("sb_vote_failed_timeout")); + Utils.showToastShort(str("revanced_sb_vote_failed_timeout")); } catch (IOException ex) { - ReVancedUtils.showToastShort(str("sb_vote_failed_unknown_error", 0, ex.getMessage())); + Utils.showToastShort(str("revanced_sb_vote_failed_unknown_error", 0, ex.getMessage())); } catch (Exception ex) { - LogHelper.printException(() -> "failed to vote for segment", ex); // should never happen + Logger.printException(() -> "failed to vote for segment", ex); // should never happen } }); } @@ -245,15 +245,15 @@ private static void voteOrRequestCategoryChange(@NonNull SponsorSegment segment, */ @Nullable public static UserStats retrieveUserStats() { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); try { UserStats stats = new UserStats(getJSONObject(SBRoutes.GET_USER_STATS, SponsorBlockSettings.getSBPrivateUserID())); - LogHelper.printDebug(() -> "user stats: " + stats); + Logger.printDebug(() -> "user stats: " + stats); return stats; } catch (IOException ex) { - LogHelper.printInfo(() -> "failed to retrieve user stats", ex); // info level, do not show a toast + Logger.printInfo(() -> "failed to retrieve user stats", ex); // info level, do not show a toast } catch (Exception ex) { - LogHelper.printException(() -> "failure retrieving user stats", ex); // should never happen + Logger.printException(() -> "failure retrieving user stats", ex); // should never happen } return null; } @@ -263,7 +263,7 @@ public static UserStats retrieveUserStats() { */ @Nullable public static String setUsername(@NonNull String username) { - ReVancedUtils.verifyOffMainThread(); + Utils.verifyOffMainThread(); try { HttpURLConnection connection = getConnectionFromRoute(SBRoutes.CHANGE_USERNAME, SponsorBlockSettings.getSBPrivateUserID(), username); final int responseCode = connection.getResponseCode(); @@ -271,10 +271,10 @@ public static String setUsername(@NonNull String username) { if (responseCode == HTTP_STATUS_CODE_SUCCESS) { return null; } - return str("sb_stats_username_change_unknown_error", responseCode, responseMessage); + return str("revanced_sb_stats_username_change_unknown_error", responseCode, responseMessage); } catch (Exception ex) { // should never happen - LogHelper.printInfo(() -> "failed to set username", ex); // do not toast - return str("sb_stats_username_change_unknown_error", 0, ex.getMessage()); + Logger.printInfo(() -> "failed to set username", ex); // do not toast + return str("revanced_sb_stats_username_change_unknown_error", 0, ex.getMessage()); } } @@ -283,19 +283,19 @@ public static void runVipCheckInBackgroundIfNeeded() { return; // User cannot be a VIP. User has never voted, created any segments, or has imported a SB user id. } long now = System.currentTimeMillis(); - if (now < (SettingsEnum.SB_LAST_VIP_CHECK.getLong() + TimeUnit.DAYS.toMillis(3))) { + if (now < (Settings.SB_LAST_VIP_CHECK.get() + TimeUnit.DAYS.toMillis(3))) { return; } - ReVancedUtils.runOnBackgroundThread(() -> { + Utils.runOnBackgroundThread(() -> { try { JSONObject json = getJSONObject(SBRoutes.IS_USER_VIP, SponsorBlockSettings.getSBPrivateUserID()); boolean vip = json.getBoolean("vip"); - SettingsEnum.SB_USER_IS_VIP.saveValue(vip); - SettingsEnum.SB_LAST_VIP_CHECK.saveValue(now); + Settings.SB_USER_IS_VIP.save(vip); + Settings.SB_LAST_VIP_CHECK.save(now); } catch (IOException ex) { - LogHelper.printInfo(() -> "Failed to check VIP (network error)", ex); // info, so no error toast is shown + Logger.printInfo(() -> "Failed to check VIP (network error)", ex); // info, so no error toast is shown } catch (Exception ex) { - LogHelper.printException(() -> "Failed to check VIP", ex); // should never happen + Logger.printException(() -> "Failed to check VIP", ex); // should never happen } }); } @@ -303,7 +303,7 @@ public static void runVipCheckInBackgroundIfNeeded() { // helpers private static HttpURLConnection getConnectionFromRoute(@NonNull Route route, String... params) throws IOException { - HttpURLConnection connection = Requester.getConnectionFromRoute(SettingsEnum.SB_API_URL.getString(), route, params); + HttpURLConnection connection = Requester.getConnectionFromRoute(Settings.SB_API_URL.get(), route, params); connection.setConnectTimeout(TIMEOUT_TCP_DEFAULT_MILLISECONDS); connection.setReadTimeout(TIMEOUT_HTTP_DEFAULT_MILLISECONDS); return connection; diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/requests/SBRoutes.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/requests/SBRoutes.java similarity index 81% rename from app/src/main/java/app/revanced/integrations/sponsorblock/requests/SBRoutes.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/requests/SBRoutes.java index 5fbe688a3a..3e1c8dafca 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/requests/SBRoutes.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/requests/SBRoutes.java @@ -1,9 +1,9 @@ -package app.revanced.integrations.sponsorblock.requests; +package app.revanced.integrations.youtube.sponsorblock.requests; -import static app.revanced.integrations.requests.Route.Method.GET; -import static app.revanced.integrations.requests.Route.Method.POST; +import static app.revanced.integrations.youtube.requests.Route.Method.GET; +import static app.revanced.integrations.youtube.requests.Route.Method.POST; -import app.revanced.integrations.requests.Route; +import app.revanced.integrations.youtube.requests.Route; class SBRoutes { static final Route IS_USER_VIP = new Route(GET, "/api/isUserVIP?userID={user_id}"); diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/CreateSegmentButtonController.java similarity index 74% rename from app/src/main/java/app/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/CreateSegmentButtonController.java index 83528d0914..dffdf9ff48 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/CreateSegmentButtonController.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.sponsorblock.ui; +package app.revanced.integrations.youtube.sponsorblock.ui; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceIdentifier; +import static app.revanced.integrations.shared.Utils.getResourceIdentifier; import android.view.View; import android.widget.ImageView; @@ -8,11 +8,11 @@ import java.lang.ref.WeakReference; import java.util.Objects; -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.videoplayer.BottomControlButton; +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.youtube.videoplayer.BottomControlButton; public class CreateSegmentButtonController { private static WeakReference buttonReference = new WeakReference<>(null); @@ -23,9 +23,9 @@ public class CreateSegmentButtonController { */ public static void initialize(View youtubeControlsLayout) { try { - LogHelper.printDebug(() -> "initializing new segment button"); + Logger.printDebug(() -> "initializing new segment button"); ImageView imageView = Objects.requireNonNull(youtubeControlsLayout.findViewById( - getResourceIdentifier("sb_sponsorblock_button", "id"))); + getResourceIdentifier("revanced_sb_create_segment_button", "id"))); imageView.setVisibility(View.GONE); imageView.setOnClickListener(v -> { SponsorBlockViewController.toggleNewSegmentLayoutVisibility(); @@ -33,7 +33,7 @@ public static void initialize(View youtubeControlsLayout) { buttonReference = new WeakReference<>(imageView); } catch (Exception ex) { - LogHelper.printException(() -> "initialize failure", ex); + Logger.printException(() -> "initialize failure", ex); } } @@ -83,12 +83,12 @@ public static void changeVisibility(boolean visible, boolean immediate) { iView.setVisibility(View.GONE); } } catch (Exception ex) { - LogHelper.printException(() -> "changeVisibility failure", ex); + Logger.printException(() -> "changeVisibility failure", ex); } } private static boolean shouldBeShown() { - return SettingsEnum.SB_ENABLED.getBoolean() && SettingsEnum.SB_CREATE_NEW_SEGMENT.getBoolean() + return Settings.SB_ENABLED.get() && Settings.SB_CREATE_NEW_SEGMENT.get() && !VideoInformation.isAtEndOfVideo(); } @@ -96,7 +96,7 @@ public static void hide() { if (!isShowing) { return; } - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); View v = buttonReference.get(); if (v == null) { return; diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/NewSegmentLayout.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/NewSegmentLayout.java similarity index 77% rename from app/src/main/java/app/revanced/integrations/sponsorblock/ui/NewSegmentLayout.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/NewSegmentLayout.java index 970462afe0..d5ee7f4278 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/NewSegmentLayout.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/NewSegmentLayout.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.sponsorblock.ui; +package app.revanced.integrations.youtube.sponsorblock.ui; import android.content.Context; import android.content.res.ColorStateList; @@ -8,13 +8,14 @@ import android.view.LayoutInflater; import android.widget.FrameLayout; import android.widget.ImageButton; -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.sponsorblock.SponsorBlockUtils; -import app.revanced.integrations.utils.LogHelper; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceDimensionPixelSize; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceIdentifier; +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.sponsorblock.SponsorBlockUtils; +import app.revanced.integrations.shared.Logger; + +import static app.revanced.integrations.shared.Utils.getResourceDimensionPixelSize; +import static app.revanced.integrations.shared.Utils.getResourceIdentifier; public final class NewSegmentLayout extends FrameLayout { private static final ColorStateList rippleColorStateList = new ColorStateList( @@ -43,7 +44,7 @@ public NewSegmentLayout(final Context context, final AttributeSet attributeSet, super(context, attributeSet, defStyleAttr, defStyleRes); LayoutInflater.from(context).inflate( - getResourceIdentifier(context, "new_segment", "layout"), this, true + getResourceIdentifier(context, "revanced_sb_new_segment", "layout"), this, true ); TypedValue rippleEffect = new TypedValue(); @@ -52,42 +53,42 @@ public NewSegmentLayout(final Context context, final AttributeSet attributeSet, initializeButton( context, - "sb_new_segment_rewind", - () -> VideoInformation.seekToRelative(-SettingsEnum.SB_CREATE_NEW_SEGMENT_STEP.getInt()), + "revanced_sb_new_segment_rewind", + () -> VideoInformation.seekToRelative(-Settings.SB_CREATE_NEW_SEGMENT_STEP.get()), "Rewind button clicked" ); initializeButton( context, - "sb_new_segment_forward", - () -> VideoInformation.seekToRelative(SettingsEnum.SB_CREATE_NEW_SEGMENT_STEP.getInt()), + "revanced_sb_new_segment_forward", + () -> VideoInformation.seekToRelative(Settings.SB_CREATE_NEW_SEGMENT_STEP.get()), "Forward button clicked" ); initializeButton( context, - "sb_new_segment_adjust", + "revanced_sb_new_segment_adjust", SponsorBlockUtils::onMarkLocationClicked, "Adjust button clicked" ); initializeButton( context, - "sb_new_segment_compare", + "revanced_sb_new_segment_compare", SponsorBlockUtils::onPreviewClicked, "Compare button clicked" ); initializeButton( context, - "sb_new_segment_edit", + "revanced_sb_new_segment_edit", SponsorBlockUtils::onEditByHandClicked, "Edit button clicked" ); initializeButton( context, - "sb_new_segment_publish", + "revanced_sb_new_segment_publish", SponsorBlockUtils::onPublishClicked, "Publish button clicked" ); @@ -115,7 +116,7 @@ private void initializeButton(final Context context, final String resourceIdenti button.setOnClickListener((v) -> { handler.apply(); - LogHelper.printDebug(() -> debugMessage); + Logger.printDebug(() -> debugMessage); }); } diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/SkipSponsorButton.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/SkipSponsorButton.java similarity index 81% rename from app/src/main/java/app/revanced/integrations/sponsorblock/ui/SkipSponsorButton.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/SkipSponsorButton.java index 47613392d5..f3b954d4f4 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/SkipSponsorButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/SkipSponsorButton.java @@ -1,9 +1,9 @@ -package app.revanced.integrations.sponsorblock.ui; +package app.revanced.integrations.youtube.sponsorblock.ui; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceColor; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceDimension; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceDimensionPixelSize; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceIdentifier; +import static app.revanced.integrations.shared.Utils.getResourceColor; +import static app.revanced.integrations.shared.Utils.getResourceDimension; +import static app.revanced.integrations.shared.Utils.getResourceDimensionPixelSize; +import static app.revanced.integrations.shared.Utils.getResourceIdentifier; import android.content.Context; import android.graphics.Canvas; @@ -19,8 +19,8 @@ import java.util.Objects; -import app.revanced.integrations.sponsorblock.SegmentPlaybackController; -import app.revanced.integrations.sponsorblock.objects.SponsorSegment; +import app.revanced.integrations.youtube.sponsorblock.SegmentPlaybackController; +import app.revanced.integrations.youtube.sponsorblock.objects.SponsorSegment; public class SkipSponsorButton extends FrameLayout { private static final boolean highContrast = true; @@ -47,9 +47,9 @@ public SkipSponsorButton(Context context, AttributeSet attributeSet, int defStyl public SkipSponsorButton(Context context, AttributeSet attributeSet, int defStyleAttr, int defStyleRes) { super(context, attributeSet, defStyleAttr, defStyleRes); - LayoutInflater.from(context).inflate(getResourceIdentifier(context, "skip_sponsor_button", "layout"), this, true); // layout:skip_ad_button + LayoutInflater.from(context).inflate(getResourceIdentifier(context, "revanced_sb_skip_sponsor_button", "layout"), this, true); // layout:skip_ad_button setMinimumHeight(getResourceDimensionPixelSize("ad_skip_ad_button_min_height")); // dimen:ad_skip_ad_button_min_height - skipSponsorBtnContainer = Objects.requireNonNull((LinearLayout) findViewById(getResourceIdentifier(context, "sb_skip_sponsor_button_container", "id"))); // id:skip_ad_button_container + skipSponsorBtnContainer = Objects.requireNonNull((LinearLayout) findViewById(getResourceIdentifier(context, "revanced_sb_skip_sponsor_button_container", "id"))); // id:skip_ad_button_container background = new Paint(); background.setColor(getResourceColor("skip_ad_button_background_color")); // color:skip_ad_button_background_color); background.setStyle(Paint.Style.FILL); @@ -57,7 +57,7 @@ public SkipSponsorButton(Context context, AttributeSet attributeSet, int defStyl border.setColor(getResourceColor("skip_ad_button_border_color")); // color:skip_ad_button_border_color); border.setStrokeWidth(getResourceDimension("ad_skip_ad_button_border_width")); // dimen:ad_skip_ad_button_border_width); border.setStyle(Paint.Style.STROKE); - skipSponsorTextView = Objects.requireNonNull((TextView) findViewById(getResourceIdentifier(context, "sb_skip_sponsor_button_text", "id"))); // id:skip_ad_button_text; + skipSponsorTextView = Objects.requireNonNull((TextView) findViewById(getResourceIdentifier(context, "revanced_sb_skip_sponsor_button_text", "id"))); // id:skip_ad_button_text; defaultBottomMargin = getResourceDimensionPixelSize("skip_button_default_bottom_margin"); // dimen:skip_button_default_bottom_margin ctaBottomMargin = getResourceDimensionPixelSize("skip_button_cta_bottom_margin"); // dimen:skip_button_cta_bottom_margin diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/SponsorBlockViewController.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/SponsorBlockViewController.java similarity index 86% rename from app/src/main/java/app/revanced/integrations/sponsorblock/ui/SponsorBlockViewController.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/SponsorBlockViewController.java index ac3a390980..12deeb8342 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/SponsorBlockViewController.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/SponsorBlockViewController.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.sponsorblock.ui; +package app.revanced.integrations.youtube.sponsorblock.ui; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceIdentifier; +import static app.revanced.integrations.shared.Utils.getResourceIdentifier; import android.content.Context; import android.view.LayoutInflater; @@ -14,11 +14,11 @@ import java.lang.ref.WeakReference; import java.util.Objects; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.shared.PlayerType; -import app.revanced.integrations.sponsorblock.objects.SponsorSegment; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.shared.PlayerType; +import app.revanced.integrations.youtube.sponsorblock.objects.SponsorSegment; public class SponsorBlockViewController { private static WeakReference inlineSponsorOverlayRef = new WeakReference<>(null); @@ -53,15 +53,15 @@ public static Context getOverLaysViewGroupContext() { */ public static void initialize(ViewGroup viewGroup) { try { - LogHelper.printDebug(() -> "initializing"); + Logger.printDebug(() -> "initializing"); // hide any old components, just in case they somehow are still hanging around hideAll(); - Context context = ReVancedUtils.getContext(); + Context context = Utils.getContext(); RelativeLayout layout = new RelativeLayout(context); layout.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT)); - LayoutInflater.from(context).inflate(getResourceIdentifier("inline_sponsor_overlay", "layout"), layout); + LayoutInflater.from(context).inflate(getResourceIdentifier("revanced_sb_inline_sponsor_overlay", "layout"), layout); inlineSponsorOverlayRef = new WeakReference<>(layout); viewGroup.addView(layout); @@ -81,17 +81,17 @@ public void onChildViewRemoved(View parent, View child) { youtubeOverlaysLayoutRef = new WeakReference<>(viewGroup); skipHighlightButtonRef = new WeakReference<>( - Objects.requireNonNull(layout.findViewById(getResourceIdentifier("sb_skip_highlight_button", "id")))); + Objects.requireNonNull(layout.findViewById(getResourceIdentifier("revanced_sb_skip_highlight_button", "id")))); skipSponsorButtonRef = new WeakReference<>( - Objects.requireNonNull(layout.findViewById(getResourceIdentifier("sb_skip_sponsor_button", "id")))); + Objects.requireNonNull(layout.findViewById(getResourceIdentifier("revanced_sb_skip_sponsor_button", "id")))); newSegmentLayoutRef = new WeakReference<>( - Objects.requireNonNull(layout.findViewById(getResourceIdentifier("sb_new_segment_view", "id")))); + Objects.requireNonNull(layout.findViewById(getResourceIdentifier("revanced_sb_new_segment_view", "id")))); newSegmentLayoutVisible = false; skipHighlight = null; skipSegment = null; } catch (Exception ex) { - LogHelper.printException(() -> "initialize failure", ex); + Logger.printException(() -> "initialize failure", ex); } } @@ -136,7 +136,7 @@ private static void updateSkipButton(@Nullable SkipSponsorButton button, public static void toggleNewSegmentLayoutVisibility() { NewSegmentLayout newSegmentLayout = newSegmentLayoutRef.get(); if (newSegmentLayout == null) { // should never happen - LogHelper.printException(() -> "toggleNewSegmentLayoutVisibility failure"); + Logger.printException(() -> "toggleNewSegmentLayoutVisibility failure"); return; } newSegmentLayoutVisible = (newSegmentLayout.getVisibility() != View.VISIBLE); @@ -179,7 +179,7 @@ private static void playerTypeChanged(@NonNull PlayerType playerType) { setSkipButtonMargins(skipSponsorButton, isWatchFullScreen); setViewVisibility(skipSponsorButton, skipSegment != null); } catch (Exception ex) { - LogHelper.printException(() -> "Player type changed failure", ex); + Logger.printException(() -> "Player type changed failure", ex); } } @@ -197,7 +197,7 @@ private static void setLayoutMargins(@NonNull View view, boolean fullScreen, int defaultBottomMargin, int ctaBottomMargin) { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams(); if (params == null) { - LogHelper.printException(() -> "Unable to setNewSegmentLayoutMargins (params are null)"); + Logger.printException(() -> "Unable to setNewSegmentLayoutMargins (params are null)"); return; } params.bottomMargin = fullScreen ? ctaBottomMargin : defaultBottomMargin; @@ -209,16 +209,16 @@ private static void setLayoutMargins(@NonNull View view, boolean fullScreen, */ public static void endOfVideoReached() { try { - LogHelper.printDebug(() -> "endOfVideoReached"); + Logger.printDebug(() -> "endOfVideoReached"); // the buttons automatically set themselves to visible when appropriate, // but if buttons are showing when the end of the video is reached then they need // to be forcefully hidden - if (!SettingsEnum.AUTO_REPEAT.getBoolean()) { + if (!Settings.AUTO_REPEAT.get()) { CreateSegmentButtonController.hide(); VotingButtonController.hide(); } } catch (Exception ex) { - LogHelper.printException(() -> "endOfVideoReached failure", ex); + Logger.printException(() -> "endOfVideoReached failure", ex); } } } diff --git a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/VotingButtonController.java b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/VotingButtonController.java similarity index 72% rename from app/src/main/java/app/revanced/integrations/sponsorblock/ui/VotingButtonController.java rename to app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/VotingButtonController.java index e0e4d555fc..581ba1ada5 100644 --- a/app/src/main/java/app/revanced/integrations/sponsorblock/ui/VotingButtonController.java +++ b/app/src/main/java/app/revanced/integrations/youtube/sponsorblock/ui/VotingButtonController.java @@ -1,6 +1,6 @@ -package app.revanced.integrations.sponsorblock.ui; +package app.revanced.integrations.youtube.sponsorblock.ui; -import static app.revanced.integrations.utils.ReVancedUtils.getResourceIdentifier; +import static app.revanced.integrations.shared.Utils.getResourceIdentifier; import android.view.View; import android.widget.ImageView; @@ -8,13 +8,13 @@ import java.lang.ref.WeakReference; import java.util.Objects; -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.sponsorblock.SegmentPlaybackController; -import app.revanced.integrations.sponsorblock.SponsorBlockUtils; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.videoplayer.BottomControlButton; +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.youtube.sponsorblock.SegmentPlaybackController; +import app.revanced.integrations.youtube.sponsorblock.SponsorBlockUtils; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.youtube.videoplayer.BottomControlButton; public class VotingButtonController { private static WeakReference buttonReference = new WeakReference<>(null); @@ -25,9 +25,9 @@ public class VotingButtonController { */ public static void initialize(View youtubeControlsLayout) { try { - LogHelper.printDebug(() -> "initializing voting button"); + Logger.printDebug(() -> "initializing voting button"); ImageView imageView = Objects.requireNonNull(youtubeControlsLayout.findViewById( - getResourceIdentifier("sb_voting_button", "id"))); + getResourceIdentifier("revanced_sb_voting_button", "id"))); imageView.setVisibility(View.GONE); imageView.setOnClickListener(v -> { SponsorBlockUtils.onVotingClicked(v.getContext()); @@ -35,7 +35,7 @@ public static void initialize(View youtubeControlsLayout) { buttonReference = new WeakReference<>(imageView); } catch (Exception ex) { - LogHelper.printException(() -> "Unable to set RelativeLayout", ex); + Logger.printException(() -> "Unable to set RelativeLayout", ex); } } @@ -85,12 +85,12 @@ public static void changeVisibility(boolean visible, boolean immediate) { iView.setVisibility(View.GONE); } } catch (Exception ex) { - LogHelper.printException(() -> "changeVisibility failure", ex); + Logger.printException(() -> "changeVisibility failure", ex); } } private static boolean shouldBeShown() { - return SettingsEnum.SB_ENABLED.getBoolean() && SettingsEnum.SB_VOTING_BUTTON.getBoolean() + return Settings.SB_ENABLED.get() && Settings.SB_VOTING_BUTTON.get() && SegmentPlaybackController.videoHasSegments() && !VideoInformation.isAtEndOfVideo(); } @@ -98,7 +98,7 @@ public static void hide() { if (!isShowing) { return; } - ReVancedUtils.verifyOnMainThread(); + Utils.verifyOnMainThread(); View v = buttonReference.get(); if (v == null) { return; diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/SwipeControlsConfigurationProvider.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt similarity index 76% rename from app/src/main/java/app/revanced/integrations/swipecontrols/SwipeControlsConfigurationProvider.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt index 69ad741726..e916186b37 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/SwipeControlsConfigurationProvider.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/SwipeControlsConfigurationProvider.kt @@ -1,9 +1,9 @@ -package app.revanced.integrations.swipecontrols +package app.revanced.integrations.youtube.swipecontrols import android.content.Context import android.graphics.Color -import app.revanced.integrations.settings.SettingsEnum -import app.revanced.integrations.shared.PlayerType +import app.revanced.integrations.youtube.settings.Settings +import app.revanced.integrations.youtube.shared.PlayerType /** * provider for configuration for volume and brightness swipe controls @@ -24,13 +24,13 @@ class SwipeControlsConfigurationProvider( * should swipe controls for volume be enabled? */ val enableVolumeControls: Boolean - get() = SettingsEnum.SWIPE_VOLUME.boolean + get() = Settings.SWIPE_VOLUME.get() /** * should swipe controls for volume be enabled? */ val enableBrightnessControl: Boolean - get() = SettingsEnum.SWIPE_BRIGHTNESS.boolean + get() = Settings.SWIPE_BRIGHTNESS.get() /** * is the video player currently in fullscreen mode? @@ -52,14 +52,14 @@ class SwipeControlsConfigurationProvider( * should press-to-swipe be enabled? */ val shouldEnablePressToSwipe: Boolean - get() = SettingsEnum.SWIPE_PRESS_TO_ENGAGE.boolean + get() = Settings.SWIPE_PRESS_TO_ENGAGE.get() /** * threshold for swipe detection * this may be called rapidly in onScroll, so we have to load it once and then leave it constant */ val swipeMagnitudeThreshold: Int - get() = SettingsEnum.SWIPE_MAGNITUDE_THRESHOLD.int + get() = Settings.SWIPE_MAGNITUDE_THRESHOLD.get() //endregion //region overlay adjustments @@ -68,25 +68,25 @@ class SwipeControlsConfigurationProvider( * should the overlay enable haptic feedback? */ val shouldEnableHapticFeedback: Boolean - get() = SettingsEnum.SWIPE_HAPTIC_FEEDBACK.boolean + get() = Settings.SWIPE_HAPTIC_FEEDBACK.get() /** * how long the overlay should be shown on changes */ val overlayShowTimeoutMillis: Long - get() = SettingsEnum.SWIPE_OVERLAY_TIMEOUT.long + get() = Settings.SWIPE_OVERLAY_TIMEOUT.get() /** * text size for the overlay, in sp */ val overlayTextSize: Int - get() = SettingsEnum.SWIPE_OVERLAY_TEXT_SIZE.int + get() = Settings.SWIPE_OVERLAY_TEXT_SIZE.get() /** * get the background color for text on the overlay, as a color int */ val overlayTextBackgroundColor: Int - get() = Color.argb(SettingsEnum.SWIPE_OVERLAY_BACKGROUND_ALPHA.int, 0, 0, 0) + get() = Color.argb(Settings.SWIPE_OVERLAY_BACKGROUND_ALPHA.get(), 0, 0, 0) /** * get the foreground color for text on the overlay, as a color int @@ -102,7 +102,7 @@ class SwipeControlsConfigurationProvider( * should the brightness be saved and restored when exiting or entering fullscreen */ val shouldSaveAndRestoreBrightness: Boolean - get() = SettingsEnum.SWIPE_SAVE_AND_RESTORE_BRIGHTNESS.boolean + get() = Settings.SWIPE_SAVE_AND_RESTORE_BRIGHTNESS.get() //endregion } \ No newline at end of file diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/SwipeControlsHostActivity.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/SwipeControlsHostActivity.kt similarity index 84% rename from app/src/main/java/app/revanced/integrations/swipecontrols/SwipeControlsHostActivity.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/SwipeControlsHostActivity.kt index 7a756b0810..838f6ecb0b 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/SwipeControlsHostActivity.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/SwipeControlsHostActivity.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.swipecontrols +package app.revanced.integrations.youtube.swipecontrols import android.app.Activity import android.os.Build @@ -6,23 +6,23 @@ import android.os.Bundle import android.view.KeyEvent import android.view.MotionEvent import android.view.ViewGroup -import app.revanced.integrations.shared.PlayerType -import app.revanced.integrations.swipecontrols.controller.AudioVolumeController -import app.revanced.integrations.swipecontrols.controller.ScreenBrightnessController -import app.revanced.integrations.swipecontrols.controller.SwipeZonesController -import app.revanced.integrations.swipecontrols.controller.VolumeKeysController -import app.revanced.integrations.swipecontrols.controller.gesture.ClassicSwipeController -import app.revanced.integrations.swipecontrols.controller.gesture.PressToSwipeController -import app.revanced.integrations.swipecontrols.controller.gesture.core.GestureController -import app.revanced.integrations.swipecontrols.misc.Rectangle -import app.revanced.integrations.swipecontrols.views.SwipeControlsOverlayLayout -import app.revanced.integrations.utils.LogHelper.printDebug -import app.revanced.integrations.utils.LogHelper.printException +import app.revanced.integrations.youtube.shared.PlayerType +import app.revanced.integrations.youtube.swipecontrols.controller.AudioVolumeController +import app.revanced.integrations.youtube.swipecontrols.controller.ScreenBrightnessController +import app.revanced.integrations.youtube.swipecontrols.controller.SwipeZonesController +import app.revanced.integrations.youtube.swipecontrols.controller.VolumeKeysController +import app.revanced.integrations.youtube.swipecontrols.controller.gesture.ClassicSwipeController +import app.revanced.integrations.youtube.swipecontrols.controller.gesture.PressToSwipeController +import app.revanced.integrations.youtube.swipecontrols.controller.gesture.core.GestureController +import app.revanced.integrations.youtube.swipecontrols.misc.Rectangle +import app.revanced.integrations.youtube.swipecontrols.views.SwipeControlsOverlayLayout +import app.revanced.integrations.shared.Logger.printDebug +import app.revanced.integrations.shared.Logger.printException 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 WatchWhileActivity at patch time + * note that the superclass is overwritten to the superclass of the MainActivity at patch time * * @smali Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity; */ diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/AudioVolumeController.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/AudioVolumeController.kt similarity index 92% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/AudioVolumeController.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/AudioVolumeController.kt index 8663d58e59..ef4bbefbcd 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/AudioVolumeController.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/AudioVolumeController.kt @@ -1,10 +1,10 @@ -package app.revanced.integrations.swipecontrols.controller +package app.revanced.integrations.youtube.swipecontrols.controller import android.content.Context import android.media.AudioManager import android.os.Build -import app.revanced.integrations.swipecontrols.misc.clamp -import app.revanced.integrations.utils.LogHelper.printException +import app.revanced.integrations.youtube.swipecontrols.misc.clamp +import app.revanced.integrations.shared.Logger.printException import kotlin.properties.Delegates /** diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/ScreenBrightnessController.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/ScreenBrightnessController.kt similarity index 93% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/ScreenBrightnessController.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/ScreenBrightnessController.kt index 238229c18b..356d981369 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/ScreenBrightnessController.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/ScreenBrightnessController.kt @@ -1,8 +1,8 @@ -package app.revanced.integrations.swipecontrols.controller +package app.revanced.integrations.youtube.swipecontrols.controller import android.app.Activity import android.view.WindowManager -import app.revanced.integrations.swipecontrols.misc.clamp +import app.revanced.integrations.youtube.swipecontrols.misc.clamp /** * controller to adjust the screen brightness level diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/SwipeZonesController.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/SwipeZonesController.kt similarity index 92% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/SwipeZonesController.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/SwipeZonesController.kt index efa05429ad..93501bf03d 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/SwipeZonesController.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/SwipeZonesController.kt @@ -1,11 +1,11 @@ -package app.revanced.integrations.swipecontrols.controller +package app.revanced.integrations.youtube.swipecontrols.controller import android.app.Activity import android.util.TypedValue import android.view.ViewGroup -import app.revanced.integrations.swipecontrols.misc.Rectangle -import app.revanced.integrations.swipecontrols.misc.applyDimension -import app.revanced.integrations.utils.ReVancedUtils +import app.revanced.integrations.youtube.swipecontrols.misc.Rectangle +import app.revanced.integrations.youtube.swipecontrols.misc.applyDimension +import app.revanced.integrations.shared.Utils import kotlin.math.min /** @@ -56,7 +56,7 @@ class SwipeZonesController( /** * id for R.id.player_view */ - private val playerViewId = ReVancedUtils.getResourceIdentifier(host, "player_view", "id") + private val playerViewId = Utils.getResourceIdentifier(host, "player_view", "id") /** * current bounding rectangle of the player diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/VolumeKeysController.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/VolumeKeysController.kt similarity index 89% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/VolumeKeysController.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/VolumeKeysController.kt index be91051084..46c82aac6b 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/VolumeKeysController.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/VolumeKeysController.kt @@ -1,7 +1,7 @@ -package app.revanced.integrations.swipecontrols.controller +package app.revanced.integrations.youtube.swipecontrols.controller import android.view.KeyEvent -import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity +import app.revanced.integrations.youtube.swipecontrols.SwipeControlsHostActivity /** * controller for custom volume button behaviour diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/ClassicSwipeController.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/ClassicSwipeController.kt similarity index 83% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/ClassicSwipeController.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/ClassicSwipeController.kt index 52f937d6a9..e4cb9cd200 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/ClassicSwipeController.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/ClassicSwipeController.kt @@ -1,13 +1,13 @@ -package app.revanced.integrations.swipecontrols.controller.gesture +package app.revanced.integrations.youtube.swipecontrols.controller.gesture import android.view.MotionEvent -import app.revanced.integrations.shared.PlayerControlsVisibilityObserver -import app.revanced.integrations.shared.PlayerControlsVisibilityObserverImpl -import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity -import app.revanced.integrations.swipecontrols.controller.gesture.core.BaseGestureController -import app.revanced.integrations.swipecontrols.controller.gesture.core.SwipeDetector -import app.revanced.integrations.swipecontrols.misc.contains -import app.revanced.integrations.swipecontrols.misc.toPoint +import app.revanced.integrations.youtube.shared.PlayerControlsVisibilityObserver +import app.revanced.integrations.youtube.shared.PlayerControlsVisibilityObserverImpl +import app.revanced.integrations.youtube.swipecontrols.SwipeControlsHostActivity +import app.revanced.integrations.youtube.swipecontrols.controller.gesture.core.BaseGestureController +import app.revanced.integrations.youtube.swipecontrols.controller.gesture.core.SwipeDetector +import app.revanced.integrations.youtube.swipecontrols.misc.contains +import app.revanced.integrations.youtube.swipecontrols.misc.toPoint /** * provides the classic swipe controls experience, as it was with 'XFenster' diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/PressToSwipeController.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/PressToSwipeController.kt similarity index 81% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/PressToSwipeController.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/PressToSwipeController.kt index 2575c814c4..bf39146211 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/PressToSwipeController.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/PressToSwipeController.kt @@ -1,11 +1,11 @@ -package app.revanced.integrations.swipecontrols.controller.gesture +package app.revanced.integrations.youtube.swipecontrols.controller.gesture import android.view.MotionEvent -import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity -import app.revanced.integrations.swipecontrols.controller.gesture.core.BaseGestureController -import app.revanced.integrations.swipecontrols.controller.gesture.core.SwipeDetector -import app.revanced.integrations.swipecontrols.misc.contains -import app.revanced.integrations.swipecontrols.misc.toPoint +import app.revanced.integrations.youtube.swipecontrols.SwipeControlsHostActivity +import app.revanced.integrations.youtube.swipecontrols.controller.gesture.core.BaseGestureController +import app.revanced.integrations.youtube.swipecontrols.controller.gesture.core.SwipeDetector +import app.revanced.integrations.youtube.swipecontrols.misc.contains +import app.revanced.integrations.youtube.swipecontrols.misc.toPoint /** * provides the press-to-swipe (PtS) swipe controls experience diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/BaseGestureController.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/BaseGestureController.kt similarity index 96% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/BaseGestureController.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/BaseGestureController.kt index 46cd8dc3d2..b3c54e449f 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/BaseGestureController.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/BaseGestureController.kt @@ -1,8 +1,8 @@ -package app.revanced.integrations.swipecontrols.controller.gesture.core +package app.revanced.integrations.youtube.swipecontrols.controller.gesture.core import android.view.GestureDetector import android.view.MotionEvent -import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity +import app.revanced.integrations.youtube.swipecontrols.SwipeControlsHostActivity /** * the common base of all [GestureController] classes. diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/GestureController.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/GestureController.kt similarity index 83% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/GestureController.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/GestureController.kt index 21cb33bd1c..31629cf452 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/GestureController.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/GestureController.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.swipecontrols.controller.gesture.core +package app.revanced.integrations.youtube.swipecontrols.controller.gesture.core import android.view.MotionEvent diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/SwipeDetector.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/SwipeDetector.kt similarity index 96% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/SwipeDetector.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/SwipeDetector.kt index 15318239dc..078acfce87 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/SwipeDetector.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/SwipeDetector.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.swipecontrols.controller.gesture.core +package app.revanced.integrations.youtube.swipecontrols.controller.gesture.core import android.view.MotionEvent import kotlin.math.abs diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/VolumeAndBrightnessScroller.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/VolumeAndBrightnessScroller.kt similarity index 84% rename from app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/VolumeAndBrightnessScroller.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/VolumeAndBrightnessScroller.kt index b5212dc40c..758e584a36 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/controller/gesture/core/VolumeAndBrightnessScroller.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/controller/gesture/core/VolumeAndBrightnessScroller.kt @@ -1,12 +1,12 @@ -package app.revanced.integrations.swipecontrols.controller.gesture.core +package app.revanced.integrations.youtube.swipecontrols.controller.gesture.core import android.content.Context import android.util.TypedValue -import app.revanced.integrations.swipecontrols.controller.AudioVolumeController -import app.revanced.integrations.swipecontrols.controller.ScreenBrightnessController -import app.revanced.integrations.swipecontrols.misc.ScrollDistanceHelper -import app.revanced.integrations.swipecontrols.misc.SwipeControlsOverlay -import app.revanced.integrations.swipecontrols.misc.applyDimension +import app.revanced.integrations.youtube.swipecontrols.controller.AudioVolumeController +import app.revanced.integrations.youtube.swipecontrols.controller.ScreenBrightnessController +import app.revanced.integrations.youtube.swipecontrols.misc.ScrollDistanceHelper +import app.revanced.integrations.youtube.swipecontrols.misc.SwipeControlsOverlay +import app.revanced.integrations.youtube.swipecontrols.misc.applyDimension /** * describes a class that controls volume and brightness based on scrolling events diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/Point.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/Point.kt similarity index 80% rename from app/src/main/java/app/revanced/integrations/swipecontrols/misc/Point.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/Point.kt index f0ed337869..eaca3270eb 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/Point.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/Point.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.swipecontrols.misc +package app.revanced.integrations.youtube.swipecontrols.misc import android.view.MotionEvent diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/Rectangle.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/Rectangle.kt similarity index 85% rename from app/src/main/java/app/revanced/integrations/swipecontrols/misc/Rectangle.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/Rectangle.kt index b35cd63b1a..5a3255e7a2 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/Rectangle.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/Rectangle.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.swipecontrols.misc +package app.revanced.integrations.youtube.swipecontrols.misc /** * a simple rectangle class diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/ScrollDistanceHelper.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/ScrollDistanceHelper.kt similarity index 95% rename from app/src/main/java/app/revanced/integrations/swipecontrols/misc/ScrollDistanceHelper.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/ScrollDistanceHelper.kt index 9948b4273d..eb7082ce4e 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/ScrollDistanceHelper.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/ScrollDistanceHelper.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.swipecontrols.misc +package app.revanced.integrations.youtube.swipecontrols.misc import kotlin.math.abs import kotlin.math.sign diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/SwipeControlsOverlay.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/SwipeControlsOverlay.kt similarity index 91% rename from app/src/main/java/app/revanced/integrations/swipecontrols/misc/SwipeControlsOverlay.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/SwipeControlsOverlay.kt index 46a3bc54c7..b4155ccfc8 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/SwipeControlsOverlay.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/SwipeControlsOverlay.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.swipecontrols.misc +package app.revanced.integrations.youtube.swipecontrols.misc /** * Interface for all overlays for swipe controls diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/SwipeControlsUtils.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/SwipeControlsUtils.kt similarity index 89% rename from app/src/main/java/app/revanced/integrations/swipecontrols/misc/SwipeControlsUtils.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/SwipeControlsUtils.kt index 92d6ed8040..a197c5109f 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/misc/SwipeControlsUtils.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/misc/SwipeControlsUtils.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.swipecontrols.misc +package app.revanced.integrations.youtube.swipecontrols.misc import android.content.Context import android.util.TypedValue diff --git a/app/src/main/java/app/revanced/integrations/swipecontrols/views/SwipeControlsOverlayLayout.kt b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt similarity index 84% rename from app/src/main/java/app/revanced/integrations/swipecontrols/views/SwipeControlsOverlayLayout.kt rename to app/src/main/java/app/revanced/integrations/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt index d585f943ae..d5f0c25ab2 100644 --- a/app/src/main/java/app/revanced/integrations/swipecontrols/views/SwipeControlsOverlayLayout.kt +++ b/app/src/main/java/app/revanced/integrations/youtube/swipecontrols/views/SwipeControlsOverlayLayout.kt @@ -1,4 +1,4 @@ -package app.revanced.integrations.swipecontrols.views +package app.revanced.integrations.youtube.swipecontrols.views import android.content.Context import android.graphics.drawable.Drawable @@ -11,10 +11,10 @@ import android.view.View import android.view.ViewGroup import android.widget.RelativeLayout import android.widget.TextView -import app.revanced.integrations.swipecontrols.SwipeControlsConfigurationProvider -import app.revanced.integrations.swipecontrols.misc.SwipeControlsOverlay -import app.revanced.integrations.swipecontrols.misc.applyDimension -import app.revanced.integrations.utils.ReVancedUtils +import app.revanced.integrations.youtube.swipecontrols.SwipeControlsConfigurationProvider +import app.revanced.integrations.youtube.swipecontrols.misc.SwipeControlsOverlay +import app.revanced.integrations.youtube.swipecontrols.misc.applyDimension +import app.revanced.integrations.shared.Utils import kotlin.math.round /** @@ -39,7 +39,7 @@ class SwipeControlsOverlayLayout( private fun getDrawable(name: String, width: Int, height: Int): Drawable { return resources.getDrawable( - ReVancedUtils.getResourceIdentifier(context, name, "drawable"), + Utils.getResourceIdentifier(context, name, "drawable"), context.theme ).apply { setTint(config.overlayForegroundColor) @@ -82,10 +82,10 @@ class SwipeControlsOverlayLayout( // 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) + 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()) diff --git a/app/src/main/java/app/revanced/integrations/videoplayer/BottomControlButton.java b/app/src/main/java/app/revanced/integrations/youtube/videoplayer/BottomControlButton.java similarity index 65% rename from app/src/main/java/app/revanced/integrations/videoplayer/BottomControlButton.java rename to app/src/main/java/app/revanced/integrations/youtube/videoplayer/BottomControlButton.java index dc30ad5cbf..aacd93677a 100644 --- a/app/src/main/java/app/revanced/integrations/videoplayer/BottomControlButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/videoplayer/BottomControlButton.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.videoplayer; +package app.revanced.integrations.youtube.videoplayer; import android.view.View; import android.view.ViewGroup; @@ -11,25 +11,25 @@ import java.lang.ref.WeakReference; import java.util.Objects; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.settings.BooleanSetting; public abstract class BottomControlButton { private static final Animation fadeIn; private static final Animation fadeOut; private final WeakReference buttonRef; - private final SettingsEnum setting; + private final BooleanSetting setting; protected boolean isVisible; static { // TODO: check if these durations are correct. - fadeIn = ReVancedUtils.getResourceAnimation("fade_in"); - fadeIn.setDuration(ReVancedUtils.getResourceInteger("fade_duration_fast")); + fadeIn = Utils.getResourceAnimation("fade_in"); + fadeIn.setDuration(Utils.getResourceInteger("fade_duration_fast")); - fadeOut = ReVancedUtils.getResourceAnimation("fade_out"); - fadeOut.setDuration(ReVancedUtils.getResourceInteger("fade_duration_scheduled")); + fadeOut = Utils.getResourceAnimation("fade_out"); + fadeOut.setDuration(Utils.getResourceInteger("fade_duration_scheduled")); } @NonNull @@ -43,18 +43,15 @@ public static Animation getButtonFadeOut() { } public BottomControlButton(@NonNull ViewGroup bottomControlsViewGroup, @NonNull String imageViewButtonId, - @NonNull SettingsEnum booleanSetting, @NonNull View.OnClickListener onClickListener, + @NonNull BooleanSetting booleanSetting, @NonNull View.OnClickListener onClickListener, @Nullable View.OnLongClickListener longClickListener) { - LogHelper.printDebug(() -> "Initializing button: " + imageViewButtonId); + Logger.printDebug(() -> "Initializing button: " + imageViewButtonId); - if (booleanSetting.returnType != SettingsEnum.ReturnType.BOOLEAN) { - throw new IllegalArgumentException(); - } setting = booleanSetting; // Create the button. ImageView imageView = Objects.requireNonNull(bottomControlsViewGroup.findViewById( - ReVancedUtils.getResourceIdentifier(imageViewButtonId, "id") + Utils.getResourceIdentifier(imageViewButtonId, "id") )); imageView.setOnClickListener(onClickListener); if (longClickListener != null) { @@ -75,7 +72,7 @@ public void setVisibility(boolean visible) { } imageView.clearAnimation(); - if (visible && setting.getBoolean()) { + if (visible && setting.get()) { imageView.startAnimation(fadeIn); imageView.setVisibility(View.VISIBLE); } else if (imageView.getVisibility() == View.VISIBLE) { diff --git a/app/src/main/java/app/revanced/integrations/videoplayer/CopyVideoUrlButton.java b/app/src/main/java/app/revanced/integrations/youtube/videoplayer/CopyVideoUrlButton.java similarity index 69% rename from app/src/main/java/app/revanced/integrations/videoplayer/CopyVideoUrlButton.java rename to app/src/main/java/app/revanced/integrations/youtube/videoplayer/CopyVideoUrlButton.java index 90eed3615c..5995da96b0 100644 --- a/app/src/main/java/app/revanced/integrations/videoplayer/CopyVideoUrlButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/videoplayer/CopyVideoUrlButton.java @@ -1,13 +1,13 @@ -package app.revanced.integrations.videoplayer; +package app.revanced.integrations.youtube.videoplayer; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; -import app.revanced.integrations.patches.CopyVideoUrlPatch; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; +import app.revanced.integrations.youtube.patches.CopyVideoUrlPatch; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; public class CopyVideoUrlButton extends BottomControlButton { @Nullable @@ -16,8 +16,8 @@ public class CopyVideoUrlButton extends BottomControlButton { public CopyVideoUrlButton(ViewGroup viewGroup) { super( viewGroup, - "copy_video_url_button", - SettingsEnum.COPY_VIDEO_URL, + "revanced_copy_video_url_button", + Settings.COPY_VIDEO_URL, view -> CopyVideoUrlPatch.copyUrl(false), view -> { CopyVideoUrlPatch.copyUrl(true); @@ -33,7 +33,7 @@ public static void initializeButton(View view) { try { instance = new CopyVideoUrlButton((ViewGroup) view); } catch (Exception ex) { - LogHelper.printException(() -> "initializeButton failure", ex); + Logger.printException(() -> "initializeButton failure", ex); } } diff --git a/app/src/main/java/app/revanced/integrations/videoplayer/CopyVideoUrlTimestampButton.java b/app/src/main/java/app/revanced/integrations/youtube/videoplayer/CopyVideoUrlTimestampButton.java similarity index 71% rename from app/src/main/java/app/revanced/integrations/videoplayer/CopyVideoUrlTimestampButton.java rename to app/src/main/java/app/revanced/integrations/youtube/videoplayer/CopyVideoUrlTimestampButton.java index a3d290ad7f..41af50ac95 100644 --- a/app/src/main/java/app/revanced/integrations/videoplayer/CopyVideoUrlTimestampButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/videoplayer/CopyVideoUrlTimestampButton.java @@ -1,13 +1,13 @@ -package app.revanced.integrations.videoplayer; +package app.revanced.integrations.youtube.videoplayer; import android.view.View; import android.view.ViewGroup; import androidx.annotation.Nullable; -import app.revanced.integrations.patches.CopyVideoUrlPatch; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; +import app.revanced.integrations.youtube.patches.CopyVideoUrlPatch; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; public class CopyVideoUrlTimestampButton extends BottomControlButton { @Nullable @@ -16,8 +16,8 @@ public class CopyVideoUrlTimestampButton extends BottomControlButton { public CopyVideoUrlTimestampButton(ViewGroup bottomControlsViewGroup) { super( bottomControlsViewGroup, - "copy_video_url_timestamp_button", - SettingsEnum.COPY_VIDEO_URL_TIMESTAMP, + "revanced_copy_video_url_timestamp_button", + Settings.COPY_VIDEO_URL_TIMESTAMP, view -> CopyVideoUrlPatch.copyUrl(true), view -> { CopyVideoUrlPatch.copyUrl(false); @@ -33,7 +33,7 @@ public static void initializeButton(View bottomControlsViewGroup) { try { instance = new CopyVideoUrlTimestampButton((ViewGroup) bottomControlsViewGroup); } catch (Exception ex) { - LogHelper.printException(() -> "initializeButton failure", ex); + Logger.printException(() -> "initializeButton failure", ex); } } diff --git a/app/src/main/java/app/revanced/integrations/videoplayer/ExternalDownloadButton.java b/app/src/main/java/app/revanced/integrations/youtube/videoplayer/ExternalDownloadButton.java similarity index 63% rename from app/src/main/java/app/revanced/integrations/videoplayer/ExternalDownloadButton.java rename to app/src/main/java/app/revanced/integrations/youtube/videoplayer/ExternalDownloadButton.java index 2e4c24ca21..5d1498fc56 100644 --- a/app/src/main/java/app/revanced/integrations/videoplayer/ExternalDownloadButton.java +++ b/app/src/main/java/app/revanced/integrations/youtube/videoplayer/ExternalDownloadButton.java @@ -1,4 +1,4 @@ -package app.revanced.integrations.videoplayer; +package app.revanced.integrations.youtube.videoplayer; import android.content.Intent; import android.content.pm.PackageManager; @@ -7,12 +7,13 @@ import androidx.annotation.Nullable; -import app.revanced.integrations.patches.VideoInformation; -import app.revanced.integrations.settings.SettingsEnum; -import app.revanced.integrations.utils.LogHelper; -import app.revanced.integrations.utils.ReVancedUtils; -import app.revanced.integrations.utils.StringRef; +import app.revanced.integrations.youtube.patches.VideoInformation; +import app.revanced.integrations.youtube.settings.Settings; +import app.revanced.integrations.shared.Logger; +import app.revanced.integrations.shared.Utils; +import app.revanced.integrations.shared.StringRef; +@SuppressWarnings("unused") public class ExternalDownloadButton extends BottomControlButton { @Nullable private static ExternalDownloadButton instance; @@ -20,8 +21,8 @@ public class ExternalDownloadButton extends BottomControlButton { public ExternalDownloadButton(ViewGroup viewGroup) { super( viewGroup, - "external_download_button", - SettingsEnum.EXTERNAL_DOWNLOADER, + "revanced_external_download_button", + Settings.EXTERNAL_DOWNLOADER, ExternalDownloadButton::onDownloadClick, null ); @@ -34,7 +35,7 @@ public static void initializeButton(View view) { try { instance = new ExternalDownloadButton((ViewGroup) view); } catch (Exception ex) { - LogHelper.printException(() -> "initializeButton failure", ex); + Logger.printException(() -> "initializeButton failure", ex); } } @@ -46,22 +47,22 @@ public static void changeVisibility(boolean showing) { } private static void onDownloadClick(View view) { - LogHelper.printDebug(() -> "External download button clicked"); + Logger.printDebug(() -> "External download button clicked"); final var context = view.getContext(); // Trim string to avoid any accidental whitespace. - var downloaderPackageName = SettingsEnum.EXTERNAL_DOWNLOADER_PACKAGE_NAME.getString().trim(); + var downloaderPackageName = Settings.EXTERNAL_DOWNLOADER_PACKAGE_NAME.get().trim(); boolean packageEnabled = false; try { packageEnabled = context.getPackageManager().getApplicationInfo(downloaderPackageName, 0).enabled; } catch (PackageManager.NameNotFoundException error) { - LogHelper.printDebug(() -> "External downloader could not be found: " + error); + Logger.printDebug(() -> "External downloader could not be found: " + error); } // If the package is not installed, show the toast if (!packageEnabled) { - ReVancedUtils.showToastLong(downloaderPackageName + " " + StringRef.str("external_downloader_not_installed_warning")); + Utils.showToastLong(StringRef.str("revanced_external_downloader_not_installed_warning", downloaderPackageName)); return; } @@ -75,9 +76,9 @@ private static void onDownloadClick(View view) { intent.putExtra("android.intent.extra.TEXT", content); context.startActivity(intent); - LogHelper.printDebug(() -> "Launched the intent with the content: " + content); + Logger.printDebug(() -> "Launched the intent with the content: " + content); } catch (Exception error) { - LogHelper.printException(() -> "Failed to launch the intent: " + error, error); + Logger.printException(() -> "Failed to launch the intent: " + error, error); } } } diff --git a/app/src/main/java/app/revanced/shared/settings/SettingsUtils.java b/app/src/main/java/app/revanced/shared/settings/SettingsUtils.java deleted file mode 100644 index be2a43667f..0000000000 --- a/app/src/main/java/app/revanced/shared/settings/SettingsUtils.java +++ /dev/null @@ -1,30 +0,0 @@ -package app.revanced.shared.settings; - -import android.content.Context; -import android.content.Intent; - -import androidx.annotation.NonNull; - -/** - * Class is used across multiple target apps. - * - * This entire class can _not_ reference: - * {@link app.revanced.integrations.settings.SettingsEnum} - * {@link app.revanced.twitch.settings.SettingsEnum} - * {@link app.revanced.tiktok.settings.SettingsEnum} - * - * or any other code that references these app specific integration classes. - */ -public class SettingsUtils { - - public static void restartApp(@NonNull Context context) { - String packageName = context.getPackageName(); - Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName); - Intent mainIntent = Intent.makeRestartActivityTask(intent.getComponent()); - // Required for API 34 and later - // Ref: https://developer.android.com/about/versions/14/behavior-changes-14#safer-intents - mainIntent.setPackage(packageName); - context.startActivity(mainIntent); - System.exit(0); - } -} diff --git a/app/src/main/java/app/revanced/tiktok/cleardisplay/RememberClearDisplayPatch.java b/app/src/main/java/app/revanced/tiktok/cleardisplay/RememberClearDisplayPatch.java deleted file mode 100644 index b9171f3c9a..0000000000 --- a/app/src/main/java/app/revanced/tiktok/cleardisplay/RememberClearDisplayPatch.java +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.tiktok.cleardisplay; - -import app.revanced.tiktok.settings.SettingsEnum; - -public class RememberClearDisplayPatch { - public static boolean getClearDisplayState() { - return SettingsEnum.CLEAR_DISPLAY.getBoolean(); - } - public static void rememberClearDisplayState(boolean newState) { - SettingsEnum.CLEAR_DISPLAY.saveValue(newState); - } -} diff --git a/app/src/main/java/app/revanced/tiktok/download/DownloadsPatch.java b/app/src/main/java/app/revanced/tiktok/download/DownloadsPatch.java deleted file mode 100644 index fcbd4ffc63..0000000000 --- a/app/src/main/java/app/revanced/tiktok/download/DownloadsPatch.java +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.tiktok.download; - -import app.revanced.tiktok.settings.SettingsEnum; - -public class DownloadsPatch { - public static String getDownloadPath() { - return SettingsEnum.DOWNLOAD_PATH.getString(); - } - - public static boolean shouldRemoveWatermark() { - return SettingsEnum.DOWNLOAD_WATERMARK.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/tiktok/settings/SettingsEnum.java b/app/src/main/java/app/revanced/tiktok/settings/SettingsEnum.java deleted file mode 100644 index 4b6d93f246..0000000000 --- a/app/src/main/java/app/revanced/tiktok/settings/SettingsEnum.java +++ /dev/null @@ -1,175 +0,0 @@ -package app.revanced.tiktok.settings; - -import android.content.Context; -import android.util.Log; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import app.revanced.tiktok.utils.LogHelper; -import app.revanced.tiktok.utils.ReVancedUtils; - -import java.util.HashMap; -import java.util.Map; - -import static app.revanced.tiktok.settings.SettingsEnum.ReturnType.BOOLEAN; -import static app.revanced.tiktok.settings.SettingsEnum.ReturnType.STRING; -import static java.lang.Boolean.FALSE; -import static java.lang.Boolean.TRUE; - -public enum SettingsEnum { - DEBUG("debug", BOOLEAN, FALSE), // Must be first value, otherwise logging during loading will not work. - REMOVE_ADS("remove_ads", BOOLEAN, TRUE, true), - HIDE_LIVE("hide_live", BOOLEAN, FALSE, true), - HIDE_STORY("hide_story", BOOLEAN, FALSE, true), - HIDE_IMAGE("hide_image", BOOLEAN, FALSE, true), - MIN_MAX_VIEWS("min_max_views", STRING, "0-" + Long.MAX_VALUE, true), - MIN_MAX_LIKES("min_max_likes", STRING, "0-" + Long.MAX_VALUE, true), - DOWNLOAD_PATH("down_path", STRING, "DCIM/TikTok"), - DOWNLOAD_WATERMARK("down_watermark", BOOLEAN, TRUE), - CLEAR_DISPLAY("clear_display", BOOLEAN, FALSE), - SIM_SPOOF("simspoof", BOOLEAN, TRUE, true), - SIM_SPOOF_ISO("simspoof_iso", STRING, "us"), - SIMSPOOF_MCCMNC("simspoof_mccmnc", STRING, "310160"), - SIMSPOOF_OP_NAME("simspoof_op_name", STRING, "T-Mobile"); - - private static final Map pathToSetting = new HashMap<>(2 * values().length); - - static { - loadAllSettings(); - for (SettingsEnum setting : values()) { - pathToSetting.put(setting.path, setting); - } - } - - @NonNull - public final String path; - @NonNull - public final Object defaultValue; - @NonNull - public final SharedPrefCategory sharedPref; - @NonNull - public final ReturnType returnType; - /** - * If the app should be rebooted, if this setting is changed - */ - public final boolean rebootApp; - - private Object value; - - SettingsEnum(String path, ReturnType returnType, Object defaultValue) { - this(path, returnType, defaultValue, SharedPrefCategory.TIKTOK_PREFS, false); - } - - SettingsEnum(String path, ReturnType returnType, Object defaultValue, boolean rebootApp) { - this(path, returnType, defaultValue, SharedPrefCategory.TIKTOK_PREFS, rebootApp); - } - - SettingsEnum(@NonNull String path, @NonNull ReturnType returnType, @NonNull Object defaultValue, @NonNull SharedPrefCategory prefName, boolean rebootApp) { - this.path = path; - this.returnType = returnType; - this.defaultValue = defaultValue; - this.sharedPref = prefName; - this.rebootApp = rebootApp; - } - - @Nullable - public static SettingsEnum getSettingsFromPath(@NonNull String str) { - return pathToSetting.get(str); - } - - private static void loadAllSettings() { - try { - Context context = ReVancedUtils.getAppContext(); - if (context == null) { - Log.e("revanced: SettingsEnum", "Context returned null! Settings NOT initialized"); - return; - } - for (SettingsEnum setting : values()) { - setting.load(context); - } - } catch (Exception ex) { - LogHelper.printException(SettingsEnum.class, "Error during load()!", ex); - } - } - - private void load(Context context) { - switch (returnType) { - case BOOLEAN: - value = sharedPref.getBoolean(context, path, (boolean) defaultValue); - break; - case INTEGER: - value = sharedPref.getInt(context, path, (Integer) defaultValue); - break; - case LONG: - value = sharedPref.getLong(context, path, (Long) defaultValue); - break; - case FLOAT: - value = sharedPref.getFloat(context, path, (Float) defaultValue); - break; - case STRING: - value = sharedPref.getString(context, path, (String) defaultValue); - break; - default: - throw new IllegalStateException(name()); - } - - LogHelper.debug(SettingsEnum.class, "Loaded Setting: " + name() + " Value: " + value); - } - - /** - * Sets, but does _not_ persistently save the value. - * - * This intentionally is a static method, to deter accidental usage - * when {@link #saveValue(Object)} was intended. - */ - public static void setValue(SettingsEnum setting, Object newValue) { - // FIXME: this should validate the parameter matches the return type - setting.value = newValue; - } - - public void saveValue(Object newValue) { - Context context = ReVancedUtils.getAppContext(); - if (context == null) { - LogHelper.printException(SettingsEnum.class, "Context on SaveValue is null!"); - return; - } - - if (returnType == BOOLEAN) { - sharedPref.saveBoolean(context, path, (Boolean) newValue); - } else { - sharedPref.saveString(context, path, newValue.toString()); - } - value = newValue; - } - - public boolean getBoolean() { - return (Boolean) value; - } - - public int getInt() { - return (Integer) value; - } - - public long getLong() { - return (Long) value; - } - - public float getFloat() { - return (Float) value; - } - - public String getString() { - return (String) value; - } - - /** - * @return the value of this setting as as generic object type. - */ - @NonNull - public Object getObjectValue() { - return value; - } - - public enum ReturnType { - BOOLEAN, INTEGER, LONG, FLOAT, STRING, - } -} diff --git a/app/src/main/java/app/revanced/tiktok/settings/SharedPrefCategory.java b/app/src/main/java/app/revanced/tiktok/settings/SharedPrefCategory.java deleted file mode 100644 index 79160ba19f..0000000000 --- a/app/src/main/java/app/revanced/tiktok/settings/SharedPrefCategory.java +++ /dev/null @@ -1,71 +0,0 @@ -package app.revanced.tiktok.settings; - -import android.content.Context; -import android.content.SharedPreferences; - -import androidx.annotation.NonNull; - -public enum SharedPrefCategory { - TIKTOK_PREFS("tiktok_revanced"); - - @NonNull - public final String prefName; - - SharedPrefCategory(@NonNull String prefName) { - this.prefName = prefName; - } - - @NonNull - @Override - public String toString() { - return prefName; - } - - private SharedPreferences getPreferences(Context context) { - return context.getSharedPreferences(prefName, Context.MODE_PRIVATE); - } - - public void saveBoolean(Context context, String key, boolean value) { - getPreferences(context).edit().putBoolean(key, value).apply(); - } - - public void saveString(Context context, String key, String value) { - getPreferences(context).edit().putString(key, value).apply(); - } - - public boolean getBoolean(Context context, String key, boolean _default) { - return getPreferences(context).getBoolean(key, _default); - } - - public Integer getInt(Context context, String key, Integer _default) { - SharedPreferences sharedPreferences = getPreferences(context); - try { - return Integer.valueOf(sharedPreferences.getString(key, _default.toString())); - } catch (ClassCastException ex) { - return sharedPreferences.getInt(key, _default); - } - } - - public Long getLong(Context context, String key, Long _default) { - SharedPreferences sharedPreferences = getPreferences(context); - try { - return Long.valueOf(sharedPreferences.getString(key, _default.toString())); - } catch (ClassCastException ex) { - return sharedPreferences.getLong(key, _default); - } - } - - public Float getFloat(Context context, String key, Float _default) { - SharedPreferences sharedPreferences = getPreferences(context); - try { - return Float.valueOf(sharedPreferences.getString(key, _default.toString())); - } catch (ClassCastException ex) { - return sharedPreferences.getFloat(key, _default); - } - } - - public String getString(Context context, String key, String _default) { - return getPreferences(context).getString(key, _default); - } - -} diff --git a/app/src/main/java/app/revanced/tiktok/settingsmenu/ReVancedPreferenceFragment.java b/app/src/main/java/app/revanced/tiktok/settingsmenu/ReVancedPreferenceFragment.java deleted file mode 100644 index 68694e7a6a..0000000000 --- a/app/src/main/java/app/revanced/tiktok/settingsmenu/ReVancedPreferenceFragment.java +++ /dev/null @@ -1,119 +0,0 @@ -package app.revanced.tiktok.settingsmenu; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceFragment; -import android.preference.PreferenceScreen; -import android.preference.SwitchPreference; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import app.revanced.integrations.utils.LogHelper; -import app.revanced.shared.settings.SettingsUtils; -import app.revanced.tiktok.settings.SettingsEnum; -import app.revanced.tiktok.settings.SharedPrefCategory; -import app.revanced.tiktok.settingsmenu.preference.DownloadPathPreference; -import app.revanced.tiktok.settingsmenu.preference.RangeValuePreference; -import app.revanced.tiktok.settingsmenu.preference.categories.DownloadsPreferenceCategory; -import app.revanced.tiktok.settingsmenu.preference.categories.FeedFilterPreferenceCategory; -import app.revanced.tiktok.settingsmenu.preference.categories.IntegrationsPreferenceCategory; -import app.revanced.tiktok.settingsmenu.preference.categories.SimSpoofPreferenceCategory; -import app.revanced.tiktok.utils.ReVancedUtils; - -@SuppressWarnings("deprecation") -public class ReVancedPreferenceFragment extends PreferenceFragment { - private boolean registered = false; - private boolean settingsInitialized = false; - - SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, str) -> { - try { - SettingsEnum setting = SettingsEnum.getSettingsFromPath(str); - if (setting == null) { - return; - } - Preference pref = findPreference(str); - if (pref == null) { - return; - } - if (pref instanceof SwitchPreference) { - SwitchPreference switchPref = (SwitchPreference) pref; - SettingsEnum.setValue(setting, switchPref.isChecked()); - } else if (pref instanceof EditTextPreference) { - EditTextPreference editPreference = (EditTextPreference) pref; - SettingsEnum.setValue(setting, editPreference.getText()); - } else if (pref instanceof ListPreference) { - ListPreference listPref = (ListPreference) pref; - SettingsEnum.setValue(setting, listPref.getValue()); - updateListPreferenceSummary((ListPreference) pref, setting); - } else if (pref instanceof RangeValuePreference) { - RangeValuePreference rangeValuePref = (RangeValuePreference) pref; - SettingsEnum.setValue(setting, rangeValuePref.getValue()); - } else if (pref instanceof DownloadPathPreference) { - DownloadPathPreference downloadPathPref = (DownloadPathPreference) pref; - SettingsEnum.setValue(setting, downloadPathPref.getValue()); - } else { - LogHelper.printException(() -> "Setting cannot be handled: " + pref.getClass() + " " + pref); - return; - } - if (ReVancedUtils.getAppContext() != null && this.settingsInitialized && setting.rebootApp) { - rebootDialog(getActivity()); - } - } catch (Exception ex) { - LogHelper.printException(() -> "OnSharedPreferenceChangeListener failure", ex); - } - }; - - private void updateListPreferenceSummary(ListPreference listPreference, SettingsEnum setting) { - String objectStringValue = setting.getObjectValue().toString(); - final int entryIndex = listPreference.findIndexOfValue(objectStringValue); - if (entryIndex >= 0) { - listPreference.setSummary(listPreference.getEntries()[entryIndex]); - listPreference.setValue(objectStringValue); - } else { - listPreference.setSummary(objectStringValue); - } - } - - @Override - public void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - this.registered = true; - - getPreferenceManager().setSharedPreferencesName(SharedPrefCategory.TIKTOK_PREFS.prefName); - getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this.listener); - - final Activity context = this.getActivity(); - PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context); - setPreferenceScreen(preferenceScreen); - - new FeedFilterPreferenceCategory(context, preferenceScreen); - new DownloadsPreferenceCategory(context, preferenceScreen); - new SimSpoofPreferenceCategory(context, preferenceScreen); - new IntegrationsPreferenceCategory(context, preferenceScreen); - - this.settingsInitialized = true; - } - - @Override - public void onDestroy() { - if (this.registered) { - getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this.listener); - this.registered = false; - } - - super.onDestroy(); - } - - private void rebootDialog(@NonNull Context context) { - new AlertDialog.Builder(context).setMessage("Refresh and restart") - .setPositiveButton("Restart", (dialog, i) -> SettingsUtils.restartApp(context)) - .setNegativeButton(android.R.string.cancel, null).show(); - } -} diff --git a/app/src/main/java/app/revanced/tiktok/utils/LogHelper.java b/app/src/main/java/app/revanced/tiktok/utils/LogHelper.java deleted file mode 100644 index d8d9a580c8..0000000000 --- a/app/src/main/java/app/revanced/tiktok/utils/LogHelper.java +++ /dev/null @@ -1,29 +0,0 @@ -package app.revanced.tiktok.utils; - -import android.util.Log; - -import app.revanced.tiktok.settings.SettingsEnum; - -/** - * TODO: replace this with the higher performance logging code from {@link app.revanced.integrations.utils.LogHelper} - */ -public class LogHelper { - - public static void debug(Class clazz, String message) { - if (SettingsEnum.DEBUG.getBoolean()) { - Log.d("revanced: " + (clazz != null ? clazz.getSimpleName() : ""), message); - } - } - - public static void printException(Class clazz, String message, Throwable ex) { - Log.e("revanced: " + (clazz != null ? clazz.getSimpleName() : ""), message, ex); - } - - public static void printException(Class clazz, String message) { - Log.e("revanced: " + (clazz != null ? clazz.getSimpleName() : ""), message); - } - - public static void info(Class clazz, String message) { - Log.i("revanced: " + (clazz != null ? clazz.getSimpleName() : ""), message); - } -} diff --git a/app/src/main/java/app/revanced/tiktok/utils/ReVancedUtils.java b/app/src/main/java/app/revanced/tiktok/utils/ReVancedUtils.java deleted file mode 100644 index 1577fd613c..0000000000 --- a/app/src/main/java/app/revanced/tiktok/utils/ReVancedUtils.java +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.tiktok.utils; - -import android.annotation.SuppressLint; -import android.content.Context; -import app.revanced.tiktok.settings.SettingsEnum; - -public class ReVancedUtils { - - @SuppressLint("StaticFieldLeak") - public static Context context; - - public static Context getAppContext() { - if (context != null) { - return context; - } - LogHelper.printException(ReVancedUtils.class, "Context is null!"); - return null; - } - - public static long[] parseMinMax(SettingsEnum setting) { - if (setting.returnType == SettingsEnum.ReturnType.STRING) { - final String[] minMax = setting.getString().split("-"); - - if (minMax.length == 2) - try { - final long min = Long.parseLong(minMax[0]); - final long max = Long.parseLong(minMax[1]); - - if (min <= max && min >= 0) return new long[]{min, max}; - - } catch (NumberFormatException ignored) { - } - } - - setting.saveValue("0-" + Long.MAX_VALUE); - return new long[]{0L, Long.MAX_VALUE}; - } -} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/twitch/api/RequestInterceptor.java b/app/src/main/java/app/revanced/twitch/api/RequestInterceptor.java deleted file mode 100644 index f571c23954..0000000000 --- a/app/src/main/java/app/revanced/twitch/api/RequestInterceptor.java +++ /dev/null @@ -1,96 +0,0 @@ -package app.revanced.twitch.api; - -import androidx.annotation.NonNull; -import app.revanced.twitch.adblock.IAdblockService; -import app.revanced.twitch.adblock.LuminousService; -import app.revanced.twitch.adblock.PurpleAdblockService; -import app.revanced.twitch.settings.SettingsEnum; -import app.revanced.twitch.utils.LogHelper; -import app.revanced.twitch.utils.ReVancedUtils; -import okhttp3.Interceptor; -import okhttp3.Response; - -import java.io.IOException; - -import static app.revanced.twitch.adblock.IAdblockService.channelName; -import static app.revanced.twitch.adblock.IAdblockService.isVod; - -public class RequestInterceptor implements Interceptor { - private IAdblockService activeService = null; - - @NonNull - @Override - public Response intercept(@NonNull Chain chain) throws IOException { - var originalRequest = chain.request(); - - LogHelper.debug("Intercepted request to URL: %s", originalRequest.url().toString()); - - // Skip if not HLS manifest request - if (!originalRequest.url().host().contains("usher.ttvnw.net")) { - return chain.proceed(originalRequest); - } - - var isVod = "no"; - if (isVod(originalRequest)) isVod = "yes"; - - LogHelper.debug("Found HLS manifest request. Is VOD? %s; Channel: %s", isVod, channelName(originalRequest)); - - // None of the services support VODs currently - if (isVod(originalRequest)) return chain.proceed(originalRequest); - - updateActiveService(); - - if (activeService != null) { - var available = activeService.isAvailable(); - var rewritten = activeService.rewriteHlsRequest(originalRequest); - - - if (!available || rewritten == null) { - ReVancedUtils.toast(String.format(ReVancedUtils.getString("revanced_embedded_ads_service_unavailable"), activeService.friendlyName()), true); - return chain.proceed(originalRequest); - } - - LogHelper.debug("Rewritten HLS stream URL: %s", rewritten.url().toString()); - - var maxAttempts = activeService.maxAttempts(); - - for (var i = 1; i <= maxAttempts; i++) { - // Execute rewritten request and close body to allow multiple proceed() calls - var response = chain.proceed(rewritten); - response.close(); - - if (!response.isSuccessful()) { - LogHelper.error("Request failed (attempt %d/%d): HTTP error %d (%s)", i, maxAttempts, response.code(), response.message()); - try { - Thread.sleep(50); - } catch (InterruptedException e) { - LogHelper.printException("Failed to sleep" ,e); - } - } else { - // Accept response from ad blocker - LogHelper.debug("Ad-blocker used"); - return chain.proceed(rewritten); - } - } - - // maxAttempts exceeded; giving up on using the ad blocker - ReVancedUtils.toast(String.format(ReVancedUtils.getString("revanced_embedded_ads_service_failed"), activeService.friendlyName()), true); - - } - - // Adblock disabled - return chain.proceed(originalRequest); - - } - - private void updateActiveService() { - var current = SettingsEnum.BLOCK_EMBEDDED_ADS.getString(); - - if (current.equals(ReVancedUtils.getString("key_revanced_proxy_luminous")) && !(activeService instanceof LuminousService)) - activeService = new LuminousService(); - else if (current.equals(ReVancedUtils.getString("key_revanced_proxy_purpleadblock")) && !(activeService instanceof PurpleAdblockService)) - activeService = new PurpleAdblockService(); - else if (current.equals(ReVancedUtils.getString("key_revanced_proxy_disabled"))) - activeService = null; - } -} diff --git a/app/src/main/java/app/revanced/twitch/patches/AudioAdsPatch.java b/app/src/main/java/app/revanced/twitch/patches/AudioAdsPatch.java deleted file mode 100644 index ac35e55815..0000000000 --- a/app/src/main/java/app/revanced/twitch/patches/AudioAdsPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.twitch.patches; - -import app.revanced.twitch.settings.SettingsEnum; - -public class AudioAdsPatch { - public static boolean shouldBlockAudioAds() { - return SettingsEnum.BLOCK_AUDIO_ADS.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/twitch/patches/AutoClaimChannelPointsPatch.java b/app/src/main/java/app/revanced/twitch/patches/AutoClaimChannelPointsPatch.java deleted file mode 100644 index dc6c750043..0000000000 --- a/app/src/main/java/app/revanced/twitch/patches/AutoClaimChannelPointsPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.twitch.patches; - -import app.revanced.twitch.settings.SettingsEnum; - -public class AutoClaimChannelPointsPatch { - public static boolean shouldAutoClaim() { - return SettingsEnum.AUTO_CLAIM_CHANNEL_POINTS.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/twitch/patches/DebugModePatch.java b/app/src/main/java/app/revanced/twitch/patches/DebugModePatch.java deleted file mode 100644 index 503ed2cb27..0000000000 --- a/app/src/main/java/app/revanced/twitch/patches/DebugModePatch.java +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.twitch.patches; - - -import app.revanced.twitch.settings.SettingsEnum; - -public class DebugModePatch { - public static boolean isDebugModeEnabled() { - return SettingsEnum.DEBUG_MODE.getBoolean(); - } -} diff --git a/app/src/main/java/app/revanced/twitch/patches/VideoAdsPatch.java b/app/src/main/java/app/revanced/twitch/patches/VideoAdsPatch.java deleted file mode 100644 index 877737dddd..0000000000 --- a/app/src/main/java/app/revanced/twitch/patches/VideoAdsPatch.java +++ /dev/null @@ -1,9 +0,0 @@ -package app.revanced.twitch.patches; - -import app.revanced.twitch.settings.SettingsEnum; - -public class VideoAdsPatch { - public static boolean shouldBlockVideoAds() { - return SettingsEnum.BLOCK_VIDEO_ADS.getBoolean(); - } -} \ No newline at end of file diff --git a/app/src/main/java/app/revanced/twitch/settings/SettingsEnum.java b/app/src/main/java/app/revanced/twitch/settings/SettingsEnum.java deleted file mode 100644 index 6a2f187e84..0000000000 --- a/app/src/main/java/app/revanced/twitch/settings/SettingsEnum.java +++ /dev/null @@ -1,170 +0,0 @@ -package app.revanced.twitch.settings; - -import android.content.Context; -import android.content.SharedPreferences; -import androidx.annotation.NonNull; -import app.revanced.twitch.utils.LogHelper; -import app.revanced.twitch.utils.ReVancedUtils; - -import static app.revanced.twitch.settings.SettingsEnum.ReturnType.BOOLEAN; -import static app.revanced.twitch.settings.SettingsEnum.ReturnType.STRING; -import static java.lang.Boolean.FALSE; -import static java.lang.Boolean.TRUE; - -public enum SettingsEnum { - /* Ads */ - BLOCK_VIDEO_ADS("revanced_block_video_ads", BOOLEAN, TRUE), - BLOCK_AUDIO_ADS("revanced_block_audio_ads", BOOLEAN, TRUE), - BLOCK_EMBEDDED_ADS("revanced_block_embedded_ads", STRING, "luminous"), - - /* Chat */ - SHOW_DELETED_MESSAGES("revanced_show_deleted_messages", STRING, "cross-out"), - AUTO_CLAIM_CHANNEL_POINTS("revanced_auto_claim_channel_points", BOOLEAN, TRUE), - - /* Misc */ - DEBUG_MODE("revanced_debug_mode", BOOLEAN, FALSE, true); - - public static final String REVANCED_PREFS = "revanced_prefs"; - - @NonNull - public final String path; - @NonNull - public final ReturnType returnType; - @NonNull - public final Object defaultValue; - /** - * If the app should be rebooted, if this setting is changed - */ - public final boolean rebootApp; - - private Object value; - - SettingsEnum(String path, ReturnType returnType, Object defaultValue) { - this(path, returnType, defaultValue, false); - } - - SettingsEnum(@NonNull String path, @NonNull ReturnType returnType, @NonNull Object defaultValue, boolean rebootApp) { - this.path = path; - this.returnType = returnType; - this.defaultValue = defaultValue; - this.rebootApp = rebootApp; - } - - static { - loadAllSettings(); - } - - private static void loadAllSettings() { - ReVancedUtils.ifContextAttached((context -> { - try { - SharedPreferences prefs = context.getSharedPreferences(REVANCED_PREFS, Context.MODE_PRIVATE); - for (SettingsEnum setting : values()) { - setting.load(prefs); - } - } catch (Exception ex) { - LogHelper.printException("Failed to load settings", ex); - } - })); - } - - private void load(SharedPreferences prefs) { - try { - switch (returnType) { - case BOOLEAN: - setValue(prefs.getBoolean(path, (Boolean) defaultValue)); - break; - // Numbers are implicitly converted from strings - case INTEGER: - case LONG: - case FLOAT: - case STRING: - setValue(prefs.getString(path, defaultValue.toString())); - break; - default: - throw new IllegalStateException(name()); - } - LogHelper.debug("Loaded setting '%s' with value %s", name(), value); - } catch (ClassCastException ex) { - LogHelper.printException("Failed to read value", ex); - } - } - - /** - * Sets, but does _not_ persistently save the value. - * - * This intentionally is a static method, to deter accidental usage - * when {@link #saveValue(Object)} was intended. - */ - public static void setValue(SettingsEnum setting, Object newValue) { - setting.setValue(newValue); - } - - private void setValue(Object newValue) { - // Implicitly convert strings to numbers depending on the ResultType - switch (returnType) { - case FLOAT: - value = Float.valueOf(newValue.toString()); - break; - case LONG: - value = Long.valueOf(newValue.toString()); - break; - case INTEGER: - value = Integer.valueOf(newValue.toString()); - break; - case BOOLEAN: - case STRING: - value = newValue; - break; - default: - throw new IllegalArgumentException(name()); - } - } - - public void saveValue(Object newValue) { - ReVancedUtils.ifContextAttached((context) -> { - SharedPreferences prefs = context.getSharedPreferences(REVANCED_PREFS, Context.MODE_PRIVATE); - if (returnType == BOOLEAN) { - prefs.edit().putBoolean(path, (Boolean)newValue).apply(); - } else { - prefs.edit().putString(path, newValue.toString()).apply(); - } - setValue(newValue); - }); - } - - public boolean getBoolean() { - return (Boolean) value; - } - - public int getInt() { - return (Integer) value; - } - - public long getLong() { - return (Long) value; - } - - public float getFloat() { - return (Float) value; - } - - public String getString() { - return (String) value; - } - - /** - * @return the value of this setting as as generic object type. - */ - @NonNull - public Object getObjectValue() { - return value; - } - - public enum ReturnType { - BOOLEAN, - INTEGER, - LONG, - FLOAT, - STRING, - } -} diff --git a/app/src/main/java/app/revanced/twitch/settingsmenu/ReVancedSettingsFragment.java b/app/src/main/java/app/revanced/twitch/settingsmenu/ReVancedSettingsFragment.java deleted file mode 100644 index 6aea969622..0000000000 --- a/app/src/main/java/app/revanced/twitch/settingsmenu/ReVancedSettingsFragment.java +++ /dev/null @@ -1,129 +0,0 @@ -package app.revanced.twitch.settingsmenu; - -import android.annotation.SuppressLint; -import android.app.AlertDialog; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.preference.SwitchPreference; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import app.revanced.shared.settings.SettingsUtils; -import app.revanced.twitch.settings.SettingsEnum; -import app.revanced.twitch.utils.LogHelper; -import app.revanced.twitch.utils.ReVancedUtils; - -public class ReVancedSettingsFragment extends PreferenceFragment { - - private boolean registered = false; - private boolean settingsInitialized = false; - - SharedPreferences.OnSharedPreferenceChangeListener listener = (sharedPreferences, key) -> { - LogHelper.debug("Setting '%s' changed", key); - syncPreference(key); - }; - - /** - * Sync preference - * @param key Preference to load. If key is null, all preferences are updated - */ - private void syncPreference(@Nullable String key) { - for (SettingsEnum setting : SettingsEnum.values()) { - if (!setting.path.equals(key) && key != null) - continue; - - Preference pref = this.findPreference(setting.path); - LogHelper.debug("Syncing setting '%s' with UI", setting.path); - - if (pref instanceof SwitchPreference) { - SettingsEnum.setValue(setting, ((SwitchPreference) pref).isChecked()); - } - else if (pref instanceof EditTextPreference) { - SettingsEnum.setValue(setting, ((EditTextPreference) pref).getText()); - } - else if (pref instanceof ListPreference) { - ListPreference listPref = (ListPreference) pref; - listPref.setSummary(listPref.getEntry()); - SettingsEnum.setValue(setting, listPref.getValue()); - } - else { - LogHelper.error("Setting '%s' cannot be handled!", pref); - } - - if (ReVancedUtils.getContext() != null && key != null && settingsInitialized && setting.rebootApp) { - showRestartDialog(getContext()); - } - - // First onChange event is caused by initial state loading - this.settingsInitialized = true; - } - } - - @SuppressLint("ResourceType") - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); - - try { - PreferenceManager mgr = getPreferenceManager(); - mgr.setSharedPreferencesName(SettingsEnum.REVANCED_PREFS); - mgr.getSharedPreferences().registerOnSharedPreferenceChangeListener(this.listener); - - addPreferencesFromResource( - getResources().getIdentifier( - SettingsEnum.REVANCED_PREFS, - "xml", - this.getContext().getPackageName() - ) - ); - - // TODO: for a developer that uses Twitch: remove duplicated settings data - // 1. remove all default values from the Patches Setting preferences (SwitchPreference, TextPreference, ListPreference) - // 2. enable this code and verify the default is applied - if (false) { - for (SettingsEnum setting : SettingsEnum.values()) { - Preference pref = this.findPreference(setting.path); - if (pref instanceof SwitchPreference) { - ((SwitchPreference) pref).setChecked(setting.getBoolean()); - } else if (pref instanceof EditTextPreference) { - ((EditTextPreference) pref).setText(setting.getObjectValue().toString()); - } else if (pref instanceof ListPreference) { - ((ListPreference) pref).setValue(setting.getObjectValue().toString()); - } - } - } - // TODO: remove this line. On load the UI should apply the values from Settings using the code above. - // It should not apply the UI values to the Settings here - syncPreference(null); - - this.registered = true; - } catch (Throwable th) { - LogHelper.printException("Error during onCreate()", th); - } - } - - @Override - public void onDestroy() { - if (this.registered) { - getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this.listener); - this.registered = false; - } - super.onDestroy(); - } - - private void showRestartDialog(@NonNull Context context) { - new AlertDialog.Builder(context). - setMessage(ReVancedUtils.getString("revanced_reboot_message")). - setPositiveButton(ReVancedUtils.getString("revanced_reboot"), - (dialog, i) -> SettingsUtils.restartApp(context)) - .setNegativeButton(android.R.string.cancel, null) - .show(); - } -} diff --git a/app/src/main/java/app/revanced/twitch/utils/LogHelper.java b/app/src/main/java/app/revanced/twitch/utils/LogHelper.java deleted file mode 100644 index 899aa20aa6..0000000000 --- a/app/src/main/java/app/revanced/twitch/utils/LogHelper.java +++ /dev/null @@ -1,55 +0,0 @@ -package app.revanced.twitch.utils; - -import android.util.Log; -import android.widget.Toast; - -import app.revanced.twitch.settings.SettingsEnum; - -/** - * TODO: replace this with the higher performance logging code from {@link app.revanced.integrations.utils.LogHelper} - */ -public class LogHelper { - - /** - * TODO: replace this with {@link app.revanced.integrations.utils.LogHelper.LogMessage#findOuterClassSimpleName()} - */ - public static String getCallOrigin() - { - try { - final StackTraceElement elem = new Throwable().getStackTrace()[/* depth */ 2]; - final String fullName = elem.getClassName(); - return fullName.substring(fullName.lastIndexOf('.') + 1) + "/" + elem.getMethodName(); - } - catch (Exception ex) { - return ""; - } - } - - public static final String TAG = "revanced"; - - public static void debug(String message, Object... args) { - Log.d(TAG, getCallOrigin() + ": " + String.format(message, args)); - } - - public static void info(String message, Object... args) { - Log.i(TAG, getCallOrigin() + ": " + String.format(message, args)); - } - - public static void error(String message, Object... args) { - String msg = getCallOrigin() + ": " + String.format(message, args); - showDebugToast(msg); - Log.e(TAG, msg); - } - - public static void printException(String message, Throwable ex) { - String msg = getCallOrigin() + ": " + message; - showDebugToast(msg + " (" + ex.getClass().getSimpleName() + ")"); - Log.e(TAG, msg, ex); - } - - private static void showDebugToast(String msg) { - if(SettingsEnum.DEBUG_MODE.getBoolean()) { - ReVancedUtils.toast(msg, false); - } - } -} diff --git a/app/src/main/java/app/revanced/twitch/utils/ReVancedUtils.java b/app/src/main/java/app/revanced/twitch/utils/ReVancedUtils.java deleted file mode 100644 index 9e9ec9569a..0000000000 --- a/app/src/main/java/app/revanced/twitch/utils/ReVancedUtils.java +++ /dev/null @@ -1,103 +0,0 @@ -package app.revanced.twitch.utils; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.os.Handler; -import android.os.Looper; -import android.widget.Toast; - -public class ReVancedUtils { - @SuppressLint("StaticFieldLeak") - public static Context context; - - /** - * Regular context getter - * @return Returns context or null if not initialized - */ - public static Context getContext() { - if (context != null) { - return context; - } - - LogHelper.error("Context is null (at %s)", LogHelper.getCallOrigin()); - return null; - } - - /** - * Execute lambda only if context attached. - */ - public static void ifContextAttached(SafeContextAccessLambda lambda) { - if (context != null) { - lambda.run(context); - return; - } - - LogHelper.error("Context is null, lambda not executed (at %s)", LogHelper.getCallOrigin()); - } - - /** - * Execute lambda only if context attached. - * @return Returns result on success or valueOnError on failure - */ - public static T ifContextAttached(SafeContextAccessReturnLambda lambda, T valueOnError) { - if (context != null) { - return lambda.run(context); - } - - LogHelper.error("Context is null, lambda not executed (at %s)", LogHelper.getCallOrigin()); - return valueOnError; - } - - public interface SafeContextAccessReturnLambda { - T run(Context ctx); - } - - public interface SafeContextAccessLambda { - void run(Context ctx); - } - - public static void runOnMainThread(Runnable runnable) { - new Handler(Looper.getMainLooper()).post(runnable); - } - - /** - * Get resource id safely - * @return May return 0 if resource not found or context not attached - */ - @SuppressLint("DiscouragedApi") - public static int getIdentifier(String name, String defType) { - return ifContextAttached( - (context) -> { - int resId = context.getResources().getIdentifier(name, defType, context.getPackageName()); - if(resId == 0) { - LogHelper.error("Resource '%s' not found (at %s)", name, LogHelper.getCallOrigin()); - } - return resId; - }, - 0 - ); - } - - /* Called from SettingsPatch smali */ - public static int getStringId(String name) { - return getIdentifier(name, "string"); - } - - /* Called from SettingsPatch smali */ - public static int getDrawableId(String name) { - return getIdentifier(name, "drawable"); - } - - public static String getString(String name) { - return ifContextAttached((c) -> c.getString(getStringId(name)), ""); - } - - public static void toast(String message) { - toast(message, true); - } - public static void toast(String message, boolean longLength) { - ifContextAttached((c) -> { - runOnMainThread(() -> Toast.makeText(c, message, longLength ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT).show()); - }); - } -} diff --git a/dummy/src/main/java/com/google/android/apps/youtube/app/watchwhile/WatchWhileActivity.java b/dummy/src/main/java/com/google/android/apps/youtube/app/watchwhile/WatchWhileActivity.java deleted file mode 100644 index d86113d09a..0000000000 --- a/dummy/src/main/java/com/google/android/apps/youtube/app/watchwhile/WatchWhileActivity.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.google.android.apps.youtube.app.watchwhile; - -import android.app.Activity; - -// Dummy class -public final class WatchWhileActivity extends Activity { } - diff --git a/gradle.properties b/gradle.properties index d389340623..ccad2d5453 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true android.useAndroidX = true -version = 1.1.0 +version = 1.2.0-dev.3 diff --git a/package-lock.json b/package-lock.json index 05a1ace3ae..6d31bf1347 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,21 @@ { "name": "revanced-integrations", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { "devDependencies": { - "@saithodev/semantic-release-backmerge": "^3.2.1", + "@saithodev/semantic-release-backmerge": "^4.0.1", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", - "gradle-semantic-release-plugin": "^1.8.0", - "semantic-release": "^22.0.8" + "gradle-semantic-release-plugin": "^1.9.1", + "semantic-release": "^23.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { "@babel/highlight": "^7.23.4", @@ -227,9 +227,9 @@ } }, "node_modules/@octokit/core": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz", - "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.1.0.tgz", + "integrity": "sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==", "dev": true, "dependencies": { "@octokit/auth-token": "^4.0.0", @@ -245,13 +245,12 @@ } }, "node_modules/@octokit/endpoint": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.2.tgz", - "integrity": "sha512-qhKW8YLIi+Kmc92FQUFGr++DYtkx/1fBv+Thua6baqnjnOsgBYJDCvWZR1YcINuHGOEQt416WOfE+A/oG60NBQ==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz", + "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==", "dev": true, "dependencies": { "@octokit/types": "^12.0.0", - "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" }, "engines": { @@ -273,18 +272,18 @@ } }, "node_modules/@octokit/openapi-types": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.2.tgz", - "integrity": "sha512-8li32fUDUeml/ACRp/njCWTsk5t17cfTM1jp9n08pBrqs5cDFJubtjsSnuz56r5Tad6jdEPJld7LxNp9dNcyjQ==", + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz", + "integrity": "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw==", "dev": true }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.4.tgz", - "integrity": "sha512-MvZx4WvfhBnt7PtH5XE7HORsO7bBk4er1FgRIUr1qJ89NR2I6bWjGyKsxk8z42FPQ34hFQm0Baanh4gzdZR4gQ==", + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz", + "integrity": "sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg==", "dev": true, "dependencies": { - "@octokit/types": "^12.3.0" + "@octokit/types": "^12.4.0" }, "engines": { "node": ">= 18" @@ -327,15 +326,14 @@ } }, "node_modules/@octokit/request": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.5.tgz", - "integrity": "sha512-zVKbNbX1xUluD9ZR4/tPs1yuYrK9xeh5fGZUXA6u04XGsTvomg0YO8/ZUC0FqAd49hAOEMFPAVUTh+2lBhOhLA==", + "version": "8.1.6", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz", + "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==", "dev": true, "dependencies": { "@octokit/endpoint": "^9.0.0", "@octokit/request-error": "^5.0.0", "@octokit/types": "^12.0.0", - "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" }, "engines": { @@ -357,12 +355,12 @@ } }, "node_modules/@octokit/types": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.3.0.tgz", - "integrity": "sha512-nJ8X2HRr234q3w/FcovDlA+ttUU4m1eJAourvfUUtwAWeqL8AsyRqfnLvVnYn3NFbUnsmzQCzLNdFerPwdmcDQ==", + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.4.0.tgz", + "integrity": "sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ==", "dev": true, "dependencies": { - "@octokit/openapi-types": "^19.0.2" + "@octokit/openapi-types": "^19.1.0" } }, "node_modules/@pnpm/config.env-replace": { @@ -386,6 +384,12 @@ "node": ">=12.22.0" } }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, "node_modules/@pnpm/npm-conf": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", @@ -401,9 +405,9 @@ } }, "node_modules/@saithodev/semantic-release-backmerge": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@saithodev/semantic-release-backmerge/-/semantic-release-backmerge-3.2.1.tgz", - "integrity": "sha512-mC9cA6lhNzpy4rKOT5jjRLhlT3myubmVeo+BqWyR2WqF5PRJpG0jaU8pBC87S11GCUHKxqXf0QQDZNPbbNP1bA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@saithodev/semantic-release-backmerge/-/semantic-release-backmerge-4.0.1.tgz", + "integrity": "sha512-WDsU28YrXSLx0xny7FgFlEk8DCKGcj6OOhA+4Q9k3te1jJD1GZuqY8sbIkVQaw9cqJ7CT+fCZUN6QDad8JW4Dg==", "dev": true, "dependencies": { "@semantic-release/error": "^3.0.0", @@ -411,96 +415,64 @@ "debug": "^4.3.4", "execa": "^5.1.1", "lodash": "^4.17.21", - "semantic-release": ">=20.0.0 <22.0.0" + "semantic-release": "^22.0.7" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/commit-analyzer": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-10.0.4.tgz", - "integrity": "sha512-pFGn99fn8w4/MHE0otb2A/l5kxgOuxaaauIh4u30ncoTJuqWj4hXTgEJ03REqjS+w1R2vPftSsO26WC61yOcpw==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", "dev": true, "dependencies": { - "conventional-changelog-angular": "^6.0.0", - "conventional-commits-filter": "^3.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "import-from": "^4.0.0", - "lodash-es": "^4.17.21", - "micromatch": "^4.0.2" + "escape-string-regexp": "5.0.0" }, "engines": { - "node": ">=18" + "node": ">=14.16" }, - "peerDependencies": { - "semantic-release": ">=20.1.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/commit-analyzer/node_modules/conventional-commits-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", - "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, "dependencies": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.1" + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" }, "engines": { "node": ">=14" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/npm": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-10.0.6.tgz", - "integrity": "sha512-DyqHrGE8aUyapA277BB+4kV0C4iMHh3sHzUWdf0jTgp5NNJxVUz76W1f57FB64Ue03him3CBXxFqQD2xGabxow==", - "dev": true, - "dependencies": { - "@semantic-release/error": "^4.0.0", - "aggregate-error": "^5.0.0", - "execa": "^8.0.0", - "fs-extra": "^11.0.0", - "lodash-es": "^4.17.21", - "nerf-dart": "^1.0.0", - "normalize-url": "^8.0.0", - "npm": "^9.5.0", - "rc": "^1.2.8", - "read-pkg": "^8.0.0", - "registry-auth-token": "^5.0.0", - "semver": "^7.1.2", - "tempy": "^3.0.0" }, - "engines": { - "node": ">=18" + "funding": { + "url": "https://github.com/sponsors/d-fischer" }, "peerDependencies": { - "semantic-release": ">=20.1.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true, - "engines": { - "node": ">=18" + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/npm/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/env-ci": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-10.0.0.tgz", + "integrity": "sha512-U4xcd/utDYFgMh0yWj07R1H6L5fwhVbmxBCpnL0DbVSDZVnsC82HONw0wxtxNkIAcua3KtbomQvIk5xFZGAQJw==", "dev": true, "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" + "execa": "^8.0.0", + "java-properties": "^1.0.2" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^18.17 || >=20.6.1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/npm/node_modules/execa": { + "node_modules/@saithodev/semantic-release-backmerge/node_modules/env-ci/node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", @@ -523,7 +495,7 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/npm/node_modules/get-stream": { + "node_modules/@saithodev/semantic-release-backmerge/node_modules/env-ci/node_modules/get-stream": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", @@ -535,164 +507,67 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/npm/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, "engines": { - "node": ">=14" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/release-notes-generator": { - "version": "11.0.7", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-11.0.7.tgz", - "integrity": "sha512-T09QB9ImmNx7Q6hY6YnnEbw/rEJ6a+22LBxfZq+pSAXg/OL/k0siwEm5cK4k1f9dE2Z2mPIjJKKohzUm0jbxcQ==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, - "dependencies": { - "conventional-changelog-angular": "^6.0.0", - "conventional-changelog-writer": "^6.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "get-stream": "^7.0.0", - "import-from": "^4.0.0", - "into-stream": "^7.0.0", - "lodash-es": "^4.17.21", - "read-pkg-up": "^10.0.0" - }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "semantic-release": ">=20.1.0" + "node": ">=16.17.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", - "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, "engines": { - "node": ">=16" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "dependencies": { - "escape-string-regexp": "5.0.0" - }, "engines": { - "node": ">=14.16" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/conventional-changelog-writer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", - "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", "dev": true, - "dependencies": { - "conventional-commits-filter": "^3.0.0", - "dateformat": "^3.0.3", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "meow": "^8.1.2", - "semver": "^7.0.0", - "split": "^1.0.1" - }, "bin": { - "conventional-changelog-writer": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/conventional-changelog-writer/node_modules/conventional-commits-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", - "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", - "dev": true, - "dependencies": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/env-ci": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-9.1.1.tgz", - "integrity": "sha512-Im2yEWeF4b2RAMAaWvGioXk6m0UNaIjD8hj28j2ij5ldnIFrDQT0+pzDvpbRkcjurhXhf/AsBKv8P2rtmGi9Aw==", - "dev": true, - "dependencies": { - "execa": "^7.0.0", - "java-properties": "^1.0.2" - }, - "engines": { - "node": "^16.14 || >=18" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/env-ci/node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" + "marked": "bin/marked.js" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/env-ci/node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true, "engines": { - "node": ">=14.18.0" + "node": ">= 16" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, "engines": { "node": ">=12" @@ -701,36 +576,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/figures": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, "dependencies": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" + "path-key": "^4.0.0" }, "engines": { - "node": ">=14" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { "node": ">=12" }, @@ -738,22 +606,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/is-stream": { + "node_modules/@saithodev/semantic-release-backmerge/node_modules/p-reduce": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", + "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", "dev": true, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, "engines": { "node": ">=12" @@ -762,244 +630,289 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/json-parse-even-better-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", - "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/lines-and-columns": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", - "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release": { + "version": "22.0.12", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-22.0.12.tgz", + "integrity": "sha512-0mhiCR/4sZb00RVFJIUlMuiBkW3NMpVIW2Gse7noqEMoFGkvfPPAImEQbkBV8xga4KOPP4FdTRYuLLy32R1fPw==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/marked": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.2.tgz", - "integrity": "sha512-ahRPGXJpjMjwSOlBoTMZAK7ATXkli5qCPxZ21TG44rx1KEo44bii4ekgTDQPNRQ4Kh7JMb9Ub1PVk1NxRSsorg==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, + "@semantic-release/commit-analyzer": "^11.0.0", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^9.0.0", + "@semantic-release/npm": "^11.0.0", + "@semantic-release/release-notes-generator": "^12.0.0", + "aggregate-error": "^5.0.0", + "cosmiconfig": "^8.0.0", + "debug": "^4.0.0", + "env-ci": "^10.0.0", + "execa": "^8.0.0", + "figures": "^6.0.0", + "find-versions": "^5.1.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^3.0.0", + "hosted-git-info": "^7.0.0", + "import-from-esm": "^1.3.1", + "lodash-es": "^4.17.21", + "marked": "^9.0.0", + "marked-terminal": "^6.0.0", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-pkg-up": "^11.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^4.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" + }, + "bin": { + "semantic-release": "bin/semantic-release.js" + }, "engines": { - "node": ">= 16" + "node": "^18.17 || >=20.6.1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/marked-terminal": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-5.2.0.tgz", - "integrity": "sha512-Piv6yNwAQXGFjZSaiNljyNFw7jKDdGrw70FSbtxEyldLsyeuV5ZHm/1wW++kWbrOF1VPnUgYOhB2oLL0ZpnekA==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", "dev": true, - "dependencies": { - "ansi-escapes": "^6.2.0", - "cardinal": "^2.1.1", - "chalk": "^5.2.0", - "cli-table3": "^0.6.3", - "node-emoji": "^1.11.0", - "supports-hyperlinks": "^2.3.0" - }, "engines": { - "node": ">=14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "marked": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" + "node": ">=18" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/execa/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "engines": { - "node": ">=10" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "node_modules/@saithodev/semantic-release-backmerge/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "node_modules/@saithodev/semantic-release-backmerge/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "node_modules/@semantic-release/changelog": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", + "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", "dev": true, "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^11.0.0", + "lodash": "^4.17.4" }, "engines": { - "node": ">=10" + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/@semantic-release/commit-analyzer": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-11.1.0.tgz", + "integrity": "sha512-cXNTbv3nXR2hlzHjAMgbuiQVtvWHTlwwISt60B+4NZv01y/QRY7p2HcJm8Eh2StzcTJoNnflvKjHH/cjFS7d5g==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "import-from-esm": "^1.0.3", + "lodash-es": "^4.17.21", + "micromatch": "^4.0.2" }, "engines": { - "node": ">=8" + "node": "^18.17 || >=20.6.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/@semantic-release/error": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", + "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "dev": true, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@semantic-release/git": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", + "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "@semantic-release/error": "^3.0.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.17" + }, + "peerDependencies": { + "semantic-release": ">=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/@semantic-release/github": { + "version": "9.2.6", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.2.6.tgz", + "integrity": "sha512-shi+Lrf6exeNZF+sBhK+P011LSbhmIAoUEgEY6SsxF8irJ+J2stwI5jkyDQ+4gzYyDImzV6LCKdYB9FXnQRWKA==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@octokit/core": "^5.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", + "@octokit/plugin-retry": "^6.0.0", + "@octokit/plugin-throttling": "^8.0.0", + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "debug": "^4.3.4", + "dir-glob": "^3.0.1", + "globby": "^14.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "issue-parser": "^6.0.0", + "lodash-es": "^4.17.21", + "mime": "^4.0.0", + "p-filter": "^4.0.0", + "url-join": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/@semantic-release/github/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "node_modules/@semantic-release/github/node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "node_modules/@semantic-release/github/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", "dev": true, - "bin": { - "semver": "bin/semver" + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/@semantic-release/github/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/@semantic-release/github/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, "engines": { "node": ">=12" @@ -1008,242 +921,134 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "node_modules/@semantic-release/npm": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-11.0.2.tgz", + "integrity": "sha512-owtf3RjyPvRE63iUKZ5/xO4uqjRpVQDUB9+nnXj0xwfIeM9pRl+cG+zGDzdftR4m3f2s4Wyf3SexW+kF5DFtWA==", "dev": true, "dependencies": { - "lodash": "^4.17.21" + "@semantic-release/error": "^4.0.0", + "aggregate-error": "^5.0.0", + "execa": "^8.0.0", + "fs-extra": "^11.0.0", + "lodash-es": "^4.17.21", + "nerf-dart": "^1.0.0", + "normalize-url": "^8.0.0", + "npm": "^10.0.0", + "rc": "^1.2.8", + "read-pkg": "^9.0.0", + "registry-auth-token": "^5.0.0", + "semver": "^7.1.2", + "tempy": "^3.0.0" + }, + "engines": { + "node": "^18.17 || >=20" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm": { - "version": "9.9.2", - "resolved": "https://registry.npmjs.org/npm/-/npm-9.9.2.tgz", - "integrity": "sha512-D3tV+W0PzJOlwo8YmO6fNzaB1CrMVYd1V+2TURF6lbCbmZKqMsYgeQfPVvqiM3zbNSJPhFEnmlEXIogH2Vq7PQ==", - "bundleDependencies": [ - "@isaacs/string-locale-compare", - "@npmcli/arborist", - "@npmcli/config", - "@npmcli/fs", - "@npmcli/map-workspaces", - "@npmcli/package-json", - "@npmcli/promise-spawn", - "@npmcli/run-script", - "abbrev", - "archy", - "cacache", - "chalk", - "ci-info", - "cli-columns", - "cli-table3", - "columnify", - "fastest-levenshtein", - "fs-minipass", - "glob", - "graceful-fs", - "hosted-git-info", - "ini", - "init-package-json", - "is-cidr", - "json-parse-even-better-errors", - "libnpmaccess", - "libnpmdiff", - "libnpmexec", - "libnpmfund", - "libnpmhook", - "libnpmorg", - "libnpmpack", - "libnpmpublish", - "libnpmsearch", - "libnpmteam", - "libnpmversion", - "make-fetch-happen", - "minimatch", - "minipass", - "minipass-pipeline", - "ms", - "node-gyp", - "nopt", - "normalize-package-data", - "npm-audit-report", - "npm-install-checks", - "npm-package-arg", - "npm-pick-manifest", - "npm-profile", - "npm-registry-fetch", - "npm-user-validate", - "npmlog", - "p-map", - "pacote", - "parse-conflict-json", - "proc-log", - "qrcode-terminal", - "read", - "semver", - "sigstore", - "spdx-expression-parse", - "ssri", - "supports-color", - "tar", - "text-table", - "tiny-relative-date", - "treeverse", - "validate-npm-package-name", - "which", - "write-file-atomic" - ], + "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@semantic-release/npm/node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^6.5.0", - "@npmcli/config": "^6.4.0", - "@npmcli/fs": "^3.1.0", - "@npmcli/map-workspaces": "^3.0.4", - "@npmcli/package-json": "^4.0.1", - "@npmcli/promise-spawn": "^6.0.2", - "@npmcli/run-script": "^6.0.2", - "abbrev": "^2.0.0", - "archy": "~1.0.0", - "cacache": "^17.1.3", - "chalk": "^5.3.0", - "ci-info": "^3.8.0", - "cli-columns": "^4.0.0", - "cli-table3": "^0.6.3", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.16", - "fs-minipass": "^3.0.2", - "glob": "^10.2.7", - "graceful-fs": "^4.2.11", - "hosted-git-info": "^6.1.1", - "ini": "^4.1.1", - "init-package-json": "^5.0.0", - "is-cidr": "^4.0.2", - "json-parse-even-better-errors": "^3.0.0", - "libnpmaccess": "^7.0.2", - "libnpmdiff": "^5.0.20", - "libnpmexec": "^6.0.4", - "libnpmfund": "^4.2.1", - "libnpmhook": "^9.0.3", - "libnpmorg": "^5.0.4", - "libnpmpack": "^5.0.20", - "libnpmpublish": "^7.5.1", - "libnpmsearch": "^6.0.2", - "libnpmteam": "^5.0.3", - "libnpmversion": "^4.0.2", - "make-fetch-happen": "^11.1.1", - "minimatch": "^9.0.3", - "minipass": "^5.0.0", - "minipass-pipeline": "^1.2.4", - "ms": "^2.1.2", - "node-gyp": "^9.4.0", - "nopt": "^7.2.0", - "normalize-package-data": "^5.0.0", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^10.1.0", - "npm-pick-manifest": "^8.0.2", - "npm-profile": "^7.0.1", - "npm-registry-fetch": "^14.0.5", - "npm-user-validate": "^2.0.0", - "npmlog": "^7.0.1", - "p-map": "^4.0.0", - "pacote": "^15.2.0", - "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", - "qrcode-terminal": "^0.12.0", - "read": "^2.1.0", - "semver": "^7.5.4", - "sigstore": "^1.9.0", - "spdx-expression-parse": "^3.0.1", - "ssri": "^10.0.4", - "supports-color": "^9.4.0", - "tar": "^6.1.15", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.0", - "which": "^3.0.1", - "write-file-atomic": "^5.0.1" - }, - "bin": { - "npm": "bin/npm-cli.js", - "npx": "bin/npx-cli.js" + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "node_modules/@semantic-release/npm/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", "dev": true, "dependencies": { - "path-key": "^4.0.0" + "escape-string-regexp": "5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@colors/colors": { - "version": "1.5.0", + "node_modules/@semantic-release/npm/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, "engines": { - "node": ">=0.1.90" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@isaacs/cliui": { - "version": "8.0.2", + "node_modules/@semantic-release/npm/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=12" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", + "node_modules/@semantic-release/npm/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { - "node": ">=12" + "node": ">=16" }, "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", + "node_modules/@semantic-release/npm/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, - "inBundle": true, - "license": "MIT" + "engines": { + "node": ">=16.17.0" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", + "node_modules/@semantic-release/npm/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, "engines": { "node": ">=12" }, @@ -1251,4516 +1056,4459 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", + "node_modules/@semantic-release/npm/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@semantic-release/npm/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/arborist": { - "version": "6.5.0", + "node_modules/@semantic-release/npm/node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.0", - "@npmcli/installed-package-contents": "^2.0.2", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^5.0.0", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^4.0.0", - "@npmcli/query": "^3.0.0", - "@npmcli/run-script": "^6.0.0", - "bin-links": "^4.0.1", - "cacache": "^17.0.4", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^6.1.1", - "json-parse-even-better-errors": "^3.0.0", - "json-stringify-nice": "^1.1.4", - "minimatch": "^9.0.0", - "nopt": "^7.0.0", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^10.1.0", - "npm-pick-manifest": "^8.0.1", - "npm-registry-fetch": "^14.0.3", - "npmlog": "^7.0.1", - "pacote": "^15.0.8", - "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.2", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^10.0.1", - "treeverse": "^3.0.0", - "walk-up-path": "^3.0.1" - }, - "bin": { - "arborist": "bin/index.js" + "path-key": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/config": { - "version": "6.4.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/map-workspaces": "^3.0.2", - "ci-info": "^3.8.0", - "ini": "^4.1.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.5", - "walk-up-path": "^3.0.1" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/disparity-colors": { - "version": "3.0.0", + "node_modules/@semantic-release/npm/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "ansi-styles": "^4.3.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/fs": { - "version": "3.1.0", + "node_modules/@semantic-release/npm/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/git": { + "node_modules/@semantic-release/npm/node_modules/signal-exit": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^6.0.0", - "lru-cache": "^7.4.4", - "npm-pick-manifest": "^8.0.0", - "proc-log": "^3.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^3.0.0" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "bin": { - "installed-package-contents": "lib/index.js" + "node": ">=14" }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.4", + "node_modules/@semantic-release/npm/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/name-from-folder": "^2.0.0", - "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "5.0.1", + "node_modules/@semantic-release/release-notes-generator": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-12.1.0.tgz", + "integrity": "sha512-g6M9AjUKAZUZnxaJZnouNBeDNTCUrJ5Ltj+VJ60gJeDaRRahcHsry9HW8yKrnKkKNkx5lbWiEP1FPMqVNQz8Kg==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "cacache": "^17.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^15.0.0", - "semver": "^7.3.5" + "conventional-changelog-angular": "^7.0.0", + "conventional-changelog-writer": "^7.0.0", + "conventional-commits-filter": "^4.0.0", + "conventional-commits-parser": "^5.0.0", + "debug": "^4.0.0", + "get-stream": "^7.0.0", + "import-from-esm": "^1.0.3", + "into-stream": "^7.0.0", + "lodash-es": "^4.17.21", + "read-pkg-up": "^11.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17 || >=20.6.1" + }, + "peerDependencies": { + "semantic-release": ">=20.1.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "2.0.0", + "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", + "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", "dev": true, - "inBundle": true, - "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "3.0.0", + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, - "inBundle": true, - "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/package-json": { - "version": "4.0.1", + "node_modules/@sindresorhus/merge-streams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", + "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^4.1.0", - "glob": "^10.2.2", - "hosted-git-info": "^6.1.1", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^5.0.0", - "proc-log": "^3.0.0", - "semver": "^7.5.3" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "6.0.2", + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true + }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "which": "^3.0.0" + "debug": "^4.3.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">= 14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/query": { - "version": "3.0.0", + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.10" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@npmcli/run-script": { - "version": "6.0.2", + "node_modules/ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/promise-spawn": "^6.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^3.0.0", - "which": "^3.0.0" + "type-fest": "^3.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@pkgjs/parseargs": { - "version": "0.11.0", + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, "engines": { - "node": ">=14" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@sigstore/bundle": { - "version": "1.1.0", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "inBundle": true, - "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.2.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.2.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@sigstore/sign": { + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/argv-formatter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", + "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", + "dev": true + }, + "node_modules/array-ify": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, + "node_modules/bottleneck": { + "version": "2.19.5", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", + "dev": true + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "inBundle": true, - "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^1.1.0", - "@sigstore/protobuf-specs": "^0.2.0", - "make-fetch-happen": "^11.0.1" + "fill-range": "^7.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@sigstore/tuf": { - "version": "1.0.3", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.2.0", - "tuf-js": "^1.1.7" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@tootallnate/once": { - "version": "2.0.0", + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 10" + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@tufjs/canonical-json": { - "version": "1.0.0", + "node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/@tufjs/models": { - "version": "1.0.4", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "1.0.0", - "minimatch": "^9.0.0" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=10" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/abbrev": { - "version": "2.0.0", + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true, - "inBundle": true, - "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/abort-controller": { - "version": "3.0.0", + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "event-target-shim": "^5.0.0" + "string-width": "^4.2.0" }, "engines": { - "node": ">=6.5" + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/agent-base": { - "version": "6.0.2", + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "debug": "4" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">= 6.0.0" + "node": ">=12" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/agentkeepalive": { - "version": "4.3.0", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "debug": "^4.1.0", - "depd": "^2.0.0", - "humanize-ms": "^1.2.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 8.0.0" + "node": ">=7.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ansi-regex": { - "version": "5.0.1", + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ansi-styles": { - "version": "4.3.0", + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "compare-func": "^2.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=16" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/aproba": { - "version": "2.0.0", + "node_modules/conventional-changelog-writer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz", + "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==", "dev": true, - "inBundle": true, - "license": "ISC" + "dependencies": { + "conventional-commits-filter": "^4.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^12.0.1", + "semver": "^7.5.2", + "split2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.mjs" + }, + "engines": { + "node": ">=16" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/archy": { - "version": "1.0.0", + "node_modules/conventional-commits-filter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz", + "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==", "dev": true, - "inBundle": true, - "license": "MIT" + "engines": { + "node": ">=16" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/are-we-there-yet": { - "version": "4.0.0", + "node_modules/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^4.1.0" + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.mjs" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=16" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/base64-js": { - "version": "1.5.1", + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/bin-links": { - "version": "4.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/binary-extensions": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/buffer": { - "version": "6.0.3", + "node_modules/crypto-random-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", + "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "type-fest": "^1.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/builtins": { - "version": "5.0.1", + "node_modules/crypto-random-string/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "semver": "^7.0.0" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/cacache": { - "version": "17.1.3", + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" + "ms": "2.1.2" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/chownr": { - "version": "2.0.0", + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true, - "inBundle": true, - "license": "ISC", "engines": { - "node": ">=10" + "node": ">=4.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ci-info": { - "version": "3.8.0", + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "inBundle": true, - "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/cidr-regex": { - "version": "3.1.1", + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", "dependencies": { - "ip-regex": "^4.1.0" + "is-obj": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "readable-stream": "^2.0.2" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true + }, + "node_modules/env-ci": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.0.0.tgz", + "integrity": "sha512-apikxMgkipkgTvMdRT9MNqWx5VLOci79F4VBd7Op/7OPjjoanjdAvn6fglMCCEf/1bAh8eOiuEVCUs4V3qP3nQ==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" + "execa": "^8.0.0", + "java-properties": "^1.0.2" }, "engines": { - "node": ">= 10" + "node": "^18.17 || >=20.6.1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/cli-table3": { - "version": "0.6.3", + "node_modules/env-ci/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "string-width": "^4.2.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": "10.* || >= 12.*" + "node": ">=16.17" }, - "optionalDependencies": { - "@colors/colors": "1.5.0" + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/clone": { - "version": "1.0.4", + "node_modules/env-ci/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { - "node": ">=0.8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/cmd-shim": { - "version": "6.0.1", + "node_modules/env-ci/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, - "inBundle": true, - "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=16.17.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/color-convert": { - "version": "2.0.1", + "node_modules/env-ci/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/color-support": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/columnify": { - "version": "1.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "engines": { - "node": ">=8.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/common-ancestor-path": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/concat-map": { - "version": "0.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/console-control-strings": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.3", + "node_modules/env-ci/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, "engines": { - "node": ">= 8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", + "node_modules/env-ci/node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "path-key": "^4.0.0" }, "engines": { - "node": ">= 8" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/cssesc": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/debug": { - "version": "4.3.4", + "node_modules/env-ci/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=6.0" + "node": ">=12" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/defaults": { - "version": "1.0.4", + "node_modules/env-ci/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" + "engines": { + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/delegates": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/depd": { - "version": "2.0.0", + "node_modules/env-ci/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/diff": { - "version": "5.1.0", + "node_modules/env-ci/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/eastasianwidth": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/env-paths": { + "node_modules/env-paths": { "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/err-code": { - "version": "2.0.3", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, - "inBundle": true, - "license": "MIT" + "dependencies": { + "is-arrayish": "^0.2.1" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/event-target-shim": { - "version": "5.0.1", + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/events": { - "version": "3.3.0", + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { - "node": ">=0.8.x" + "node": ">=0.8.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/fastest-levenshtein": { - "version": "1.0.16", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "inBundle": true, - "license": "MIT", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, "engines": { - "node": ">= 4.9.1" + "node": ">=4" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/foreground-child": { - "version": "3.1.1", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">=14" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/fs-minipass": { - "version": "3.0.2", + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "minipass": "^5.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8.6.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/fs.realpath": { - "version": "1.0.0", + "node_modules/fastq": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz", + "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==", "dev": true, - "inBundle": true, - "license": "ISC" + "dependencies": { + "reusify": "^1.0.4" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/function-bind": { - "version": "1.1.1", + "node_modules/figures": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/figures/-/figures-6.0.1.tgz", + "integrity": "sha512-0oY/olScYD4IhQ8u//gCPA4F3mlTn2dacYmiDm/mbDQvpmLjV4uH+zhsQ5IyXRyvqkvtUkXkNdGvg5OFJTCsuQ==", "dev": true, - "inBundle": true, - "license": "MIT" + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/gauge": { - "version": "5.0.1", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^4.0.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "to-regex-range": "^5.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/glob": { - "version": "10.2.7", + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" + "locate-path": "^2.0.0" }, - "bin": { - "glob": "dist/cjs/src/bin.js" + "engines": { + "node": ">=4" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", + "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-versions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", + "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", + "dev": true, + "dependencies": { + "semver-regex": "^4.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/graceful-fs": { - "version": "4.2.11", + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", "dev": true, - "inBundle": true, - "license": "ISC" + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/has": { - "version": "1.0.3", + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "function-bind": "^1.1.1" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">= 0.4.0" + "node": ">=14.14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/has-unicode": { - "version": "2.0.1", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, - "inBundle": true, - "license": "ISC" + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/hosted-git-info": { - "version": "6.1.1", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^7.5.1" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "inBundle": true, - "license": "BSD-2-Clause" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/http-proxy-agent": { - "version": "5.0.0", + "node_modules/git-log-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", + "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "~0.6.6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/https-proxy-agent": { - "version": "5.0.1", + "node_modules/git-log-parser/node_modules/split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "agent-base": "6", - "debug": "4" + "through2": "~2.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/humanize-ms": { - "version": "1.2.1", + "node_modules/globby": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", + "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "ms": "^2.0.0" + "@sindresorhus/merge-streams": "^1.0.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/iconv-lite": { - "version": "0.6.3", + "node_modules/globby/node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ieee754": { - "version": "1.2.1", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/gradle-semantic-release-plugin": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/gradle-semantic-release-plugin/-/gradle-semantic-release-plugin-1.9.1.tgz", + "integrity": "sha512-lCrw22itszP/FLSL3N61E40vH1+CU95/4LG9ZF+Fxr8tcx7EPthh2eqVPAq67udFlM8ZgO2LETnn8LSDRq1J2w==", "dev": true, "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/KengoTODA" } ], - "inBundle": true, - "license": "BSD-3-Clause" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "minimatch": "^9.0.0" + "promisified-properties": "^3.0.0", + "split2": "^4.1.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=18" + }, + "peerDependencies": { + "semantic-release": "^23.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, - "inBundle": true, - "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, "engines": { - "node": ">=0.8.19" + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/indent-string": { + "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/inflight": { - "version": "1.0.6", + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/inherits": { - "version": "2.0.4", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ini": { - "version": "4.1.1", + "node_modules/hook-std": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", + "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", "dev": true, - "inBundle": true, - "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/init-package-json": { - "version": "5.0.0", + "node_modules/hosted-git-info": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", + "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "npm-package-arg": "^10.0.0", - "promzard": "^1.0.0", - "read": "^2.0.0", - "read-package-json": "^6.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" + "lru-cache": "^10.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ip": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ip-regex": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/is-cidr": { - "version": "4.0.2", + "node_modules/http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", "dependencies": { - "cidr-regex": "^3.1.1" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=10" + "node": ">= 14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/is-core-module": { - "version": "2.13.0", + "node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "has": "^1.0.3" + "agent-base": "^7.0.2", + "debug": "4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { - "node": ">=8" + "node": ">=10.17.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/isexe": { - "version": "2.0.0", + "node_modules/ignore": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, - "inBundle": true, - "license": "ISC" + "engines": { + "node": ">= 4" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/jackspeak": { - "version": "2.2.1", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.0", + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "inBundle": true, - "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=4" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/json-stringify-nice": { - "version": "1.1.4", + "node_modules/import-from-esm": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.3.tgz", + "integrity": "sha512-U3Qt/CyfFpTUv6LOP2jRTLYjphH6zg3okMfHbyqRa/W2w6hr8OsJWVggNlR4jxuojQy81TgTJTxgSkyoteRGMQ==", "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" + "dependencies": { + "debug": "^4.3.4", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": ">=16.20" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/jsonparse": { - "version": "1.3.1", + "node_modules/import-meta-resolve": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", + "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "inBundle": true, - "license": "MIT" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/just-diff": { - "version": "6.0.2", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, - "inBundle": true, - "license": "MIT" + "engines": { + "node": ">=8" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/just-diff-apply": { - "version": "5.5.0", + "node_modules/index-to-position": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", + "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", "dev": true, - "inBundle": true, - "license": "MIT" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmaccess": { - "version": "7.0.2", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/into-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", + "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "npm-package-arg": "^10.1.0", - "npm-registry-fetch": "^14.0.3" + "from2": "^2.3.0", + "p-is-promise": "^3.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmdiff": { - "version": "5.0.20", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "@npmcli/arborist": "^6.5.0", - "@npmcli/disparity-colors": "^3.0.0", - "@npmcli/installed-package-contents": "^2.0.2", - "binary-extensions": "^2.2.0", - "diff": "^5.1.0", - "minimatch": "^9.0.0", - "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8", - "tar": "^6.1.13" + "hasown": "^2.0.0" }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmexec": { - "version": "6.0.4", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^6.5.0", - "@npmcli/run-script": "^6.0.0", - "ci-info": "^3.7.1", - "npm-package-arg": "^10.1.0", - "npmlog": "^7.0.1", - "pacote": "^15.0.8", - "proc-log": "^3.0.0", - "read": "^2.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "walk-up-path": "^3.0.1" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmfund": { - "version": "4.2.1", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^6.5.0" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmhook": { - "version": "9.0.3", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^14.0.3" + "is-extglob": "^2.1.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmorg": { - "version": "5.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^14.0.3" - }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=0.12.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmpack": { - "version": "5.0.20", + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^6.5.0", - "@npmcli/run-script": "^6.0.0", - "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmpublish": { - "version": "7.5.1", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ci-info": "^3.6.1", - "normalize-package-data": "^5.0.0", - "npm-package-arg": "^10.1.0", - "npm-registry-fetch": "^14.0.3", - "proc-log": "^3.0.0", - "semver": "^7.3.7", - "sigstore": "^1.4.0", - "ssri": "^10.0.1" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmsearch": { - "version": "6.0.2", + "node_modules/is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "npm-registry-fetch": "^14.0.3" + "text-extensions": "^2.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmteam": { - "version": "5.0.3", + "node_modules/is-unicode-supported": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", + "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^14.0.3" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/libnpmversion": { - "version": "4.0.2", + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/issue-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "@npmcli/git": "^4.0.1", - "@npmcli/run-script": "^6.0.0", - "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.7" + "lodash.capitalize": "^4.2.1", + "lodash.escaperegexp": "^4.1.2", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.uniqby": "^4.7.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=10.13" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/lru-cache": { - "version": "7.18.3", + "node_modules/java-properties": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", + "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", "dev": true, - "inBundle": true, - "license": "ISC", "engines": { - "node": ">=12" + "node": ">= 0.6.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/make-fetch-happen": { - "version": "11.1.1", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" + "argparse": "^2.0.1" }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minimatch": { - "version": "9.0.3", + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" + "universalify": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass": { - "version": "5.0.0", + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=8" - } + "engines": [ + "node >= 0.2.0" + ] }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-collect": { - "version": "1.0.2", + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "minipass": "^3.0.0" + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" + "bin": { + "JSONStream": "bin.js" }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-fetch": { - "version": "3.0.3", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, - "inBundle": true, - "license": "MIT", "dependencies": { - "minipass": "^5.0.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" + "node": ">=4" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "minipass": "^3.0.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" }, "engines": { - "node": ">= 8" + "node": ">=4" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-json-stream": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" + "node": ">=4" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-pipeline": { - "version": "1.2.4", + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true + }, + "node_modules/lodash.capitalize": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", + "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", + "dev": true + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", + "dev": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "dev": true + }, + "node_modules/lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": "14 || >=16.14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", + "node_modules/marked": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-11.1.1.tgz", + "integrity": "sha512-EgxRjgK9axsQuUa/oKMx5DEY8oXpKJfk61rT5iY3aRlgU6QJtUcxU5OAymdhCvWvhYcd9FKmO5eQoX8m9VGJXg==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" + "bin": { + "marked": "bin/marked.js" }, "engines": { - "node": ">=8" + "node": ">= 18" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-sized": { - "version": "1.0.3", + "node_modules/marked-terminal": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.2.0.tgz", + "integrity": "sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "minipass": "^3.0.0" + "ansi-escapes": "^6.2.0", + "cardinal": "^2.1.1", + "chalk": "^5.3.0", + "cli-table3": "^0.6.3", + "node-emoji": "^2.1.3", + "supports-hyperlinks": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <12" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", + "node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, "engines": { "node": ">= 8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/mkdirp": { - "version": "1.0.4", + "node_modules/mime": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.1.tgz", + "integrity": "sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA==", "dev": true, - "inBundle": true, - "license": "MIT", + "funding": [ + "https://github.com/sponsors/broofa" + ], "bin": { - "mkdirp": "bin/cmd.js" + "mime": "bin/cli.js" }, "engines": { - "node": ">=10" + "node": ">=16" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/mute-stream": { - "version": "1.0.0", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "inBundle": true, - "license": "ISC", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp": { - "version": "9.4.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^11.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^12.13 || ^14.13 || >=16" - } + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/abbrev": { - "version": "1.1.1", - "dev": true, - "inBundle": true, - "license": "ISC" + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/are-we-there-yet": { - "version": "3.0.1", + "node_modules/nerf-dart": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", + "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", + "dev": true + }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node": ">=18" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/gauge": { - "version": "4.0.4", + "node_modules/normalize-package-data": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", + "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" + "hosted-git-info": "^7.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/glob": { - "version": "7.2.3", + "node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, "engines": { - "node": "*" + "node": ">=14.16" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/nopt": { - "version": "6.0.0", + "node_modules/npm": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.4.0.tgz", + "integrity": "sha512-RS7Mx0OVfXlOcQLRePuDIYdFCVBPCNapWHplDK+mh7GDdP/Tvor4ocuybRRPSvfcRb2vjRJt1fHCqw3cr8qACQ==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/run-script", + "@sigstore/tuf", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "cli-columns", + "cli-table3", + "columnify", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmhook", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "normalize-package-data", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "npmlog", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "spdx-expression-parse", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which", + "write-file-atomic" + ], "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "abbrev": "^1.0.0" + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^7.2.1", + "@npmcli/config": "^8.0.2", + "@npmcli/fs": "^3.1.0", + "@npmcli/map-workspaces": "^3.0.4", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.1", + "@npmcli/run-script": "^7.0.4", + "@sigstore/tuf": "^2.3.0", + "abbrev": "^2.0.0", + "archy": "~1.0.0", + "cacache": "^18.0.2", + "chalk": "^5.3.0", + "ci-info": "^4.0.0", + "cli-columns": "^4.0.0", + "cli-table3": "^0.6.3", + "columnify": "^1.6.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^7.0.1", + "ini": "^4.1.1", + "init-package-json": "^6.0.0", + "is-cidr": "^5.0.3", + "json-parse-even-better-errors": "^3.0.1", + "libnpmaccess": "^8.0.1", + "libnpmdiff": "^6.0.3", + "libnpmexec": "^7.0.4", + "libnpmfund": "^5.0.1", + "libnpmhook": "^10.0.0", + "libnpmorg": "^6.0.1", + "libnpmpack": "^6.0.3", + "libnpmpublish": "^9.0.2", + "libnpmsearch": "^7.0.0", + "libnpmteam": "^6.0.0", + "libnpmversion": "^5.0.1", + "make-fetch-happen": "^13.0.0", + "minimatch": "^9.0.3", + "minipass": "^7.0.4", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^10.0.1", + "nopt": "^7.2.0", + "normalize-package-data": "^6.0.0", + "npm-audit-report": "^5.0.0", + "npm-install-checks": "^6.3.0", + "npm-package-arg": "^11.0.1", + "npm-pick-manifest": "^9.0.0", + "npm-profile": "^9.0.0", + "npm-registry-fetch": "^16.1.0", + "npm-user-validate": "^2.0.0", + "npmlog": "^7.0.1", + "p-map": "^4.0.0", + "pacote": "^17.0.6", + "parse-conflict-json": "^3.0.1", + "proc-log": "^3.0.0", + "qrcode-terminal": "^0.12.0", + "read": "^2.1.0", + "semver": "^7.5.4", + "spdx-expression-parse": "^3.0.1", + "ssri": "^10.0.5", + "supports-color": "^9.4.0", + "tar": "^6.2.0", + "text-table": "~0.2.0", + "tiny-relative-date": "^1.3.0", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^5.0.0", + "which": "^4.0.0", + "write-file-atomic": "^5.0.1" }, "bin": { - "nopt": "bin/nopt.js" + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/npmlog": { - "version": "6.0.2", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "inBundle": true, - "license": "ISC", "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" + "path-key": "^3.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/readable-stream": { - "version": "3.6.2", + "node_modules/npm/node_modules/@colors/colors": { + "version": "1.5.0", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, + "optional": true, "engines": { - "node": ">= 6" + "node": ">=0.1.90" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/node-gyp/node_modules/which": { - "version": "2.0.2", + "node_modules/npm/node_modules/@isaacs/cliui": { + "version": "8.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">= 8" + "node": ">=12" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/nopt": { - "version": "7.2.0", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/normalize-package-data": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^6.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" + "node": ">=12" }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-audit-report": { - "version": "5.0.0", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", "dev": true, "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "license": "MIT" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-bundled": { - "version": "3.0.0", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "npm-normalize-package-bin": "^3.0.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-install-checks": { - "version": "6.2.0", + "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, "inBundle": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "semver": "^7.1.1" + "ansi-regex": "^6.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "3.0.1", + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", "dev": true, "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "license": "ISC" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-package-arg": { - "version": "10.1.0", + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "2.2.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "hosted-git-info": "^6.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-packlist": { - "version": "7.0.4", + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "7.3.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "ignore-walk": "^6.0.0" + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^3.1.0", + "@npmcli/installed-package-contents": "^2.0.2", + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/metavuln-calculator": "^7.0.0", + "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/query": "^3.0.1", + "@npmcli/run-script": "^7.0.2", + "bin-links": "^4.0.1", + "cacache": "^18.0.0", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^7.0.1", + "json-parse-even-better-errors": "^3.0.0", + "json-stringify-nice": "^1.1.4", + "minimatch": "^9.0.0", + "nopt": "^7.0.0", + "npm-install-checks": "^6.2.0", + "npm-package-arg": "^11.0.1", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^16.0.0", + "npmlog": "^7.0.1", + "pacote": "^17.0.4", + "parse-conflict-json": "^3.0.0", + "proc-log": "^3.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^10.0.5", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + }, + "bin": { + "arborist": "bin/index.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-pick-manifest": { - "version": "8.0.2", + "node_modules/npm/node_modules/@npmcli/config": { + "version": "8.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^10.0.0", - "semver": "^7.3.5" + "@npmcli/map-workspaces": "^3.0.2", + "ci-info": "^4.0.0", + "ini": "^4.1.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-profile": { - "version": "7.0.1", + "node_modules/npm/node_modules/@npmcli/disparity-colors": { + "version": "3.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^14.0.0", - "proc-log": "^3.0.0" + "ansi-styles": "^4.3.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-registry-fetch": { - "version": "14.0.5", + "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "make-fetch-happen": "^11.0.0", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^10.0.0", - "proc-log": "^3.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npm-user-validate": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/npmlog": { - "version": "7.0.1", + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "3.1.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "are-we-there-yet": "^4.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^5.0.0", - "set-blocking": "^2.0.0" + "semver": "^7.3.5" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/once": { - "version": "1.4.0", + "node_modules/npm/node_modules/@npmcli/git": { + "version": "5.0.4", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "wrappy": "1" + "@npmcli/promise-spawn": "^7.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^3.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/p-map": { - "version": "4.0.0", + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "2.0.2", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "aggregate-error": "^3.0.0" + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" }, - "engines": { - "node": ">=10" + "bin": { + "installed-package-contents": "lib/index.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/pacote": { - "version": "15.2.0", + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "3.0.4", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^4.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^6.0.1", - "@npmcli/run-script": "^6.0.0", - "cacache": "^17.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^5.0.0", - "npm-package-arg": "^10.0.0", - "npm-packlist": "^7.0.0", - "npm-pick-manifest": "^8.0.0", - "npm-registry-fetch": "^14.0.0", - "proc-log": "^3.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^6.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^1.3.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/parse-conflict-json": { - "version": "3.0.1", + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "cacache": "^18.0.0", "json-parse-even-better-errors": "^3.0.0", - "just-diff": "^6.0.0", - "just-diff-apply": "^5.2.0" + "pacote": "^17.0.0", + "semver": "^7.3.5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/path-is-absolute": { - "version": "1.0.1", + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=0.10.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/path-key": { - "version": "3.1.1", + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "3.0.0", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/path-scurry": { - "version": "1.9.2", + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "5.0.0", "dev": true, "inBundle": true, - "license": "BlueOak-1.0.0", + "license": "ISC", "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.5.3" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.1.1", + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", + "dependencies": { + "which": "^4.0.0" + }, "engines": { - "node": "14 || >=16.14" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.0.13", + "node_modules/npm/node_modules/@npmcli/query": { + "version": "3.0.1", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "postcss-selector-parser": "^6.0.10" }, "engines": { - "node": ">=4" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/proc-log": { - "version": "3.0.0", + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "7.0.4", "dev": true, "inBundle": true, "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "which": "^4.0.0" + }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/process": { - "version": "0.11.10", + "node_modules/npm/node_modules/@pkgjs/parseargs": { + "version": "0.11.0", "dev": true, "inBundle": true, "license": "MIT", + "optional": true, "engines": { - "node": ">= 0.6.0" + "node": ">=14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/promise-all-reject-late": { - "version": "1.0.1", + "node_modules/npm/node_modules/@sigstore/bundle": { + "version": "2.1.1", "dev": true, "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/promise-call-limit": { - "version": "1.0.2", + "node_modules/npm/node_modules/@sigstore/core": { + "version": "0.2.0", "dev": true, "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" + "license": "Apache-2.0", + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.2.1", "dev": true, "inBundle": true, - "license": "ISC" + "license": "Apache-2.0", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/promise-retry": { - "version": "2.0.1", + "node_modules/npm/node_modules/@sigstore/sign": { + "version": "2.2.1", "dev": true, "inBundle": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" + "@sigstore/bundle": "^2.1.1", + "@sigstore/core": "^0.2.0", + "@sigstore/protobuf-specs": "^0.2.1", + "make-fetch-happen": "^13.0.0" }, "engines": { - "node": ">=10" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/promzard": { - "version": "1.0.0", + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "2.3.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "Apache-2.0", "dependencies": { - "read": "^2.0.0" + "@sigstore/protobuf-specs": "^0.2.1", + "tuf-js": "^2.2.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/qrcode-terminal": { - "version": "0.12.0", + "node_modules/npm/node_modules/@sigstore/verify": { + "version": "0.1.0", "dev": true, "inBundle": true, - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.1.1", + "@sigstore/core": "^0.2.0", + "@sigstore/protobuf-specs": "^0.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/read": { - "version": "2.1.0", + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "mute-stream": "~1.0.0" - }, + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/read-cmd-shim": { - "version": "4.0.0", + "node_modules/npm/node_modules/@tufjs/models": { + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.3" + }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/read-package-json": { - "version": "6.0.4", + "node_modules/npm/node_modules/abbrev": { + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^5.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/read-package-json-fast": { - "version": "3.0.2", + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" + "debug": "^4.3.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">= 14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/readable-stream": { - "version": "4.4.0", + "node_modules/npm/node_modules/aggregate-error": { + "version": "3.1.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/retry": { - "version": "0.12.0", + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": ">= 4" + "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/rimraf": { - "version": "3.0.2", + "node_modules/npm/node_modules/ansi-styles": { + "version": "6.2.1", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", + "node_modules/npm/node_modules/aproba": { + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "license": "ISC" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/are-we-there-yet": { + "version": "4.0.2", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bin-links": { + "version": "4.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" }, "engines": { - "node": "*" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/safe-buffer": { - "version": "5.2.1", + "node_modules/npm/node_modules/binary-extensions": { + "version": "2.2.0", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "inBundle": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/safer-buffer": { - "version": "2.1.2", + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.1", "dev": true, "inBundle": true, "license": "MIT", - "optional": true + "dependencies": { + "balanced-match": "^1.0.0" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/semver": { - "version": "7.5.4", + "node_modules/npm/node_modules/builtins": { + "version": "5.0.1", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "semver": "^7.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", + "node_modules/npm/node_modules/cacache": { + "version": "18.0.2", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" }, "engines": { - "node": ">=10" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/set-blocking": { - "version": "2.0.0", + "node_modules/npm/node_modules/chalk": { + "version": "5.3.0", "dev": true, "inBundle": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/shebang-command": { + "node_modules/npm/node_modules/chownr": { "version": "2.0.0", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, + "license": "ISC", "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/shebang-regex": { - "version": "3.0.0", + "node_modules/npm/node_modules/ci-info": { + "version": "4.0.0", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "inBundle": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/signal-exit": { - "version": "4.0.2", + "node_modules/npm/node_modules/cidr-regex": { + "version": "4.0.3", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "^5.0.0" + }, "engines": { "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/sigstore": { - "version": "1.9.0", + "node_modules/npm/node_modules/clean-stack": { + "version": "2.2.0", "dev": true, "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^1.1.0", - "@sigstore/protobuf-specs": "^0.2.0", - "@sigstore/sign": "^1.0.0", - "@sigstore/tuf": "^1.0.3", - "make-fetch-happen": "^11.0.1" - }, - "bin": { - "sigstore": "bin/sigstore.js" - }, + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/smart-buffer": { - "version": "4.2.0", + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", "dev": true, "inBundle": true, "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" + "node": ">= 10" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/socks": { - "version": "2.7.1", + "node_modules/npm/node_modules/cli-table3": { + "version": "0.6.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" + "string-width": "^4.2.0" }, "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/socks-proxy-agent": { - "version": "7.0.0", + "node_modules/npm/node_modules/clone": { + "version": "1.0.4", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, "engines": { - "node": ">= 10" + "node": ">=0.8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/spdx-correct": { - "version": "3.2.0", + "node_modules/npm/node_modules/cmd-shim": { + "version": "6.0.2", "dev": true, "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "inBundle": true, - "license": "CC-BY-3.0" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/spdx-expression-parse": { - "version": "3.0.1", + "node_modules/npm/node_modules/color-convert": { + "version": "2.0.1", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.13", + "node_modules/npm/node_modules/color-name": { + "version": "1.1.4", "dev": true, "inBundle": true, - "license": "CC0-1.0" + "license": "MIT" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/ssri": { - "version": "10.0.4", + "node_modules/npm/node_modules/color-support": { + "version": "1.1.3", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "minipass": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "bin": { + "color-support": "bin.js" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/string_decoder": { - "version": "1.3.0", + "node_modules/npm/node_modules/columnify": { + "version": "1.6.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "safe-buffer": "~5.2.0" + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/string-width": { - "version": "4.2.3", + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } + "license": "ISC" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", + "node_modules/npm/node_modules/console-control-strings": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/cross-spawn": { + "version": "7.0.3", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/strip-ansi": { - "version": "6.0.1", + "node_modules/npm/node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "ansi-regex": "^5.0.1" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" + "bin": { + "cssesc": "bin/cssesc" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/supports-color": { - "version": "9.4.0", + "node_modules/npm/node_modules/debug": { + "version": "4.3.4", "dev": true, "inBundle": true, "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, "engines": { - "node": ">=12" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/tar": { - "version": "6.1.15", + "node_modules/npm/node_modules/debug/node_modules/ms": { + "version": "2.1.2", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } + "license": "MIT" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", + "node_modules/npm/node_modules/defaults": { + "version": "1.0.4", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "minipass": "^3.0.0" + "clone": "^1.0.2" }, - "engines": { - "node": ">= 8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", + "node_modules/npm/node_modules/diff": { + "version": "5.1.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, + "license": "BSD-3-Clause", "engines": { - "node": ">=8" + "node": ">=0.3.1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/text-table": { + "node_modules/npm/node_modules/eastasianwidth": { "version": "0.2.0", "dev": true, "inBundle": true, "license": "MIT" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", "dev": true, "inBundle": true, "license": "MIT" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/treeverse": { - "version": "3.0.0", + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/tuf-js": { - "version": "1.1.7", + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "@tufjs/models": "1.0.4", - "debug": "^4.3.4", - "make-fetch-happen": "^11.1.1" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">= 4.9.1" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/unique-filename": { - "version": "3.0.0", + "node_modules/npm/node_modules/foreground-child": { + "version": "3.1.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "unique-slug": "^4.0.0" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/unique-slug": { - "version": "4.0.0", + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.3", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "imurmurhash": "^0.1.4" + "minipass": "^7.0.3" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/util-deprecate": { - "version": "1.0.2", + "node_modules/npm/node_modules/function-bind": { + "version": "1.1.2", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", + "node_modules/npm/node_modules/gauge": { + "version": "5.0.1", "dev": true, "inBundle": true, - "license": "Apache-2.0", + "license": "ISC", "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^4.0.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/validate-npm-package-name": { - "version": "5.0.0", + "node_modules/npm/node_modules/glob": { + "version": "10.3.10", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "builtins": "^5.0.0" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/walk-up-path": { - "version": "3.0.1", + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", "dev": true, "inBundle": true, "license": "ISC" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wcwidth": { - "version": "1.0.1", + "node_modules/npm/node_modules/has-unicode": { + "version": "2.0.1", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } + "license": "ISC" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/which": { - "version": "3.0.1", + "node_modules/npm/node_modules/hasown": { + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/which.js" + "function-bind": "^1.1.2" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">= 0.4" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wide-align": { - "version": "1.1.5", + "node_modules/npm/node_modules/hosted-git-info": { + "version": "7.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wrap-ansi": { - "version": "8.1.0", + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.1.1", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } + "license": "BSD-2-Clause" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", + "node_modules/npm/node_modules/http-proxy-agent": { "version": "7.0.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">= 14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "7.0.2", "dev": true, "inBundle": true, "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "engines": { + "node": ">= 14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", "dev": true, "inBundle": true, "license": "MIT", - "engines": { - "node": ">=12" + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", + "node_modules/npm/node_modules/ignore-walk": { + "version": "6.0.4", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "minimatch": "^9.0.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=0.8.19" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/wrappy": { - "version": "1.0.2", + "node_modules/npm/node_modules/indent-string": { + "version": "4.0.0", "dev": true, "inBundle": true, - "license": "ISC" + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/write-file-atomic": { - "version": "5.0.1", + "node_modules/npm/node_modules/ini": { + "version": "4.1.1", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/onetime": { + "node_modules/npm/node_modules/init-package-json": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "p-try": "^2.0.0" + "npm-package-arg": "^11.0.0", + "promzard": "^1.0.0", + "read": "^2.0.0", + "read-package-json": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^5.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/npm/node_modules/ip": { + "version": "2.0.0", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } + "inBundle": true, + "license": "MIT" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/p-reduce": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", - "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", + "node_modules/npm/node_modules/ip-regex": { + "version": "5.0.0", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=12" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/parse-json": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", - "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", + "node_modules/npm/node_modules/is-cidr": { + "version": "5.0.3", "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", "dependencies": { - "@babel/code-frame": "^7.21.4", - "error-ex": "^1.3.2", - "json-parse-even-better-errors": "^3.0.0", - "lines-and-columns": "^2.0.3", - "type-fest": "^3.8.0" + "cidr-regex": "4.0.3" }, "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=14" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/parse-json/node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "node_modules/npm/node_modules/is-core-module": { + "version": "2.13.1", "dev": true, - "engines": { - "node": ">=14.16" + "inBundle": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/npm/node_modules/is-lambda": { + "version": "1.0.1", "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "inBundle": true, + "license": "MIT" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/read-pkg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz", - "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", + "node_modules/npm/node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/jackspeak": { + "version": "2.3.6", "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", "dependencies": { - "@types/normalize-package-data": "^2.4.1", - "normalize-package-data": "^6.0.0", - "parse-json": "^7.0.0", - "type-fest": "^4.2.0" + "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">=16" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/read-pkg-up": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.1.0.tgz", - "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==", + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "3.0.1", "dev": true, - "dependencies": { - "find-up": "^6.3.0", - "read-pkg": "^8.1.0", - "type-fest": "^4.2.0" - }, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/read-pkg-up/node_modules/type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", "dev": true, - "engines": { - "node": ">=16" - }, + "inBundle": true, + "license": "ISC", "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/read-pkg/node_modules/type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release": { - "version": "21.1.2", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-21.1.2.tgz", - "integrity": "sha512-kz76azHrT8+VEkQjoCBHE06JNQgTgsC4bT8XfCzb7DHcsk9vG3fqeMVik8h5rcWCYi2Fd+M3bwA7BG8Z8cRwtA==", + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "8.0.2", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "@semantic-release/commit-analyzer": "^10.0.0", - "@semantic-release/error": "^4.0.0", - "@semantic-release/github": "^9.0.0", - "@semantic-release/npm": "^10.0.2", - "@semantic-release/release-notes-generator": "^11.0.0", - "aggregate-error": "^5.0.0", - "cosmiconfig": "^8.0.0", - "debug": "^4.0.0", - "env-ci": "^9.0.0", - "execa": "^8.0.0", - "figures": "^5.0.0", - "find-versions": "^5.1.0", - "get-stream": "^6.0.0", - "git-log-parser": "^1.2.0", - "hook-std": "^3.0.0", - "hosted-git-info": "^7.0.0", - "lodash-es": "^4.17.21", - "marked": "^5.0.0", - "marked-terminal": "^5.1.1", - "micromatch": "^4.0.2", - "p-each-series": "^3.0.0", - "p-reduce": "^3.0.0", - "read-pkg-up": "^10.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.3.2", - "semver-diff": "^4.0.0", - "signale": "^1.2.1", - "yargs": "^17.5.1" - }, - "bin": { - "semantic-release": "bin/semantic-release.js" + "npm-package-arg": "^11.0.1", + "npm-registry-fetch": "^16.0.0" }, "engines": { - "node": ">=18" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "node_modules/npm/node_modules/libnpmdiff": { + "version": "6.0.6", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.2.1", + "@npmcli/disparity-colors": "^3.0.0", + "@npmcli/installed-package-contents": "^2.0.2", + "binary-extensions": "^2.2.0", + "diff": "^5.1.0", + "minimatch": "^9.0.0", + "npm-package-arg": "^11.0.1", + "pacote": "^17.0.4", + "tar": "^6.2.0" + }, "engines": { - "node": ">=18" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "node_modules/npm/node_modules/libnpmexec": { + "version": "7.0.7", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" + "@npmcli/arborist": "^7.2.1", + "@npmcli/run-script": "^7.0.2", + "ci-info": "^4.0.0", + "npm-package-arg": "^11.0.1", + "npmlog": "^7.0.1", + "pacote": "^17.0.4", + "proc-log": "^3.0.0", + "read": "^2.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "walk-up-path": "^3.0.1" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/npm/node_modules/libnpmfund": { + "version": "5.0.4", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "@npmcli/arborist": "^7.2.1" }, "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/execa/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "node_modules/npm/node_modules/libnpmhook": { + "version": "10.0.1", "dev": true, - "engines": { - "node": ">=16" + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^16.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/npm/node_modules/libnpmorg": { + "version": "6.0.2", "dev": true, - "engines": { - "node": ">=14" + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^16.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "node_modules/npm/node_modules/libnpmpack": { + "version": "6.0.6", "dev": true, - "engines": { - "node": ">=12" + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^7.2.1", + "@npmcli/run-script": "^7.0.2", + "npm-package-arg": "^11.0.1", + "pacote": "^17.0.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "node_modules/npm/node_modules/libnpmpublish": { + "version": "9.0.4", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" + "ci-info": "^4.0.0", + "normalize-package-data": "^6.0.0", + "npm-package-arg": "^11.0.1", + "npm-registry-fetch": "^16.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.7", + "sigstore": "^2.2.0", + "ssri": "^10.0.5" }, "engines": { - "node": ">=8" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@saithodev/semantic-release-backmerge/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "node_modules/npm/node_modules/libnpmsearch": { + "version": "7.0.1", "dev": true, - "engines": { - "node": ">=10" + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^16.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@semantic-release/changelog": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", - "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", + "node_modules/npm/node_modules/libnpmteam": { + "version": "6.0.1", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "fs-extra": "^11.0.0", - "lodash": "^4.17.4" + "aproba": "^2.0.0", + "npm-registry-fetch": "^16.0.0" }, "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "semantic-release": ">=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@semantic-release/commit-analyzer": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-11.1.0.tgz", - "integrity": "sha512-cXNTbv3nXR2hlzHjAMgbuiQVtvWHTlwwISt60B+4NZv01y/QRY7p2HcJm8Eh2StzcTJoNnflvKjHH/cjFS7d5g==", + "node_modules/npm/node_modules/libnpmversion": { + "version": "5.0.2", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "conventional-changelog-angular": "^7.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "import-from-esm": "^1.0.3", - "lodash-es": "^4.17.21", - "micromatch": "^4.0.2" + "@npmcli/git": "^5.0.3", + "@npmcli/run-script": "^7.0.2", + "json-parse-even-better-errors": "^3.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.7" }, "engines": { - "node": "^18.17 || >=20.6.1" - }, - "peerDependencies": { - "semantic-release": ">=20.1.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@semantic-release/error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", - "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", + "node_modules/npm/node_modules/lru-cache": { + "version": "10.1.0", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=14.17" + "node": "14 || >=16.14" } }, - "node_modules/@semantic-release/git": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", - "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "13.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "execa": "^5.0.0", - "lodash": "^4.17.4", - "micromatch": "^4.0.0", - "p-reduce": "^2.0.0" + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" }, "engines": { - "node": ">=14.17" - }, - "peerDependencies": { - "semantic-release": ">=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@semantic-release/github": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.2.3.tgz", - "integrity": "sha512-FAjXb1F84CVI6IG8fWi+XS9ErYD+s3MHkP03zBa3+GyUrV4kqwYu/WPppIciHxujGFR51SAWPkOY5rnH6ZlrxA==", + "node_modules/npm/node_modules/minimatch": { + "version": "9.0.3", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "@octokit/core": "^5.0.0", - "@octokit/plugin-paginate-rest": "^9.0.0", - "@octokit/plugin-retry": "^6.0.0", - "@octokit/plugin-throttling": "^8.0.0", - "@semantic-release/error": "^4.0.0", - "aggregate-error": "^5.0.0", - "debug": "^4.3.4", - "dir-glob": "^3.0.1", - "globby": "^14.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "issue-parser": "^6.0.0", - "lodash-es": "^4.17.21", - "mime": "^3.0.0", - "p-filter": "^3.0.0", - "url-join": "^5.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=18" + "node": ">=16 || 14 >=14.17" }, - "peerDependencies": { - "semantic-release": ">=20.1.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@semantic-release/github/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "node_modules/npm/node_modules/minipass": { + "version": "7.0.4", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=18" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/@semantic-release/github/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "node_modules/npm/node_modules/minipass-collect": { + "version": "2.0.1", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" + "minipass": "^7.0.3" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/@semantic-release/github/node_modules/clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "node_modules/npm/node_modules/minipass-fetch": { + "version": "3.0.4", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "escape-string-regexp": "5.0.0" + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" }, "engines": { - "node": ">=14.16" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "encoding": "^0.1.13" } }, - "node_modules/@semantic-release/github/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", "dev": true, - "engines": { - "node": ">=12" + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@semantic-release/github/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 8" } }, - "node_modules/@semantic-release/npm": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-11.0.1.tgz", - "integrity": "sha512-nFcT0pgVwpXsPkzjqP3ObH+pILeN1AbYscCDuYwgZEPZukL+RsGhrtdT4HA1Gjb/y1bVbE90JNtMIcgRi5z/Fg==", + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "@semantic-release/error": "^4.0.0", - "aggregate-error": "^5.0.0", - "execa": "^8.0.0", - "fs-extra": "^11.0.0", - "lodash-es": "^4.17.21", - "nerf-dart": "^1.0.0", - "normalize-url": "^8.0.0", - "npm": "^10.0.0", - "rc": "^1.2.8", - "read-pkg": "^9.0.0", - "registry-auth-token": "^5.0.0", - "semver": "^7.1.2", - "tempy": "^3.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": "^18.17 || >=20" - }, - "peerDependencies": { - "semantic-release": ">=20.1.0" + "node": ">=8" } }, - "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", + "node_modules/npm/node_modules/minipass-json-stream": { + "version": "1.0.1", "dev": true, - "engines": { - "node": ">=18" + "inBundle": true, + "license": "MIT", + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" } }, - "node_modules/@semantic-release/npm/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", + "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/@semantic-release/npm/node_modules/clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "escape-string-regexp": "5.0.0" + "minipass": "^3.0.0" }, "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/@semantic-release/npm/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", "dev": true, - "engines": { - "node": ">=12" + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, - "node_modules/@semantic-release/npm/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "minipass": "^3.0.0" }, "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": ">=8" } }, - "node_modules/@semantic-release/npm/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", "dev": true, - "engines": { - "node": ">=16" + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, - "node_modules/@semantic-release/npm/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "node_modules/npm/node_modules/minizlib": { + "version": "2.1.2", "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, "engines": { - "node": ">=16.17.0" + "node": ">= 8" } }, - "node_modules/@semantic-release/npm/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "node_modules/npm/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">=12" + "node": ">=8" + } + }, + "node_modules/npm/node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=10" } }, - "node_modules/@semantic-release/npm/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@semantic-release/npm/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/npm/node_modules/negotiator": { + "version": "0.6.3", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.6" } }, - "node_modules/@semantic-release/npm/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "node_modules/npm/node_modules/node-gyp": { + "version": "10.0.1", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "path-key": "^4.0.0" + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^4.0.0" }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "bin": { + "node-gyp": "bin/node-gyp.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@semantic-release/npm/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "node_modules/npm/node_modules/nopt": { + "version": "7.2.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "mimic-fn": "^4.0.0" + "abbrev": "^2.0.0" }, - "engines": { - "node": ">=12" + "bin": { + "nopt": "bin/nopt.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@semantic-release/npm/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/npm/node_modules/normalize-package-data": { + "version": "6.0.0", "dev": true, - "engines": { - "node": ">=12" + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "is-core-module": "^2.8.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@semantic-release/npm/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/npm/node_modules/npm-audit-report": { + "version": "5.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@semantic-release/npm/node_modules/strip-final-newline": { + "node_modules/npm/node_modules/npm-bundled": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "engines": { - "node": ">=12" + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@semantic-release/release-notes-generator": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-12.1.0.tgz", - "integrity": "sha512-g6M9AjUKAZUZnxaJZnouNBeDNTCUrJ5Ltj+VJ60gJeDaRRahcHsry9HW8yKrnKkKNkx5lbWiEP1FPMqVNQz8Kg==", + "node_modules/npm/node_modules/npm-install-checks": { + "version": "6.3.0", "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", "dependencies": { - "conventional-changelog-angular": "^7.0.0", - "conventional-changelog-writer": "^7.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "get-stream": "^7.0.0", - "import-from-esm": "^1.0.3", - "into-stream": "^7.0.0", - "lodash-es": "^4.17.21", - "read-pkg-up": "^11.0.0" + "semver": "^7.1.1" }, "engines": { - "node": "^18.17 || >=20.6.1" - }, - "peerDependencies": { - "semantic-release": ">=20.1.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", - "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "3.0.1", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "node_modules/npm/node_modules/npm-package-arg": { + "version": "11.0.1", "dev": true, - "engines": { - "node": ">=10" + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", - "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", - "dev": true, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true - }, - "node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "node_modules/npm/node_modules/npm-packlist": { + "version": "8.0.2", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "debug": "^4.3.4" + "ignore-walk": "^6.0.4" }, "engines": { - "node": ">= 14" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "9.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" }, "engines": { - "node": ">=8" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/ansi-escapes": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", - "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "node_modules/npm/node_modules/npm-profile": { + "version": "9.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "type-fest": "^3.0.0" + "npm-registry-fetch": "^16.0.0", + "proc-log": "^3.0.0" }, "engines": { - "node": ">=14.16" + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "16.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/npm/node_modules/npm-user-validate": { + "version": "2.0.0", "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/npm/node_modules/npmlog": { + "version": "7.0.1", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "color-convert": "^2.0.1" + "are-we-there-yet": "^4.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^5.0.0", + "set-blocking": "^2.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/argv-formatter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", - "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", - "dev": true - }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "node_modules/npm/node_modules/p-map": { + "version": "4.0.0", "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true - }, - "node_modules/bottleneck": { - "version": "2.19.5", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "dev": true - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/npm/node_modules/pacote": { + "version": "17.0.6", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "fill-range": "^7.0.1" + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^7.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^16.0.0", + "proc-log": "^3.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^7.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^2.2.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" }, "engines": { - "node": ">=8" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "3.0.1", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, "engines": { - "node": ">=6" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/npm/node_modules/path-key": { + "version": "3.1.1", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "node_modules/npm/node_modules/path-scurry": { + "version": "1.10.1", "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "6.0.15", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, - "bin": { - "cdl": "bin/cdl.js" + "engines": { + "node": ">=4" } }, - "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "node_modules/npm/node_modules/proc-log": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", "dev": true, - "engines": { - "node": ">=10" + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.1", "dev": true, - "engines": { - "node": ">=6" + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "node_modules/npm/node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "string-width": "^4.2.0" + "err-code": "^2.0.2", + "retry": "^0.12.0" }, "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" + "node": ">=10" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/npm/node_modules/promzard": { + "version": "1.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "read": "^2.0.0" }, "engines": { - "node": ">=12" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "node_modules/npm/node_modules/read": { + "version": "2.1.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" + "mute-stream": "~1.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "4.0.0", "dev": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/conventional-changelog-angular": { + "node_modules/npm/node_modules/read-package-json": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", - "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "compare-func": "^2.0.0" + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0" }, "engines": { - "node": ">=16" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/conventional-changelog-writer": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz", - "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==", + "node_modules/npm/node_modules/read-package-json-fast": { + "version": "3.0.2", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "conventional-commits-filter": "^4.0.0", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "meow": "^12.0.1", - "semver": "^7.5.2", - "split2": "^4.0.0" - }, - "bin": { - "conventional-changelog-writer": "cli.mjs" + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" }, "engines": { - "node": ">=16" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/conventional-commits-filter": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz", - "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==", + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">= 4" } }, - "node_modules/conventional-commits-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", - "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.5.4", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "is-text-path": "^2.0.0", - "JSONStream": "^1.3.5", - "meow": "^12.0.1", - "split2": "^4.0.0" + "lru-cache": "^6.0.0" }, "bin": { - "conventional-commits-parser": "cli.mjs" + "semver": "bin/semver.js" }, "engines": { - "node": ">=16" + "node": ">=10" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "node_modules/cosmiconfig": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", - "integrity": "sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==", + "node_modules/npm/node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=14" + "node": ">=10" } }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/npm/node_modules/set-blocking": { + "version": "2.0.0", "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } + "inBundle": true, + "license": "ISC" }, - "node_modules/crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "node_modules/npm/node_modules/shebang-command": { + "version": "2.0.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "type-fest": "^1.0.1" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/crypto-random-string/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "node_modules/npm/node_modules/shebang-regex": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "node_modules/npm/node_modules/signal-exit": { + "version": "4.1.0", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": "*" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/npm/node_modules/sigstore": { + "version": "2.2.0", "dev": true, + "inBundle": true, + "license": "Apache-2.0", "dependencies": { - "ms": "2.1.2" + "@sigstore/bundle": "^2.1.1", + "@sigstore/core": "^0.2.0", + "@sigstore/protobuf-specs": "^0.2.1", + "@sigstore/sign": "^2.2.1", + "@sigstore/tuf": "^2.3.0", + "@sigstore/verify": "^0.1.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "node_modules/npm/node_modules/socks": { + "version": "2.7.1", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" }, "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 10.13.0", + "npm": ">= 3.0.0" } }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "8.0.2", "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 14" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.2.0", "dev": true, - "engines": { - "node": ">=4.0.0" + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.3.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" }, - "node_modules/dir-glob": { + "node_modules/npm/node_modules/spdx-expression-parse": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.16", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/ssri": { + "version": "10.0.5", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "is-obj": "^2.0.0" + "minipass": "^7.0.3" }, "engines": { - "node": ">=8" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", + "node_modules/npm/node_modules/string-width": { + "version": "4.2.3", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "readable-stream": "^2.0.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", - "dev": true - }, - "node_modules/env-ci": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-10.0.0.tgz", - "integrity": "sha512-U4xcd/utDYFgMh0yWj07R1H6L5fwhVbmxBCpnL0DbVSDZVnsC82HONw0wxtxNkIAcua3KtbomQvIk5xFZGAQJw==", + "node_modules/npm/node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "execa": "^8.0.0", - "java-properties": "^1.0.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": "^18.17 || >=20.6.1" + "node": ">=8" } }, - "node_modules/env-ci/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": ">=8" } }, - "node_modules/env-ci/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "node_modules/npm/node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", "dev": true, - "engines": { - "node": ">=16" + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/env-ci/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, "engines": { - "node": ">=16.17.0" + "node": ">=8" } }, - "node_modules/env-ci/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "node_modules/npm/node_modules/supports-color": { + "version": "9.4.0", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/env-ci/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/npm/node_modules/tar": { + "version": "6.2.0", "dev": true, - "engines": { - "node": ">=12" + "inBundle": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=10" } }, - "node_modules/env-ci/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "path-key": "^4.0.0" + "minipass": "^3.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 8" } }, - "node_modules/env-ci/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "mimic-fn": "^4.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/env-ci/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/npm/node_modules/tar/node_modules/minipass": { + "version": "5.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/env-ci/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "inBundle": true, + "license": "MIT" }, - "node_modules/env-ci/node_modules/strip-final-newline": { + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/treeverse": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/npm/node_modules/tuf-js": { + "version": "2.2.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "is-arrayish": "^0.2.1" + "@tufjs/models": "2.0.0", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/npm/node_modules/unique-filename": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, "engines": { - "node": ">=6" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/npm/node_modules/unique-slug": { + "version": "4.0.0", "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, "engines": { - "node": ">=0.8.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "5.0.0", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "builtins": "^5.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "node_modules/npm/node_modules/walk-up-path": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/wcwidth": { + "version": "1.0.1", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "defaults": "^1.0.3" + } + }, + "node_modules/npm/node_modules/which": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" }, "engines": { - "node": ">=8.6.0" + "node": "^16.13.0 || >=18.0.0" } }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "node_modules/npm/node_modules/which/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/npm/node_modules/wide-align": { + "version": "1.1.5", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "reusify": "^1.0.4" + "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "node_modules/figures": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.0.1.tgz", - "integrity": "sha512-0oY/olScYD4IhQ8u//gCPA4F3mlTn2dacYmiDm/mbDQvpmLjV4uH+zhsQ5IyXRyvqkvtUkXkNdGvg5OFJTCsuQ==", + "node_modules/npm/node_modules/wrap-ansi": { + "version": "8.1.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "is-unicode-supported": "^2.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/npm/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/find-up-simple": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", - "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/find-versions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", - "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "semver-regex": "^4.0.5" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" @@ -5769,117 +5517,83 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", + "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/fs-extra": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", - "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", + "node_modules/npm/node_modules/write-file-atomic": { + "version": "5.0.1", "dev": true, + "inBundle": true, + "license": "ISC", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">=14.14" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node_modules/npm/node_modules/yallist": { + "version": "4.0.0", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "inBundle": true, + "license": "ISC" }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" + "dependencies": { + "wrappy": "1" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, "engines": { - "node": ">=10" + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/git-log-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", - "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==", - "dev": true, - "dependencies": { - "argv-formatter": "~1.0.0", - "spawn-error-forwarder": "~1.0.0", - "split2": "~1.0.0", - "stream-combiner2": "~1.1.1", - "through2": "~2.0.0", - "traverse": "~0.6.6" - } - }, - "node_modules/git-log-parser/node_modules/split2": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", - "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", - "dev": true, - "dependencies": { - "through2": "~2.0.0" - } - }, - "node_modules/git-log-parser/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/p-each-series": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", + "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", - "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", + "node_modules/p-filter": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz", + "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==", "dev": true, "dependencies": { - "@sindresorhus/merge-streams": "^1.0.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" + "p-map": "^7.0.1" }, "engines": { "node": ">=18" @@ -5888,248 +5602,238 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby/node_modules/path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "node_modules/p-is-promise": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", + "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/gradle-semantic-release-plugin": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/gradle-semantic-release-plugin/-/gradle-semantic-release-plugin-1.8.0.tgz", - "integrity": "sha512-lRoKlLJvQbvRykDf6nWVuf/XyHEO9TL8dcnLX9lDag8zn5tkOqp5Tctb4re1YEek0zsSVAVX/1nw5lkV5pfm/Q==", + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/KengoTODA" - } - ], "dependencies": { - "promisified-properties": "^2.0.27", - "split2": "^4.1.0" + "p-try": "^1.0.0" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "semantic-release": "^22.0.5" + "node": ">=4" } }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" + "p-limit": "^1.1.0" }, "engines": { - "node": ">=0.4.7" + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.1.tgz", + "integrity": "sha512-2wnaR0XL/FDOj+TgpDuRb2KTjLnu3Fma6b1ZUwGY7LcqenMcvP/YFpjpbPKY6WVGsbuJZRuoUz8iPrt8ORnAFw==", + "dev": true, + "engines": { + "node": ">=18" }, - "optionalDependencies": { - "uglify-js": "^3.1.4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hard-rejection": { + "node_modules/p-reduce": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", + "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "dependencies": { - "function-bind": "^1.1.2" + "callsites": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/hook-std": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", - "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hosted-git-info": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", - "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", - "dev": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } + "node_modules/parsimmon": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.1.tgz", + "integrity": "sha512-u7p959wLfGAhJpSDJVYXoyMCXWYwHia78HhRBWqk7AIbxdmlrfdp5wX0l3xv/iTSH5HvhN9K7o26hwwpgS5Nmw==", + "dev": true }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.3.tgz", - "integrity": "sha512-B7gr+F6MkqB3uzINHXNctGieGsRTMwIBgxkp0yq/5BwcuDzD4A8wQpHQW6vDAm1uKSLQghmRdD9sKqf2vJ1cEg==", + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true, "engines": { - "node": "14 || >=16.14" + "node": ">=4" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, "engines": { - "node": ">= 14" + "node": ">=8" } }, - "node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, "engines": { - "node": ">= 14" + "node": ">=8" } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { - "node": ">=10.17.0" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", "dev": true, "engines": { - "node": ">= 4" + "node": ">=4" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/pkg-conf": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", + "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", "dev": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/import-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", - "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", - "dev": true, - "engines": { - "node": ">=12.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, - "node_modules/import-from-esm": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.3.tgz", - "integrity": "sha512-U3Qt/CyfFpTUv6LOP2jRTLYjphH6zg3okMfHbyqRa/W2w6hr8OsJWVggNlR4jxuojQy81TgTJTxgSkyoteRGMQ==", + "node_modules/promisified-properties": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/promisified-properties/-/promisified-properties-3.0.0.tgz", + "integrity": "sha512-ARteuBuUpPg/+spsMhcKHvdtOW/q8btyyVYYxxegGgx+7u9ix9at8DjP2KM2t8+4SuI8wBLt+3X876FMQx91yQ==", "dev": true, "dependencies": { - "debug": "^4.3.4", - "import-meta-resolve": "^4.0.0" + "parsimmon": "^1.13.0" }, "engines": { - "node": ">=16.20" + "node": ">=18", + "npm": ">=7.12" } }, - "node_modules/import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" } }, - "node_modules/index-to-position": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", - "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", + "node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, "engines": { "node": ">=18" }, @@ -6137,314 +5841,340 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/into-stream": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", - "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", + "node_modules/read-pkg-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", + "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", + "deprecated": "Renamed to read-package-up", "dev": true, "dependencies": { - "from2": "^2.3.0", - "p-is-promise": "^3.0.0" + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.1.tgz", + "integrity": "sha512-7ZnJYTp6uc04uYRISWtiX3DSKB/fxNQT0B5o1OUeCqiQiwF+JC9+rJiZIDrPrNCLLuTqyQmh4VdQqh/ZOkv9MQ==", "dev": true, - "dependencies": { - "hasown": "^2.0.0" + "engines": { + "node": ">=16" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/read-pkg/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/read-pkg/node_modules/type-fest": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.1.tgz", + "integrity": "sha512-7ZnJYTp6uc04uYRISWtiX3DSKB/fxNQT0B5o1OUeCqiQiwF+JC9+rJiZIDrPrNCLLuTqyQmh4VdQqh/ZOkv9MQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", "dev": true, - "engines": { - "node": ">=0.12.0" + "dependencies": { + "esprima": "~4.0.0" } }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "node_modules/registry-auth-token": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", + "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", "dev": true, + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, "engines": { - "node": ">=8" + "node": ">=14" } }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-plain-object": { + "node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/is-text-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", - "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "text-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" + "queue-microtask": "^1.2.2" } }, - "node_modules/is-unicode-supported": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", - "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "node_modules/issue-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", - "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", + "node_modules/semantic-release": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-23.0.0.tgz", + "integrity": "sha512-Jz7jEWO2igTtske112gC4PPE2whCMVrsgxUPG3/SZI7VE357suIUZFlJd1Yu0g2I6RPc2HxNEfUg7KhmDTjwqg==", "dev": true, "dependencies": { - "lodash.capitalize": "^4.2.1", - "lodash.escaperegexp": "^4.1.2", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.uniqby": "^4.7.0" + "@semantic-release/commit-analyzer": "^11.0.0", + "@semantic-release/error": "^4.0.0", + "@semantic-release/github": "^9.0.0", + "@semantic-release/npm": "^11.0.0", + "@semantic-release/release-notes-generator": "^12.0.0", + "aggregate-error": "^5.0.0", + "cosmiconfig": "^9.0.0", + "debug": "^4.0.0", + "env-ci": "^11.0.0", + "execa": "^8.0.0", + "figures": "^6.0.0", + "find-versions": "^5.1.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^3.0.0", + "hosted-git-info": "^7.0.0", + "import-from-esm": "^1.3.1", + "lodash-es": "^4.17.21", + "marked": "^11.0.0", + "marked-terminal": "^6.0.0", + "micromatch": "^4.0.2", + "p-each-series": "^3.0.0", + "p-reduce": "^3.0.0", + "read-pkg-up": "^11.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^4.0.0", + "signale": "^1.2.1", + "yargs": "^17.5.1" + }, + "bin": { + "semantic-release": "bin/semantic-release.js" }, "engines": { - "node": ">=10.13" + "node": ">=20.8.1" } }, - "node_modules/java-properties": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", - "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", + "node_modules/semantic-release/node_modules/@semantic-release/error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", + "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", "dev": true, "engines": { - "node": ">= 0.6.0" + "node": ">=18" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/semantic-release/node_modules/aggregate-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, "dependencies": { - "argparse": "^2.0.1" + "clean-stack": "^5.2.0", + "indent-string": "^5.0.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "node_modules/semantic-release/node_modules/clean-stack": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", "dev": true, "dependencies": { - "universalify": "^2.0.0" + "escape-string-regexp": "5.0.0" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "node_modules/semantic-release/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, - "engines": [ - "node >= 0.2.0" - ] + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "node_modules/semantic-release/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": "*" + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "node_modules/semantic-release/node_modules/execa/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "node_modules/semantic-release/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "engines": { + "node": ">=16.17.0" + } }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "node_modules/semantic-release/node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "engines": { + "node": ">=12" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semantic-release/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, "engines": { - "node": ">=4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/load-json-file/node_modules/parse-json": { + "node_modules/semantic-release/node_modules/mimic-fn": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "node_modules/semantic-release/node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", "dev": true, "dependencies": { - "p-locate": "^6.0.0" + "path-key": "^4.0.0" }, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -6453,12530 +6183,693 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true - }, - "node_modules/lodash.capitalize": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", - "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", - "dev": true - }, - "node_modules/lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "dev": true - }, - "node_modules/lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true - }, - "node_modules/lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "dev": true - }, - "node_modules/lodash.uniqby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/marked": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", - "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 16" - } - }, - "node_modules/marked-terminal": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.1.0.tgz", - "integrity": "sha512-QaCSF6NV82oo6K0szEnmc65ooDeW0T/Adcyf0fcW+Hto2GT1VADFg8dn1zaeHqzj65fqDH1hMNChGNRaC/lbkA==", - "dev": true, - "dependencies": { - "ansi-escapes": "^6.2.0", - "cardinal": "^2.1.1", - "chalk": "^5.3.0", - "cli-table3": "^0.6.3", - "node-emoji": "^2.1.0", - "supports-hyperlinks": "^3.0.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "marked": ">=1 <11" - } - }, - "node_modules/meow": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", - "dev": true, - "engines": { - "node": ">=16.10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/nerf-dart": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", - "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", - "dev": true - }, - "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/normalize-package-data": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", - "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", - "dev": true, - "dependencies": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.2.4.tgz", - "integrity": "sha512-umEuYneVEYO9KoEEI8n2sSGmNQeqco/3BSeacRlqIkCzw4E7XGtYSWMeJobxzr6hZ2n9cM+u5TsMTcC5bAgoWA==", - "bundleDependencies": [ - "@isaacs/string-locale-compare", - "@npmcli/arborist", - "@npmcli/config", - "@npmcli/fs", - "@npmcli/map-workspaces", - "@npmcli/package-json", - "@npmcli/promise-spawn", - "@npmcli/run-script", - "@sigstore/tuf", - "abbrev", - "archy", - "cacache", - "chalk", - "ci-info", - "cli-columns", - "cli-table3", - "columnify", - "fastest-levenshtein", - "fs-minipass", - "glob", - "graceful-fs", - "hosted-git-info", - "ini", - "init-package-json", - "is-cidr", - "json-parse-even-better-errors", - "libnpmaccess", - "libnpmdiff", - "libnpmexec", - "libnpmfund", - "libnpmhook", - "libnpmorg", - "libnpmpack", - "libnpmpublish", - "libnpmsearch", - "libnpmteam", - "libnpmversion", - "make-fetch-happen", - "minimatch", - "minipass", - "minipass-pipeline", - "ms", - "node-gyp", - "nopt", - "normalize-package-data", - "npm-audit-report", - "npm-install-checks", - "npm-package-arg", - "npm-pick-manifest", - "npm-profile", - "npm-registry-fetch", - "npm-user-validate", - "npmlog", - "p-map", - "pacote", - "parse-conflict-json", - "proc-log", - "qrcode-terminal", - "read", - "semver", - "spdx-expression-parse", - "ssri", - "strip-ansi", - "supports-color", - "tar", - "text-table", - "tiny-relative-date", - "treeverse", - "validate-npm-package-name", - "which", - "write-file-atomic" - ], - "dev": true, - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.2.1", - "@npmcli/config": "^8.0.2", - "@npmcli/fs": "^3.1.0", - "@npmcli/map-workspaces": "^3.0.4", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.2", - "@sigstore/tuf": "^2.2.0", - "abbrev": "^2.0.0", - "archy": "~1.0.0", - "cacache": "^18.0.0", - "chalk": "^5.3.0", - "ci-info": "^4.0.0", - "cli-columns": "^4.0.0", - "cli-table3": "^0.6.3", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.16", - "fs-minipass": "^3.0.3", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "hosted-git-info": "^7.0.1", - "ini": "^4.1.1", - "init-package-json": "^6.0.0", - "is-cidr": "^5.0.3", - "json-parse-even-better-errors": "^3.0.0", - "libnpmaccess": "^8.0.1", - "libnpmdiff": "^6.0.3", - "libnpmexec": "^7.0.4", - "libnpmfund": "^5.0.1", - "libnpmhook": "^10.0.0", - "libnpmorg": "^6.0.1", - "libnpmpack": "^6.0.3", - "libnpmpublish": "^9.0.2", - "libnpmsearch": "^7.0.0", - "libnpmteam": "^6.0.0", - "libnpmversion": "^5.0.1", - "make-fetch-happen": "^13.0.0", - "minimatch": "^9.0.3", - "minipass": "^7.0.4", - "minipass-pipeline": "^1.2.4", - "ms": "^2.1.2", - "node-gyp": "^10.0.1", - "nopt": "^7.2.0", - "normalize-package-data": "^6.0.0", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.1", - "npm-pick-manifest": "^9.0.0", - "npm-profile": "^9.0.0", - "npm-registry-fetch": "^16.1.0", - "npm-user-validate": "^2.0.0", - "npmlog": "^7.0.1", - "p-map": "^4.0.0", - "pacote": "^17.0.4", - "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", - "qrcode-terminal": "^0.12.0", - "read": "^2.1.0", - "semver": "^7.5.4", - "spdx-expression-parse": "^3.0.1", - "ssri": "^10.0.5", - "strip-ansi": "^7.1.0", - "supports-color": "^9.4.0", - "tar": "^6.2.0", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.0", - "which": "^4.0.0", - "write-file-atomic": "^5.0.1" - }, - "bin": { - "npm": "bin/npm-cli.js", - "npx": "bin/npx-cli.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/@colors/colors": { - "version": "1.5.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/npm/node_modules/@isaacs/cliui": { - "version": "8.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.2.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.0", - "@npmcli/installed-package-contents": "^2.0.2", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.0.0", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/query": "^3.0.1", - "@npmcli/run-script": "^7.0.2", - "bin-links": "^4.0.1", - "cacache": "^18.0.0", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.1", - "json-parse-even-better-errors": "^3.0.0", - "json-stringify-nice": "^1.1.4", - "minimatch": "^9.0.0", - "nopt": "^7.0.0", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.1", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.2", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^10.0.5", - "treeverse": "^3.0.0", - "walk-up-path": "^3.0.1" - }, - "bin": { - "arborist": "bin/index.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/map-workspaces": "^3.0.2", - "ci-info": "^4.0.0", - "ini": "^4.1.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.5", - "walk-up-path": "^3.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/disparity-colors": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ansi-styles": "^4.3.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/@npmcli/fs": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "bin": { - "installed-package-contents": "lib/index.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/name-from-folder": "^2.0.0", - "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cacache": "^18.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^17.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^3.0.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/query": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^10.0.0", - "read-package-json-fast": "^3.0.0", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.2.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "make-fetch-happen": "^13.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.2.1", - "tuf-js": "^2.1.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@tufjs/canonical-json": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@tufjs/models": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/abbrev": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/abort-controller": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/npm/node_modules/agent-base": { - "version": "7.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/npm/node_modules/ansi-styles": { - "version": "6.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/aproba": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/archy": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/are-we-there-yet": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^4.1.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/base64-js": { - "version": "1.5.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/bin-links": { - "version": "4.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/binary-extensions": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/npm/node_modules/buffer": { - "version": "6.0.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/npm/node_modules/builtins": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/npm/node_modules/cacache": { - "version": "18.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/npm/node_modules/chownr": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/ci-info": { - "version": "4.0.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cidr-regex": { - "version": "4.0.3", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "^5.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/cli-columns/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cli-columns/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cli-table3": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/npm/node_modules/clone": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npm/node_modules/cmd-shim": { - "version": "6.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/npm/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/color-support": { - "version": "1.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/npm/node_modules/columnify": { - "version": "1.6.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/npm/node_modules/columnify/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/columnify/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/common-ancestor-path": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/console-control-strings": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/cssesc": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/debug": { - "version": "4.3.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/defaults": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/delegates": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/diff": { - "version": "5.1.0", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/npm/node_modules/eastasianwidth": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/npm/node_modules/env-paths": { - "version": "2.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/event-target-shim": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/events": { - "version": "3.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0" - }, - "node_modules/npm/node_modules/fastest-levenshtein": { - "version": "1.0.16", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/npm/node_modules/foreground-child": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/fs-minipass": { - "version": "3.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/function-bind": { - "version": "1.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/npm/node_modules/gauge": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^4.0.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/gauge/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/gauge/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/glob": { - "version": "10.3.10", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/has-unicode": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/hasown": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/npm/node_modules/hosted-git-info": { - "version": "7.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npm/node_modules/http-proxy-agent": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/iconv-lite": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm/node_modules/ieee754": { - "version": "1.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "BSD-3-Clause" - }, - "node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minimatch": "^9.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/npm/node_modules/indent-string": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ini": { - "version": "4.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/init-package-json": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^11.0.0", - "promzard": "^1.0.0", - "read": "^2.0.0", - "read-package-json": "^7.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/ip": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/ip-regex": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/is-cidr": { - "version": "5.0.3", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "cidr-regex": "4.0.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/is-core-module": { - "version": "2.13.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/is-lambda": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/jackspeak": { - "version": "2.3.6", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/json-stringify-nice": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/jsonparse": { - "version": "1.3.1", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff": { - "version": "6.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff-apply": { - "version": "5.5.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/disparity-colors": "^3.0.0", - "@npmcli/installed-package-contents": "^2.0.2", - "binary-extensions": "^2.2.0", - "diff": "^5.1.0", - "minimatch": "^9.0.0", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", - "tar": "^6.2.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmexec": { - "version": "7.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.1", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "proc-log": "^3.0.0", - "read": "^2.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "walk-up-path": "^3.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^7.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmpack": { - "version": "6.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ci-info": "^4.0.0", - "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.7", - "sigstore": "^2.1.0", - "ssri": "^10.0.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmversion": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.3", - "@npmcli/run-script": "^7.0.2", - "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/lru-cache": { - "version": "10.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/npm/node_modules/make-fetch-happen": { - "version": "13.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/minimatch": { - "version": "9.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/minipass": { - "version": "7.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/npm/node_modules/minipass-collect": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-fetch": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-json-stream": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-pipeline": { - "version": "1.2.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/mkdirp": { - "version": "1.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/mute-stream": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npm/node_modules/node-gyp": { - "version": "10.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^4.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/nopt": { - "version": "7.2.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/normalize-package-data": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-audit-report": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-bundled": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-install-checks": { - "version": "6.3.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-packlist": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ignore-walk": "^6.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "9.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-profile": { - "version": "9.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "16.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "make-fetch-happen": "^13.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-user-validate": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npmlog": { - "version": "7.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^4.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^5.0.0", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/p-map": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/pacote": { - "version": "17.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", - "cacache": "^18.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^2.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/parse-conflict-json": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "just-diff": "^6.0.0", - "just-diff-apply": "^5.2.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/path-key": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/path-scurry": { - "version": "1.10.1", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.0.13", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/proc-log": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/process": { - "version": "0.11.10", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/npm/node_modules/promise-all-reject-late": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-call-limit": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/promise-retry": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/promzard": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "read": "^2.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/qrcode-terminal": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" - } - }, - "node_modules/npm/node_modules/read": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "mute-stream": "~1.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/read-cmd-shim": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json-fast": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/readable-stream": { - "version": "4.4.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/retry": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/npm/node_modules/safe-buffer": { - "version": "5.2.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/safer-buffer": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true - }, - "node_modules/npm/node_modules/semver": { - "version": "7.5.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/set-blocking": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/shebang-command": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/shebang-regex": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/signal-exit": { - "version": "4.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/sigstore": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "@sigstore/sign": "^2.1.0", - "@sigstore/tuf": "^2.1.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/smart-buffer": { - "version": "4.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks": { - "version": "2.7.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "socks": "^2.7.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-exceptions": { - "version": "2.3.0", - "dev": true, - "inBundle": true, - "license": "CC-BY-3.0" - }, - "node_modules/npm/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.16", - "dev": true, - "inBundle": true, - "license": "CC0-1.0" - }, - "node_modules/npm/node_modules/ssri": { - "version": "10.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/string_decoder": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/npm/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/supports-color": { - "version": "9.4.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/npm/node_modules/tar": { - "version": "6.2.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/treeverse": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/models": "2.0.0", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/unique-filename": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/unique-slug": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "builtins": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/walk-up-path": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/npm/node_modules/which": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/which/node_modules/isexe": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/npm/node_modules/wide-align": { - "version": "1.1.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/npm/node_modules/wrap-ansi": { - "version": "8.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/write-file-atomic": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-each-series": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", - "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", - "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", - "dev": true, - "dependencies": { - "p-map": "^5.1.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-is-promise": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", - "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", - "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", - "dev": true, - "dependencies": { - "aggregate-error": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map/node_modules/aggregate-error": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", - "dev": true, - "dependencies": { - "clean-stack": "^4.0.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map/node_modules/clean-stack": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", - "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-reduce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", - "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parsimmon": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.1.tgz", - "integrity": "sha512-u7p959wLfGAhJpSDJVYXoyMCXWYwHia78HhRBWqk7AIbxdmlrfdp5wX0l3xv/iTSH5HvhN9K7o26hwwpgS5Nmw==", - "dev": true - }, - "node_modules/path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", - "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", - "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "load-json-file": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pkg-conf/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "node_modules/promisified-properties": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/promisified-properties/-/promisified-properties-2.0.27.tgz", - "integrity": "sha512-fmx256M3b0QcHnqOj+Ok127LoYpmnYRf7g2OyLl7qD7Z0fzNbIZhHHIPKyvegbA29iAPP5BVWv7BJ/y2cMHHjA==", - "dev": true, - "dependencies": { - "parsimmon": "^1.13.0" - }, - "engines": { - "node": ">=14.16", - "npm": ">=7.12" - } - }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/read-pkg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", - "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.3", - "normalize-package-data": "^6.0.0", - "parse-json": "^8.0.0", - "type-fest": "^4.6.0", - "unicorn-magic": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", - "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", - "deprecated": "Renamed to read-package-up", - "dev": true, - "dependencies": { - "find-up-simple": "^1.0.0", - "read-pkg": "^9.0.0", - "type-fest": "^4.6.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg/node_modules/json-parse-even-better-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", - "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-pkg/node_modules/parse-json": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.0.1.tgz", - "integrity": "sha512-soKUg/q/8bcfuF3+plsbYldE74cVEVEPSC1BUPIGTaX1byXdz6Fo+CVYBdH0jj/5xWsFrNRksl11QkBgHqPQeQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.13", - "index-to-position": "^0.1.1", - "json-parse-even-better-errors": "^3.0.0", - "type-fest": "^4.7.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", - "dev": true, - "dependencies": { - "esprima": "~4.0.0" - } - }, - "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", - "dev": true, - "dependencies": { - "@pnpm/npm-conf": "^2.1.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/semantic-release": { - "version": "22.0.8", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-22.0.8.tgz", - "integrity": "sha512-55rb31jygqIYsGU/rY+gXXm2fnxBIWo9azOjxbqKsPnq7p70zwZ5v+xnD7TxJC+zvS3sy1eHLGXYWCaX3WI76A==", - "dev": true, - "dependencies": { - "@semantic-release/commit-analyzer": "^11.0.0", - "@semantic-release/error": "^4.0.0", - "@semantic-release/github": "^9.0.0", - "@semantic-release/npm": "^11.0.0", - "@semantic-release/release-notes-generator": "^12.0.0", - "aggregate-error": "^5.0.0", - "cosmiconfig": "^8.0.0", - "debug": "^4.0.0", - "env-ci": "^10.0.0", - "execa": "^8.0.0", - "figures": "^6.0.0", - "find-versions": "^5.1.0", - "get-stream": "^6.0.0", - "git-log-parser": "^1.2.0", - "hook-std": "^3.0.0", - "hosted-git-info": "^7.0.0", - "import-from-esm": "^1.3.1", - "lodash-es": "^4.17.21", - "marked": "^9.0.0", - "marked-terminal": "^6.0.0", - "micromatch": "^4.0.2", - "p-each-series": "^3.0.0", - "p-reduce": "^3.0.0", - "read-pkg-up": "^11.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.3.2", - "semver-diff": "^4.0.0", - "signale": "^1.2.1", - "yargs": "^17.5.1" - }, - "bin": { - "semantic-release": "bin/semantic-release.js" - }, - "engines": { - "node": "^18.17 || >=20.6.1" - } - }, - "node_modules/semantic-release/node_modules/@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/semantic-release/node_modules/aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "dependencies": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "5.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/semantic-release/node_modules/execa/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true, - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/semantic-release/node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/p-reduce": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", - "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/semantic-release/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semver-regex": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", - "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/signale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", - "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", - "dev": true, - "dependencies": { - "chalk": "^2.3.2", - "figures": "^2.0.0", - "pkg-conf": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/signale/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/signale/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/signale/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/signale/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/signale/node_modules/figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/signale/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/signale/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "dev": true, - "dependencies": { - "unicode-emoji-modifier-base": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spawn-error-forwarder": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", - "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", - "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", - "dev": true - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split2": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", - "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==", - "dev": true, - "engines": { - "node": ">= 10.x" - } - }, - "node_modules/stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", - "dev": true, - "dependencies": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/temp-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", - "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", - "dev": true, - "engines": { - "node": ">=14.16" - } - }, - "node_modules/tempy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", - "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", - "dev": true, - "dependencies": { - "is-stream": "^3.0.0", - "temp-dir": "^3.0.0", - "type-fest": "^2.12.2", - "unique-string": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/text-extensions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", - "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/traverse": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", - "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/uglify-js": { - "version": "3.17.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", - "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/unique-string": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", - "dev": true, - "dependencies": { - "crypto-random-string": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", - "dev": true - }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/url-join": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", - "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "optional": true - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@octokit/auth-token": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", - "dev": true - }, - "@octokit/core": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz", - "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==", - "dev": true, - "requires": { - "@octokit/auth-token": "^4.0.0", - "@octokit/graphql": "^7.0.0", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/endpoint": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.2.tgz", - "integrity": "sha512-qhKW8YLIi+Kmc92FQUFGr++DYtkx/1fBv+Thua6baqnjnOsgBYJDCvWZR1YcINuHGOEQt416WOfE+A/oG60NBQ==", - "dev": true, - "requires": { - "@octokit/types": "^12.0.0", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/graphql": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", - "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", - "dev": true, - "requires": { - "@octokit/request": "^8.0.1", - "@octokit/types": "^12.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/openapi-types": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.2.tgz", - "integrity": "sha512-8li32fUDUeml/ACRp/njCWTsk5t17cfTM1jp9n08pBrqs5cDFJubtjsSnuz56r5Tad6jdEPJld7LxNp9dNcyjQ==", - "dev": true - }, - "@octokit/plugin-paginate-rest": { - "version": "9.1.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.4.tgz", - "integrity": "sha512-MvZx4WvfhBnt7PtH5XE7HORsO7bBk4er1FgRIUr1qJ89NR2I6bWjGyKsxk8z42FPQ34hFQm0Baanh4gzdZR4gQ==", - "dev": true, - "requires": { - "@octokit/types": "^12.3.0" - } - }, - "@octokit/plugin-retry": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz", - "integrity": "sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog==", - "dev": true, - "requires": { - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "bottleneck": "^2.15.3" - } - }, - "@octokit/plugin-throttling": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.1.3.tgz", - "integrity": "sha512-pfyqaqpc0EXh5Cn4HX9lWYsZ4gGbjnSmUILeu4u2gnuM50K/wIk9s1Pxt3lVeVwekmITgN/nJdoh43Ka+vye8A==", - "dev": true, - "requires": { - "@octokit/types": "^12.2.0", - "bottleneck": "^2.15.3" - } - }, - "@octokit/request": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.5.tgz", - "integrity": "sha512-zVKbNbX1xUluD9ZR4/tPs1yuYrK9xeh5fGZUXA6u04XGsTvomg0YO8/ZUC0FqAd49hAOEMFPAVUTh+2lBhOhLA==", - "dev": true, - "requires": { - "@octokit/endpoint": "^9.0.0", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "@octokit/request-error": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", - "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", - "dev": true, - "requires": { - "@octokit/types": "^12.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/types": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.3.0.tgz", - "integrity": "sha512-nJ8X2HRr234q3w/FcovDlA+ttUU4m1eJAourvfUUtwAWeqL8AsyRqfnLvVnYn3NFbUnsmzQCzLNdFerPwdmcDQ==", - "dev": true, - "requires": { - "@octokit/openapi-types": "^19.0.2" - } - }, - "@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", - "dev": true - }, - "@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", - "dev": true, - "requires": { - "graceful-fs": "4.2.10" - } - }, - "@pnpm/npm-conf": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", - "dev": true, - "requires": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" - } - }, - "@saithodev/semantic-release-backmerge": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@saithodev/semantic-release-backmerge/-/semantic-release-backmerge-3.2.1.tgz", - "integrity": "sha512-mC9cA6lhNzpy4rKOT5jjRLhlT3myubmVeo+BqWyR2WqF5PRJpG0jaU8pBC87S11GCUHKxqXf0QQDZNPbbNP1bA==", - "dev": true, - "requires": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.1.0", - "debug": "^4.3.4", - "execa": "^5.1.1", - "lodash": "^4.17.21", - "semantic-release": ">=20.0.0 <22.0.0" - }, - "dependencies": { - "@semantic-release/commit-analyzer": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-10.0.4.tgz", - "integrity": "sha512-pFGn99fn8w4/MHE0otb2A/l5kxgOuxaaauIh4u30ncoTJuqWj4hXTgEJ03REqjS+w1R2vPftSsO26WC61yOcpw==", - "dev": true, - "requires": { - "conventional-changelog-angular": "^6.0.0", - "conventional-commits-filter": "^3.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "import-from": "^4.0.0", - "lodash-es": "^4.17.21", - "micromatch": "^4.0.2" - }, - "dependencies": { - "conventional-commits-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", - "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", - "dev": true, - "requires": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.1" - } - } - } - }, - "@semantic-release/npm": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-10.0.6.tgz", - "integrity": "sha512-DyqHrGE8aUyapA277BB+4kV0C4iMHh3sHzUWdf0jTgp5NNJxVUz76W1f57FB64Ue03him3CBXxFqQD2xGabxow==", - "dev": true, - "requires": { - "@semantic-release/error": "^4.0.0", - "aggregate-error": "^5.0.0", - "execa": "^8.0.0", - "fs-extra": "^11.0.0", - "lodash-es": "^4.17.21", - "nerf-dart": "^1.0.0", - "normalize-url": "^8.0.0", - "npm": "^9.5.0", - "rc": "^1.2.8", - "read-pkg": "^8.0.0", - "registry-auth-token": "^5.0.0", - "semver": "^7.1.2", - "tempy": "^3.0.0" - }, - "dependencies": { - "@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true - }, - "aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "requires": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - } - }, - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - } - } - }, - "@semantic-release/release-notes-generator": { - "version": "11.0.7", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-11.0.7.tgz", - "integrity": "sha512-T09QB9ImmNx7Q6hY6YnnEbw/rEJ6a+22LBxfZq+pSAXg/OL/k0siwEm5cK4k1f9dE2Z2mPIjJKKohzUm0jbxcQ==", - "dev": true, - "requires": { - "conventional-changelog-angular": "^6.0.0", - "conventional-changelog-writer": "^6.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "get-stream": "^7.0.0", - "import-from": "^4.0.0", - "into-stream": "^7.0.0", - "lodash-es": "^4.17.21", - "read-pkg-up": "^10.0.0" - }, - "dependencies": { - "get-stream": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", - "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", - "dev": true - } - } - }, - "clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", - "dev": true, - "requires": { - "escape-string-regexp": "5.0.0" - } - }, - "conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", - "dev": true, - "requires": { - "compare-func": "^2.0.0" - } - }, - "conventional-changelog-writer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", - "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", - "dev": true, - "requires": { - "conventional-commits-filter": "^3.0.0", - "dateformat": "^3.0.3", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "meow": "^8.1.2", - "semver": "^7.0.0", - "split": "^1.0.1" - }, - "dependencies": { - "conventional-commits-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", - "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", - "dev": true, - "requires": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.1" - } - } - } - }, - "env-ci": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-9.1.1.tgz", - "integrity": "sha512-Im2yEWeF4b2RAMAaWvGioXk6m0UNaIjD8hj28j2ij5ldnIFrDQT0+pzDvpbRkcjurhXhf/AsBKv8P2rtmGi9Aw==", - "dev": true, - "requires": { - "execa": "^7.0.0", - "java-properties": "^1.0.2" - }, - "dependencies": { - "execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - } - }, - "human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "dev": true - } - } - }, - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true - }, - "figures": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", - "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", - "dev": true, - "requires": { - "escape-string-regexp": "^5.0.0", - "is-unicode-supported": "^1.2.0" - } - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true - }, - "indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", - "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", - "dev": true - }, - "lines-and-columns": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", - "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "marked": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.2.tgz", - "integrity": "sha512-ahRPGXJpjMjwSOlBoTMZAK7ATXkli5qCPxZ21TG44rx1KEo44bii4ekgTDQPNRQ4Kh7JMb9Ub1PVk1NxRSsorg==", - "dev": true - }, - "marked-terminal": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-5.2.0.tgz", - "integrity": "sha512-Piv6yNwAQXGFjZSaiNljyNFw7jKDdGrw70FSbtxEyldLsyeuV5ZHm/1wW++kWbrOF1VPnUgYOhB2oLL0ZpnekA==", - "dev": true, - "requires": { - "ansi-escapes": "^6.2.0", - "cardinal": "^2.1.1", - "chalk": "^5.2.0", - "cli-table3": "^0.6.3", - "node-emoji": "^1.11.0", - "supports-hyperlinks": "^2.3.0" - } - }, - "meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "requires": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "requires": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - } - } - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "requires": { - "lodash": "^4.17.21" - } - }, - "npm": { - "version": "9.9.2", - "resolved": "https://registry.npmjs.org/npm/-/npm-9.9.2.tgz", - "integrity": "sha512-D3tV+W0PzJOlwo8YmO6fNzaB1CrMVYd1V+2TURF6lbCbmZKqMsYgeQfPVvqiM3zbNSJPhFEnmlEXIogH2Vq7PQ==", - "dev": true, - "requires": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^6.5.0", - "@npmcli/config": "^6.4.0", - "@npmcli/fs": "^3.1.0", - "@npmcli/map-workspaces": "^3.0.4", - "@npmcli/package-json": "^4.0.1", - "@npmcli/promise-spawn": "^6.0.2", - "@npmcli/run-script": "^6.0.2", - "abbrev": "^2.0.0", - "archy": "~1.0.0", - "cacache": "^17.1.3", - "chalk": "^5.3.0", - "ci-info": "^3.8.0", - "cli-columns": "^4.0.0", - "cli-table3": "^0.6.3", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.16", - "fs-minipass": "^3.0.2", - "glob": "^10.2.7", - "graceful-fs": "^4.2.11", - "hosted-git-info": "^6.1.1", - "ini": "^4.1.1", - "init-package-json": "^5.0.0", - "is-cidr": "^4.0.2", - "json-parse-even-better-errors": "^3.0.0", - "libnpmaccess": "^7.0.2", - "libnpmdiff": "^5.0.20", - "libnpmexec": "^6.0.4", - "libnpmfund": "^4.2.1", - "libnpmhook": "^9.0.3", - "libnpmorg": "^5.0.4", - "libnpmpack": "^5.0.20", - "libnpmpublish": "^7.5.1", - "libnpmsearch": "^6.0.2", - "libnpmteam": "^5.0.3", - "libnpmversion": "^4.0.2", - "make-fetch-happen": "^11.1.1", - "minimatch": "^9.0.3", - "minipass": "^5.0.0", - "minipass-pipeline": "^1.2.4", - "ms": "^2.1.2", - "node-gyp": "^9.4.0", - "nopt": "^7.2.0", - "normalize-package-data": "^5.0.0", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^10.1.0", - "npm-pick-manifest": "^8.0.2", - "npm-profile": "^7.0.1", - "npm-registry-fetch": "^14.0.5", - "npm-user-validate": "^2.0.0", - "npmlog": "^7.0.1", - "p-map": "^4.0.0", - "pacote": "^15.2.0", - "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", - "qrcode-terminal": "^0.12.0", - "read": "^2.1.0", - "semver": "^7.5.4", - "sigstore": "^1.9.0", - "spdx-expression-parse": "^3.0.1", - "ssri": "^10.0.4", - "supports-color": "^9.4.0", - "tar": "^6.1.15", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.0", - "which": "^3.0.1", - "write-file-atomic": "^5.0.1" - }, - "dependencies": { - "@colors/colors": { - "version": "1.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "@isaacs/cliui": { - "version": "8.0.2", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "bundled": true, - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "@isaacs/string-locale-compare": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "@npmcli/arborist": { - "version": "6.5.0", - "bundled": true, - "dev": true, - "requires": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.0", - "@npmcli/installed-package-contents": "^2.0.2", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^5.0.0", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^4.0.0", - "@npmcli/query": "^3.0.0", - "@npmcli/run-script": "^6.0.0", - "bin-links": "^4.0.1", - "cacache": "^17.0.4", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^6.1.1", - "json-parse-even-better-errors": "^3.0.0", - "json-stringify-nice": "^1.1.4", - "minimatch": "^9.0.0", - "nopt": "^7.0.0", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^10.1.0", - "npm-pick-manifest": "^8.0.1", - "npm-registry-fetch": "^14.0.3", - "npmlog": "^7.0.1", - "pacote": "^15.0.8", - "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.2", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^10.0.1", - "treeverse": "^3.0.0", - "walk-up-path": "^3.0.1" - } - }, - "@npmcli/config": { - "version": "6.4.0", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/map-workspaces": "^3.0.2", - "ci-info": "^3.8.0", - "ini": "^4.1.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.5", - "walk-up-path": "^3.0.1" - } - }, - "@npmcli/disparity-colors": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.3.0" - } - }, - "@npmcli/fs": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "semver": "^7.3.5" - } - }, - "@npmcli/git": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/promise-spawn": "^6.0.0", - "lru-cache": "^7.4.4", - "npm-pick-manifest": "^8.0.0", - "proc-log": "^3.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^3.0.0" - } - }, - "@npmcli/installed-package-contents": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - } - }, - "@npmcli/map-workspaces": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/name-from-folder": "^2.0.0", - "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" - } - }, - "@npmcli/metavuln-calculator": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "cacache": "^17.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^15.0.0", - "semver": "^7.3.5" - } - }, - "@npmcli/name-from-folder": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "@npmcli/node-gyp": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "@npmcli/package-json": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/git": "^4.1.0", - "glob": "^10.2.2", - "hosted-git-info": "^6.1.1", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^5.0.0", - "proc-log": "^3.0.0", - "semver": "^7.5.3" - } - }, - "@npmcli/promise-spawn": { - "version": "6.0.2", - "bundled": true, - "dev": true, - "requires": { - "which": "^3.0.0" - } - }, - "@npmcli/query": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "@npmcli/run-script": { - "version": "6.0.2", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/promise-spawn": "^6.0.0", - "node-gyp": "^9.0.0", - "read-package-json-fast": "^3.0.0", - "which": "^3.0.0" - } - }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "bundled": true, - "dev": true, - "optional": true - }, - "@sigstore/bundle": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "@sigstore/protobuf-specs": "^0.2.0" - } - }, - "@sigstore/protobuf-specs": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "@sigstore/sign": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "@sigstore/bundle": "^1.1.0", - "@sigstore/protobuf-specs": "^0.2.0", - "make-fetch-happen": "^11.0.1" - } - }, - "@sigstore/tuf": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "@sigstore/protobuf-specs": "^0.2.0", - "tuf-js": "^1.1.7" - } - }, - "@tootallnate/once": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "@tufjs/canonical-json": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "@tufjs/models": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "requires": { - "@tufjs/canonical-json": "1.0.0", - "minimatch": "^9.0.0" - } - }, - "abbrev": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "agent-base": { - "version": "6.0.2", - "bundled": true, - "dev": true, - "requires": { - "debug": "4" - } - }, - "agentkeepalive": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "debug": "^4.1.0", - "depd": "^2.0.0", - "humanize-ms": "^1.2.1" - } - }, - "aggregate-error": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "aproba": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "are-we-there-yet": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^4.1.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "bundled": true, - "dev": true - }, - "bin-links": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" - } - }, - "binary-extensions": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "buffer": { - "version": "6.0.3", - "bundled": true, - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "builtins": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "cacache": { - "version": "17.1.3", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - } - }, - "chalk": { - "version": "5.3.0", - "bundled": true, - "dev": true - }, - "chownr": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "ci-info": { - "version": "3.8.0", - "bundled": true, - "dev": true - }, - "cidr-regex": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "ip-regex": "^4.1.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "cli-columns": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - } - }, - "cli-table3": { - "version": "0.6.3", - "bundled": true, - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "string-width": "^4.2.0" - } - }, - "clone": { - "version": "1.0.4", - "bundled": true, - "dev": true - }, - "cmd-shim": { - "version": "6.0.1", - "bundled": true, - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "bundled": true, - "dev": true - }, - "color-support": { - "version": "1.1.3", - "bundled": true, - "dev": true - }, - "columnify": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "requires": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - } - }, - "common-ancestor-path": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "bundled": true, - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "cssesc": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "debug": { - "version": "4.3.4", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true - } - } - }, - "defaults": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "requires": { - "clone": "^1.0.2" - } - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "depd": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "diff": { - "version": "5.1.0", - "bundled": true, - "dev": true - }, - "eastasianwidth": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "bundled": true, - "dev": true - }, - "encoding": { - "version": "0.1.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "env-paths": { - "version": "2.2.1", - "bundled": true, - "dev": true - }, - "err-code": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "events": { - "version": "3.3.0", - "bundled": true, - "dev": true - }, - "exponential-backoff": { - "version": "3.1.1", - "bundled": true, - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.16", - "bundled": true, - "dev": true - }, - "foreground-child": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - } - }, - "fs-minipass": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^5.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "gauge": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^4.0.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - } - }, - "glob": { - "version": "10.2.7", - "bundled": true, - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" - } - }, - "graceful-fs": { - "version": "4.2.11", - "bundled": true, - "dev": true - }, - "has": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "hosted-git-info": { - "version": "6.1.1", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^7.5.1" - } - }, - "http-cache-semantics": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "http-proxy-agent": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "humanize-ms": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ieee754": { - "version": "1.2.1", - "bundled": true, - "dev": true - }, - "ignore-walk": { - "version": "6.0.3", - "bundled": true, - "dev": true, - "requires": { - "minimatch": "^9.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true, - "dev": true - }, - "ini": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "init-package-json": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "npm-package-arg": "^10.0.0", - "promzard": "^1.0.0", - "read": "^2.0.0", - "read-package-json": "^6.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" - } - }, - "ip": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "ip-regex": { - "version": "4.3.0", - "bundled": true, - "dev": true - }, - "is-cidr": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "cidr-regex": "^3.1.1" - } - }, - "is-core-module": { - "version": "2.13.0", - "bundled": true, - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "is-lambda": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "jackspeak": { - "version": "2.2.1", - "bundled": true, - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, - "json-parse-even-better-errors": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "json-stringify-nice": { - "version": "1.1.4", - "bundled": true, - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "bundled": true, - "dev": true - }, - "just-diff": { - "version": "6.0.2", - "bundled": true, - "dev": true - }, - "just-diff-apply": { - "version": "5.5.0", - "bundled": true, - "dev": true - }, - "libnpmaccess": { - "version": "7.0.2", - "bundled": true, - "dev": true, - "requires": { - "npm-package-arg": "^10.1.0", - "npm-registry-fetch": "^14.0.3" - } - }, - "libnpmdiff": { - "version": "5.0.20", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^6.5.0", - "@npmcli/disparity-colors": "^3.0.0", - "@npmcli/installed-package-contents": "^2.0.2", - "binary-extensions": "^2.2.0", - "diff": "^5.1.0", - "minimatch": "^9.0.0", - "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8", - "tar": "^6.1.13" - } - }, - "libnpmexec": { - "version": "6.0.4", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^6.5.0", - "@npmcli/run-script": "^6.0.0", - "ci-info": "^3.7.1", - "npm-package-arg": "^10.1.0", - "npmlog": "^7.0.1", - "pacote": "^15.0.8", - "proc-log": "^3.0.0", - "read": "^2.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "walk-up-path": "^3.0.1" - } - }, - "libnpmfund": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^6.5.0" - } - }, - "libnpmhook": { - "version": "9.0.3", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^14.0.3" - } - }, - "libnpmorg": { - "version": "5.0.4", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^14.0.3" - } - }, - "libnpmpack": { - "version": "5.0.20", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^6.5.0", - "@npmcli/run-script": "^6.0.0", - "npm-package-arg": "^10.1.0", - "pacote": "^15.0.8" - } - }, - "libnpmpublish": { - "version": "7.5.1", - "bundled": true, - "dev": true, - "requires": { - "ci-info": "^3.6.1", - "normalize-package-data": "^5.0.0", - "npm-package-arg": "^10.1.0", - "npm-registry-fetch": "^14.0.3", - "proc-log": "^3.0.0", - "semver": "^7.3.7", - "sigstore": "^1.4.0", - "ssri": "^10.0.1" - } - }, - "libnpmsearch": { - "version": "6.0.2", - "bundled": true, - "dev": true, - "requires": { - "npm-registry-fetch": "^14.0.3" - } - }, - "libnpmteam": { - "version": "5.0.3", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^14.0.3" - } - }, - "libnpmversion": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/git": "^4.0.1", - "@npmcli/run-script": "^6.0.0", - "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.7" - } - }, - "lru-cache": { - "version": "7.18.3", - "bundled": true, - "dev": true - }, - "make-fetch-happen": { - "version": "11.1.1", - "bundled": true, - "dev": true, - "requires": { - "agentkeepalive": "^4.2.1", - "cacache": "^17.0.0", - "http-cache-semantics": "^4.1.1", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^10.0.0" - } - }, - "minimatch": { - "version": "9.0.3", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "minipass": { - "version": "5.0.0", - "bundled": true, - "dev": true - }, - "minipass-collect": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass-fetch": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "requires": { - "encoding": "^0.1.13", - "minipass": "^5.0.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - } - }, - "minipass-flush": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass-json-stream": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass-sized": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minizlib": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "bundled": true, - "dev": true - }, - "ms": { - "version": "2.1.3", - "bundled": true, - "dev": true - }, - "mute-stream": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "bundled": true, - "dev": true - }, - "node-gyp": { - "version": "9.4.0", - "bundled": true, - "dev": true, - "requires": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^11.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "are-we-there-yet": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "gauge": { - "version": "4.0.4", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - } - }, - "glob": { - "version": "7.2.3", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "nopt": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "abbrev": "^1.0.0" - } - }, - "npmlog": { - "version": "6.0.2", - "bundled": true, - "dev": true, - "requires": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - } - }, - "readable-stream": { - "version": "3.6.2", - "bundled": true, - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "signal-exit": { - "version": "3.0.7", - "bundled": true, - "dev": true - }, - "which": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "nopt": { - "version": "7.2.0", - "bundled": true, - "dev": true, - "requires": { - "abbrev": "^2.0.0" - } - }, - "normalize-package-data": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "^6.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - } - }, - "npm-audit-report": { - "version": "5.0.0", - "bundled": true, - "dev": true - }, - "npm-bundled": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "npm-normalize-package-bin": "^3.0.0" - } - }, - "npm-install-checks": { - "version": "6.2.0", - "bundled": true, - "dev": true, - "requires": { - "semver": "^7.1.1" - } - }, - "npm-normalize-package-bin": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "npm-package-arg": { - "version": "10.1.0", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "^6.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - } - }, - "npm-packlist": { - "version": "7.0.4", - "bundled": true, - "dev": true, - "requires": { - "ignore-walk": "^6.0.0" - } - }, - "npm-pick-manifest": { - "version": "8.0.2", - "bundled": true, - "dev": true, - "requires": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^10.0.0", - "semver": "^7.3.5" - } - }, - "npm-profile": { - "version": "7.0.1", - "bundled": true, - "dev": true, - "requires": { - "npm-registry-fetch": "^14.0.0", - "proc-log": "^3.0.0" - } - }, - "npm-registry-fetch": { - "version": "14.0.5", - "bundled": true, - "dev": true, - "requires": { - "make-fetch-happen": "^11.0.0", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^10.0.0", - "proc-log": "^3.0.0" - } - }, - "npm-user-validate": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "npmlog": { - "version": "7.0.1", - "bundled": true, - "dev": true, - "requires": { - "are-we-there-yet": "^4.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^5.0.0", - "set-blocking": "^2.0.0" - } - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "p-map": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "pacote": { - "version": "15.2.0", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/git": "^4.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^6.0.1", - "@npmcli/run-script": "^6.0.0", - "cacache": "^17.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^5.0.0", - "npm-package-arg": "^10.0.0", - "npm-packlist": "^7.0.0", - "npm-pick-manifest": "^8.0.0", - "npm-registry-fetch": "^14.0.0", - "proc-log": "^3.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^6.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^1.3.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - } - }, - "parse-conflict-json": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "json-parse-even-better-errors": "^3.0.0", - "just-diff": "^6.0.0", - "just-diff-apply": "^5.2.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "3.1.1", - "bundled": true, - "dev": true - }, - "path-scurry": { - "version": "1.9.2", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" - }, - "dependencies": { - "lru-cache": { - "version": "9.1.1", - "bundled": true, - "dev": true - } - } - }, - "postcss-selector-parser": { - "version": "6.0.13", - "bundled": true, - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "proc-log": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "process": { - "version": "0.11.10", - "bundled": true, - "dev": true - }, - "promise-all-reject-late": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "promise-call-limit": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "promise-retry": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - } - }, - "promzard": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "read": "^2.0.0" - } - }, - "qrcode-terminal": { - "version": "0.12.0", - "bundled": true, - "dev": true - }, - "read": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "mute-stream": "~1.0.0" - } - }, - "read-cmd-shim": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "read-package-json": { - "version": "6.0.4", - "bundled": true, - "dev": true, - "requires": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^5.0.0", - "npm-normalize-package-bin": "^3.0.0" - } - }, - "read-package-json-fast": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - } - }, - "readable-stream": { - "version": "4.4.0", - "bundled": true, - "dev": true, - "requires": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10" - } - }, - "retry": { - "version": "0.12.0", - "bundled": true, - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, - "safe-buffer": { - "version": "5.2.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "7.5.4", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "4.0.2", - "bundled": true, - "dev": true - }, - "sigstore": { - "version": "1.9.0", - "bundled": true, - "dev": true, - "requires": { - "@sigstore/bundle": "^1.1.0", - "@sigstore/protobuf-specs": "^0.2.0", - "@sigstore/sign": "^1.0.0", - "@sigstore/tuf": "^1.0.3", - "make-fetch-happen": "^11.0.1" - } - }, - "smart-buffer": { - "version": "4.2.0", - "bundled": true, - "dev": true - }, - "socks": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "requires": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - } - }, - "socks-proxy-agent": { - "version": "7.0.0", - "bundled": true, - "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - } - }, - "spdx-correct": { - "version": "3.2.0", - "bundled": true, - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "bundled": true, - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.13", - "bundled": true, - "dev": true - }, - "ssri": { - "version": "10.0.4", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^5.0.0" - } - }, - "string_decoder": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "9.4.0", - "bundled": true, - "dev": true - }, - "tar": { - "version": "6.1.15", - "bundled": true, - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "fs-minipass": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - } - } - }, - "text-table": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, - "tiny-relative-date": { - "version": "1.3.0", - "bundled": true, - "dev": true - }, - "treeverse": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "tuf-js": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "@tufjs/models": "1.0.4", - "debug": "^4.3.4", - "make-fetch-happen": "^11.1.1" - } - }, - "unique-filename": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "unique-slug": "^4.0.0" - } - }, - "unique-slug": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - }, - "walk-up-path": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "wcwidth": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "which": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wide-align": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "wrap-ansi": { - "version": "8.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "bundled": true, - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "write-file-atomic": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - } - }, - "yallist": { - "version": "4.0.0", - "bundled": true, - "dev": true - } - } - }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-reduce": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", - "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", - "dev": true - }, - "parse-json": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz", - "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.21.4", - "error-ex": "^1.3.2", - "json-parse-even-better-errors": "^3.0.0", - "lines-and-columns": "^2.0.3", - "type-fest": "^3.8.0" - }, - "dependencies": { - "type-fest": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", - "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true - } - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - }, - "read-pkg": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz", - "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.1", - "normalize-package-data": "^6.0.0", - "parse-json": "^7.0.0", - "type-fest": "^4.2.0" - }, - "dependencies": { - "type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.1.0.tgz", - "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==", - "dev": true, - "requires": { - "find-up": "^6.3.0", - "read-pkg": "^8.1.0", - "type-fest": "^4.2.0" - }, - "dependencies": { - "type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", - "dev": true - } - } - }, - "semantic-release": { - "version": "21.1.2", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-21.1.2.tgz", - "integrity": "sha512-kz76azHrT8+VEkQjoCBHE06JNQgTgsC4bT8XfCzb7DHcsk9vG3fqeMVik8h5rcWCYi2Fd+M3bwA7BG8Z8cRwtA==", - "dev": true, - "requires": { - "@semantic-release/commit-analyzer": "^10.0.0", - "@semantic-release/error": "^4.0.0", - "@semantic-release/github": "^9.0.0", - "@semantic-release/npm": "^10.0.2", - "@semantic-release/release-notes-generator": "^11.0.0", - "aggregate-error": "^5.0.0", - "cosmiconfig": "^8.0.0", - "debug": "^4.0.0", - "env-ci": "^9.0.0", - "execa": "^8.0.0", - "figures": "^5.0.0", - "find-versions": "^5.1.0", - "get-stream": "^6.0.0", - "git-log-parser": "^1.2.0", - "hook-std": "^3.0.0", - "hosted-git-info": "^7.0.0", - "lodash-es": "^4.17.21", - "marked": "^5.0.0", - "marked-terminal": "^5.1.1", - "micromatch": "^4.0.2", - "p-each-series": "^3.0.0", - "p-reduce": "^3.0.0", - "read-pkg-up": "^10.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.3.2", - "semver-diff": "^4.0.0", - "signale": "^1.2.1", - "yargs": "^17.5.1" - }, - "dependencies": { - "@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true - }, - "aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "requires": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - } - }, - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "dependencies": { - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - } - } - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - } - } - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - }, - "supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true - } - } - }, - "@semantic-release/changelog": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", - "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==", - "dev": true, - "requires": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "fs-extra": "^11.0.0", - "lodash": "^4.17.4" - } - }, - "@semantic-release/commit-analyzer": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-11.1.0.tgz", - "integrity": "sha512-cXNTbv3nXR2hlzHjAMgbuiQVtvWHTlwwISt60B+4NZv01y/QRY7p2HcJm8Eh2StzcTJoNnflvKjHH/cjFS7d5g==", - "dev": true, - "requires": { - "conventional-changelog-angular": "^7.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "import-from-esm": "^1.0.3", - "lodash-es": "^4.17.21", - "micromatch": "^4.0.2" - } - }, - "@semantic-release/error": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz", - "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==", - "dev": true - }, - "@semantic-release/git": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz", - "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==", - "dev": true, - "requires": { - "@semantic-release/error": "^3.0.0", - "aggregate-error": "^3.0.0", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "execa": "^5.0.0", - "lodash": "^4.17.4", - "micromatch": "^4.0.0", - "p-reduce": "^2.0.0" - } - }, - "@semantic-release/github": { - "version": "9.2.3", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.2.3.tgz", - "integrity": "sha512-FAjXb1F84CVI6IG8fWi+XS9ErYD+s3MHkP03zBa3+GyUrV4kqwYu/WPppIciHxujGFR51SAWPkOY5rnH6ZlrxA==", - "dev": true, - "requires": { - "@octokit/core": "^5.0.0", - "@octokit/plugin-paginate-rest": "^9.0.0", - "@octokit/plugin-retry": "^6.0.0", - "@octokit/plugin-throttling": "^8.0.0", - "@semantic-release/error": "^4.0.0", - "aggregate-error": "^5.0.0", - "debug": "^4.3.4", - "dir-glob": "^3.0.1", - "globby": "^14.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "issue-parser": "^6.0.0", - "lodash-es": "^4.17.21", - "mime": "^3.0.0", - "p-filter": "^3.0.0", - "url-join": "^5.0.0" - }, - "dependencies": { - "@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true - }, - "aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "requires": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - } - }, - "clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", - "dev": true, - "requires": { - "escape-string-regexp": "5.0.0" - } - }, - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true - }, - "indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true - } - } - }, - "@semantic-release/npm": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-11.0.1.tgz", - "integrity": "sha512-nFcT0pgVwpXsPkzjqP3ObH+pILeN1AbYscCDuYwgZEPZukL+RsGhrtdT4HA1Gjb/y1bVbE90JNtMIcgRi5z/Fg==", - "dev": true, - "requires": { - "@semantic-release/error": "^4.0.0", - "aggregate-error": "^5.0.0", - "execa": "^8.0.0", - "fs-extra": "^11.0.0", - "lodash-es": "^4.17.21", - "nerf-dart": "^1.0.0", - "normalize-url": "^8.0.0", - "npm": "^10.0.0", - "rc": "^1.2.8", - "read-pkg": "^9.0.0", - "registry-auth-token": "^5.0.0", - "semver": "^7.1.2", - "tempy": "^3.0.0" - }, - "dependencies": { - "@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true - }, - "aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "requires": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - } - }, - "clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", - "dev": true, - "requires": { - "escape-string-regexp": "5.0.0" - } - }, - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true - }, - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true - }, - "indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - } - } - }, - "@semantic-release/release-notes-generator": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-12.1.0.tgz", - "integrity": "sha512-g6M9AjUKAZUZnxaJZnouNBeDNTCUrJ5Ltj+VJ60gJeDaRRahcHsry9HW8yKrnKkKNkx5lbWiEP1FPMqVNQz8Kg==", - "dev": true, - "requires": { - "conventional-changelog-angular": "^7.0.0", - "conventional-changelog-writer": "^7.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", - "debug": "^4.0.0", - "get-stream": "^7.0.0", - "import-from-esm": "^1.0.3", - "into-stream": "^7.0.0", - "lodash-es": "^4.17.21", - "read-pkg-up": "^11.0.0" - }, - "dependencies": { - "get-stream": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz", - "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==", - "dev": true - } - } - }, - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true - }, - "@sindresorhus/merge-streams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz", - "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==", - "dev": true - }, - "@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true - }, - "@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true - }, - "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "dev": true, - "requires": { - "debug": "^4.3.4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-escapes": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", - "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", - "dev": true, - "requires": { - "type-fest": "^3.0.0" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "argv-formatter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz", - "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==", - "dev": true - }, - "array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true - }, - "before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true - }, - "bottleneck": { - "version": "2.19.5", - "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz", - "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - } - }, - "cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", - "dev": true, - "requires": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - } - }, - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-table3": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "string-width": "^4.2.0" - } - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "requires": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "conventional-changelog-angular": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", - "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", - "dev": true, - "requires": { - "compare-func": "^2.0.0" - } - }, - "conventional-changelog-writer": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz", - "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==", - "dev": true, - "requires": { - "conventional-commits-filter": "^4.0.0", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "meow": "^12.0.1", - "semver": "^7.5.2", - "split2": "^4.0.0" - } - }, - "conventional-commits-filter": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz", - "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==", - "dev": true - }, - "conventional-commits-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", - "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", - "dev": true, - "requires": { - "is-text-path": "^2.0.0", - "JSONStream": "^1.3.5", - "meow": "^12.0.1", - "split2": "^4.0.0" - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true - }, - "cosmiconfig": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", - "integrity": "sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==", - "dev": true, - "requires": { - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypto-random-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", - "dev": true, - "requires": { - "type-fest": "^1.0.1" - }, - "dependencies": { - "type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true - } - } - }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, - "requires": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true - } - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", - "dev": true - }, - "env-ci": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-10.0.0.tgz", - "integrity": "sha512-U4xcd/utDYFgMh0yWj07R1H6L5fwhVbmxBCpnL0DbVSDZVnsC82HONw0wxtxNkIAcua3KtbomQvIk5xFZGAQJw==", - "dev": true, - "requires": { - "execa": "^8.0.0", - "java-properties": "^1.0.2" - }, - "dependencies": { - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - } - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "figures": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/figures/-/figures-6.0.1.tgz", - "integrity": "sha512-0oY/olScYD4IhQ8u//gCPA4F3mlTn2dacYmiDm/mbDQvpmLjV4uH+zhsQ5IyXRyvqkvtUkXkNdGvg5OFJTCsuQ==", - "dev": true, - "requires": { - "is-unicode-supported": "^2.0.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", - "dev": true, - "requires": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - } - }, - "find-up-simple": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", - "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", - "dev": true - }, - "find-versions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", - "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", - "dev": true, - "requires": { - "semver-regex": "^4.0.5" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-extra": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", - "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "git-log-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", - "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==", - "dev": true, - "requires": { - "argv-formatter": "~1.0.0", - "spawn-error-forwarder": "~1.0.0", - "split2": "~1.0.0", - "stream-combiner2": "~1.1.1", - "through2": "~2.0.0", - "traverse": "~0.6.6" - }, - "dependencies": { - "split2": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", - "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==", - "dev": true, - "requires": { - "through2": "~2.0.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globby": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz", - "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==", - "dev": true, - "requires": { - "@sindresorhus/merge-streams": "^1.0.0", - "fast-glob": "^3.3.2", - "ignore": "^5.2.4", - "path-type": "^5.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.1.0" - }, - "dependencies": { - "path-type": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", - "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "gradle-semantic-release-plugin": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/gradle-semantic-release-plugin/-/gradle-semantic-release-plugin-1.8.0.tgz", - "integrity": "sha512-lRoKlLJvQbvRykDf6nWVuf/XyHEO9TL8dcnLX9lDag8zn5tkOqp5Tctb4re1YEek0zsSVAVX/1nw5lkV5pfm/Q==", - "dev": true, - "requires": { - "promisified-properties": "^2.0.27", - "split2": "^4.1.0" - } - }, - "handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - }, - "hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dev": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "hook-std": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz", - "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==", - "dev": true - }, - "hosted-git-info": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", - "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", - "dev": true, - "requires": { - "lru-cache": "^10.0.1" - }, - "dependencies": { - "lru-cache": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.3.tgz", - "integrity": "sha512-B7gr+F6MkqB3uzINHXNctGieGsRTMwIBgxkp0yq/5BwcuDzD4A8wQpHQW6vDAm1uKSLQghmRdD9sKqf2vJ1cEg==", - "dev": true - } - } - }, - "http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", - "dev": true, - "requires": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - } - }, - "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", - "dev": true, - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } - } - }, - "import-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-4.0.0.tgz", - "integrity": "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==", - "dev": true - }, - "import-from-esm": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.3.tgz", - "integrity": "sha512-U3Qt/CyfFpTUv6LOP2jRTLYjphH6zg3okMfHbyqRa/W2w6hr8OsJWVggNlR4jxuojQy81TgTJTxgSkyoteRGMQ==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "import-meta-resolve": "^4.0.0" - } - }, - "import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "index-to-position": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", - "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", - "dev": true - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "into-stream": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz", - "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==", - "dev": true, - "requires": { - "from2": "^2.3.0", - "p-is-promise": "^3.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-text-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", - "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", - "dev": true, - "requires": { - "text-extensions": "^2.0.0" - } - }, - "is-unicode-supported": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz", - "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "issue-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", - "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", - "dev": true, - "requires": { - "lodash.capitalize": "^4.2.1", - "lodash.escaperegexp": "^4.1.2", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.uniqby": "^4.7.0" - } - }, - "java-properties": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz", - "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - } - } - }, - "locate-path": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", - "dev": true, - "requires": { - "p-locate": "^6.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true - }, - "lodash.capitalize": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", - "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==", - "dev": true - }, - "lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", - "dev": true - }, - "lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", - "dev": true - }, - "lodash.uniqby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", - "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true - }, - "marked": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", - "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", - "dev": true - }, - "marked-terminal": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.1.0.tgz", - "integrity": "sha512-QaCSF6NV82oo6K0szEnmc65ooDeW0T/Adcyf0fcW+Hto2GT1VADFg8dn1zaeHqzj65fqDH1hMNChGNRaC/lbkA==", - "dev": true, - "requires": { - "ansi-escapes": "^6.2.0", - "cardinal": "^2.1.1", - "chalk": "^5.3.0", - "cli-table3": "^0.6.3", - "node-emoji": "^2.1.0", - "supports-hyperlinks": "^3.0.0" - } - }, - "meow": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - } - }, - "modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "nerf-dart": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz", - "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==", - "dev": true - }, - "node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - } - }, - "normalize-package-data": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz", - "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==", - "dev": true, - "requires": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - } - }, - "normalize-url": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", - "dev": true - }, - "npm": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.2.4.tgz", - "integrity": "sha512-umEuYneVEYO9KoEEI8n2sSGmNQeqco/3BSeacRlqIkCzw4E7XGtYSWMeJobxzr6hZ2n9cM+u5TsMTcC5bAgoWA==", - "dev": true, - "requires": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.2.1", - "@npmcli/config": "^8.0.2", - "@npmcli/fs": "^3.1.0", - "@npmcli/map-workspaces": "^3.0.4", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.2", - "@sigstore/tuf": "^2.2.0", - "abbrev": "^2.0.0", - "archy": "~1.0.0", - "cacache": "^18.0.0", - "chalk": "^5.3.0", - "ci-info": "^4.0.0", - "cli-columns": "^4.0.0", - "cli-table3": "^0.6.3", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.16", - "fs-minipass": "^3.0.3", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "hosted-git-info": "^7.0.1", - "ini": "^4.1.1", - "init-package-json": "^6.0.0", - "is-cidr": "^5.0.3", - "json-parse-even-better-errors": "^3.0.0", - "libnpmaccess": "^8.0.1", - "libnpmdiff": "^6.0.3", - "libnpmexec": "^7.0.4", - "libnpmfund": "^5.0.1", - "libnpmhook": "^10.0.0", - "libnpmorg": "^6.0.1", - "libnpmpack": "^6.0.3", - "libnpmpublish": "^9.0.2", - "libnpmsearch": "^7.0.0", - "libnpmteam": "^6.0.0", - "libnpmversion": "^5.0.1", - "make-fetch-happen": "^13.0.0", - "minimatch": "^9.0.3", - "minipass": "^7.0.4", - "minipass-pipeline": "^1.2.4", - "ms": "^2.1.2", - "node-gyp": "^10.0.1", - "nopt": "^7.2.0", - "normalize-package-data": "^6.0.0", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.1", - "npm-pick-manifest": "^9.0.0", - "npm-profile": "^9.0.0", - "npm-registry-fetch": "^16.1.0", - "npm-user-validate": "^2.0.0", - "npmlog": "^7.0.1", - "p-map": "^4.0.0", - "pacote": "^17.0.4", - "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", - "qrcode-terminal": "^0.12.0", - "read": "^2.1.0", - "semver": "^7.5.4", - "spdx-expression-parse": "^3.0.1", - "ssri": "^10.0.5", - "strip-ansi": "^7.1.0", - "supports-color": "^9.4.0", - "tar": "^6.2.0", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.0", - "which": "^4.0.0", - "write-file-atomic": "^5.0.1" - }, - "dependencies": { - "@colors/colors": { - "version": "1.5.0", - "bundled": true, - "dev": true, - "optional": true - }, - "@isaacs/cliui": { - "version": "8.0.2", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "9.2.2", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - } - } - }, - "@isaacs/string-locale-compare": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "@npmcli/agent": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "requires": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.1" - } - }, - "@npmcli/arborist": { - "version": "7.2.1", - "bundled": true, - "dev": true, - "requires": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.0", - "@npmcli/installed-package-contents": "^2.0.2", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.0.0", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/query": "^3.0.1", - "@npmcli/run-script": "^7.0.2", - "bin-links": "^4.0.1", - "cacache": "^18.0.0", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.1", - "json-parse-even-better-errors": "^3.0.0", - "json-stringify-nice": "^1.1.4", - "minimatch": "^9.0.0", - "nopt": "^7.0.0", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.1", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.2", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^10.0.5", - "treeverse": "^3.0.0", - "walk-up-path": "^3.0.1" - } - }, - "@npmcli/config": { - "version": "8.0.2", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/map-workspaces": "^3.0.2", - "ci-info": "^4.0.0", - "ini": "^4.1.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.5", - "walk-up-path": "^3.0.1" - } - }, - "@npmcli/disparity-colors": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - } - } - }, - "@npmcli/fs": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "semver": "^7.3.5" - } - }, - "@npmcli/git": { - "version": "5.0.3", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/promise-spawn": "^7.0.0", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^4.0.0" - } - }, - "@npmcli/installed-package-contents": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - } - }, - "@npmcli/map-workspaces": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/name-from-folder": "^2.0.0", - "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" - } - }, - "@npmcli/metavuln-calculator": { - "version": "7.0.0", - "bundled": true, - "dev": true, - "requires": { - "cacache": "^18.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^17.0.0", - "semver": "^7.3.5" - } - }, - "@npmcli/name-from-folder": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "@npmcli/node-gyp": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "@npmcli/package-json": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/git": "^5.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^3.0.0", - "semver": "^7.5.3" - } - }, - "@npmcli/promise-spawn": { - "version": "7.0.0", - "bundled": true, - "dev": true, - "requires": { - "which": "^4.0.0" - } - }, - "@npmcli/query": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.10" - } - }, - "@npmcli/run-script": { - "version": "7.0.2", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^10.0.0", - "read-package-json-fast": "^3.0.0", - "which": "^4.0.0" - } - }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "bundled": true, - "dev": true, - "optional": true - }, - "@sigstore/bundle": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "@sigstore/protobuf-specs": "^0.2.1" - } - }, - "@sigstore/protobuf-specs": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "@sigstore/sign": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "requires": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "make-fetch-happen": "^13.0.0" - } - }, - "@sigstore/tuf": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "requires": { - "@sigstore/protobuf-specs": "^0.2.1", - "tuf-js": "^2.1.0" - } - }, - "@tufjs/canonical-json": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "@tufjs/models": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.3" - } - }, - "abbrev": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "abort-controller": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "agent-base": { - "version": "7.1.0", - "bundled": true, - "dev": true, - "requires": { - "debug": "^4.3.4" - } - }, - "aggregate-error": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ansi-regex": { - "version": "6.0.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "are-we-there-yet": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^4.1.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "base64-js": { - "version": "1.5.1", - "bundled": true, - "dev": true - }, - "bin-links": { - "version": "4.0.3", - "bundled": true, - "dev": true, - "requires": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" - } - }, - "binary-extensions": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "buffer": { - "version": "6.0.3", - "bundled": true, - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "builtins": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "semver": "^7.0.0" - } - }, - "cacache": { - "version": "18.0.0", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - } - }, - "chalk": { - "version": "5.3.0", - "bundled": true, - "dev": true - }, - "chownr": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "ci-info": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "cidr-regex": { - "version": "4.0.3", - "bundled": true, - "dev": true, - "requires": { - "ip-regex": "^5.0.0" - } - }, - "clean-stack": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "cli-columns": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "cli-table3": { - "version": "0.6.3", - "bundled": true, - "dev": true, - "requires": { - "@colors/colors": "1.5.0", - "string-width": "^4.2.0" - } - }, - "clone": { - "version": "1.0.4", - "bundled": true, - "dev": true - }, - "cmd-shim": { - "version": "6.0.2", - "bundled": true, - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "bundled": true, - "dev": true - }, - "color-support": { - "version": "1.1.3", - "bundled": true, - "dev": true - }, - "columnify": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "requires": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "common-ancestor-path": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "bundled": true, - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "cssesc": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "debug": { - "version": "4.3.4", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "bundled": true, - "dev": true - } - } - }, - "defaults": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "requires": { - "clone": "^1.0.2" - } - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "diff": { - "version": "5.1.0", - "bundled": true, - "dev": true - }, - "eastasianwidth": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "bundled": true, - "dev": true - }, - "encoding": { - "version": "0.1.13", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "env-paths": { - "version": "2.2.1", - "bundled": true, - "dev": true - }, - "err-code": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "events": { - "version": "3.3.0", - "bundled": true, - "dev": true - }, - "exponential-backoff": { - "version": "3.1.1", - "bundled": true, - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.16", - "bundled": true, - "dev": true - }, - "foreground-child": { - "version": "3.1.1", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - } - }, - "fs-minipass": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^7.0.3" - } - }, - "function-bind": { - "version": "1.1.2", - "bundled": true, - "dev": true - }, - "gauge": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^4.0.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "glob": { - "version": "10.3.10", - "bundled": true, - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "graceful-fs": { - "version": "4.2.11", - "bundled": true, - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "hasown": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "hosted-git-info": { - "version": "7.0.1", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^10.0.1" - } - }, - "http-cache-semantics": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "http-proxy-agent": { - "version": "7.0.0", - "bundled": true, - "dev": true, - "requires": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - } - }, - "https-proxy-agent": { - "version": "7.0.2", - "bundled": true, - "dev": true, - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - }, - "iconv-lite": { - "version": "0.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ieee754": { - "version": "1.2.1", - "bundled": true, - "dev": true - }, - "ignore-walk": { - "version": "6.0.3", - "bundled": true, - "dev": true, - "requires": { - "minimatch": "^9.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "indent-string": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "ini": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "init-package-json": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "npm-package-arg": "^11.0.0", - "promzard": "^1.0.0", - "read": "^2.0.0", - "read-package-json": "^7.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" - } - }, - "ip": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "ip-regex": { - "version": "5.0.0", - "bundled": true, - "dev": true - }, - "is-cidr": { - "version": "5.0.3", - "bundled": true, - "dev": true, - "requires": { - "cidr-regex": "4.0.3" - } - }, - "is-core-module": { - "version": "2.13.1", - "bundled": true, - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "is-lambda": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "jackspeak": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, - "json-parse-even-better-errors": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "json-stringify-nice": { - "version": "1.1.4", - "bundled": true, - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "bundled": true, - "dev": true - }, - "just-diff": { - "version": "6.0.2", - "bundled": true, - "dev": true - }, - "just-diff-apply": { - "version": "5.5.0", - "bundled": true, - "dev": true - }, - "libnpmaccess": { - "version": "8.0.1", - "bundled": true, - "dev": true, - "requires": { - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0" - } - }, - "libnpmdiff": { - "version": "6.0.3", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/disparity-colors": "^3.0.0", - "@npmcli/installed-package-contents": "^2.0.2", - "binary-extensions": "^2.2.0", - "diff": "^5.1.0", - "minimatch": "^9.0.0", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", - "tar": "^6.2.0" - } - }, - "libnpmexec": { - "version": "7.0.4", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.1", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "proc-log": "^3.0.0", - "read": "^2.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "walk-up-path": "^3.0.1" - } - }, - "libnpmfund": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^7.2.1" - } - }, - "libnpmhook": { - "version": "10.0.0", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" - } - }, - "libnpmorg": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" - } - }, - "libnpmpack": { - "version": "6.0.3", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4" - } - }, - "libnpmpublish": { - "version": "9.0.2", - "bundled": true, - "dev": true, - "requires": { - "ci-info": "^4.0.0", - "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.7", - "sigstore": "^2.1.0", - "ssri": "^10.0.5" - } - }, - "libnpmsearch": { - "version": "7.0.0", - "bundled": true, - "dev": true, - "requires": { - "npm-registry-fetch": "^16.0.0" - } - }, - "libnpmteam": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" - } - }, - "libnpmversion": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/git": "^5.0.3", - "@npmcli/run-script": "^7.0.2", - "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.7" - } - }, - "lru-cache": { - "version": "10.0.2", - "bundled": true, - "dev": true, - "requires": { - "semver": "^7.3.5" - } - }, - "make-fetch-happen": { - "version": "13.0.0", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - } - }, - "minimatch": { - "version": "9.0.3", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "minipass": { - "version": "7.0.4", - "bundled": true, - "dev": true - }, - "minipass-collect": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass-fetch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "encoding": "^0.1.13", - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - } - }, - "minipass-flush": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass-json-stream": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass-sized": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minizlib": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "bundled": true, - "dev": true - }, - "ms": { - "version": "2.1.3", - "bundled": true, - "dev": true - }, - "mute-stream": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "bundled": true, - "dev": true - }, - "node-gyp": { - "version": "10.0.1", - "bundled": true, - "dev": true, - "requires": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^4.0.0" - } - }, - "nopt": { - "version": "7.2.0", - "bundled": true, - "dev": true, - "requires": { - "abbrev": "^2.0.0" - } - }, - "normalize-package-data": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - } - }, - "npm-audit-report": { - "version": "5.0.0", - "bundled": true, - "dev": true - }, - "npm-bundled": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "npm-normalize-package-bin": "^3.0.0" - } - }, - "npm-install-checks": { - "version": "6.3.0", - "bundled": true, - "dev": true, - "requires": { - "semver": "^7.1.1" - } - }, - "npm-normalize-package-bin": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "npm-package-arg": { - "version": "11.0.1", - "bundled": true, - "dev": true, - "requires": { - "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - } - }, - "npm-packlist": { - "version": "8.0.0", - "bundled": true, - "dev": true, - "requires": { - "ignore-walk": "^6.0.0" - } - }, - "npm-pick-manifest": { - "version": "9.0.0", - "bundled": true, - "dev": true, - "requires": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - } - }, - "npm-profile": { - "version": "9.0.0", - "bundled": true, - "dev": true, - "requires": { - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0" - } - }, - "npm-registry-fetch": { - "version": "16.1.0", - "bundled": true, - "dev": true, - "requires": { - "make-fetch-happen": "^13.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" - } - }, - "npm-user-validate": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "npmlog": { - "version": "7.0.1", - "bundled": true, - "dev": true, - "requires": { - "are-we-there-yet": "^4.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^5.0.0", - "set-blocking": "^2.0.0" - } - }, - "p-map": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "pacote": { - "version": "17.0.4", - "bundled": true, - "dev": true, - "requires": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", - "cacache": "^18.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^2.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - } - }, - "parse-conflict-json": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "json-parse-even-better-errors": "^3.0.0", - "just-diff": "^6.0.0", - "just-diff-apply": "^5.2.0" - } - }, - "path-key": { - "version": "3.1.1", - "bundled": true, - "dev": true - }, - "path-scurry": { - "version": "1.10.1", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - } - }, - "postcss-selector-parser": { - "version": "6.0.13", - "bundled": true, - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "proc-log": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "process": { - "version": "0.11.10", - "bundled": true, - "dev": true - }, - "promise-all-reject-late": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "promise-call-limit": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "promise-retry": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - } - }, - "promzard": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "read": "^2.0.0" - } - }, - "qrcode-terminal": { - "version": "0.12.0", - "bundled": true, - "dev": true - }, - "read": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "mute-stream": "~1.0.0" - } - }, - "read-cmd-shim": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "read-package-json": { - "version": "7.0.0", - "bundled": true, - "dev": true, - "requires": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - } - }, - "read-package-json-fast": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - } - }, - "readable-stream": { - "version": "4.4.2", - "bundled": true, - "dev": true, - "requires": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - } - }, - "retry": { - "version": "0.12.0", - "bundled": true, - "dev": true - }, - "safe-buffer": { - "version": "5.2.1", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "7.5.4", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "sigstore": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "@sigstore/sign": "^2.1.0", - "@sigstore/tuf": "^2.1.0" - } - }, - "smart-buffer": { - "version": "4.2.0", - "bundled": true, - "dev": true - }, - "socks": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "requires": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - } - }, - "socks-proxy-agent": { - "version": "8.0.2", - "bundled": true, - "dev": true, - "requires": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "socks": "^2.7.1" - } - }, - "spdx-correct": { - "version": "3.2.0", - "bundled": true, - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "bundled": true, - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.16", - "bundled": true, - "dev": true - }, - "ssri": { - "version": "10.0.5", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^7.0.3" - } - }, - "string_decoder": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "strip-ansi": { - "version": "7.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - } - } - }, - "supports-color": { - "version": "9.4.0", - "bundled": true, - "dev": true - }, - "tar": { - "version": "6.2.0", - "bundled": true, - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "fs-minipass": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "bundled": true, - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - } - } - }, - "minipass": { - "version": "5.0.0", - "bundled": true, - "dev": true - } - } - }, - "text-table": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, - "tiny-relative-date": { - "version": "1.3.0", - "bundled": true, - "dev": true - }, - "treeverse": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "tuf-js": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "@tufjs/models": "2.0.0", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.0" - } - }, - "unique-filename": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "unique-slug": "^4.0.0" - } - }, - "unique-slug": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "5.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtins": "^5.0.0" - } - }, - "walk-up-path": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "wcwidth": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "which": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "isexe": "^3.1.1" - }, - "dependencies": { - "isexe": { - "version": "3.1.1", - "bundled": true, - "dev": true - } - } - }, - "wide-align": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "wrap-ansi": { - "version": "8.1.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "9.2.2", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - } - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@7.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "write-file-atomic": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - } - }, - "yallist": { - "version": "4.0.0", - "bundled": true, - "dev": true - } - } - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "p-each-series": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", - "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==", - "dev": true - }, - "p-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-3.0.0.tgz", - "integrity": "sha512-QtoWLjXAW++uTX67HZQz1dbTpqBfiidsB6VtQUC9iR85S120+s0T5sO6s+B5MLzFcZkrEd/DGMmCjR+f2Qpxwg==", - "dev": true, - "requires": { - "p-map": "^5.1.0" - } - }, - "p-is-promise": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", - "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", - "dev": true - }, - "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "requires": { - "yocto-queue": "^1.0.0" - } - }, - "p-locate": { + "node_modules/semantic-release/node_modules/onetime": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", - "dev": true, - "requires": { - "p-limit": "^4.0.0" - } - }, - "p-map": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", - "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", - "dev": true, - "requires": { - "aggregate-error": "^4.0.0" - }, - "dependencies": { - "aggregate-error": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", - "dev": true, - "requires": { - "clean-stack": "^4.0.0", - "indent-string": "^5.0.0" - } - }, - "clean-stack": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", - "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", - "dev": true, - "requires": { - "escape-string-regexp": "5.0.0" - } - }, - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true - }, - "indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true - } - } - }, - "p-reduce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", - "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", - "dev": true - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parsimmon": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.1.tgz", - "integrity": "sha512-u7p959wLfGAhJpSDJVYXoyMCXWYwHia78HhRBWqk7AIbxdmlrfdp5wX0l3xv/iTSH5HvhN9K7o26hwwpgS5Nmw==", - "dev": true - }, - "path-exists": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - }, - "pkg-conf": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", - "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "load-json-file": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - } - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promisified-properties": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/promisified-properties/-/promisified-properties-2.0.27.tgz", - "integrity": "sha512-fmx256M3b0QcHnqOj+Ok127LoYpmnYRf7g2OyLl7qD7Z0fzNbIZhHHIPKyvegbA29iAPP5BVWv7BJ/y2cMHHjA==", - "dev": true, - "requires": { - "parsimmon": "^1.13.0" - } - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "read-pkg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", - "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.3", - "normalize-package-data": "^6.0.0", - "parse-json": "^8.0.0", - "type-fest": "^4.6.0", - "unicorn-magic": "^0.1.0" - }, "dependencies": { - "json-parse-even-better-errors": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz", - "integrity": "sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==", - "dev": true - }, - "parse-json": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.0.1.tgz", - "integrity": "sha512-soKUg/q/8bcfuF3+plsbYldE74cVEVEPSC1BUPIGTaX1byXdz6Fo+CVYBdH0jj/5xWsFrNRksl11QkBgHqPQeQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "index-to-position": "^0.1.1", - "json-parse-even-better-errors": "^3.0.0", - "type-fest": "^4.7.1" - } - }, - "type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz", - "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==", - "dev": true, - "requires": { - "find-up-simple": "^1.0.0", - "read-pkg": "^9.0.0", - "type-fest": "^4.6.0" + "mimic-fn": "^4.0.0" }, - "dependencies": { - "type-fest": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.8.2.tgz", - "integrity": "sha512-mcvrCjixA5166hSrUoJgGb9gBQN4loMYyj9zxuMs/66ibHNEFd5JXMw37YVDx58L4/QID9jIzdTBB4mDwDJ6KQ==", - "dev": true - } - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - } - }, - "redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", - "dev": true, - "requires": { - "esprima": "~4.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "node_modules/semantic-release/node_modules/p-reduce": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", + "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", "dev": true, - "requires": { - "@pnpm/npm-conf": "^2.1.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "node_modules/semantic-release/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/semantic-release/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "requires": { - "queue-microtask": "^1.2.2" + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "semantic-release": { - "version": "22.0.8", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-22.0.8.tgz", - "integrity": "sha512-55rb31jygqIYsGU/rY+gXXm2fnxBIWo9azOjxbqKsPnq7p70zwZ5v+xnD7TxJC+zvS3sy1eHLGXYWCaX3WI76A==", + "node_modules/semantic-release/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "requires": { - "@semantic-release/commit-analyzer": "^11.0.0", - "@semantic-release/error": "^4.0.0", - "@semantic-release/github": "^9.0.0", - "@semantic-release/npm": "^11.0.0", - "@semantic-release/release-notes-generator": "^12.0.0", - "aggregate-error": "^5.0.0", - "cosmiconfig": "^8.0.0", - "debug": "^4.0.0", - "env-ci": "^10.0.0", - "execa": "^8.0.0", - "figures": "^6.0.0", - "find-versions": "^5.1.0", - "get-stream": "^6.0.0", - "git-log-parser": "^1.2.0", - "hook-std": "^3.0.0", - "hosted-git-info": "^7.0.0", - "import-from-esm": "^1.3.1", - "lodash-es": "^4.17.21", - "marked": "^9.0.0", - "marked-terminal": "^6.0.0", - "micromatch": "^4.0.2", - "p-each-series": "^3.0.0", - "p-reduce": "^3.0.0", - "read-pkg-up": "^11.0.0", - "resolve-from": "^5.0.0", - "semver": "^7.3.2", - "semver-diff": "^4.0.0", - "signale": "^1.2.1", - "yargs": "^17.5.1" + "engines": { + "node": ">=12" }, - "dependencies": { - "@semantic-release/error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz", - "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==", - "dev": true - }, - "aggregate-error": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", - "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", - "dev": true, - "requires": { - "clean-stack": "^5.2.0", - "indent-string": "^5.0.0" - } - }, - "clean-stack": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", - "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", - "dev": true, - "requires": { - "escape-string-regexp": "5.0.0" - } - }, - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "dev": true - }, - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "dependencies": { - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true - } - } - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "dev": true - }, - "indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true - }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "dev": true - }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dev": true, - "requires": { - "path-key": "^4.0.0" - } - }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "requires": { - "mimic-fn": "^4.0.0" - } - }, - "p-reduce": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", - "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==", - "dev": true - }, - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "dev": true - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "semver": { + "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, - "requires": { + "dependencies": { "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "semver-diff": { + "node_modules/semver-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", "dev": true, - "requires": { + "dependencies": { "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "semver-regex": { + "node_modules/semver-regex": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", - "dev": true + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } }, - "shebang-command": { + "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { + "dependencies": { "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + } }, - "signal-exit": { + "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "signale": { + "node_modules/signale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz", "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==", "dev": true, - "requires": { + "dependencies": { "chalk": "^2.3.2", "figures": "^2.0.0", "pkg-conf": "^2.1.0" }, + "engines": { + "node": ">=6" + } + }, + "node_modules/signale/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/signale/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/signale/node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/signale/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "skin-tone": { + "node_modules/skin-tone": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", "dev": true, - "requires": { + "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "slash": { + "node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", - "dev": true + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "source-map": { + "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "spawn-error-forwarder": { + "node_modules/spawn-error-forwarder": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz", "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==", "dev": true }, - "spdx-correct": { + "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "requires": { + "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "node_modules/spdx-exceptions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz", + "integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==", "dev": true }, - "spdx-expression-parse": { + "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "requires": { + "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-license-ids": { + "node_modules/spdx-license-ids": { "version": "3.0.16", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", "dev": true }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, - "requires": { - "through": "2" + "engines": { + "node": ">= 10.x" } }, - "split2": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz", - "integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==", - "dev": true - }, - "stream-combiner2": { + "node_modules/stream-combiner2": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", "dev": true, - "requires": { + "dependencies": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" } }, - "string_decoder": { + "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, - "requires": { + "dependencies": { "safe-buffer": "~5.1.0" } }, - "string-width": { + "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-ansi": { + "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { + "dependencies": { "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-bom": { + "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "strip-final-newline": { + "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, - "requires": { - "min-indent": "^1.0.0" + "engines": { + "node": ">=6" } }, - "strip-json-comments": { + "node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "supports-color": { + "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "supports-hyperlinks": { + "node_modules/supports-hyperlinks": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" } }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "temp-dir": { + "node_modules/temp-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", - "dev": true + "dev": true, + "engines": { + "node": ">=14.16" + } }, - "tempy": { + "node_modules/tempy": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz", "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==", "dev": true, - "requires": { + "dependencies": { "is-stream": "^3.0.0", "temp-dir": "^3.0.0", "type-fest": "^2.12.2", "unique-string": "^3.0.0" }, - "dependencies": { - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true - }, - "type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true - } + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tempy/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "text-extensions": { + "node_modules/text-extensions": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", - "dev": true + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "through": { + "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", "dev": true }, - "to-regex-range": { + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "requires": { + "dependencies": { "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "traverse": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.7.tgz", - "integrity": "sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==", - "dev": true - }, - "trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true + "node_modules/traverse": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", + "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "type-fest": { + "node_modules/type-fest": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", - "dev": true + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "uglify-js": { + "node_modules/uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "dev": true, - "optional": true + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } }, - "unicode-emoji-modifier-base": { + "node_modules/unicode-emoji-modifier-base": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "unicorn-magic": { + "node_modules/unicorn-magic": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "unique-string": { + "node_modules/unique-string": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", "dev": true, - "requires": { + "dependencies": { "crypto-random-string": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "universal-user-agent": { + "node_modules/universal-user-agent": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", "dev": true }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } }, - "url-join": { + "node_modules/url-join": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", - "dev": true + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } }, - "util-deprecate": { + "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "validate-npm-package-license": { + "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "wordwrap": { + "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true }, - "wrap-ansi": { + "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, - "xtend": { + "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4" + } }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "dev": true, + "engines": { + "node": ">=10" + } }, - "yallist": { + "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "requires": { + "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", @@ -18985,26 +6878,18 @@ "y18n": "^5.0.5", "yargs-parser": "^21.1.1" }, - "dependencies": { - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } + "engines": { + "node": ">=12" } }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - }, - "yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } } } } diff --git a/package.json b/package.json index 08aa83c908..3101070000 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "devDependencies": { - "@saithodev/semantic-release-backmerge": "^3.2.1", + "@saithodev/semantic-release-backmerge": "^4.0.1", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", - "gradle-semantic-release-plugin": "^1.8.0", - "semantic-release": "^22.0.8" + "gradle-semantic-release-plugin": "^1.9.1", + "semantic-release": "^23.0.0" } }