From 97857fcdcccdef948e32a382dc760c2e759b5606 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 28 Apr 2026 14:04:31 -0700 Subject: [PATCH 01/31] feat(appium): add Unity SDK support --- appium/scripts/run-local.sh | 139 ++++++++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 4 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 21fa51f..2f08173 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -60,7 +60,7 @@ via flags or env vars. Options: --platform=P ios | android - --sdk=S flutter | react-native | cordova | capacitor | dotnet | expo + --sdk=S flutter | react-native | cordova | capacitor | dotnet | expo | unity --device=NAME Device/simulator/AVD name (default: iPhone 17 / Samsung Galaxy S26) --appium-port=N Appium server port (default: 4723). Use unique values when running multiple sessions in parallel on the same host. @@ -92,6 +92,9 @@ Env vars (set in .env or export): DOTNET_DIR .NET MAUI SDK repo root (default: ../../DotNet/OneSignal-DotNet-SDK) DOTNET_TFM .NET target framework moniker base (default: net10.0) DOTNET_ANDROID_ABI .NET Android ABI to pack (default: host arch) + UNITY_DIR Unity SDK repo root (default: ../../OneSignal-Unity-SDK) + UNITY_PATH Path to Unity Editor binary + (default: /Applications/Unity/Hub/Editor/6000.3.6f1/Unity.app/Contents/MacOS/Unity) OS_VERSION Platform version (default: 26.2 / 16) IOS_SIMULATOR iOS simulator name (default: iPhone 17) IOS_RUNTIME simctl runtime id (default: iOS-26-2) @@ -145,7 +148,7 @@ prompt_choice() { } prompt_choice PLATFORM "Select platform:" ios android -prompt_choice SDK_TYPE "Select SDK type:" flutter react-native cordova capacitor dotnet expo +prompt_choice SDK_TYPE "Select SDK type:" flutter react-native cordova capacitor dotnet expo unity case "$PLATFORM" in ios|android) ;; @@ -153,8 +156,8 @@ case "$PLATFORM" in esac case "$SDK_TYPE" in - flutter|react-native|cordova|capacitor|dotnet|expo) ;; - *) error "SDK_TYPE must be 'flutter', 'react-native', 'cordova', 'capacitor', 'dotnet', or 'expo', got '$SDK_TYPE'" ;; + flutter|react-native|cordova|capacitor|dotnet|expo\unity) ;; + *) error "SDK_TYPE must be 'flutter', 'react-native', 'cordova', 'capacitor', 'dotnet', 'expo', or 'unity' got '$SDK_TYPE'" ;; esac # ── Real-device validation + signing setup ──────────────────────────────────── @@ -263,6 +266,19 @@ elif [[ "$SDK_TYPE" == "dotnet" ]]; then esac APP_PATH="${APP_PATH:-$DEMO_DIR/bin/Debug/${DOTNET_TFM}-android/com.onesignal.example-Signed.apk}" fi +elif [[ "$SDK_TYPE" == "unity" ]]; then + UNITY_DIR="${UNITY_DIR:-$SDK_ROOT/OneSignal-Unity-SDK}" + [[ -d "$UNITY_DIR" ]] || error "Unity SDK not found at $UNITY_DIR — set UNITY_DIR in .env" + DEMO_DIR="$UNITY_DIR/examples/demo" + UNITY_PATH="${UNITY_PATH:-/Applications/Unity/Hub/Editor/6000.3.6f1/Unity.app/Contents/MacOS/Unity}" + if [[ "$PLATFORM" == "ios" ]]; then + # Unity batchmode emits an Xcode project under Build/iOS; we then run + # xcodebuild -configuration Release into a fixed derived data path so + # the resulting .app lives at a deterministic location. + APP_PATH="${APP_PATH:-$DEMO_DIR/Build/iOS-DerivedData/Build/Products/Release-iphonesimulator/Unity-iPhone.app}" + else + APP_PATH="${APP_PATH:-$DEMO_DIR/Build/Android/onesignal-demo.apk}" + fi fi # ── Platform defaults ──────────────────────────────────────────────────────── @@ -1069,6 +1085,115 @@ build_dotnet_android() { info "App built: $APP_PATH" } +write_unity_demo_env() { + if [[ -n "${ONESIGNAL_APP_ID:-}" && -n "${ONESIGNAL_API_KEY:-}" ]]; then + info "Writing .env for demo app..." + cat > "$DEMO_DIR/.env" <&2 + error "Unity batchmode build failed" + fi + + [[ -d "$xcode_dir/Unity-iPhone.xcodeproj" ]] || error "Unity build produced no Xcode project — see $log" + + if [[ -f "$xcode_dir/Podfile" ]]; then + local lock="$xcode_dir/Podfile.lock" + local stamp="$derived/.podfile.lock.stamp" + if [[ ! -f "$lock" ]] || [[ ! -f "$stamp" ]] || ! cmp -s "$lock" "$stamp"; then + info "Installing CocoaPods..." + (cd "$xcode_dir" && pod install) + mkdir -p "$(dirname "$stamp")" + cp "$lock" "$stamp" 2>/dev/null || true + else + info "Pods up to date, skipping pod install" + fi + fi + + local ws="$xcode_dir/Unity-iPhone.xcworkspace" + info "Building release .app for simulator..." + if [[ -d "$ws" ]]; then + xcodebuild \ + -workspace "$ws" \ + -scheme Unity-iPhone \ + -configuration Release \ + -sdk iphonesimulator \ + -derivedDataPath "$derived" \ + -quiet \ + ONLY_ACTIVE_ARCH=YES \ + CODE_SIGN_IDENTITY="-" \ + CODE_SIGNING_ALLOWED=YES \ + build + else + xcodebuild \ + -project "$xcode_dir/Unity-iPhone.xcodeproj" \ + -scheme Unity-iPhone \ + -configuration Release \ + -sdk iphonesimulator \ + -derivedDataPath "$derived" \ + -quiet \ + ONLY_ACTIVE_ARCH=YES \ + CODE_SIGN_IDENTITY="-" \ + CODE_SIGNING_ALLOWED=YES \ + build + fi + + [[ -d "$APP_PATH" ]] || error ".app not found after build at $APP_PATH" + info "App built: $APP_PATH" +} + +build_unity_android() { + write_unity_demo_env + + [[ -x "$UNITY_PATH" ]] || error "Unity Editor not found at $UNITY_PATH — set UNITY_PATH in .env" + + local log="$DEMO_DIR/Build/build-android.log" + mkdir -p "$DEMO_DIR/Build/Android" + + info "Building APK from Unity (batchmode, log: $log)..." + if ! "$UNITY_PATH" -batchmode -nographics -quit -buildTarget Android \ + -projectPath "$DEMO_DIR" -executeMethod BuildScript.BuildAndroidEmulator \ + -logFile "$log"; then + unity_license_hint "$log" >&2 + error "Unity batchmode build failed" + fi + + [[ -f "$APP_PATH" ]] || error ".apk not found after build at $APP_PATH — see $log" + info "App built: $APP_PATH" +} + build_app() { if [[ "$SKIP_BUILD" == true ]]; then if [[ "$PLATFORM" == "ios" && ! -d "$APP_PATH" ]] || [[ "$PLATFORM" == "android" && ! -f "$APP_PATH" ]]; then @@ -1114,6 +1239,12 @@ build_app() { else build_expo_android fi + elif [[ "$SDK_TYPE" == "unity" ]]; then + if [[ "$PLATFORM" == "ios" ]]; then + build_unity_ios + else + build_unity_android + fi fi } From c0b89817baab26f8c616a1cb83750888ffebe302 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 28 Apr 2026 14:17:31 -0700 Subject: [PATCH 02/31] feat(appium): add Unity build caching --- appium/scripts/run-local.sh | 135 ++++++++++++++++++++++++++++++++++-- 1 file changed, 130 insertions(+), 5 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 2f08173..4b5df22 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -272,10 +272,11 @@ elif [[ "$SDK_TYPE" == "unity" ]]; then DEMO_DIR="$UNITY_DIR/examples/demo" UNITY_PATH="${UNITY_PATH:-/Applications/Unity/Hub/Editor/6000.3.6f1/Unity.app/Contents/MacOS/Unity}" if [[ "$PLATFORM" == "ios" ]]; then - # Unity batchmode emits an Xcode project under Build/iOS; we then run - # xcodebuild -configuration Release into a fixed derived data path so - # the resulting .app lives at a deterministic location. - APP_PATH="${APP_PATH:-$DEMO_DIR/Build/iOS-DerivedData/Build/Products/Release-iphonesimulator/Unity-iPhone.app}" + # Unity batchmode emits an Xcode project under Build/iOS named + # `Unity-iPhone.xcodeproj` (a fixed Unity convention), but the *product* + # name is configured to `OneSignalDemo` in Player Settings, so xcodebuild + # produces `OneSignalDemo.app`. + APP_PATH="${APP_PATH:-$DEMO_DIR/Build/iOS-DerivedData/Build/Products/Release-iphonesimulator/OneSignalDemo.app}" else APP_PATH="${APP_PATH:-$DEMO_DIR/Build/Android/onesignal-demo.apk}" fi @@ -1093,11 +1094,94 @@ ONESIGNAL_APP_ID=$ONESIGNAL_APP_ID ONESIGNAL_API_KEY=$ONESIGNAL_API_KEY E2E_MODE=true EOF + # DotEnv loads from Application.streamingAssetsPath/.env in the built + # player; the demo's project-root .env is only read in the editor. + # Copy in lockstep so the built .app/.apk has the same E2E_MODE flag, + # which the AccessibilityBridge gates on. + mkdir -p "$DEMO_DIR/Assets/StreamingAssets" + cp "$DEMO_DIR/.env" "$DEMO_DIR/Assets/StreamingAssets/.env" else warn "ONESIGNAL_APP_ID / ONESIGNAL_API_KEY not set — skipping demo .env" fi } +# Hash any source/asset/config file under the given roots that can affect the +# compiled .app/.apk for a Unity build. Mirrors `dotnet_hash_paths` in spirit: +# centralised so SDK and demo hashes stay in sync. Skips Unity-managed caches +# (Library/, Temp/, Build/, Logs/) and editor-private dirs (UserSettings/, +# *~ doc/sample folders Unity excludes from imports). +unity_hash_paths() { + # Unity projects routinely have spaces in paths (e.g. "Build Profiles/"), + # so we use NUL-delimited find/xargs throughout. Sorting the per-file + # shasum output (rather than the input list) keeps results deterministic + # without needing a `sort -z`-capable host. + find "$@" \ + -type f \ + ! -path "*/Library/*" \ + ! -path "*/Temp/*" \ + ! -path "*/Build/*" \ + ! -path "*/Logs/*" \ + ! -path "*/UserSettings/*" \ + ! -path "*/Documentation~/*" \ + ! -path "*/Samples~/*" \ + \( -name "*.cs" -o -name "*.asmdef" -o -name "*.asmref" \ + -o -name "*.meta" -o -name "*.json" -o -name "*.xml" \ + -o -name "*.plist" -o -name "*.strings" \ + -o -name "*.h" -o -name "*.m" -o -name "*.mm" -o -name "*.swift" \ + -o -name "*.a" -o -name "*.aar" -o -name "*.jar" \ + -o -name "*.so" -o -name "*.dll" -o -name "*.dylib" \ + -o -name "*.uxml" -o -name "*.uss" -o -name "*.unity" \ + -o -name "*.prefab" -o -name "*.asset" -o -name "*.mat" \ + -o -name "*.shader" -o -name "*.png" -o -name "*.jpg" \ + -o -name "*.txt" -o -name ".env" \) \ + -print0 2>/dev/null \ + | xargs -0 shasum 2>/dev/null \ + | sort \ + | shasum \ + | awk '{print $1}' +} + +# SDK package roots for a given platform. The Unity SDK rarely changes during +# day-to-day demo work, so we hash and fold it into the demo hash so SDK edits +# still cascade-invalidate the cached build artifact. +unity_sdk_paths() { + local platform="$1" # ios | android + echo "$UNITY_DIR/com.onesignal.unity.core" + if [[ "$platform" == "ios" ]]; then + echo "$UNITY_DIR/com.onesignal.unity.ios" + else + echo "$UNITY_DIR/com.onesignal.unity.android" + fi +} + +unity_sdk_inputs_hash() { + local platform="$1" + local roots=() + while IFS= read -r p; do roots+=("$p"); done < <(unity_sdk_paths "$platform") + unity_hash_paths "${roots[@]}" +} + +# Demo hash folds in the SDK hash so an SDK edit busts the demo cache too. +unity_demo_inputs_hash() { + local sdk_hash="$1" + local demo_hash + demo_hash=$(unity_hash_paths "$DEMO_DIR/Assets" "$DEMO_DIR/Packages" \ + "$DEMO_DIR/ProjectSettings") + # Fold the demo .env in separately — `unity_hash_paths` only finds it when + # passed as a directory glob, but here we want the file hash if it exists. + local env_hash="" + [[ -f "$DEMO_DIR/.env" ]] && env_hash=$(shasum < "$DEMO_DIR/.env" | awk '{print $1}') + printf '%s\n%s\n%s\n' "$sdk_hash" "$demo_hash" "$env_hash" | shasum | awk '{print $1}' +} + +unity_build_is_cached() { + local stamp="$1" artifact="$2" hash="$3" + [[ -e "$artifact" ]] || return 1 + [[ -f "$stamp" ]] || return 1 + [[ "$(cat "$stamp")" == "$hash" ]] || return 1 + return 0 +} + unity_license_hint() { cat </dev/null | head -1) + [[ -z "$found" ]] && found=$(find "$derived" -path "*/Build/Products/*" \ + -maxdepth 5 -name "*.app" \ + -not -name "*.appex" 2>/dev/null | head -1) + [[ -n "$found" ]] || error ".app not found anywhere under $derived" + APP_PATH="$found" + fi + mkdir -p "$(dirname "$stamp")" + echo "$demo_hash" > "$stamp" info "App built: $APP_PATH" } @@ -1179,6 +1291,17 @@ build_unity_android() { [[ -x "$UNITY_PATH" ]] || error "Unity Editor not found at $UNITY_PATH — set UNITY_PATH in .env" + local sdk_hash demo_hash + sdk_hash=$(unity_sdk_inputs_hash android) + demo_hash=$(unity_demo_inputs_hash "$sdk_hash") + + local stamp="$DEMO_DIR/Build/.unity-build-android.stamp" + if unity_build_is_cached "$stamp" "$APP_PATH" "$demo_hash"; then + info "Unity SDK + demo source unchanged, skipping Android rebuild" + info "App: $APP_PATH" + return + fi + local log="$DEMO_DIR/Build/build-android.log" mkdir -p "$DEMO_DIR/Build/Android" @@ -1191,6 +1314,8 @@ build_unity_android() { fi [[ -f "$APP_PATH" ]] || error ".apk not found after build at $APP_PATH — see $log" + mkdir -p "$(dirname "$stamp")" + echo "$demo_hash" > "$stamp" info "App built: $APP_PATH" } From a7acbaf0f9bd27b0e62bb91af6482f0fa592a724 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 28 Apr 2026 16:27:45 -0700 Subject: [PATCH 03/31] fix(appium): improve Unity build failure hints --- appium/scripts/run-local.sh | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 4b5df22..352e844 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -156,8 +156,8 @@ case "$PLATFORM" in esac case "$SDK_TYPE" in - flutter|react-native|cordova|capacitor|dotnet|expo\unity) ;; - *) error "SDK_TYPE must be 'flutter', 'react-native', 'cordova', 'capacitor', 'dotnet', 'expo', or 'unity' got '$SDK_TYPE'" ;; + flutter|react-native|cordova|capacitor|dotnet|expo|unity) ;; + *) error "SDK_TYPE must be 'flutter', 'react-native', 'cordova', 'capacitor', 'dotnet', 'expo', or 'unity', got '$SDK_TYPE'" ;; esac # ── Real-device validation + signing setup ──────────────────────────────────── @@ -1182,15 +1182,29 @@ unity_build_is_cached() { return 0 } -unity_license_hint() { - cat </dev/null; then + cat </dev/null; then + cat </dev/null; then + echo "Cause: C# compile error. First few errors from the log:" + grep -E "error CS[0-9]+:|error:" "$log" 2>/dev/null | head -5 | sed 's/^/ /' + else + echo "See the log above for details." + fi } build_unity_ios() { @@ -1221,7 +1235,7 @@ build_unity_ios() { if ! "$UNITY_PATH" -batchmode -nographics -quit -buildTarget iOS \ -projectPath "$DEMO_DIR" -executeMethod BuildScript.BuildiOSSimulator \ -logFile "$log"; then - unity_license_hint "$log" >&2 + unity_failure_hint "$log" >&2 error "Unity batchmode build failed" fi @@ -1309,7 +1323,7 @@ build_unity_android() { if ! "$UNITY_PATH" -batchmode -nographics -quit -buildTarget Android \ -projectPath "$DEMO_DIR" -executeMethod BuildScript.BuildAndroidEmulator \ -logFile "$log"; then - unity_license_hint "$log" >&2 + unity_failure_hint "$log" >&2 error "Unity batchmode build failed" fi From 628b6b0000611d72c4a28da405aab793f7616fc2 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Fri, 1 May 2026 19:41:46 -0700 Subject: [PATCH 04/31] fix(appium): extend IAM retry tap to native iOS --- appium/tests/helpers/app.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 51b2b4d..15b4863 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -917,18 +917,18 @@ async function switchToIAMWebView(expectedTitle: string, timeoutMs: number) { } /** - * The first tap on a freshly-scrolled IAM trigger button on Flutter is - * intermittently dropped: the driver reports the tap delivered, but the - * onPressed never fires -- most likely intercepted by a leftover OneSignal - * IAM container window from the previous IAM, which outlives - * `isWebViewVisible() === false`. The button itself stays tappable, so if - * no WebView appears in 2.5s we re-fetch the handle and tap again. - * Banners normally render well under 1.1s, so the gate is only paid on - * the (rarer) miss path. + * Two distinct races land in the same place. On Flutter, the first tap on a + * freshly-scrolled IAM trigger button is intermittently swallowed by a + * leftover OneSignal IAM container window from the previous IAM that + * outlives `isWebViewVisible() === false`. On native iOS, `addTrigger` + * invoked during the previous IAM's post-dismiss cleanup occasionally fails + * to re-evaluate so no message is presented. In both cases a second tap + * (= another `addTrigger` call once the SDK has settled) succeeds. Skip on + * Android (non-Flutter), where neither race has been observed. */ async function tapIamTrigger(buttonId: string) { await (await scrollToEl(buttonId)).click(); - if (!isFlutterSDK) return; + if (getPlatform() === 'android' && !isFlutterSDK) return; try { await driver.waitUntil(() => isWebViewVisible(), { timeout: 2_500 }); } catch { From e5c3ce998dced26277faf16a29c013afa28dbd5b Mon Sep 17 00:00:00 2001 From: Fadi George Date: Fri, 1 May 2026 20:26:21 -0700 Subject: [PATCH 05/31] fix(appium): wait for scroll view after IAM close --- appium/tests/helpers/app.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 15b4863..944ae4a 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -967,6 +967,17 @@ export async function checkInAppMessage(opts: { timeout: 15_000, timeoutMsg: 'IAM webview still visible after closing', }); + // The IAM container UIView hosting the WKWebView can outlive the WebView + // itself by a few hundred ms (dismiss animation), intercepting both + // accessibility hit-tests and pointer events. Wait for the home-screen + // scroll view to become hit-testable again before returning, so the next + // step's swipes/queries don't race the teardown. + if (!isWebViewSDK) { + const main = await byTestId('main_scroll_view'); + await main + .waitForDisplayed({ timeout: timeoutMs }) + .catch(() => {/* best-effort; caller will surface real failure */}); + } } await ensureMainWebViewContext(); } From 3deb6296aee40f6f3b73851869ff7c36fbb327c8 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Fri, 1 May 2026 21:02:18 -0700 Subject: [PATCH 06/31] refactor(appium): remove unused isWebViewVisible import --- appium/tests/specs/03_iam.spec.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/appium/tests/specs/03_iam.spec.ts b/appium/tests/specs/03_iam.spec.ts index e68fc3b..abc3243 100644 --- a/appium/tests/specs/03_iam.spec.ts +++ b/appium/tests/specs/03_iam.spec.ts @@ -1,10 +1,4 @@ -import { - checkInAppMessage, - checkTooltip, - isWebViewVisible, - scrollToEl, - waitForAppReady, -} from '../helpers/app'; +import { checkInAppMessage, checkTooltip, scrollToEl, waitForAppReady } from '../helpers/app'; import { byTestId, expectToggleState } from '../helpers/selectors'; describe('In-App Messaging', () => { From 48a1ec68b8a860e69fa2f4e01b450629aa2811ee Mon Sep 17 00:00:00 2001 From: Fadi George Date: Fri, 1 May 2026 21:25:01 -0700 Subject: [PATCH 07/31] refactor(appium): extract openModal helper --- appium/tests/helpers/app.ts | 60 +++++++++++++++++---------- appium/tests/specs/04_alias.spec.ts | 13 ++---- appium/tests/specs/05_email.spec.ts | 9 ++-- appium/tests/specs/06_sms.spec.ts | 8 +--- appium/tests/specs/07_tag.spec.ts | 22 ++-------- appium/tests/specs/08_outcome.spec.ts | 19 ++------- appium/tests/specs/09_trigger.spec.ts | 10 ++--- appium/tests/specs/10_event.spec.ts | 20 ++++----- 8 files changed, 65 insertions(+), 96 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 944ae4a..97936b2 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -15,6 +15,7 @@ const sdkType = getSdkType(); export const isWebViewSDK = sdkType === 'capacitor' || sdkType === 'cordova'; export const isBrowserStack = Boolean(process.env.BROWSERSTACK_USERNAME); const isFlutterSDK = sdkType === 'flutter'; +const isUnitySDK = sdkType === 'unity'; export function isBrowserStackIos(): boolean { return isBrowserStack && getPlatform() === 'ios'; @@ -518,13 +519,8 @@ export async function waitForAppReady(opts: { skipLogin?: boolean } = {}) { * Tap the login button, enter an external user ID, and confirm. */ export async function loginUser(externalUserId: string) { - const loginButton = await byTestId('login_user_button'); - await loginButton.click(); - - const userIdInput = await byTestId('login_user_id_input'); - await userIdInput.waitForDisplayed({ timeout: 5_000 }); + const userIdInput = await openModal('login_user_button', 'login_user_id_input'); await userIdInput.setValue(externalUserId); - await confirmModal('singleinput_confirm_button'); } @@ -562,6 +558,35 @@ export async function confirmModal(buttonTestId: string, timeoutMs = 5_000) { await btn.waitForExist({ timeout: timeoutMs, reverse: true }); } +/** + * Tap a button expected to open a modal/dialog and wait for one of its + * elements (`expectedTestId`) to appear. On Unity-iOS the first tap is + * occasionally swallowed when fired right after a previous modal's + * dismissal animation; if the expected element doesn't show up within + * `firstTryMs`, re-tap once. Reactive (state-gated), no fixed sleeps. + */ +export async function openModal(triggerTestId: string, expectedTestId: string, firstTryMs = 2_500) { + const maxAttempts = isUnitySDK && getPlatform() === 'ios' ? 3 : 1; + + for (let attempt = 1; ; attempt++) { + console.log(`Attempt ${attempt} to open modal "${triggerTestId}"`); + try { + const trigger = await scrollToEl(triggerTestId); + await trigger.click(); + + const expected = await byTestId(expectedTestId); + await expected.waitForExist({ timeout: firstTryMs }); + return expected; + } catch (err) { + if (attempt >= maxAttempts) { + throw new Error( + `Modal element "${expectedTestId}" not present after ${attempt} tap(s) on "${triggerTestId}": ${err}`, + ); + } + } + } +} + /** * Add a single tag via the UI. */ @@ -917,14 +942,8 @@ async function switchToIAMWebView(expectedTitle: string, timeoutMs: number) { } /** - * Two distinct races land in the same place. On Flutter, the first tap on a - * freshly-scrolled IAM trigger button is intermittently swallowed by a - * leftover OneSignal IAM container window from the previous IAM that - * outlives `isWebViewVisible() === false`. On native iOS, `addTrigger` - * invoked during the previous IAM's post-dismiss cleanup occasionally fails - * to re-evaluate so no message is presented. In both cases a second tap - * (= another `addTrigger` call once the SDK has settled) succeeds. Skip on - * Android (non-Flutter), where neither race has been observed. + * On Flutter the first tap is intermittently swallowed by a leftover IAM + * container window. If no WebView appears in 2.5s, re-tap. */ async function tapIamTrigger(buttonId: string) { await (await scrollToEl(buttonId)).click(); @@ -974,9 +993,9 @@ export async function checkInAppMessage(opts: { // step's swipes/queries don't race the teardown. if (!isWebViewSDK) { const main = await byTestId('main_scroll_view'); - await main - .waitForDisplayed({ timeout: timeoutMs }) - .catch(() => {/* best-effort; caller will surface real failure */}); + await main.waitForDisplayed({ timeout: timeoutMs }).catch(() => { + /* best-effort; caller will surface real failure */ + }); } } await ensureMainWebViewContext(); @@ -1010,12 +1029,7 @@ export async function expectSnackbar(text: string, timeoutMs = 5_000) { export async function checkTooltip(buttonId: string, key: string) { const tooltip = tooltipContent[key]; - - const infoIcon = await scrollToEl(buttonId); - await infoIcon.click(); - - const titleEl = await byTestId('tooltip_title'); - await titleEl.waitForDisplayed({ timeout: 5_000 }); + const titleEl = await openModal(buttonId, 'tooltip_title'); const title = await titleEl.getText(); expect(title).toBe(tooltip.title); diff --git a/appium/tests/specs/04_alias.spec.ts b/appium/tests/specs/04_alias.spec.ts index 82005f0..5cbcb3a 100644 --- a/appium/tests/specs/04_alias.spec.ts +++ b/appium/tests/specs/04_alias.spec.ts @@ -2,6 +2,7 @@ import { checkTooltip, confirmModal, expectPairInSection, + openModal, scrollToEl, waitForAppReady, } from '../helpers/app'; @@ -22,11 +23,7 @@ describe('Aliases', () => { }); it('can add an alias', async () => { - const addButton = await scrollToEl('add_alias_button'); - await addButton.click(); - - const labelInput = await byTestId('alias_label_input'); - await labelInput.waitForDisplayed({ timeout: 5_000 }); + const labelInput = await openModal('add_alias_button', 'alias_label_input'); await labelInput.setValue('test_label'); const idInput = await byTestId('alias_id_input'); @@ -38,14 +35,10 @@ describe('Aliases', () => { }); it('can add multiple aliases', async () => { - const addButton = await scrollToEl('add_multiple_aliases_button'); - await addButton.click(); - - const addRowButton = await byTestId('multipair_add_row_button'); + const addRowButton = await openModal('add_multiple_aliases_button', 'multipair_add_row_button'); await addRowButton.click(); const label0 = await byTestId('multipair_key_0'); - await label0.waitForDisplayed({ timeout: 5_000 }); await label0.setValue('test_label_2'); const id0 = await byTestId('multipair_value_0'); diff --git a/appium/tests/specs/05_email.spec.ts b/appium/tests/specs/05_email.spec.ts index 40ec6fb..f69cf68 100644 --- a/appium/tests/specs/05_email.spec.ts +++ b/appium/tests/specs/05_email.spec.ts @@ -1,4 +1,4 @@ -import { checkTooltip, confirmModal, scrollToEl, waitForAppReady } from '../helpers/app'; +import { checkTooltip, confirmModal, openModal, scrollToEl, waitForAppReady } from '../helpers/app'; import { byTestId, getTestData } from '../helpers/selectors.js'; describe('Emails', () => { @@ -15,12 +15,9 @@ describe('Emails', () => { const { email } = getTestData(); // add email - const addButton = await scrollToEl('add_email_button'); - await addButton.click(); - - const emailInput = await byTestId('email_input'); - await emailInput.waitForDisplayed({ timeout: 5_000 }); + const emailInput = await openModal('add_email_button', 'email_input'); await emailInput.setValue(email); + await confirmModal('singleinput_confirm_button'); let el = await byTestId(`emails_value_${email}`); diff --git a/appium/tests/specs/06_sms.spec.ts b/appium/tests/specs/06_sms.spec.ts index d51c61b..a3a1e49 100644 --- a/appium/tests/specs/06_sms.spec.ts +++ b/appium/tests/specs/06_sms.spec.ts @@ -1,4 +1,4 @@ -import { checkTooltip, confirmModal, scrollToEl, waitForAppReady } from '../helpers/app'; +import { checkTooltip, confirmModal, openModal, scrollToEl, waitForAppReady } from '../helpers/app'; import { byTestId, getTestData } from '../helpers/selectors.js'; describe('SMS', () => { @@ -14,11 +14,7 @@ describe('SMS', () => { it('can add and remove sms', async () => { const { sms } = getTestData(); - const addButton = await scrollToEl('add_sms_button'); - await addButton.click(); - - const smsInput = await byTestId('sms_input'); - await smsInput.waitForDisplayed({ timeout: 5_000 }); + const smsInput = await openModal('add_sms_button', 'sms_input'); await smsInput.setValue(sms); await confirmModal('singleinput_confirm_button'); diff --git a/appium/tests/specs/07_tag.spec.ts b/appium/tests/specs/07_tag.spec.ts index 7b31341..f20225e 100644 --- a/appium/tests/specs/07_tag.spec.ts +++ b/appium/tests/specs/07_tag.spec.ts @@ -2,6 +2,7 @@ import { checkTooltip, confirmModal, expectPairInSection, + openModal, scrollToEl, waitForAppReady, } from '../helpers/app'; @@ -22,12 +23,7 @@ describe('Tags', () => { }); it('can add and remove a tag', async () => { - const addButton = await scrollToEl('add_tag_button'); - await addButton.click(); - - // add tag - const keyInput = await byTestId('tag_key_input'); - await keyInput.waitForDisplayed({ timeout: 5_000 }); + const keyInput = await openModal('add_tag_button', 'tag_key_input'); await keyInput.setValue('test_tag'); const valueInput = await byTestId('tag_value_input'); @@ -46,12 +42,7 @@ describe('Tags', () => { }); it('can add and remove multiple tags', async () => { - const addButton = await scrollToEl('add_multiple_tags_button'); - await addButton.click(); - - // add tags - const key0 = await byTestId('multipair_key_0'); - await key0.waitForDisplayed({ timeout: 5_000 }); + const key0 = await openModal('add_multiple_tags_button', 'multipair_key_0'); await key0.setValue('test_tag_2'); const value0 = await byTestId('multipair_value_0'); @@ -72,12 +63,7 @@ describe('Tags', () => { await expectPairInSection('tags', 'test_tag_2', 'test_tag_value_2'); await expectPairInSection('tags', 'test_tag_3', 'test_tag_value_3'); - // remove tags - const removeButton = await scrollToEl('remove_tags_button'); - await removeButton.click(); - - const tag2Checkbox = await byTestId('remove_checkbox_test_tag_2'); - await tag2Checkbox.waitForDisplayed({ timeout: 5_000 }); + const tag2Checkbox = await openModal('remove_tags_button', 'remove_checkbox_test_tag_2'); await tag2Checkbox.click(); const tag3Checkbox = await byTestId('remove_checkbox_test_tag_3'); diff --git a/appium/tests/specs/08_outcome.spec.ts b/appium/tests/specs/08_outcome.spec.ts index b029c5c..a4d3821 100644 --- a/appium/tests/specs/08_outcome.spec.ts +++ b/appium/tests/specs/08_outcome.spec.ts @@ -2,6 +2,7 @@ import { checkTooltip, dismissKeyboard, expectSnackbar, + openModal, scrollToEl, waitForAppReady, } from '../helpers/app'; @@ -18,11 +19,7 @@ describe('Outcomes', () => { }); it('can send a normal outcome', async () => { - const sendButton = await scrollToEl('send_outcome_button'); - await sendButton.click(); - - const nameInput = await byTestId('outcome_name_input'); - await nameInput.waitForDisplayed({ timeout: 5_000 }); + const nameInput = await openModal('send_outcome_button', 'outcome_name_input'); await nameInput.setValue('test_normal'); await dismissKeyboard(); @@ -36,11 +33,7 @@ describe('Outcomes', () => { }); it('can send a unique outcome', async () => { - const sendButton = await scrollToEl('send_outcome_button'); - await sendButton.click(); - - const nameInput = await byTestId('outcome_name_input'); - await nameInput.waitForDisplayed({ timeout: 5_000 }); + const nameInput = await openModal('send_outcome_button', 'outcome_name_input'); await nameInput.setValue('test_unique'); await dismissKeyboard(); @@ -54,11 +47,7 @@ describe('Outcomes', () => { }); it('can send an outcome with value', async () => { - const sendButton = await scrollToEl('send_outcome_button'); - await sendButton.click(); - - const nameInput = await byTestId('outcome_name_input'); - await nameInput.waitForDisplayed({ timeout: 5_000 }); + const nameInput = await openModal('send_outcome_button', 'outcome_name_input'); const withValueRadio = await byTestId('outcome_type_value_radio'); await withValueRadio.click(); diff --git a/appium/tests/specs/09_trigger.spec.ts b/appium/tests/specs/09_trigger.spec.ts index 8649913..36a7dfb 100644 --- a/appium/tests/specs/09_trigger.spec.ts +++ b/appium/tests/specs/09_trigger.spec.ts @@ -2,16 +2,14 @@ import { checkTooltip, confirmModal, expectPairInSection, + openModal, scrollToEl, waitForAppReady, } from '../helpers/app'; import { byTestId } from '../helpers/selectors.js'; async function addMultipleTriggers() { - const addButton = await scrollToEl('add_multiple_triggers_button'); - await addButton.click(); - - const addRowButton = await byTestId('multipair_add_row_button'); + const addRowButton = await openModal('add_multiple_triggers_button', 'multipair_add_row_button'); await addRowButton.click(); const key0 = await byTestId('multipair_key_0'); @@ -48,11 +46,9 @@ describe('Triggers', () => { }); it('can add and remove trigger', async () => { - const addButton = await scrollToEl('add_trigger_button'); - await addButton.click(); + const keyInput = await openModal('add_trigger_button', 'trigger_key_input'); // add trigger - const keyInput = await byTestId('trigger_key_input'); await keyInput.waitForDisplayed({ timeout: 5_000 }); await keyInput.setValue('test_trigger_key'); diff --git a/appium/tests/specs/10_event.spec.ts b/appium/tests/specs/10_event.spec.ts index 7df2e9e..d3f7990 100644 --- a/appium/tests/specs/10_event.spec.ts +++ b/appium/tests/specs/10_event.spec.ts @@ -1,4 +1,10 @@ -import { checkTooltip, expectSnackbar, scrollToEl, waitForAppReady } from '../helpers/app'; +import { + checkTooltip, + expectSnackbar, + openModal, + scrollToEl, + waitForAppReady, +} from '../helpers/app'; import { byTestId, getTestData } from '../helpers/selectors.js'; const TEST_JSON = { @@ -31,11 +37,7 @@ describe('Custom Events', () => { it('can send a custom event with no properties', async () => { const { customEvent } = getTestData(); - const sendButton = await scrollToEl('track_event_button'); - await sendButton.click(); - - const nameInput = await byTestId('event_name_input'); - await nameInput.waitForDisplayed({ timeout: 5_000 }); + const nameInput = await openModal('track_event_button', 'event_name_input'); await nameInput.setValue(`${customEvent}_no_props`); const trackBtn = await byTestId('event_track_button'); @@ -46,11 +48,7 @@ describe('Custom Events', () => { it('can send a custom event with properties', async () => { const { customEvent } = getTestData(); - const sendButton = await scrollToEl('track_event_button'); - await sendButton.click(); - - const nameInput = await byTestId('event_name_input'); - await nameInput.waitForDisplayed({ timeout: 5_000 }); + const nameInput = await openModal('track_event_button', 'event_name_input'); await nameInput.setValue(`${customEvent}_with_props`); const propertiesInput = await byTestId('event_properties_input'); From 912edfe8b11e33c038a232885e0551ec6cc1b672 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Fri, 1 May 2026 22:16:39 -0700 Subject: [PATCH 08/31] refactor(appium): suppress first attempt log --- appium/tests/helpers/app.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 97936b2..fe07976 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -569,7 +569,9 @@ export async function openModal(triggerTestId: string, expectedTestId: string, f const maxAttempts = isUnitySDK && getPlatform() === 'ios' ? 3 : 1; for (let attempt = 1; ; attempt++) { - console.log(`Attempt ${attempt} to open modal "${triggerTestId}"`); + if (attempt > 1) { + console.info(`Attempt ${attempt} to open modal "${triggerTestId}"`); + } try { const trigger = await scrollToEl(triggerTestId); await trigger.click(); From eabe4d3a2d3ea45b14cd7cf02acf85d403ea7bdf Mon Sep 17 00:00:00 2001 From: Fadi George Date: Fri, 1 May 2026 22:36:45 -0700 Subject: [PATCH 09/31] refactor(appium): simplify openModal, drop Unity retry --- appium/tests/helpers/app.ts | 55 ++++++++++++++++----------- appium/tests/specs/09_trigger.spec.ts | 9 ++--- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index fe07976..a2eb366 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -560,32 +560,41 @@ export async function confirmModal(buttonTestId: string, timeoutMs = 5_000) { /** * Tap a button expected to open a modal/dialog and wait for one of its - * elements (`expectedTestId`) to appear. On Unity-iOS the first tap is - * occasionally swallowed when fired right after a previous modal's - * dismissal animation; if the expected element doesn't show up within - * `firstTryMs`, re-tap once. Reactive (state-gated), no fixed sleeps. + * elements (`expectedTestId`) to appear. On iOS we briefly wait for the + * trigger to settle before tapping: Unity UI Toolkit relayouts the section + * after a previous test's teardown (dialog dismiss, list row removal), and + * that shift can land the queued tap on empty space, producing a 5s + * "modal element not found" timeout. Native iOS/Android views don't need + * this — their click dispatch already waits for layout to settle. */ -export async function openModal(triggerTestId: string, expectedTestId: string, firstTryMs = 2_500) { - const maxAttempts = isUnitySDK && getPlatform() === 'ios' ? 3 : 1; +export async function openModal(triggerTestId: string, expectedTestId: string, firstTryMs = 5_000) { + const trigger = await scrollToEl(triggerTestId); + if (getSdkType() === 'unity') { + await waitForStablePosition(trigger); + } + await trigger.click(); + const expected = await byTestId(expectedTestId); + await expected.waitForExist({ timeout: firstTryMs }); + return expected; +} - for (let attempt = 1; ; attempt++) { - if (attempt > 1) { - console.info(`Attempt ${attempt} to open modal "${triggerTestId}"`); - } - try { - const trigger = await scrollToEl(triggerTestId); - await trigger.click(); - - const expected = await byTestId(expectedTestId); - await expected.waitForExist({ timeout: firstTryMs }); - return expected; - } catch (err) { - if (attempt >= maxAttempts) { - throw new Error( - `Modal element "${expectedTestId}" not present after ${attempt} tap(s) on "${triggerTestId}": ${err}`, - ); - } +async function waitForStablePosition( + el: { getLocation(): Promise<{ x: number; y: number }> }, + timeoutMs = 1_000, + pollMs = 100, +) { + let prev: number | null = null; + let stableHits = 0; + const deadline = Date.now() + timeoutMs; + while (Date.now() < deadline) { + const loc = await el.getLocation().catch(() => null); + if (loc && prev !== null && Math.abs(loc.y - prev) < 1) { + if (++stableHits >= 2) return; + } else { + stableHits = 0; } + prev = loc ? loc.y : null; + await driver.pause(pollMs); } } diff --git a/appium/tests/specs/09_trigger.spec.ts b/appium/tests/specs/09_trigger.spec.ts index 36a7dfb..ffc86a0 100644 --- a/appium/tests/specs/09_trigger.spec.ts +++ b/appium/tests/specs/09_trigger.spec.ts @@ -71,11 +71,10 @@ describe('Triggers', () => { await addMultipleTriggers(); // remove triggers - const removeButton = await scrollToEl('remove_triggers_button'); - await removeButton.click(); - - const trigger2Checkbox = await byTestId('remove_checkbox_test_trigger_key_2'); - await trigger2Checkbox.waitForDisplayed({ timeout: 5_000 }); + const trigger2Checkbox = await openModal( + 'remove_triggers_button', + 'remove_checkbox_test_trigger_key_2', + ); await trigger2Checkbox.click(); const trigger3Checkbox = await byTestId('remove_checkbox_test_trigger_key_3'); From 2b4db67b3b9bc7de6b5a12307088ad1bc8f4b451 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Mon, 11 May 2026 11:46:28 -0700 Subject: [PATCH 10/31] chore(appium): bump deps, pin vite-plus to 0.1.20 --- appium/bun.lock | 336 ++++++++++++++++++------------------ appium/package.json | 26 +-- appium/scripts/run-local.sh | 16 ++ 3 files changed, 200 insertions(+), 178 deletions(-) diff --git a/appium/bun.lock b/appium/bun.lock index 2779ad6..43f6aae 100644 --- a/appium/bun.lock +++ b/appium/bun.lock @@ -5,24 +5,24 @@ "": { "name": "@onesignal/appium-e2e", "devDependencies": { - "@types/node": "^25.6.0", - "@wdio/browserstack-service": "^9.27.0", - "@wdio/cli": "^9.27.0", - "@wdio/junit-reporter": "^9.27.0", - "@wdio/local-runner": "^9.27.0", - "@wdio/mocha-framework": "^9.27.0", + "@types/node": "^25.6.2", + "@wdio/browserstack-service": "^9.27.1", + "@wdio/cli": "^9.27.1", + "@wdio/junit-reporter": "^9.27.1", + "@wdio/local-runner": "^9.27.1", + "@wdio/mocha-framework": "^9.27.1", "@wdio/shared-store-service": "^9.27.0", - "@wdio/spec-reporter": "^9.27.0", + "@wdio/spec-reporter": "^9.27.1", "tsx": "^4.21.0", - "typescript": "^6.0.2", - "vite-plus": "latest", - "webdriverio": "^9.27.0", + "typescript": "^6.0.3", + "vite-plus": "0.1.20", + "webdriverio": "^9.27.1", }, }, }, "overrides": { - "vite": "npm:@voidzero-dev/vite-plus-core@latest", - "vitest": "npm:@voidzero-dev/vite-plus-test@latest", + "vite": "npm:@voidzero-dev/vite-plus-core@0.1.20", + "vitest": "npm:@voidzero-dev/vite-plus-test@0.1.20", }, "packages": { "@arr/every": ["@arr/every@1.0.1", "", {}, "sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg=="], @@ -35,7 +35,7 @@ "@browserstack/wdio-browserstack-service": ["@browserstack/wdio-browserstack-service@2.0.2", "", { "dependencies": { "@bufbuild/protobuf": "^2.5.2", "@grpc/grpc-js": "1.13.3" } }, "sha512-G8QefAej1fAZwIxCF5FeM5bZVrqpWXTepokzd2clGmzi9tVrHbmR4jC1L8rRGTK2X88uym8Yzb+idw9FbkJztw=="], - "@bufbuild/protobuf": ["@bufbuild/protobuf@2.11.0", "", {}, "sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ=="], + "@bufbuild/protobuf": ["@bufbuild/protobuf@2.12.0", "", {}, "sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA=="], "@colors/colors": ["@colors/colors@1.6.0", "", {}, "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="], @@ -131,119 +131,121 @@ "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], - "@jest/diff-sequences": ["@jest/diff-sequences@30.3.0", "", {}, "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA=="], + "@jest/diff-sequences": ["@jest/diff-sequences@30.4.0", "", {}, "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g=="], - "@jest/expect-utils": ["@jest/expect-utils@30.3.0", "", { "dependencies": { "@jest/get-type": "30.1.0" } }, "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA=="], + "@jest/expect-utils": ["@jest/expect-utils@30.4.1", "", { "dependencies": { "@jest/get-type": "30.1.0" } }, "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ=="], "@jest/get-type": ["@jest/get-type@30.1.0", "", {}, "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA=="], - "@jest/pattern": ["@jest/pattern@30.0.1", "", { "dependencies": { "@types/node": "*", "jest-regex-util": "30.0.1" } }, "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA=="], + "@jest/pattern": ["@jest/pattern@30.4.0", "", { "dependencies": { "@types/node": "*", "jest-regex-util": "30.4.0" } }, "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg=="], - "@jest/schemas": ["@jest/schemas@30.0.5", "", { "dependencies": { "@sinclair/typebox": "^0.34.0" } }, "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA=="], + "@jest/schemas": ["@jest/schemas@30.4.1", "", { "dependencies": { "@sinclair/typebox": "^0.34.0" } }, "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q=="], - "@jest/types": ["@jest/types@30.3.0", "", { "dependencies": { "@jest/pattern": "30.0.1", "@jest/schemas": "30.0.5", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", "@types/yargs": "^17.0.33", "chalk": "^4.1.2" } }, "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw=="], + "@jest/types": ["@jest/types@30.4.1", "", { "dependencies": { "@jest/pattern": "30.4.0", "@jest/schemas": "30.4.1", "@types/istanbul-lib-coverage": "^2.0.6", "@types/istanbul-reports": "^3.0.4", "@types/node": "*", "@types/yargs": "^17.0.33", "chalk": "^4.1.2" } }, "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ=="], "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], "@js-sdsl/ordered-map": ["@js-sdsl/ordered-map@4.4.2", "", {}, "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="], + "@nodable/entities": ["@nodable/entities@2.1.0", "", {}, "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA=="], + "@open-draft/until": ["@open-draft/until@1.0.3", "", {}, "sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q=="], - "@oxc-project/runtime": ["@oxc-project/runtime@0.123.0", "", {}, "sha512-wRf0z8saz9tHLcK3YeTeBmwISrpy4bBimvKxUmryiIhbt+ZJb0nwwJNL3D8xpeWbNfZlGSlzRBZbfcbApIGZJw=="], + "@oxc-project/runtime": ["@oxc-project/runtime@0.127.0", "", {}, "sha512-UQYLxAhDDPHm++szfa4z0RTdcPq5vaywrAoEA2n1YaAKeanXQdjHsoT6x1gP3U97RN8LZ7yHsSOrKPCcA6mCqw=="], - "@oxc-project/types": ["@oxc-project/types@0.123.0", "", {}, "sha512-YtECP/y8Mj1lSHiUWGSRzy/C6teUKlS87dEfuVKT09LgQbUsBW1rNg+MiJ4buGu3yuADV60gbIvo9/HplA56Ew=="], + "@oxc-project/types": ["@oxc-project/types@0.127.0", "", {}, "sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ=="], - "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.43.0", "", { "os": "android", "cpu": "arm" }, "sha512-CgU2s+/9hHZgo0IxVxrbMPrMj+tJ6VM3mD7Mr/4oiz4FNTISLoCvRmB5nk4wAAle045RtRjd86m673jwPyb1OQ=="], + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.46.0", "", { "os": "android", "cpu": "arm" }, "sha512-b1doV4WRcJU+BESSlCvCjV+5CEr/T6h0frArAdV26Nir+gGNFNaylvDiiMPfF1pxeV0txZEs38ojzJaxBYg+ng=="], - "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.43.0", "", { "os": "android", "cpu": "arm64" }, "sha512-T9OfRwjA/EdYxAqbvR7TtqLv5nIrwPXuCtTwOHtS7aR9uXyn74ZYgzgTo6/ZwvTq9DY4W+DsV09hB2EXgn9EbA=="], + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.46.0", "", { "os": "android", "cpu": "arm64" }, "sha512-v6+HhjsoV3GO0u2u9jLSAZrvWfTraDxKofUIQ7/ktS7tzS+epVsxdHmeM+XxuNcAY/nWxxU1Sg4JcGTNRXraBA=="], - "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.43.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-o3i49ZUSJWANzXMAAVY1wnqb65hn4JVzwlRQ5qfcwhRzIA8lGVaud31Q3by5ALHPrksp5QEaKCQF9aAS3TXpZA=="], + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.46.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3eeooJGrqGIlI5MyryDZsAcKXSmKIgAD4yYtfRrRJzXZ0UTFZtiSveIur56YPrGMYZwT4XyVhHsMqrNwr1XeFA=="], - "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.43.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-vWECzzCFkb0kK6jaHjbtC5sC3adiNWtqawFCxhpvsWlzVeKmv5bNvkB4nux+o4JKWTpHCM57NDK/MeXt44txmA=="], + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.46.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-QG8BDM0CXWbu84k2SKmCqfEddPQPFiBicwtYnLqHRWZZl57HbtOLRMac/KTq2NO4AEc4ICCBpFxJIV9zcqYfkQ=="], - "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.43.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-rgz8JpkKiI/umOf7fl9gwKyQasC8bs5SYHy6g7e4SunfLBY3+8ATcD5caIg8KLGEtKFm5ujKaH8EfjcmnhzTLg=="], + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.46.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-9DdCqS/n2ncu/Chazvt3cpgAjAmIGQDz7hFKSrNItMApyV/Ja9mz3hD4JakIE3nS8PW9smEbPWnb389QLBY4nw=="], - "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.43.0", "", { "os": "linux", "cpu": "arm" }, "sha512-nWYnF3vIFzT4OM1qL/HSf1Yuj96aBuKWSaObXHSWliwAk2rcj7AWd6Lf7jowEBQMo4wCZVnueIGw/7C4u0KTBQ=="], + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.46.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Dgs7VeE2jT0LHMhw6tPEt0xQYe54kBqHEovmWsv4FVQlegCOvlIJNx0S8n4vj8WUtpT+Z6BD2HhKJPLglLxvZg=="], - "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.43.0", "", { "os": "linux", "cpu": "arm" }, "sha512-sFg+NWJbLfupYTF4WELHAPSnLPOn1jiDZ33Z1jfDnTaA+cC3iB35x0FMMZTFdFOz3icRIArncwCcemJFGXu6TQ=="], + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.46.0", "", { "os": "linux", "cpu": "arm" }, "sha512-Zxn3adhTH13JKnU4xXJj8FeEfF680XjXh3gSShKl57HCMBRde2tUJTgogV/1MSHA80PJEVrDa7r66TLVq3Ia7Q=="], - "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.43.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-MelWqv68tX6wZEILDrTc9yewiGXe7im62+5x0bNXlCYFOZdA+VnYiJfAihbROsZ5fm90p9C3haFrqjj43XnlAA=="], + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.46.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-+TWipjrgVM8D7aIdDD0tlr3teLTTvQTn7QTE5BpT10H1Fj82gfdn9X6nn2sDgx/MepuSCfSnzFNJq2paLL0OiA=="], - "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.43.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-ROaWfYh+6BSJ1Arwy5ujijTlwnZetxDxzBpDc1oBR4d7rfrPBqzeyjd5WOudowzQUgyavl2wEpzn1hw3jWcqLA=="], + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.46.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-aAUPBWJ1lGwwnxZUEDLJ94+Iy6MuwJwPxUgO4sCA5mEEyDk7b+cDQ+JpX1VR150Zoyd+D49gsrUzpUK5h587Eg=="], - "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.43.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-PJRs/uNxmFipJJ8+SyKHh7Y7VZIKQicqrrBzvfyM5CtKi8D7yZKTwUOZV3ffxmiC2e7l1SDJpkBEOyue5NAFsg=="], + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.46.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ufBCJukyFX/UDrokP/r6BGDoTInnsDs7bxyzKAgMiZlt2Qu8GPJSJ6Zm6whIiJzKk0naxA8ilwmbO1LMw6Htxw=="], - "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.43.0", "", { "os": "linux", "cpu": "none" }, "sha512-j6biGAgzIhj+EtHXlbNumvwG7XqOIdiU4KgIWRXAEj/iUbHKukKW8eXa4MIwpQwW1YkxovduKtzEAPnjlnAhVQ=="], + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.46.0", "", { "os": "linux", "cpu": "none" }, "sha512-eqtlC2YmPqjun76R1gVfGLuKWx7NuEnLEAudZ7n6ipSKbCZTqIKSs1b5Y8K/JHZsRpLkeSmAAjig5HOIg8fQzQ=="], - "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.43.0", "", { "os": "linux", "cpu": "none" }, "sha512-RYWxAcslKxvy7yri24Xm9cmD0RiANaiEPs007EFG6l9h1ChM69Q5SOzACaCoz4Z9dEplnhhneeBaTWMEdpgIbA=="], + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.46.0", "", { "os": "linux", "cpu": "none" }, "sha512-yccVOO2nMXkQLGgy0He3EQEwKD7NF0zEk+/OWmroznkqXyJdN6bfK0LtNnr6/14Bh3FjpYq7bP33l/VloCnxpA=="], - "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.43.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-DT6Q8zfQQy3jxpezAsBACEHNUUixKSYTwdXeXojNHe4DQOoxjPdjr3Szu6BRNjxLykZM/xMNmp9ElOIyDppwtw=="], + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.46.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-aAf7fG23OQCey6VRPj9IeCraoYtpgtx0ZyJ1CXkPyT1wjzBE7c3xtuxHe/AdHaJfVVb/SXpSk8Gl1LzyQupSqw=="], - "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.43.0", "", { "os": "linux", "cpu": "x64" }, "sha512-R8Yk7iYcuZORXmCfFZClqbDxRZgZ9/HEidUuBNdoX8Ptx07cMePnMVJ/woB84lFIDjh2ROHVaOP40Ds3rBXFqg=="], + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.46.0", "", { "os": "linux", "cpu": "x64" }, "sha512-q0JPsTMyJNjYrBvYFDz4WbVsafNZaPCZv4RnFypRotLqpKROtBZcEaXQW4eb9YmvLU3NckVemLJnzkSZSdmOxw=="], - "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.43.0", "", { "os": "linux", "cpu": "x64" }, "sha512-F2YYqyvnQNvi320RWZNAvsaWEHwmW3k4OwNJ1hZxRKXupY63expbBaNp6jAgvYs7y/g546vuQnGHQuCBhslhLQ=="], + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.46.0", "", { "os": "linux", "cpu": "x64" }, "sha512-7LsLY9Cw57GPkhSR+duI3mt9baRczK/DtHYSldQ4BEU92da9igBQNl4z7Vq5U9NNPsh1FmpKvv1q9WDtiUQR1A=="], - "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.43.0", "", { "os": "none", "cpu": "arm64" }, "sha512-OE6TdietLXV3F6c7pNIhx/9YC1/2YFwjU9DPc/fbjxIX19hNIaP1rS0cFjCGJlGX+cVJwIKWe8Mos+LdQ1yAJw=="], + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.46.0", "", { "os": "none", "cpu": "arm64" }, "sha512-lHiBOz8Duaku7JtRNLlps3j++eOaICPZSd8FCVmTDM4DFOPT71Bjn7g6iar1z7StXlKRweUKxWUs4sA+zWGDXg=="], - "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.43.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-0nWK6a7pGkbdoypfVicmV9k/N1FwjPZENoqhlTU+5HhZnAhpIO3za30nEE33u6l6tuy9OVfpdXUqxUgZ+4lbZw=="], + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.46.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-/5ktYUliP89RhgC37DBH1x20U5zPSZMy3cMEcO0j3793rbHP9MWsknBwQB6eozRzWmYrh0IFM/p20EbPvDlYlg=="], - "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.43.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-9aokTR4Ft+tRdvgN/pKzSkVy2ksc4/dCpDm9L/xFrbIw0yhLtASLbvoG/5WOTUh/BRPPnfGTsWznEqv0dlOmhA=="], + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.46.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-3WTnoiuIr8XvV0DIY7SN+1uJSwKf4sPpcbHfobcRT9JutGcLaef/miyBB87jxd3aqH+mS0+G5lsgHuXLUwjjpQ=="], - "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.43.0", "", { "os": "win32", "cpu": "x64" }, "sha512-4bPgdQux2ZLWn3bf2TTXXMHcJB4lenmuxrLqygPmvCJ104Yqzj1UctxSRzR31TiJ4MLaG22RK8dUsVpJtrCz5g=="], + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.46.0", "", { "os": "win32", "cpu": "x64" }, "sha512-IXxiQpkYnOwNfP23vzwSfhdpxJzyiPTY7eTn6dn3DsriKddESzM8i6kfq9R7CD/PUJwCvQT22NgtygBeug3KoA=="], - "@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.20.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-KKQcIHZHMxqpHUA1VXIbOG6chNCFkUWbQy6M+AFVtPKkA/3xAeJkJ3njoV66bfzwPHRcWQO+kcj5XqtbkjakoA=="], + "@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.22.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-/exgXceakHbQrzaHTtKOe7MuDATaWMCCWpsCDQCZKeYhLGXzComipTrCYnHzAXrdnNBb5r5K+RRf5A6ormrhMA=="], - "@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.20.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-7HeVMuclGfG+NLZi2ybY0T4fMI7/XxO/208rJk+zEIloKkVnlh11Wd241JMGwgNFXn+MLJbOqOfojDb2Dt4L1g=="], + "@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.22.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-xFGdIahlmUbK+/MpZ5y08D0ewMGLDbd2Vki5wxVFYg50lSrtgPAtdDl+kqKZLNaFu0zpMar8n9wv1le05sL/jw=="], - "@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.20.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-zxhUwz+WSxE6oWlZLK2z2ps9yC6ebmgoYmjAl0Oa48+GqkZ56NVgo+wb8DURNv6xrggzHStQxqQxe3mK51HZag=="], + "@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.22.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-53RvC9f77eUo+V1dfQNwGVnsIfPJFMibRR0ee128EUpYNDOZe/ojmCfuXJeU7cY91V7r7fZSm42KPJocXUX8og=="], - "@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.20.0", "", { "os": "linux", "cpu": "x64" }, "sha512-/1l6FnahC9im8PK+Ekkx/V3yetO/PzZnJegE2FXcv/iXEhbeVxP/ouiTYcUQu9shT1FWJCSNti1VJHH+21Y1dg=="], + "@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.22.0", "", { "os": "linux", "cpu": "x64" }, "sha512-evZcJAZ9hjNyuN69RnXwbt+U2pAOcYt+yvqukgugiCkRm4iBZ0R0CvpY1tgfG2XcGUhEPh8dljO+nPZTEVGpCQ=="], - "@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.20.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-oPZ5Yz8sVdo7P/5q+i3IKeix31eFZ55JAPa1+RGPoe9PoaYVsdMvR6Jvib6YtrqoJnFPlg3fjEjlEPL8VBKYJA=="], + "@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.22.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-7jTO+k1mr5BxRAI2fxc1NRcE3MAbHNZ0Vef9SD1yAR6d1E6qEv5D/D7yuHpQpw6AO3qoecSVo2Jzr+JirN61+w=="], - "@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.20.0", "", { "os": "win32", "cpu": "x64" }, "sha512-4stx8RHj3SP9vQyRF/yZbz5igtPvYMEUR8CUoha4BVNZihi39DpCR8qkU7lpjB5Ga1DRMo2pHaA4bdTOMaY4mw=="], + "@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.22.0", "", { "os": "win32", "cpu": "x64" }, "sha512-7lbl9XFcqO+scsynxMzTQdl0XUe6sBUCyY/oGWvCB+JmV4U+70vzSyZJdTEzzxtkZiNnUVFFh9RJLmoiQSne+w=="], - "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.58.0", "", { "os": "android", "cpu": "arm" }, "sha512-1T7UN3SsWWxpWyWGn1cT3ASNJOo+pI3eUkmEl7HgtowapcV8kslYpFQcYn431VuxghXakPNlbjRwhqmR37PFOg=="], + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.61.0", "", { "os": "android", "cpu": "arm" }, "sha512-6eZBPgiigK5txqoVgRqxbaxiom4lM8AP8CyKPPvpzKnQ3iFRFOIDc+0AapF+qsUSwjOzr5SGk4SxQDpQhkSJMQ=="], - "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.58.0", "", { "os": "android", "cpu": "arm64" }, "sha512-GryzujxuiRv2YFF7bRy8mKcxlbuAN+euVUtGJt9KKbLT8JBUIosamVhcthLh+VEr6KE6cjeVMAQxKAzJcoN7dg=="], + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.61.0", "", { "os": "android", "cpu": "arm64" }, "sha512-CkwLR69MUnyv5wjzebvbbtTSUwqLxM35CXE79bHqDIK+NtKmPEUpStTcLQRZMCo4MP0qRT6TXIQVpK0ZVScnMA=="], - "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.58.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-7/bRSJIwl4GxeZL9rPZ11anNTyUO9epZrfEJH/ZMla3+/gbQ6xZixh9nOhsZ0QwsTW7/5J2A/fHbD1udC5DQQA=="], + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.61.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-8JbefTkbmvqkqWjmQrHke+MdpgT2UghhD/ktM4FOQSpGeCgbMToJEKdl9zwhr/YWTl92i4QI1KiTwVExpcUN8A=="], - "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.58.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-EqdtJSiHweS2vfILNrpyJ6HUwpEq2g7+4Zx1FPi4hu3Hu7tC3znF6ufbXO8Ub2LD4mGgznjI7kSdku9NDD1Mkg=="], + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.61.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-uWpoxDT47hTnDLcdEh5jVbso8rlTTu5o0zuqa9J8E0JAKmIWn7kGFEIB03Pycn2hd2vKxybPGLhjURy/9We5FQ=="], - "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.58.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-VQt5TH4M42mY20F545G637RKxV/yjwVtKk2vfXuazfReSIiuvWBnv+FVSvIV5fKVTJNjt3GSJibh6JecbhGdBw=="], + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.61.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-K/o4hEyW7flfMel0iBVznmMBt7VIMHGdjADocHKpK1DUF9erpWnJ+BSSWd2W0c8K3mPtpph+CuHzRU6CI3l9jQ=="], - "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.58.0", "", { "os": "linux", "cpu": "arm" }, "sha512-fBYcj4ucwpAtjJT3oeBdFBYKvNyjRSK+cyuvBOTQjh0jvKp4yeA4S/D0IsCHus/VPaNG5L48qQkh+Vjy3HL2/Q=="], + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.61.0", "", { "os": "linux", "cpu": "arm" }, "sha512-P6040ZkcyweJ0Po9yEFqJCdvZnf3VNCGs1SIHgXDf8AAQNC6ID/heXQs9iSgo2FH7gKaKq32VWc59XZwL34C5Q=="], - "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.58.0", "", { "os": "linux", "cpu": "arm" }, "sha512-0BeuFfwlUHlJ1xpEdSD1YO3vByEFGPg36uLjK1JgFaxFb4W6w17F8ET8sz5cheZ4+x5f2xzdnRrrWv83E3Yd8g=="], + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.61.0", "", { "os": "linux", "cpu": "arm" }, "sha512-bwxrGCzTZkuB+THv2TQ1aTkVEfv5oz8sl+0XZZCpoYzErJD8OhPQOTA0ENPd1zJz8QsVdSzSrS2umKtPq4/JXg=="], - "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.58.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-TXlZgnPTlxrQzxG9ZXU7BNwx1Ilrr17P3GwZY0If2EzrinqRH3zXPc3HrRcBJgcsoZNMuNL5YivtkJYgp467UQ=="], + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.61.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-vkhb9/wKguMkLlrm3FoJW/Xmdv31GgYAE+x8lxxQ+7HeOxXUySI0q36a3NTVIuQUdLzxCI1zzMGsk1o37FOe3w=="], - "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.58.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-zSoYRo5dxHLcUx93Stl2hW3hSNjPt99O70eRVWt5A1zwJ+FPjeCCANCD2a9R4JbHsdcl11TIQOjyigcRVOH2mw=="], + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.61.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-bl1dQh8LnVqsj6oOQAcxwbuOmNJkwc4p6o//HTBZhNTzJy21TLDwAviMqUFNUxDHkPGpmdKTSN4tWTjLryP8xg=="], - "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.58.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NQ0U/lqxH2/VxBYeAIvMNUK1y0a1bJ3ZicqkF2c6wfakbEciP9jvIE4yNzCFpZaqeIeRYaV7AVGqEO1yrfVPjA=="], + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.61.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-QoOX6KB2IiEpyOj/HKqaxi+NQHPnOgNgnr22n9N4ANJCzXkUlj1UmeAbFb4PpqdlHIzvGDM5xZ0OKtcLq9RhiQ=="], - "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.58.0", "", { "os": "linux", "cpu": "none" }, "sha512-X9J+kr3gIC9FT8GuZt0ekzpNUtkBVzMVU4KiKDSlocyQuEgi3gBbXYN8UkQiV77FTusLDPsovjo95YedHr+3yg=="], + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.61.0", "", { "os": "linux", "cpu": "none" }, "sha512-1TGcTerjY6p152wCof3oKElccq3xHljS/Mucp04gV/4ATpP6nO7YNnp7opEg6SHkv2a57/b4b8Ndm9znJ1/qAw=="], - "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.58.0", "", { "os": "linux", "cpu": "none" }, "sha512-CDze3pi1OO3Wvb/QsXjmLEY4XPKGM6kIo82ssNOgmcl1IdndF9VSGAE38YLhADWmOac7fjqhBw82LozuUVxD0Q=="], + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.61.0", "", { "os": "linux", "cpu": "none" }, "sha512-65wXEmZIrX2ADwC8i/qFL4EWLSbeuBpAm3suuX1vu4IQkKd+wLT/HU/BOl84kp91u2SxPkPDyQgu4yrqp8vwVA=="], - "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.58.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-b/89glbxFaEAcA6Uf1FvCNecBJEgcUTsV1quzrqXM/o4R1M4u+2KCVuyGCayN2UpsRWtGGLb+Ver0tBBpxaPog=="], + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.61.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-TVvhgMvor7Qa6COeXxCJ7ENOM+lcAOGsQ0iUdPSCv2hxb9qSHLQ4XF1h50S6RE1gBOJ0WV3rNukg4JJJP1LWRA=="], - "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.58.0", "", { "os": "linux", "cpu": "x64" }, "sha512-0/yYpkq9VJFCEcuRlrViGj8pJUFFvNS4EkEREaN7CB1EcLXJIaVSSa5eCihwBGXtOZxhnblWgxks9juRdNQI7w=="], + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.61.0", "", { "os": "linux", "cpu": "x64" }, "sha512-SjpS5uYuFoDnDdZPwZE59ndF95AsY47R5MliuneTWR1pDm2CxGJaYXbKULI71t5TVfLQUWmrHEGRL9xvuq6dnA=="], - "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.58.0", "", { "os": "linux", "cpu": "x64" }, "sha512-hr6FNvmcAXiH+JxSvaJ4SJ1HofkdqEElXICW9sm3/Rd5eC3t7kzvmLyRAB3NngKO2wzXRCAm4Z/mGWfrsS4X8w=="], + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.61.0", "", { "os": "linux", "cpu": "x64" }, "sha512-gGfAeGD4sNJGILZbc/yKcIimO9wQnPMoYp9swAaKeEtwsSQAbU+rsdQze5SBtIP6j0QDzeYd4XSSUCRCF+LIeQ=="], - "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.58.0", "", { "os": "none", "cpu": "arm64" }, "sha512-R+O368VXgRql1K6Xar+FEo7NEwfo13EibPMoTv3sesYQedRXd6m30Dh/7lZMxnrQVFfeo4EOfYIP4FpcgWQNHg=="], + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.61.0", "", { "os": "none", "cpu": "arm64" }, "sha512-OlVT0LrG/ct33EVtWRyR+B/othwmDWeRxfi13wUdPeb3lAT5TgTcFDcfLfarZtzB4W1nWF/zICMgYdkggX2WmQ=="], - "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.58.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Q0FZiAY/3c4YRj4z3h9K1PgaByrifrfbBoODSeX7gy97UtB7pySPUQfC2B/GbxWU6k7CzQrRy5gME10PltLAFQ=="], + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.61.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-vI//NZPJk6DToiovPtaiwD4iQ7kO1r5ReWQD0sOOyKRtP3E2f6jxin4uvwi3OvDzHA2EFfd7DcZl5dtkQh7g1w=="], - "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.58.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-Y8FKBABrSPp9H0QkRLHDHOSUgM/309a3IvOVgPcVxYcX70wxJrk608CuTg7w+C6vEd724X5wJoNkBcGYfH7nNQ=="], + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.61.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-0ySj4/4zd2XjePs3XAQq7IigIstN4LPQZgCyigX5/ERMLjdWAJfnxcTsrtxZxuij8guJW8foXuHmhGxW0H4dDA=="], - "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.58.0", "", { "os": "win32", "cpu": "x64" }, "sha512-bCn5rbiz5My+Bj7M09sDcnqW0QJyINRVxdZ65x1/Y2tGrMwherwK/lpk+HRQCKvXa8pcaQdF5KY5j54VGZLwNg=="], + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.61.0", "", { "os": "win32", "cpu": "x64" }, "sha512-0xgSiyeqDLDZxXoe9CVJrOx3TUVsfyoOY7cNi03JbItNcC9WCZqrSNdrAbHONxhSPaVh/lzfnDcON1RqSUMhHw=="], "@percy/appium-app": ["@percy/appium-app@2.1.0", "", { "dependencies": { "@percy/sdk-utils": "^1.30.9", "tmp": "^0.2.3" } }, "sha512-XVigKgAcXEerIch3Ufngac07gOH4KnfTDp/xyPujDyjvAZSWfIyIRnojmfbLEs2HnZEnmFFoEMX6ZB4Tk0SO/Q=="], - "@percy/sdk-utils": ["@percy/sdk-utils@1.31.11", "", { "dependencies": { "pac-proxy-agent": "^7.0.2" } }, "sha512-I4/Bx2RqSx/k00qVU0t/wcYudeyVRARQPdMnRZ/JvEZRZmXo0u+mHHpvZ5liHvnlpvWq6dv2WRA5MVy+GZHUhA=="], + "@percy/sdk-utils": ["@percy/sdk-utils@1.31.13", "", { "dependencies": { "pac-proxy-agent": "^7.0.2" } }, "sha512-0JW+ngBKLjkhbsI6ZD8wnWDV1U/S66X4vBrJqHLSi8t8BygQrulAwKLrtSV27DHCxz3a+zptTMBQufwFbal5gg=="], "@percy/selenium-webdriver": ["@percy/selenium-webdriver@2.2.6", "", { "dependencies": { "@percy/sdk-utils": "^1.31.10", "node-request-interceptor": "^0.6.3" } }, "sha512-5aeJh3ncYQl1Ug8/eazae8Ux281cvUX87e5YvHTFnLKtELaqJEb2k0NoNZbnWpPgAdz7yxeZZgTEbDn9HTOSYA=="], @@ -259,7 +261,7 @@ "@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="], - "@protobufjs/codegen": ["@protobufjs/codegen@2.0.4", "", {}, "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="], + "@protobufjs/codegen": ["@protobufjs/codegen@2.0.5", "", {}, "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g=="], "@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.0", "", {}, "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="], @@ -267,15 +269,15 @@ "@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="], - "@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="], + "@protobufjs/inquire": ["@protobufjs/inquire@1.1.1", "", {}, "sha512-mnzgDV26ueAvk7rsbt9L7bE0SuAoqyuys/sMMrmVcN5x9VsxpcG3rqAUSgDyLp0UZlmNfIbQ4fHfCtreVBk8Ew=="], "@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="], "@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="], - "@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="], + "@protobufjs/utf8": ["@protobufjs/utf8@1.1.1", "", {}, "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg=="], - "@puppeteer/browsers": ["@puppeteer/browsers@2.13.0", "", { "dependencies": { "debug": "^4.4.3", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", "semver": "^7.7.4", "tar-fs": "^3.1.1", "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" } }, "sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA=="], + "@puppeteer/browsers": ["@puppeteer/browsers@2.13.2", "", { "dependencies": { "debug": "^4.4.3", "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", "semver": "^7.7.4", "tar-fs": "^3.1.1", "yargs": "^17.7.2" }, "bin": { "browsers": "lib/cjs/main-cli.js" } }, "sha512-5EUZSUIc37H6aIXyWO0Z4y8NlF8NnjgmqeQgOGiswAU7pY0HOo16ho4+alIWmSfdZnjqBRawMsP3I5YqLSn6kw=="], "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], @@ -301,7 +303,7 @@ "@types/mocha": ["@types/mocha@10.0.10", "", {}, "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q=="], - "@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], + "@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], @@ -325,63 +327,63 @@ "@vitest/snapshot": ["@vitest/snapshot@2.1.9", "", { "dependencies": { "@vitest/pretty-format": "2.1.9", "magic-string": "^0.30.12", "pathe": "^1.1.2" } }, "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ=="], - "@vitest/utils": ["@vitest/utils@4.1.4", "", { "dependencies": { "@vitest/pretty-format": "4.1.4", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw=="], + "@vitest/utils": ["@vitest/utils@4.1.6", "", { "dependencies": { "@vitest/pretty-format": "4.1.6", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" } }, "sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ=="], - "@voidzero-dev/vite-plus-core": ["@voidzero-dev/vite-plus-core@0.1.16", "", { "dependencies": { "@oxc-project/runtime": "=0.123.0", "@oxc-project/types": "=0.123.0", "lightningcss": "^1.30.2", "postcss": "^8.5.6" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.21.7", "@tsdown/exe": "0.21.7", "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "publint": "^0.3.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0", "yaml": "^2.4.2" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "publint", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "typescript", "unplugin-unused", "yaml"] }, "sha512-fOyf14CXjcXqANFs2fCXEX+0Tn9ZjmqfFV+qTnARwIF1Kzl8WquO4XtvlDgs/fTQ91H4AyoNUgkvWdKS+C4xYA=="], + "@voidzero-dev/vite-plus-core": ["@voidzero-dev/vite-plus-core@0.1.20", "", { "dependencies": { "@oxc-project/runtime": "=0.127.0", "@oxc-project/types": "=0.127.0", "lightningcss": "^1.30.2", "postcss": "^8.5.6" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.21.10", "@tsdown/exe": "0.21.10", "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "publint": "^0.3.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0", "yaml": "^2.4.2" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "publint", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "typescript", "unplugin-unused", "yaml"] }, "sha512-4KmzRfzwTeG3JuvDijrdqWusSgRvLMKDPrVsDdtbDVVjEMq0VnM8lSH+Nvepd6Pg+SuSVUP212OIfH/3Yn1bfA=="], - "@voidzero-dev/vite-plus-darwin-arm64": ["@voidzero-dev/vite-plus-darwin-arm64@0.1.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-InG0ZmuGh7DTrn7zWQ0UvKapElphKI6G1oYfys+jraedG70EhIIee9gtO+mTE1T0bF67SgAcLXwNyaiNda0XwA=="], + "@voidzero-dev/vite-plus-darwin-arm64": ["@voidzero-dev/vite-plus-darwin-arm64@0.1.20", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ykCOJk91h0IEMvljYGTauI4Svxr/CatZAitofvtEFqaTCLE3n06QCHD8qWphMM784VnPz1G/J2xuewxbQduNlg=="], - "@voidzero-dev/vite-plus-darwin-x64": ["@voidzero-dev/vite-plus-darwin-x64@0.1.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-LGNrECstuhkCRKRj/dE98Xcprw8HU3VMIMJnZsnDR2C5RB2HADNIu21at/a/G3giA9eWm7uhtPp9FvUtTCK9TA=="], + "@voidzero-dev/vite-plus-darwin-x64": ["@voidzero-dev/vite-plus-darwin-x64@0.1.20", "", { "os": "darwin", "cpu": "x64" }, "sha512-5XxNW9cYEh85Z4BErALyWh/tLP/NZmxNXzUQ0FanhHreI2Zq7FfgbSqQNvC7/sYsPYTWf74RlxmIjzV7R/Lb5Q=="], - "@voidzero-dev/vite-plus-linux-arm64-gnu": ["@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-AoFKu6dIOtlkp/mwmtU8ES2uzoaxCHhIym1Tk7qMxyvke4IXnye6VDc4kPMRQwD8mwR3T3bO0HuaEEHxrIWDxw=="], + "@voidzero-dev/vite-plus-linux-arm64-gnu": ["@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.20", "", { "os": "linux", "cpu": "arm64" }, "sha512-Mc7npPBd9t/h0haURVCZGae+TfB0Yx2Ex8HbPKOVA4hnN9ynlMhMpLRFfTQAicDKYbEGDhfBcbCIX0vVv4vacA=="], - "@voidzero-dev/vite-plus-linux-arm64-musl": ["@voidzero-dev/vite-plus-linux-arm64-musl@0.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-PloCsGTRIhcXIpUOJ6PqVG8gYNpq+ooJNyqy5sQ82BRnJuo8oV7uBLFvg0X9B3Bzh+vO1F8/+92+o5TiL35JMg=="], + "@voidzero-dev/vite-plus-linux-arm64-musl": ["@voidzero-dev/vite-plus-linux-arm64-musl@0.1.20", "", { "os": "linux", "cpu": "arm64" }, "sha512-Oh/pxMdTLR/wsDl/OONjItjLOeTewFBLuKkH5RQmcI9g3AVqKzLj1/uawujgysBI5E25tonRRK7I2q/zu8Uqvg=="], - "@voidzero-dev/vite-plus-linux-x64-gnu": ["@voidzero-dev/vite-plus-linux-x64-gnu@0.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-nY9/2g+qjhwsW5U3MrFLlx+bOBsdOJiO2HzbxQy7jo/S3jPTnXhFlrRegQuAmqrHAXrSdNwgblgRpICKhx1xZg=="], + "@voidzero-dev/vite-plus-linux-x64-gnu": ["@voidzero-dev/vite-plus-linux-x64-gnu@0.1.20", "", { "os": "linux", "cpu": "x64" }, "sha512-msO1ZoUX5aSK8L6kN1C3XQO4CcH9aFsNPRSNcO1cjk1kTnaLyVYzkVxgvbh3vk7nzZAAMkmyZ4SlMpqJrdahrg=="], - "@voidzero-dev/vite-plus-linux-x64-musl": ["@voidzero-dev/vite-plus-linux-x64-musl@0.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-JGKEAMoXqzdr9lHT/13uRNV9uzrSYXAFhjAfIC8WEQMG2VUFksvq5/TOc26hzmzbqu+bxRmfN8h1aVTDL8KwFg=="], + "@voidzero-dev/vite-plus-linux-x64-musl": ["@voidzero-dev/vite-plus-linux-x64-musl@0.1.20", "", { "os": "linux", "cpu": "x64" }, "sha512-U93urREvg23ZFDkxKkkfWWIOI4GI9erhbWAZpXG+GeYqygWKrVC6PUTXiuexVg3/CFg2sSMTdm1W6V7TFG5hYA=="], - "@voidzero-dev/vite-plus-test": ["@voidzero-dev/vite-plus-test@0.1.16", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@voidzero-dev/vite-plus-core": "0.1.16", "es-module-lexer": "^1.7.0", "obug": "^2.1.1", "pixelmatch": "^7.1.0", "pngjs": "^7.0.0", "sirv": "^3.0.2", "std-env": "^4.0.0", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "ws": "^8.18.3" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/ui": "4.1.2", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/ui", "happy-dom", "jsdom"] }, "sha512-d/rJPX/heMzoAFdnpZsp04MAa6nw1yH1tA4mVCV4m8goVcE9nAvt69mjLMzE8N/rYIQOSgenf3hDXuQRuD6OKQ=="], + "@voidzero-dev/vite-plus-test": ["@voidzero-dev/vite-plus-test@0.1.20", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", "@voidzero-dev/vite-plus-core": "0.1.20", "es-module-lexer": "^1.7.0", "obug": "^2.1.1", "pixelmatch": "^7.1.0", "pngjs": "^7.0.0", "sirv": "^3.0.2", "std-env": "^4.0.0", "tinybench": "^2.9.0", "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "ws": "^8.18.3" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", "@vitest/coverage-istanbul": "4.1.5", "@vitest/coverage-v8": "4.1.5", "@vitest/ui": "4.1.5", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"] }, "sha512-vy2dJYw1bhgQ/+BrQrfwPlSKzQ2mm3YLJ9kGF7Yo0UJ2P3XKpshtgFIWLjSg/IASnC93OAx0c/7j3NM0I1RMuA=="], - "@voidzero-dev/vite-plus-win32-arm64-msvc": ["@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-IugPUCLY7HmiPcCeuHKUqO1+G2vxHnYzAGhS02AixD0sJLTAIKCUANDOiVUFf/HMw+jh/UkugW7MWek8lf/JrQ=="], + "@voidzero-dev/vite-plus-win32-arm64-msvc": ["@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.20", "", { "os": "win32", "cpu": "arm64" }, "sha512-deXfe3h2OpzKV88s1PMUgVOJfN9LlnDDpIEVH6y2+YAXwlTSO7YeKBj2QmyS6ALZCI4Rfp4HOsB0OKMVBfEqww=="], - "@voidzero-dev/vite-plus-win32-x64-msvc": ["@voidzero-dev/vite-plus-win32-x64-msvc@0.1.16", "", { "os": "win32", "cpu": "x64" }, "sha512-tq93CIeMs92HF7rdylJknRiyzMOWMKCmpw+g8nl5Q5nmUDNLUsrL3CGfbyqjgbruuPnIr761r9MfydPqZU/cYg=="], + "@voidzero-dev/vite-plus-win32-x64-msvc": ["@voidzero-dev/vite-plus-win32-x64-msvc@0.1.20", "", { "os": "win32", "cpu": "x64" }, "sha512-ygdgQgo0N9oUI1Q2IdYBcvr+KLY6riaqLY/bkWNYtvHS4uk8a4GuEd0F08znWt2E8sFm29i35bYIzI6fFY2EBg=="], - "@wdio/browserstack-service": ["@wdio/browserstack-service@9.27.0", "", { "dependencies": { "@browserstack/ai-sdk-node": "1.5.17", "@browserstack/wdio-browserstack-service": "^2.0.2", "@percy/appium-app": "^2.0.9", "@percy/selenium-webdriver": "^2.2.2", "@types/gitconfiglocal": "^2.0.1", "@wdio/logger": "9.18.0", "@wdio/reporter": "9.27.0", "@wdio/types": "9.27.0", "browserstack-local": "^1.5.1", "chalk": "^5.3.0", "csv-writer": "^1.6.0", "formdata-node": "5.0.1", "git-repo-info": "^2.1.1", "gitconfiglocal": "^2.1.0", "glob": "^11.0.0", "tar": "^7.5.7", "undici": "^6.21.3", "uuid": "^11.1.0", "webdriverio": "9.27.0", "winston-transport": "^4.5.0", "yauzl": "^3.0.0" }, "peerDependencies": { "@wdio/cli": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, "sha512-q3byJlIdzsfgkNC8mtifp9PTvNFbTeChN6WOMtrmaM1q2lxFRjkNMpOi94au2oAlFJi1UvY6vsMqpw/5F+4xeQ=="], + "@wdio/browserstack-service": ["@wdio/browserstack-service@9.27.1", "", { "dependencies": { "@browserstack/ai-sdk-node": "1.5.17", "@browserstack/wdio-browserstack-service": "^2.0.2", "@percy/appium-app": "^2.0.9", "@percy/selenium-webdriver": "^2.2.2", "@types/gitconfiglocal": "^2.0.1", "@wdio/logger": "9.18.0", "@wdio/reporter": "9.27.1", "@wdio/types": "9.27.1", "browserstack-local": "^1.5.1", "chalk": "^5.3.0", "csv-writer": "^1.6.0", "formdata-node": "5.0.1", "git-repo-info": "^2.1.1", "gitconfiglocal": "^2.1.0", "glob": "^11.0.0", "tar": "^7.5.11", "undici": "^6.24.0", "uuid": "^11.1.0", "webdriverio": "9.27.1", "winston-transport": "^4.5.0", "yauzl": "^3.0.0" }, "peerDependencies": { "@wdio/cli": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, "sha512-Pu6xy0lehavjIW6+Oho/x0BRWmekNLQkctkNzy6OPll4sPZzwPWwaN/DHHY5DzLihve9jhSBv2IN3B3yVBpveg=="], - "@wdio/cli": ["@wdio/cli@9.27.0", "", { "dependencies": { "@vitest/snapshot": "^2.1.1", "@wdio/config": "9.27.0", "@wdio/globals": "9.27.0", "@wdio/logger": "9.18.0", "@wdio/protocols": "9.27.0", "@wdio/types": "9.27.0", "@wdio/utils": "9.27.0", "async-exit-hook": "^2.0.1", "chalk": "^5.4.1", "chokidar": "^4.0.0", "create-wdio": "9.27.0", "dotenv": "^17.2.0", "import-meta-resolve": "^4.0.0", "lodash.flattendeep": "^4.4.0", "lodash.pickby": "^4.6.0", "lodash.union": "^4.6.0", "read-pkg-up": "^10.0.0", "tsx": "^4.7.2", "webdriverio": "9.27.0", "yargs": "^17.7.2" }, "bin": { "wdio": "bin/wdio.js" } }, "sha512-k3kSs1sWTnDwdFLdBua7j5O//0N9k3qTj2nkyfMnkCEzOU00UMV2Y0f/yzNrn8BkkvohrJmwdEQPYx7rNhfj9g=="], + "@wdio/cli": ["@wdio/cli@9.27.1", "", { "dependencies": { "@vitest/snapshot": "^2.1.1", "@wdio/config": "9.27.1", "@wdio/globals": "9.27.1", "@wdio/logger": "9.18.0", "@wdio/protocols": "9.27.1", "@wdio/types": "9.27.1", "@wdio/utils": "9.27.1", "async-exit-hook": "^2.0.1", "chalk": "^5.4.1", "chokidar": "^4.0.0", "create-wdio": "9.27.1", "dotenv": "^17.2.0", "import-meta-resolve": "^4.0.0", "lodash.flattendeep": "^4.4.0", "lodash.pickby": "^4.6.0", "lodash.union": "^4.6.0", "read-pkg-up": "^10.0.0", "tsx": "^4.7.2", "webdriverio": "9.27.1", "yargs": "^17.7.2" }, "bin": { "wdio": "bin/wdio.js" } }, "sha512-FxwHq7UZs81FWHWUhk3F/Nh2U8VpKzJrrDTminj8EYquNzsBOr6gw11M4lENuQ+Cre/aS01cxZYkgTYWkPGrOw=="], - "@wdio/config": ["@wdio/config@9.27.0", "", { "dependencies": { "@wdio/logger": "9.18.0", "@wdio/types": "9.27.0", "@wdio/utils": "9.27.0", "deepmerge-ts": "^7.0.3", "glob": "^10.2.2", "import-meta-resolve": "^4.0.0", "jiti": "^2.6.1" } }, "sha512-9y8z7ugIbU6ycKrA2SqCpKh1/hobut2rDq9CLt/BNVzSlebBBVOTMiAt1XroZzcPnA7/ZqpbkpOsbpPUaAQuNQ=="], + "@wdio/config": ["@wdio/config@9.27.1", "", { "dependencies": { "@wdio/logger": "9.18.0", "@wdio/types": "9.27.1", "@wdio/utils": "9.27.1", "deepmerge-ts": "^7.0.3", "glob": "^10.2.2", "import-meta-resolve": "^4.0.0", "jiti": "^2.6.1" } }, "sha512-QVfSCqcpMfVum9KlpxgjaLlSLXkc53UQ2CPJU+IUVBp8LkbSyeX972HQS8V9Hnn6vSPE1dYScItg7wblnJ8RQg=="], - "@wdio/dot-reporter": ["@wdio/dot-reporter@9.27.0", "", { "dependencies": { "@wdio/reporter": "9.27.0", "@wdio/types": "9.27.0", "chalk": "^5.0.1" } }, "sha512-gYFCTeEHZxzqdXCn/L519HDAFpci+dsdfzLHg+2XMlzIWEGSgHxMIr4/iLjvCwDgCSLeh+XvsBsPm3U+qOtwdg=="], + "@wdio/dot-reporter": ["@wdio/dot-reporter@9.27.1", "", { "dependencies": { "@wdio/reporter": "9.27.1", "@wdio/types": "9.27.1", "chalk": "^5.0.1" } }, "sha512-MF42psa0wEZp6UsBsmiS8uSkDBrVDtncBhyHi34aLkiBuZ+exftO910KKXD3c5QNJcZwV2ps8eayjuqLdFp0XQ=="], - "@wdio/globals": ["@wdio/globals@9.27.0", "", { "peerDependencies": { "expect-webdriverio": "^5.6.5", "webdriverio": "^9.0.0" } }, "sha512-yT6EAyvEqm+wFD11fg89BMxvFkYLgnIVCihfJx+k73Gm3utL/DfZQpSheQdwrlQzu5p7jHi/JwOD76740F5Peg=="], + "@wdio/globals": ["@wdio/globals@9.27.1", "", { "peerDependencies": { "expect-webdriverio": "^5.6.5", "webdriverio": "^9.0.0" } }, "sha512-jm6gTQ6Qo3EOBY6PA09U/5Pf17WLEJM1/lTfhc6jzLFE770EuhuhbuphqrInH0hVR9WMyWtSZQ+LRCcLfcmOPQ=="], - "@wdio/junit-reporter": ["@wdio/junit-reporter@9.27.0", "", { "dependencies": { "@wdio/reporter": "9.27.0", "@wdio/types": "9.27.0", "json-stringify-safe": "^5.0.1", "junit-report-builder": "^5.1.1" } }, "sha512-C9IGHRdPfuU2av+3psmiCJnf2G52wEmyO5i/kYPF3ZaQT2/r6aFk2lTXU/gm/vNuIOmxIpUckK9j0fFqaRU4+g=="], + "@wdio/junit-reporter": ["@wdio/junit-reporter@9.27.1", "", { "dependencies": { "@wdio/reporter": "9.27.1", "@wdio/types": "9.27.1", "json-stringify-safe": "^5.0.1", "junit-report-builder": "^5.1.1" } }, "sha512-/JBQhkx9pzxpLbNBiwJ29FYD0Fqj0Hw35YmP1JJmulQVFwHBRoG/AjVNYM+epKJMLitXdEJ32Txc3HuPGVz/JA=="], - "@wdio/local-runner": ["@wdio/local-runner@9.27.0", "", { "dependencies": { "@types/node": "^20.1.0", "@wdio/logger": "9.18.0", "@wdio/repl": "9.16.2", "@wdio/runner": "9.27.0", "@wdio/types": "9.27.0", "@wdio/xvfb": "9.27.0", "exit-hook": "^4.0.0", "expect-webdriverio": "^5.6.5", "split2": "^4.1.0", "stream-buffers": "^3.0.2" } }, "sha512-0AqAbz1UhZ9e72ebqH4/B9/qOy0LVm3iOOYp16Rz2zkE5DOudLPPn3DpakafqW22Z7Q+Wb/23KRttPMrq0rOxw=="], + "@wdio/local-runner": ["@wdio/local-runner@9.27.1", "", { "dependencies": { "@types/node": "^20.1.0", "@wdio/logger": "9.18.0", "@wdio/repl": "9.16.2", "@wdio/runner": "9.27.1", "@wdio/types": "9.27.1", "@wdio/xvfb": "9.27.1", "exit-hook": "^4.0.0", "expect-webdriverio": "^5.6.5", "split2": "^4.1.0", "stream-buffers": "^3.0.2" } }, "sha512-Uvol8Je1VrCUDZqLT1/fhrvXOGpAGcjEXd69LbhupFAVv336fGX+aonJlWV8VJyWow55xSW4zmKnaLIhpFk3Uw=="], "@wdio/logger": ["@wdio/logger@9.18.0", "", { "dependencies": { "chalk": "^5.1.2", "loglevel": "^1.6.0", "loglevel-plugin-prefix": "^0.8.4", "safe-regex2": "^5.0.0", "strip-ansi": "^7.1.0" } }, "sha512-HdzDrRs+ywAqbXGKqe1i/bLtCv47plz4TvsHFH3j729OooT5VH38ctFn5aLXgECmiAKDkmH/A6kOq2Zh5DIxww=="], - "@wdio/mocha-framework": ["@wdio/mocha-framework@9.27.0", "", { "dependencies": { "@types/mocha": "^10.0.6", "@types/node": "^20.11.28", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.0", "@wdio/utils": "9.27.0", "mocha": "^10.3.0" } }, "sha512-bngxUgV7FRcrcPsf5oeNBPHMBCiQoMAg6fdv0iaaOvmNQOzu2y5hB/dmLBH8FjXby4Ni/H6ea2oA2MPwJYW9FA=="], + "@wdio/mocha-framework": ["@wdio/mocha-framework@9.27.1", "", { "dependencies": { "@types/mocha": "^10.0.6", "@types/node": "^20.11.28", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.1", "@wdio/utils": "9.27.1", "mocha": "^10.3.0" } }, "sha512-HJ2FtV6qgy7Rs7xGKjyGIKMtFBlCRfxiK9jTElRlOPyQjv79BHc1+sDcQpvufunKuma35rLUCuwtbeY3HotJVg=="], - "@wdio/protocols": ["@wdio/protocols@9.27.0", "", {}, "sha512-rIk69BsY1+6uU2PEN5FiRpI6K7HJ86YHzZRFBe4iRzKXQgGNk1zWzbdVJIuNFoOWsnmYUkK42KSSOT4Le6EmiQ=="], + "@wdio/protocols": ["@wdio/protocols@9.27.1", "", {}, "sha512-Ril46AmySoiYX9nuKqFr3SNJqquU3VmF9FzSndQlDib0G3oA4pYx9wcBXvdvkFxRjjmFwQDzmvztKrssAHymgw=="], "@wdio/repl": ["@wdio/repl@9.16.2", "", { "dependencies": { "@types/node": "^20.1.0" } }, "sha512-FLTF0VL6+o5BSTCO7yLSXocm3kUnu31zYwzdsz4n9s5YWt83sCtzGZlZpt7TaTzb3jVUfxuHNQDTb8UMkCu0lQ=="], - "@wdio/reporter": ["@wdio/reporter@9.27.0", "", { "dependencies": { "@types/node": "^20.1.0", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.0", "diff": "^8.0.2", "object-inspect": "^1.12.0" } }, "sha512-JsazSrpdKrUEz0RkZcNzHHO9EaoJsWnjzi8Lk3hyI3e2T0M0d/EZTaYwLU+zZXr9VRJBulv8DhRfmBx+gbY2jw=="], + "@wdio/reporter": ["@wdio/reporter@9.27.1", "", { "dependencies": { "@types/node": "^20.1.0", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.1", "diff": "^8.0.2", "object-inspect": "^1.12.0" } }, "sha512-2ueVjd5hOCclfC+GV3yhaN/4Tids1mXMcpPtNTPushHIQY4gLmBqqKDe5RSXAED3bNU+DRdHq2uBiZTBd4QDJg=="], - "@wdio/runner": ["@wdio/runner@9.27.0", "", { "dependencies": { "@types/node": "^20.11.28", "@wdio/config": "9.27.0", "@wdio/dot-reporter": "9.27.0", "@wdio/globals": "9.27.0", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.0", "@wdio/utils": "9.27.0", "deepmerge-ts": "^7.0.3", "webdriver": "9.27.0", "webdriverio": "9.27.0" }, "peerDependencies": { "expect-webdriverio": "^5.6.5" } }, "sha512-PAuvuq0GaziutDXO8pZkUmca/qFGnGY2O3e4mQtqDUZbkyxYF4W68WJWhkvwuDAvN5GH1V+K/FBmiwL8m+roxw=="], + "@wdio/runner": ["@wdio/runner@9.27.1", "", { "dependencies": { "@types/node": "^20.11.28", "@wdio/config": "9.27.1", "@wdio/dot-reporter": "9.27.1", "@wdio/globals": "9.27.1", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.1", "@wdio/utils": "9.27.1", "deepmerge-ts": "^7.0.3", "webdriver": "9.27.1", "webdriverio": "9.27.1" }, "peerDependencies": { "expect-webdriverio": "^5.6.5" } }, "sha512-vd/cVrI1++TAqs85CJFt0eJT3/fr1njMBV5I0GDjsHN6J0g9hemJk3VV7T4x1cBtAnCPlj22Q2Bzy4JhYN2gLg=="], - "@wdio/shared-store-service": ["@wdio/shared-store-service@9.27.0", "", { "dependencies": { "@polka/parse": "^1.0.0-next.0", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.0", "polka": "^0.5.2", "webdriverio": "9.27.0" } }, "sha512-9TdXYVaPSnbD9v44c+qu9jJaXFvuSccPwJqME4aZGYqrsxOKYrqeEpLcEznUuC0kXO1xN3oCc451/hEiGZqezw=="], + "@wdio/shared-store-service": ["@wdio/shared-store-service@9.27.1", "", { "dependencies": { "@polka/parse": "^1.0.0-next.0", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.1", "polka": "^0.5.2", "webdriverio": "9.27.1" } }, "sha512-8NSYBxtA7yWUdYoDcqPQidMaS2PcGfXX2adX58SiwJT7XOdvfu56CO0uExnW/eawaaq1iKmAhmJgTJNYRf6d+g=="], - "@wdio/spec-reporter": ["@wdio/spec-reporter@9.27.0", "", { "dependencies": { "@wdio/reporter": "9.27.0", "@wdio/types": "9.27.0", "chalk": "^5.1.2", "easy-table": "^1.2.0", "pretty-ms": "^9.0.0" } }, "sha512-pSrSfflFGthCc14B/4VZqthrz6T5/N+PDqpIOf+bfwJwtPgVlzZoLzbkKYDmCYHGDlDFt1QrZS9WQ5Qw2Qz/Ow=="], + "@wdio/spec-reporter": ["@wdio/spec-reporter@9.27.1", "", { "dependencies": { "@wdio/reporter": "9.27.1", "@wdio/types": "9.27.1", "chalk": "^5.1.2", "easy-table": "^1.2.0", "pretty-ms": "^9.0.0" } }, "sha512-q9UMJJbCcP+nCOojIvOIcsXnerhHICmWu94guRMRYPbW2IsG/5VM/uhzwru8SU/1WRXLtKgTjkuXXsjzjVpf2w=="], - "@wdio/types": ["@wdio/types@9.27.0", "", { "dependencies": { "@types/node": "^20.1.0" } }, "sha512-DQJ+OdRBqUBcQ30DN2Z651hEVh3OoxnlDUSRqlWy9An2AY6v9rYWTj825B6zsj5pLLEToYO1tfwWq0ab183pXg=="], + "@wdio/types": ["@wdio/types@9.27.1", "", { "dependencies": { "@types/node": "^20.1.0" } }, "sha512-EHBNCvLmvpYerln4mb/OBxzKtnavL2wdenjhwuYjzkZMOWHgm/uLXH6sLThM0y6DIbCU72Asth16fo1eDcsofA=="], - "@wdio/utils": ["@wdio/utils@9.27.0", "", { "dependencies": { "@puppeteer/browsers": "^2.2.0", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.0", "decamelize": "^6.0.0", "deepmerge-ts": "^7.0.3", "edgedriver": "^6.1.2", "geckodriver": "^6.1.0", "get-port": "^7.0.0", "import-meta-resolve": "^4.0.0", "locate-app": "^2.2.24", "mitt": "^3.0.1", "safaridriver": "^1.0.0", "split2": "^4.2.0", "wait-port": "^1.1.0" } }, "sha512-fUasd5OKJTy2seJfWnYZ9xlxTtY0p/Kyeuh7Tbb8kcofBqmBi2fTvM3sfZlo1tGQX9yCh+IS2N7hlfyFMmuZ+w=="], + "@wdio/utils": ["@wdio/utils@9.27.1", "", { "dependencies": { "@puppeteer/browsers": "^2.2.0", "@wdio/logger": "9.18.0", "@wdio/types": "9.27.1", "decamelize": "^6.0.0", "deepmerge-ts": "^7.0.3", "edgedriver": "^6.1.2", "geckodriver": "^6.1.0", "get-port": "^7.0.0", "import-meta-resolve": "^4.0.0", "locate-app": "^2.2.24", "mitt": "^3.0.1", "safaridriver": "^1.0.0", "split2": "^4.2.0", "wait-port": "^1.1.0" } }, "sha512-s2w1tFrvmpdkZ33LYsIw4ONRdWIIm4MxkyIuibbcG1ILV5fFMS9rU59csHuWIM0KhJoEoLU+fzE3ze9O7TpWhw=="], - "@wdio/xvfb": ["@wdio/xvfb@9.27.0", "", { "dependencies": { "@wdio/logger": "9.18.0" } }, "sha512-sumk8m5wzOPMs8TizfQkWG0MTqe0p1yfu77ouz+xy1hNW+gaSf99uiU3lvz4rSghloM1esKfqRCFQibJI4+d/w=="], + "@wdio/xvfb": ["@wdio/xvfb@9.27.1", "", { "dependencies": { "@wdio/logger": "9.18.0" } }, "sha512-7qOnrAF+3o+bg0ijqIoxsXloCQZ9sG9o8Jt9btg4NiyC6mRIQoqxnQBDo0M/v4ZnmAaz/hSCDvQNU0Y/7baNZA=="], "@zip.js/zip.js": ["@zip.js/zip.js@2.8.26", "", {}, "sha512-RQ4h9F6DOiHxpdocUDrOl6xBM+yOtz+LkUol47AVWcfebGBDpZ7w7Xvz9PS24JgXvLGiXXzSAfdCdVy1tPlaFA=="], @@ -415,33 +417,33 @@ "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], - "axios": ["axios@1.15.0", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q=="], + "axios": ["axios@1.16.0", "", { "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w=="], - "b4a": ["b4a@1.8.0", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg=="], + "b4a": ["b4a@1.8.1", "", { "peerDependencies": { "react-native-b4a": "*" }, "optionalPeers": ["react-native-b4a"] }, "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw=="], "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "bare-events": ["bare-events@2.8.2", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ=="], - "bare-fs": ["bare-fs@4.7.0", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-xzqKsCFxAek9aezYhjJuJRXBIaYlg/0OGDTZp+T8eYmYMlm66cs6cYko02drIyjN2CBbi+I6L7YfXyqpqtKRXA=="], + "bare-fs": ["bare-fs@4.7.1", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw=="], - "bare-os": ["bare-os@3.8.7", "", {}, "sha512-G4Gr1UsGeEy2qtDTZwL7JFLo2wapUarz7iTMcYcMFdS89AIQuBoyjgXZz0Utv7uHs3xA9LckhVbeBi8lEQrC+w=="], + "bare-os": ["bare-os@3.9.1", "", {}, "sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ=="], "bare-path": ["bare-path@3.0.0", "", { "dependencies": { "bare-os": "^3.0.1" } }, "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw=="], - "bare-stream": ["bare-stream@2.13.0", "", { "dependencies": { "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": { "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-abort-controller", "bare-buffer", "bare-events"] }, "sha512-3zAJRZMDFGjdn+RVnNpF9kuELw+0Fl3lpndM4NcEOhb9zwtSo/deETfuIwMSE5BXanA0FrN1qVjffGwAg2Y7EA=="], + "bare-stream": ["bare-stream@2.13.1", "", { "dependencies": { "streamx": "^2.25.0", "teex": "^1.0.1" }, "peerDependencies": { "bare-abort-controller": "*", "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-abort-controller", "bare-buffer", "bare-events"] }, "sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow=="], - "bare-url": ["bare-url@2.4.0", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-NSTU5WN+fy/L0DDenfE8SXQna4voXuW0FHM7wH8i3/q9khUSchfPbPezO4zSFMnDGIf9YE+mt/RWhZgNRKRIXA=="], + "bare-url": ["bare-url@2.4.3", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ=="], "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], - "basic-ftp": ["basic-ftp@5.2.2", "", {}, "sha512-1tDrzKsdCg70WGvbFss/ulVAxupNauGnOlgpyjKzeQxzyllBLS0CGLV7tjIXTK3ZQA9/FBEm9qyFFN1bciA6pw=="], + "basic-ftp": ["basic-ftp@5.3.1", "", {}, "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw=="], "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], - "brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], + "brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], @@ -497,7 +499,7 @@ "crc32-stream": ["crc32-stream@6.0.0", "", { "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^4.0.0" } }, "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g=="], - "create-wdio": ["create-wdio@9.27.0", "", { "dependencies": { "chalk": "^5.3.0", "commander": "^14.0.0", "cross-spawn": "^7.0.3", "ejs": "^3.1.10", "execa": "^9.6.0", "import-meta-resolve": "^4.1.0", "inquirer": "^12.7.0", "normalize-package-data": "^7.0.0", "read-pkg-up": "^10.1.0", "recursive-readdir": "^2.2.3", "semver": "^7.6.3", "type-fest": "^4.41.0", "yargs": "^17.7.2" }, "bin": { "create-wdio": "bin/wdio.js" } }, "sha512-6ot1WVks07Otj+5jDsi/NU0L3avsIA9C1mh0MtlXsR6kSvZNxwc56NH6sX3M1p+5e8Ysl777Vs4PqmgHh7LrNg=="], + "create-wdio": ["create-wdio@9.27.1", "", { "dependencies": { "chalk": "^5.3.0", "commander": "^14.0.0", "cross-spawn": "^7.0.3", "ejs": "^3.1.10", "execa": "^9.6.0", "import-meta-resolve": "^4.1.0", "inquirer": "^12.7.0", "normalize-package-data": "^7.0.0", "read-pkg-up": "^10.1.0", "recursive-readdir": "^2.2.3", "semver": "^7.6.3", "type-fest": "^4.41.0", "yargs": "^17.7.2" }, "bin": { "create-wdio": "bin/wdio.js" } }, "sha512-/cpc9s3iJWYBhglj8x0DhxH4OMSAh4daYnJg0E93XTCnv+jmS+Nb88Yq+fl1hvNEziTOPn4A93+6nEfiVuwdIQ=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], @@ -539,7 +541,7 @@ "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], - "dotenv": ["dotenv@17.4.1", "", {}, "sha512-k8DaKGP6r1G30Lx8V4+pCsLzKr8vLmV2paqEj1Y55GdAgJuIqpRp5FfajGF8KtwMxCz9qJc6wUIJnm053d/WCw=="], + "dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], @@ -597,7 +599,7 @@ "exit-hook": ["exit-hook@4.0.0", "", {}, "sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ=="], - "expect": ["expect@30.3.0", "", { "dependencies": { "@jest/expect-utils": "30.3.0", "@jest/get-type": "30.1.0", "jest-matcher-utils": "30.3.0", "jest-message-util": "30.3.0", "jest-mock": "30.3.0", "jest-util": "30.3.0" } }, "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q=="], + "expect": ["expect@30.4.1", "", { "dependencies": { "@jest/expect-utils": "30.4.1", "@jest/get-type": "30.1.0", "jest-matcher-utils": "30.4.1", "jest-message-util": "30.4.1", "jest-mock": "30.4.1", "jest-util": "30.4.1" } }, "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA=="], "expect-webdriverio": ["expect-webdriverio@5.6.5", "", { "dependencies": { "@vitest/snapshot": "^4.0.16", "deep-eql": "^5.0.2", "expect": "^30.2.0", "jest-matcher-utils": "^30.2.0" }, "peerDependencies": { "@wdio/globals": "^9.0.0", "@wdio/logger": "^9.0.0", "webdriverio": "^9.0.0" } }, "sha512-5ot+Apo0bEvMD/nqzWymQpgyWnOdu0kVpmahLx5T7NzUc6RyifucZ24Gsfr6F6C8yRGBhmoFh7ZeY+W9kteEBQ=="], @@ -607,9 +609,9 @@ "fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="], - "fast-xml-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="], + "fast-xml-builder": ["fast-xml-builder@1.2.0", "", { "dependencies": { "path-expression-matcher": "^1.5.0", "xml-naming": "^0.1.0" } }, "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q=="], - "fast-xml-parser": ["fast-xml-parser@5.5.11", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.4.0", "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-QL0eb0YbSTVWF6tTf1+LEMSgtCEjBYPpnAjoLC8SscESlAjXEIRJ7cHtLG0pLeDFaZLa4VKZLArtA/60ZS7vyA=="], + "fast-xml-parser": ["fast-xml-parser@5.7.3", "", { "dependencies": { "@nodable/entities": "^2.1.0", "fast-xml-builder": "^1.1.7", "path-expression-matcher": "^1.5.0", "strnum": "^2.2.3" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg=="], "fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], @@ -627,7 +629,7 @@ "flat": ["flat@5.0.2", "", { "bin": { "flat": "cli.js" } }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="], - "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], + "follow-redirects": ["follow-redirects@1.16.0", "", {}, "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw=="], "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], @@ -653,7 +655,7 @@ "get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], - "get-tsconfig": ["get-tsconfig@4.13.7", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q=="], + "get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="], "get-uri": ["get-uri@6.0.5", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg=="], @@ -677,7 +679,7 @@ "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], - "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + "hasown": ["hasown@2.0.3", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg=="], "he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="], @@ -711,7 +713,7 @@ "inquirer": ["inquirer@12.11.1", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/prompts": "^7.10.1", "@inquirer/type": "^3.0.10", "mute-stream": "^2.0.0", "run-async": "^4.0.6", "rxjs": "^7.8.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw=="], - "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], + "ip-address": ["ip-address@10.2.0", "", {}, "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="], "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], @@ -741,19 +743,19 @@ "jake": ["jake@10.9.4", "", { "dependencies": { "async": "^3.2.6", "filelist": "^1.0.4", "picocolors": "^1.1.1" }, "bin": { "jake": "bin/cli.js" } }, "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA=="], - "jest-diff": ["jest-diff@30.3.0", "", { "dependencies": { "@jest/diff-sequences": "30.3.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "pretty-format": "30.3.0" } }, "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ=="], + "jest-diff": ["jest-diff@30.4.1", "", { "dependencies": { "@jest/diff-sequences": "30.4.0", "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "pretty-format": "30.4.1" } }, "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA=="], - "jest-matcher-utils": ["jest-matcher-utils@30.3.0", "", { "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "jest-diff": "30.3.0", "pretty-format": "30.3.0" } }, "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA=="], + "jest-matcher-utils": ["jest-matcher-utils@30.4.1", "", { "dependencies": { "@jest/get-type": "30.1.0", "chalk": "^4.1.2", "jest-diff": "30.4.1", "pretty-format": "30.4.1" } }, "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A=="], - "jest-message-util": ["jest-message-util@30.3.0", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@jest/types": "30.3.0", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "picomatch": "^4.0.3", "pretty-format": "30.3.0", "slash": "^3.0.0", "stack-utils": "^2.0.6" } }, "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw=="], + "jest-message-util": ["jest-message-util@30.4.1", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@jest/types": "30.4.1", "@types/stack-utils": "^2.0.3", "chalk": "^4.1.2", "graceful-fs": "^4.2.11", "jest-util": "30.4.1", "picomatch": "^4.0.3", "pretty-format": "30.4.1", "slash": "^3.0.0", "stack-utils": "^2.0.6" } }, "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ=="], - "jest-mock": ["jest-mock@30.3.0", "", { "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", "jest-util": "30.3.0" } }, "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog=="], + "jest-mock": ["jest-mock@30.4.1", "", { "dependencies": { "@jest/types": "30.4.1", "@types/node": "*", "jest-util": "30.4.1" } }, "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw=="], - "jest-regex-util": ["jest-regex-util@30.0.1", "", {}, "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA=="], + "jest-regex-util": ["jest-regex-util@30.4.0", "", {}, "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg=="], - "jest-util": ["jest-util@30.3.0", "", { "dependencies": { "@jest/types": "30.3.0", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.3" } }, "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg=="], + "jest-util": ["jest-util@30.4.1", "", { "dependencies": { "@jest/types": "30.4.1", "@types/node": "*", "chalk": "^4.1.2", "ci-info": "^4.2.0", "graceful-fs": "^4.2.11", "picomatch": "^4.0.3" } }, "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw=="], - "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], @@ -765,7 +767,7 @@ "jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="], - "junit-report-builder": ["junit-report-builder@5.1.1", "", { "dependencies": { "lodash": "^4.17.21", "make-dir": "^3.1.0", "xmlbuilder": "^15.1.1" } }, "sha512-ZNOIIGMzqCGcHQEA2Q4rIQQ3Df6gSIfne+X9Rly9Bc2y55KxAZu8iGv+n2pP0bLf0XAOctJZgeloC54hWzCahQ=="], + "junit-report-builder": ["junit-report-builder@5.1.2", "", { "dependencies": { "lodash": "^4.18.1", "make-dir": "^3.1.0", "xmlbuilder": "^15.1.1" } }, "sha512-HzvLbEQcoqN2LmGnloShxu2hLadi/rkOTU3zt61UeMICLS0wGDvbf8neIi6+bGkxMnAePIcFMFnbqV+r6YvwxA=="], "lazystream": ["lazystream@1.0.1", "", { "dependencies": { "readable-stream": "^2.0.5" } }, "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw=="], @@ -825,7 +827,7 @@ "long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="], - "lru-cache": ["lru-cache@11.3.3", "", {}, "sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ=="], + "lru-cache": ["lru-cache@11.3.6", "", {}, "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], @@ -857,7 +859,7 @@ "mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="], - "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], "netmask": ["netmask@2.1.1", "", {}, "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA=="], @@ -879,11 +881,11 @@ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], - "oxfmt": ["oxfmt@0.43.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.43.0", "@oxfmt/binding-android-arm64": "0.43.0", "@oxfmt/binding-darwin-arm64": "0.43.0", "@oxfmt/binding-darwin-x64": "0.43.0", "@oxfmt/binding-freebsd-x64": "0.43.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.43.0", "@oxfmt/binding-linux-arm-musleabihf": "0.43.0", "@oxfmt/binding-linux-arm64-gnu": "0.43.0", "@oxfmt/binding-linux-arm64-musl": "0.43.0", "@oxfmt/binding-linux-ppc64-gnu": "0.43.0", "@oxfmt/binding-linux-riscv64-gnu": "0.43.0", "@oxfmt/binding-linux-riscv64-musl": "0.43.0", "@oxfmt/binding-linux-s390x-gnu": "0.43.0", "@oxfmt/binding-linux-x64-gnu": "0.43.0", "@oxfmt/binding-linux-x64-musl": "0.43.0", "@oxfmt/binding-openharmony-arm64": "0.43.0", "@oxfmt/binding-win32-arm64-msvc": "0.43.0", "@oxfmt/binding-win32-ia32-msvc": "0.43.0", "@oxfmt/binding-win32-x64-msvc": "0.43.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-KTYNG5ISfHSdmeZ25Xzb3qgz9EmQvkaGAxgBY/p38+ZiAet3uZeu7FnMwcSQJg152Qwl0wnYAxDc+Z/H6cvrwA=="], + "oxfmt": ["oxfmt@0.46.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.46.0", "@oxfmt/binding-android-arm64": "0.46.0", "@oxfmt/binding-darwin-arm64": "0.46.0", "@oxfmt/binding-darwin-x64": "0.46.0", "@oxfmt/binding-freebsd-x64": "0.46.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.46.0", "@oxfmt/binding-linux-arm-musleabihf": "0.46.0", "@oxfmt/binding-linux-arm64-gnu": "0.46.0", "@oxfmt/binding-linux-arm64-musl": "0.46.0", "@oxfmt/binding-linux-ppc64-gnu": "0.46.0", "@oxfmt/binding-linux-riscv64-gnu": "0.46.0", "@oxfmt/binding-linux-riscv64-musl": "0.46.0", "@oxfmt/binding-linux-s390x-gnu": "0.46.0", "@oxfmt/binding-linux-x64-gnu": "0.46.0", "@oxfmt/binding-linux-x64-musl": "0.46.0", "@oxfmt/binding-openharmony-arm64": "0.46.0", "@oxfmt/binding-win32-arm64-msvc": "0.46.0", "@oxfmt/binding-win32-ia32-msvc": "0.46.0", "@oxfmt/binding-win32-x64-msvc": "0.46.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-CopwJOwPAjZ9p76fCvz+mSOJTw9/NY3cSksZK3VO/bUQ8UoEcketNgUuYS0UB3p+R9XnXe7wGGXUmyFxc7QxJA=="], - "oxlint": ["oxlint@1.58.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.58.0", "@oxlint/binding-android-arm64": "1.58.0", "@oxlint/binding-darwin-arm64": "1.58.0", "@oxlint/binding-darwin-x64": "1.58.0", "@oxlint/binding-freebsd-x64": "1.58.0", "@oxlint/binding-linux-arm-gnueabihf": "1.58.0", "@oxlint/binding-linux-arm-musleabihf": "1.58.0", "@oxlint/binding-linux-arm64-gnu": "1.58.0", "@oxlint/binding-linux-arm64-musl": "1.58.0", "@oxlint/binding-linux-ppc64-gnu": "1.58.0", "@oxlint/binding-linux-riscv64-gnu": "1.58.0", "@oxlint/binding-linux-riscv64-musl": "1.58.0", "@oxlint/binding-linux-s390x-gnu": "1.58.0", "@oxlint/binding-linux-x64-gnu": "1.58.0", "@oxlint/binding-linux-x64-musl": "1.58.0", "@oxlint/binding-openharmony-arm64": "1.58.0", "@oxlint/binding-win32-arm64-msvc": "1.58.0", "@oxlint/binding-win32-ia32-msvc": "1.58.0", "@oxlint/binding-win32-x64-msvc": "1.58.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-t4s9leczDMqlvOSjnbCQe7gtoLkWgBGZ7sBdCJ9EOj5IXFSG/X7OAzK4yuH4iW+4cAYe8kLFbC8tuYMwWZm+Cg=="], + "oxlint": ["oxlint@1.61.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.61.0", "@oxlint/binding-android-arm64": "1.61.0", "@oxlint/binding-darwin-arm64": "1.61.0", "@oxlint/binding-darwin-x64": "1.61.0", "@oxlint/binding-freebsd-x64": "1.61.0", "@oxlint/binding-linux-arm-gnueabihf": "1.61.0", "@oxlint/binding-linux-arm-musleabihf": "1.61.0", "@oxlint/binding-linux-arm64-gnu": "1.61.0", "@oxlint/binding-linux-arm64-musl": "1.61.0", "@oxlint/binding-linux-ppc64-gnu": "1.61.0", "@oxlint/binding-linux-riscv64-gnu": "1.61.0", "@oxlint/binding-linux-riscv64-musl": "1.61.0", "@oxlint/binding-linux-s390x-gnu": "1.61.0", "@oxlint/binding-linux-x64-gnu": "1.61.0", "@oxlint/binding-linux-x64-musl": "1.61.0", "@oxlint/binding-openharmony-arm64": "1.61.0", "@oxlint/binding-win32-arm64-msvc": "1.61.0", "@oxlint/binding-win32-ia32-msvc": "1.61.0", "@oxlint/binding-win32-x64-msvc": "1.61.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-ZC0ALuhDZ6ivOFG+sy0D0pEDN49EvsId98zVlmYdkcXHsEM14m/qTNUEsUpiFiCVbpIxYtVBmmLE87nsbUHohQ=="], - "oxlint-tsgolint": ["oxlint-tsgolint@0.20.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.20.0", "@oxlint-tsgolint/darwin-x64": "0.20.0", "@oxlint-tsgolint/linux-arm64": "0.20.0", "@oxlint-tsgolint/linux-x64": "0.20.0", "@oxlint-tsgolint/win32-arm64": "0.20.0", "@oxlint-tsgolint/win32-x64": "0.20.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-/Uc9TQyN1l8w9QNvXtVHYtz+SzDJHKpb5X0UnHodl0BVzijUPk0LPlDOHAvogd1UI+iy9ZSF6gQxEqfzUxCULQ=="], + "oxlint-tsgolint": ["oxlint-tsgolint@0.22.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.22.0", "@oxlint-tsgolint/darwin-x64": "0.22.0", "@oxlint-tsgolint/linux-arm64": "0.22.0", "@oxlint-tsgolint/linux-x64": "0.22.0", "@oxlint-tsgolint/win32-arm64": "0.22.0", "@oxlint-tsgolint/win32-x64": "0.22.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-ku4MecLmCQIj1ScCtzNAqTuyl0BJQ02B36fJT+c5XQihHpYSFak+FC3GYO5fPyYk4oDwi0w0S7hTvrpNzuZhig=="], "p-limit": ["p-limit@4.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ=="], @@ -923,15 +925,15 @@ "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], - "pixelmatch": ["pixelmatch@7.1.0", "", { "dependencies": { "pngjs": "^7.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "sha512-1wrVzJ2STrpmONHKBy228LM1b84msXDUoAzVEl0R8Mz4Ce6EPr+IVtxm8+yvrqLYMHswREkjYFaMxnyGnaY3Ng=="], + "pixelmatch": ["pixelmatch@7.2.0", "", { "dependencies": { "pngjs": "^7.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "sha512-xhcb4yHu9sM/G7foGzoLtXYcC0zHEaOXXjRKhGup0fw78Nf2Tkiapv4EQyMzrbcmQPsllAI7DbFY2UT7PlI9Pg=="], "pngjs": ["pngjs@7.0.0", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="], "polka": ["polka@0.5.2", "", { "dependencies": { "@polka/url": "^0.5.0", "trouter": "^2.0.1" } }, "sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw=="], - "postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], + "postcss": ["postcss@8.5.14", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg=="], - "pretty-format": ["pretty-format@30.3.0", "", { "dependencies": { "@jest/schemas": "30.0.5", "ansi-styles": "^5.2.0", "react-is": "^18.3.1" } }, "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ=="], + "pretty-format": ["pretty-format@30.4.1", "", { "dependencies": { "@jest/schemas": "30.4.1", "ansi-styles": "^5.2.0", "react-is-18": "npm:react-is@^18.3.1", "react-is-19": "npm:react-is@^19.2.5" } }, "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw=="], "pretty-ms": ["pretty-ms@9.3.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ=="], @@ -941,7 +943,7 @@ "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], - "protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="], + "protobufjs": ["protobufjs@7.5.7", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.1", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-NGnrxS/nLKUo5nkbVQxlC71sB4hdfImdYIbFeSCidxtwATx0AHRPcANSLd0q5Bb2BkoSWo2iisQhGg5/r+ihbA=="], "proxy-agent": ["proxy-agent@6.5.0", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.5" } }, "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A=="], @@ -953,7 +955,9 @@ "randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="], - "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + "react-is-18": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + + "react-is-19": ["react-is@19.2.6", "", {}, "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw=="], "read-pkg": ["read-pkg@8.1.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" } }, "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ=="], @@ -985,13 +989,13 @@ "safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], - "safe-regex2": ["safe-regex2@5.1.0", "", { "dependencies": { "ret": "~0.5.0" }, "bin": { "safe-regex2": "bin/safe-regex2.js" } }, "sha512-pNHAuBW7TrcleFHsxBr5QMi/Iyp0ENjUKz7GCcX1UO7cMh+NmVK6HxQckNL1tJp1XAJVjG6B8OKIPqodqj9rtw=="], + "safe-regex2": ["safe-regex2@5.1.1", "", { "dependencies": { "ret": "~0.5.0" }, "bin": { "safe-regex2": "bin/safe-regex2.js" } }, "sha512-mOSBvHGDZMuIEZMdOz/aCEYDCv0E7nfcNsIhUF+/P+xC7Hyf3FkvymqgPbg9D1EdSGu+uKbJgy09K/RKKc7kJA=="], "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="], "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], - "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + "semver": ["semver@7.8.0", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA=="], "serialize-error": ["serialize-error@12.0.0", "", { "dependencies": { "type-fest": "^4.31.0" } }, "sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw=="], @@ -1011,7 +1015,7 @@ "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], - "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], + "socks": ["socks@2.8.9", "", { "dependencies": { "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" } }, "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw=="], "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], @@ -1033,7 +1037,7 @@ "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="], - "std-env": ["std-env@4.0.0", "", {}, "sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ=="], + "std-env": ["std-env@4.1.0", "", {}, "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ=="], "stream-buffers": ["stream-buffers@3.0.3", "", {}, "sha512-pqMqwQCso0PBJt2PQmDO0cFj0lyqmiwOMiMSkVtRokl7e+ZTRYgDHKnuZNbqjiJXgsg4nuqtD/zxuo9KqTp0Yw=="], @@ -1055,15 +1059,15 @@ "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], - "strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], + "strnum": ["strnum@2.3.0", "", {}, "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q=="], "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], - "tar": ["tar@7.5.13", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng=="], + "tar": ["tar@7.5.15", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ=="], "tar-fs": ["tar-fs@3.1.2", "", { "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" }, "optionalDependencies": { "bare-fs": "^4.0.1", "bare-path": "^3.0.0" } }, "sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw=="], - "tar-stream": ["tar-stream@3.1.8", "", { "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ=="], + "tar-stream": ["tar-stream@3.2.0", "", { "dependencies": { "b4a": "^1.6.4", "bare-fs": "^4.5.5", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg=="], "teex": ["teex@1.0.1", "", { "dependencies": { "streamx": "^2.12.5" } }, "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg=="], @@ -1071,7 +1075,7 @@ "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], - "tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], + "tinyexec": ["tinyexec@1.1.2", "", {}, "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA=="], "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="], @@ -1097,9 +1101,9 @@ "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], - "typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], - "undici": ["undici@6.24.1", "", {}, "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA=="], + "undici": ["undici@6.25.0", "", {}, "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg=="], "undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], @@ -1111,13 +1115,13 @@ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - "uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="], + "uuid": ["uuid@11.1.1", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ=="], "validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="], - "vite": ["@voidzero-dev/vite-plus-core@0.1.16", "", { "dependencies": { "@oxc-project/runtime": "=0.123.0", "@oxc-project/types": "=0.123.0", "lightningcss": "^1.30.2", "postcss": "^8.5.6" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.21.7", "@tsdown/exe": "0.21.7", "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "publint": "^0.3.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0", "yaml": "^2.4.2" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "publint", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "typescript", "unplugin-unused", "yaml"] }, "sha512-fOyf14CXjcXqANFs2fCXEX+0Tn9ZjmqfFV+qTnARwIF1Kzl8WquO4XtvlDgs/fTQ91H4AyoNUgkvWdKS+C4xYA=="], + "vite": ["@voidzero-dev/vite-plus-core@0.1.20", "", { "dependencies": { "@oxc-project/runtime": "=0.127.0", "@oxc-project/types": "=0.127.0", "lightningcss": "^1.30.2", "postcss": "^8.5.6" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.21.10", "@tsdown/exe": "0.21.10", "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "publint": "^0.3.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0", "yaml": "^2.4.2" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "publint", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "typescript", "unplugin-unused", "yaml"] }, "sha512-4KmzRfzwTeG3JuvDijrdqWusSgRvLMKDPrVsDdtbDVVjEMq0VnM8lSH+Nvepd6Pg+SuSVUP212OIfH/3Yn1bfA=="], - "vite-plus": ["vite-plus@0.1.16", "", { "dependencies": { "@oxc-project/types": "=0.123.0", "@voidzero-dev/vite-plus-core": "0.1.16", "@voidzero-dev/vite-plus-test": "0.1.16", "oxfmt": "=0.43.0", "oxlint": "=1.58.0", "oxlint-tsgolint": "=0.20.0" }, "optionalDependencies": { "@voidzero-dev/vite-plus-darwin-arm64": "0.1.16", "@voidzero-dev/vite-plus-darwin-x64": "0.1.16", "@voidzero-dev/vite-plus-linux-arm64-gnu": "0.1.16", "@voidzero-dev/vite-plus-linux-arm64-musl": "0.1.16", "@voidzero-dev/vite-plus-linux-x64-gnu": "0.1.16", "@voidzero-dev/vite-plus-linux-x64-musl": "0.1.16", "@voidzero-dev/vite-plus-win32-arm64-msvc": "0.1.16", "@voidzero-dev/vite-plus-win32-x64-msvc": "0.1.16" }, "bin": { "vp": "bin/vp", "oxfmt": "bin/oxfmt", "oxlint": "bin/oxlint" } }, "sha512-sgYHc5zWLSDInaHb/abvEA7UOwh7sUWuyNt+Slphj55jPvzodT8Dqw115xyKwDARTuRFSpm1eo/t58qZ8/NylQ=="], + "vite-plus": ["vite-plus@0.1.20", "", { "dependencies": { "@oxc-project/types": "=0.127.0", "@voidzero-dev/vite-plus-core": "0.1.20", "@voidzero-dev/vite-plus-test": "0.1.20", "oxfmt": "=0.46.0", "oxlint": "=1.61.0", "oxlint-tsgolint": "=0.22.0" }, "optionalDependencies": { "@voidzero-dev/vite-plus-darwin-arm64": "0.1.20", "@voidzero-dev/vite-plus-darwin-x64": "0.1.20", "@voidzero-dev/vite-plus-linux-arm64-gnu": "0.1.20", "@voidzero-dev/vite-plus-linux-arm64-musl": "0.1.20", "@voidzero-dev/vite-plus-linux-x64-gnu": "0.1.20", "@voidzero-dev/vite-plus-linux-x64-musl": "0.1.20", "@voidzero-dev/vite-plus-win32-arm64-msvc": "0.1.20", "@voidzero-dev/vite-plus-win32-x64-msvc": "0.1.20" }, "bin": { "vp": "bin/vp", "oxfmt": "bin/oxfmt", "oxlint": "bin/oxlint" } }, "sha512-hxJqXTxiiFhszwAeD0MvKlztVuXE4TztTdJ64BPxGqgY67F0PDa5eZkUsrN91Ae8aYUMfweW6V/J57OUO9/0zw=="], "wait-port": ["wait-port@1.1.0", "", { "dependencies": { "chalk": "^4.1.2", "commander": "^9.3.0", "debug": "^4.3.4" }, "bin": { "wait-port": "bin/wait-port.js" } }, "sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q=="], @@ -1125,9 +1129,9 @@ "web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="], - "webdriver": ["webdriver@9.27.0", "", { "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", "@wdio/config": "9.27.0", "@wdio/logger": "9.18.0", "@wdio/protocols": "9.27.0", "@wdio/types": "9.27.0", "@wdio/utils": "9.27.0", "deepmerge-ts": "^7.0.3", "https-proxy-agent": "^7.0.6", "undici": "^6.21.3", "ws": "^8.8.0" } }, "sha512-w07ThZND48SIr0b4S7eFougYUyclmoUwdmju8yXvEJiXYjDjeYUpl8wZrYPEYRBylxpSx+sBHfEUBrPQkcTTRQ=="], + "webdriver": ["webdriver@9.27.1", "", { "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", "@wdio/config": "9.27.1", "@wdio/logger": "9.18.0", "@wdio/protocols": "9.27.1", "@wdio/types": "9.27.1", "@wdio/utils": "9.27.1", "deepmerge-ts": "^7.0.3", "https-proxy-agent": "^7.0.6", "undici": "^6.21.3", "ws": "^8.8.0" } }, "sha512-vr6h+RNQ75O2cofgVrdupGxtKjPEBaBYx/lHCHe0giJfAK01oL0U/yrOksJi7kmpev/daN93ldFPhlIlmWtv8Q=="], - "webdriverio": ["webdriverio@9.27.0", "", { "dependencies": { "@types/node": "^20.11.30", "@types/sinonjs__fake-timers": "^8.1.5", "@wdio/config": "9.27.0", "@wdio/logger": "9.18.0", "@wdio/protocols": "9.27.0", "@wdio/repl": "9.16.2", "@wdio/types": "9.27.0", "@wdio/utils": "9.27.0", "archiver": "^7.0.1", "aria-query": "^5.3.0", "cheerio": "^1.0.0-rc.12", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", "grapheme-splitter": "^1.0.4", "htmlfy": "^0.8.1", "is-plain-obj": "^4.1.0", "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "query-selector-shadow-dom": "^1.0.1", "resq": "^1.11.0", "rgb2hex": "0.2.5", "serialize-error": "^12.0.0", "urlpattern-polyfill": "^10.0.0", "webdriver": "9.27.0" }, "peerDependencies": { "puppeteer-core": ">=22.x || <=24.x" }, "optionalPeers": ["puppeteer-core"] }, "sha512-Y4FbMf4bKBXpPB0lYpglzQ2GfDDe6uojmMZl85uPyrDx18NW7mqN84ZawGoIg/FRvcLaVhcOzc98WOPo725Rag=="], + "webdriverio": ["webdriverio@9.27.1", "", { "dependencies": { "@types/node": "^20.11.30", "@types/sinonjs__fake-timers": "^8.1.5", "@wdio/config": "9.27.1", "@wdio/logger": "9.18.0", "@wdio/protocols": "9.27.1", "@wdio/repl": "9.16.2", "@wdio/types": "9.27.1", "@wdio/utils": "9.27.1", "archiver": "^7.0.1", "aria-query": "^5.3.0", "cheerio": "^1.0.0-rc.12", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", "grapheme-splitter": "^1.0.4", "htmlfy": "^0.8.1", "is-plain-obj": "^4.1.0", "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", "query-selector-shadow-dom": "^1.0.1", "resq": "^1.11.0", "rgb2hex": "0.2.5", "serialize-error": "^12.0.0", "urlpattern-polyfill": "^10.0.0", "webdriver": "9.27.1" }, "peerDependencies": { "puppeteer-core": ">=22.x || <=24.x" }, "optionalPeers": ["puppeteer-core"] }, "sha512-iPaIU/DluYY7zfLiwXDdoLU/6ZW8eup4PNwQikrCzTfvH/ITllRhFUe6NRDTEEePSxxRTeXAn9nehCs98xWGVA=="], "whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="], @@ -1147,6 +1151,8 @@ "ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], + "xml-naming": ["xml-naming@0.1.0", "", {}, "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw=="], + "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], @@ -1177,23 +1183,23 @@ "@jest/types/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], - "@vitest/utils/@vitest/pretty-format": ["@vitest/pretty-format@4.1.4", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A=="], + "@vitest/utils/@vitest/pretty-format": ["@vitest/pretty-format@4.1.6", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw=="], "@vitest/utils/tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], "@wdio/config/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], - "@wdio/local-runner/@types/node": ["@types/node@20.19.39", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw=="], + "@wdio/local-runner/@types/node": ["@types/node@20.19.40", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xxx6M2IpSTnnKcR0cMvIiohkiCx20/oRPtWGbenFygKCGl3zqUzdNjQ/1V4solq1LU+dgv0nQzeGOuqkqZGg0Q=="], - "@wdio/mocha-framework/@types/node": ["@types/node@20.19.39", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw=="], + "@wdio/mocha-framework/@types/node": ["@types/node@20.19.40", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xxx6M2IpSTnnKcR0cMvIiohkiCx20/oRPtWGbenFygKCGl3zqUzdNjQ/1V4solq1LU+dgv0nQzeGOuqkqZGg0Q=="], - "@wdio/repl/@types/node": ["@types/node@20.19.39", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw=="], + "@wdio/repl/@types/node": ["@types/node@20.19.40", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xxx6M2IpSTnnKcR0cMvIiohkiCx20/oRPtWGbenFygKCGl3zqUzdNjQ/1V4solq1LU+dgv0nQzeGOuqkqZGg0Q=="], - "@wdio/reporter/@types/node": ["@types/node@20.19.39", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw=="], + "@wdio/reporter/@types/node": ["@types/node@20.19.40", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xxx6M2IpSTnnKcR0cMvIiohkiCx20/oRPtWGbenFygKCGl3zqUzdNjQ/1V4solq1LU+dgv0nQzeGOuqkqZGg0Q=="], - "@wdio/runner/@types/node": ["@types/node@20.19.39", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw=="], + "@wdio/runner/@types/node": ["@types/node@20.19.40", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xxx6M2IpSTnnKcR0cMvIiohkiCx20/oRPtWGbenFygKCGl3zqUzdNjQ/1V4solq1LU+dgv0nQzeGOuqkqZGg0Q=="], - "@wdio/types/@types/node": ["@types/node@20.19.39", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw=="], + "@wdio/types/@types/node": ["@types/node@20.19.40", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xxx6M2IpSTnnKcR0cMvIiohkiCx20/oRPtWGbenFygKCGl3zqUzdNjQ/1V4solq1LU+dgv0nQzeGOuqkqZGg0Q=="], "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], @@ -1207,7 +1213,7 @@ "archiver-utils/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - "cheerio/undici": ["undici@7.24.7", "", {}, "sha512-H/nlJ/h0ggGC+uRL3ovD+G0i4bqhvsDOpbDv7At5eFLlj2b41L8QliGbnl2H7SnDiYhENphh1tQFJZf+MyfLsQ=="], + "cheerio/undici": ["undici@7.25.0", "", {}, "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ=="], "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -1223,7 +1229,7 @@ "edgedriver/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], - "expect-webdriverio/@vitest/snapshot": ["@vitest/snapshot@4.1.4", "", { "dependencies": { "@vitest/pretty-format": "4.1.4", "@vitest/utils": "4.1.4", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-MCjCFgaS8aZz+m5nTcEcgk/xhWv0rEH4Yl53PPlMXOZ1/Ka2VcZU6CJ+MgYCZbcJvzGhQRjVrGQNZqkGPttIKw=="], + "expect-webdriverio/@vitest/snapshot": ["@vitest/snapshot@4.1.6", "", { "dependencies": { "@vitest/pretty-format": "4.1.6", "@vitest/utils": "4.1.6", "magic-string": "^0.30.21", "pathe": "^2.0.3" } }, "sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw=="], "extract-zip/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], @@ -1319,11 +1325,11 @@ "wait-port/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], - "webdriver/@types/node": ["@types/node@20.19.39", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw=="], + "webdriver/@types/node": ["@types/node@20.19.40", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xxx6M2IpSTnnKcR0cMvIiohkiCx20/oRPtWGbenFygKCGl3zqUzdNjQ/1V4solq1LU+dgv0nQzeGOuqkqZGg0Q=="], "webdriver/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], - "webdriverio/@types/node": ["@types/node@20.19.39", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw=="], + "webdriverio/@types/node": ["@types/node@20.19.40", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-xxx6M2IpSTnnKcR0cMvIiohkiCx20/oRPtWGbenFygKCGl3zqUzdNjQ/1V4solq1LU+dgv0nQzeGOuqkqZGg0Q=="], "wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -1369,11 +1375,11 @@ "edgedriver/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - "expect-webdriverio/@vitest/snapshot/@vitest/pretty-format": ["@vitest/pretty-format@4.1.4", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-ddmDHU0gjEUyEVLxtZa7xamrpIefdEETu3nZjWtHeZX4QxqJ7tRxSteHVXJOcr8jhiLoGAhkK4WJ3WqBpjx42A=="], + "expect-webdriverio/@vitest/snapshot/@vitest/pretty-format": ["@vitest/pretty-format@4.1.6", "", { "dependencies": { "tinyrainbow": "^3.1.0" } }, "sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw=="], "expect-webdriverio/@vitest/snapshot/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], - "filelist/minimatch/brace-expansion": ["brace-expansion@2.0.3", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA=="], + "filelist/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], "geckodriver/https-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], @@ -1397,15 +1403,15 @@ "mocha/find-up/path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], - "mocha/minimatch/brace-expansion": ["brace-expansion@2.0.3", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA=="], + "mocha/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], "mocha/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], "read-pkg/normalize-package-data/hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], - "readdir-glob/minimatch/brace-expansion": ["brace-expansion@2.0.3", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA=="], + "readdir-glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], - "recursive-readdir/minimatch/brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="], + "recursive-readdir/minimatch/brace-expansion": ["brace-expansion@1.1.14", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g=="], "wait-port/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], @@ -1417,13 +1423,13 @@ "@wdio/config/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "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" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], - "@wdio/config/glob/minimatch/brace-expansion": ["brace-expansion@2.0.3", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA=="], + "@wdio/config/glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], "@wdio/config/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "archiver-utils/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "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" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], - "archiver-utils/glob/minimatch/brace-expansion": ["brace-expansion@2.0.3", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA=="], + "archiver-utils/glob/minimatch/brace-expansion": ["brace-expansion@2.1.0", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w=="], "archiver-utils/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], diff --git a/appium/package.json b/appium/package.json index cdfbe90..baa995d 100644 --- a/appium/package.json +++ b/appium/package.json @@ -9,22 +9,22 @@ "test:ios": "wdio run wdio.ios.conf.ts" }, "devDependencies": { - "@types/node": "^25.6.0", - "@wdio/browserstack-service": "^9.27.0", - "@wdio/cli": "^9.27.0", - "@wdio/junit-reporter": "^9.27.0", - "@wdio/local-runner": "^9.27.0", - "@wdio/mocha-framework": "^9.27.0", + "@types/node": "^25.6.2", + "@wdio/browserstack-service": "^9.27.1", + "@wdio/cli": "^9.27.1", + "@wdio/junit-reporter": "^9.27.1", + "@wdio/local-runner": "^9.27.1", + "@wdio/mocha-framework": "^9.27.1", "@wdio/shared-store-service": "^9.27.0", - "@wdio/spec-reporter": "^9.27.0", + "@wdio/spec-reporter": "^9.27.1", "tsx": "^4.21.0", - "typescript": "^6.0.2", - "vite-plus": "latest", - "webdriverio": "^9.27.0" + "typescript": "^6.0.3", + "vite-plus": "0.1.20", + "webdriverio": "^9.27.1" }, "overrides": { - "vite": "npm:@voidzero-dev/vite-plus-core@latest", - "vitest": "npm:@voidzero-dev/vite-plus-test@latest" + "vite": "npm:@voidzero-dev/vite-plus-core@0.1.20", + "vitest": "npm:@voidzero-dev/vite-plus-test@0.1.20" }, - "packageManager": "bun@1.3.12" + "packageManager": "bun@1.3.13" } diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 352e844..79dfb97 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -1494,7 +1494,23 @@ start_device() { } # ── 2. Start Appium ────────────────────────────────────────────────────────── +# Kill leftover WDA processes from prior runs. Appium aborts WDA with +# `SIGABRT` when it can't bind to port 8100 (its default), and the most +# common holder of 8100 is a stale `WebDriverAgentRunner-Runner` from an +# earlier crashed attempt or a Ctrl-C'd session. The accompanying +# `xcodebuild` wrapper also hangs onto its derived data lock. Killing +# both is cheap when nothing's running and prevents the cascading +# "Address already in use" → `xcodebuild exited with code 65` → wdio +# "Unable to start WebDriverAgent session" failure mode. +cleanup_stale_wda() { + [[ "$PLATFORM" == "ios" ]] || return 0 + pkill -9 -f "WebDriverAgentRunner-Runner" 2>/dev/null || true + pkill -9 -f "xcodebuild.*WebDriverAgent" 2>/dev/null || true +} + start_appium() { + cleanup_stale_wda + if curl -s "http://localhost:$APPIUM_PORT/status" | grep -q '"ready":true' 2>/dev/null; then info "Appium already running on port $APPIUM_PORT" return From 79e1126e34afe4577026c158f92801862958b179 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Mon, 11 May 2026 18:08:40 -0700 Subject: [PATCH 11/31] chore(appium): bump Unity to 6000.4.6f1, deduplicate xcodebuild --- appium/scripts/run-local.sh | 39 +++++++++++++++---------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 79dfb97..656aff3 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -270,7 +270,7 @@ elif [[ "$SDK_TYPE" == "unity" ]]; then UNITY_DIR="${UNITY_DIR:-$SDK_ROOT/OneSignal-Unity-SDK}" [[ -d "$UNITY_DIR" ]] || error "Unity SDK not found at $UNITY_DIR — set UNITY_DIR in .env" DEMO_DIR="$UNITY_DIR/examples/demo" - UNITY_PATH="${UNITY_PATH:-/Applications/Unity/Hub/Editor/6000.3.6f1/Unity.app/Contents/MacOS/Unity}" + UNITY_PATH="${UNITY_PATH:-/Applications/Unity/Hub/Editor/6000.4.6f1/Unity.app/Contents/MacOS/Unity}" if [[ "$PLATFORM" == "ios" ]]; then # Unity batchmode emits an Xcode project under Build/iOS named # `Unity-iPhone.xcodeproj` (a fixed Unity convention), but the *product* @@ -1256,32 +1256,25 @@ build_unity_ios() { local ws="$xcode_dir/Unity-iPhone.xcworkspace" info "Building release .app for simulator..." + local target_args if [[ -d "$ws" ]]; then - xcodebuild \ - -workspace "$ws" \ - -scheme Unity-iPhone \ - -configuration Release \ - -sdk iphonesimulator \ - -derivedDataPath "$derived" \ - -quiet \ - ONLY_ACTIVE_ARCH=YES \ - CODE_SIGN_IDENTITY="-" \ - CODE_SIGNING_ALLOWED=YES \ - build + target_args=(-workspace "$ws") else - xcodebuild \ - -project "$xcode_dir/Unity-iPhone.xcodeproj" \ - -scheme Unity-iPhone \ - -configuration Release \ - -sdk iphonesimulator \ - -derivedDataPath "$derived" \ - -quiet \ - ONLY_ACTIVE_ARCH=YES \ - CODE_SIGN_IDENTITY="-" \ - CODE_SIGNING_ALLOWED=YES \ - build + target_args=(-project "$xcode_dir/Unity-iPhone.xcodeproj") fi + xcodebuild \ + "${target_args[@]}" \ + -scheme Unity-iPhone \ + -configuration Release \ + -sdk iphonesimulator \ + -derivedDataPath "$derived" \ + -quiet \ + ONLY_ACTIVE_ARCH=YES \ + CODE_SIGN_IDENTITY="-" \ + CODE_SIGNING_ALLOWED=YES \ + build + if [[ ! -d "$APP_PATH" ]]; then # Fallback: Unity's product name (and thus the .app filename) is set in # Player Settings, so it can drift from our default. Search the derived From 93433fc56342128aff64efa2728b7248dbacfeb0 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 12 May 2026 00:00:19 -0700 Subject: [PATCH 12/31] fix(appium): avoid accidental taps on Unity iOS --- appium/tests/helpers/app.ts | 73 ++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 17 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index a2eb366..504a6aa 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -34,7 +34,15 @@ async function swipeMainContent(direction: 'up' | 'down', distance: 'small' | 'n // Coordinates must be integers in WebView contexts (Capacitor/Cordova), // where chromedriver enforces W3C `actions` typing strictly. Native // UiAutomator2/XCUITest tolerate floats but rounding is harmless there. - const centerX = Math.round(width / 2); + // Unity iOS: anchor in the left section-padding gutter (x≈10pt; sections + // pad 16pt). XCUITest swipes can otherwise land PointerDown on a centered + // button and trigger AccessibilityBridge's E2E tap fallback before the + // drag generates enough PointerMove distance to cancel it (fast `mobile: + // scroll` gestures sometimes report Down/Up without intermediate Move). + // Other SDKs route swipes through native scroll containers that don't + // dispatch into our element handlers, so center is fine. + const swipeX = + sdkType === 'unity' && getPlatform() === 'ios' ? 10 : Math.round(width / 2); const startY = Math.round(direction === 'down' ? height * 0.85 : height * 0.15); const endY = Math.round(direction === 'down' ? startY - swipeDistance : startY + swipeDistance); @@ -51,10 +59,10 @@ async function swipeMainContent(direction: 'up' | 'down', distance: 'small' | 'n const SWIPE_TIMEOUT_MS = 5_000; const action = browser .action('pointer', { parameters: { pointerType: 'touch' } }) - .move({ x: centerX, y: startY }) + .move({ x: swipeX, y: startY }) .down() .pause(50) - .move({ duration: moveDurationMs, x: centerX, y: endY }) + .move({ duration: moveDurationMs, x: swipeX, y: endY }) .up() .perform(); let timer: NodeJS.Timeout | undefined; @@ -123,10 +131,15 @@ export async function scrollToEl( // Native fast path: pre-warms the scroll view so the loop below either // returns immediately or has very little work left. + // Unity iOS opts out: `mobile: scroll` synthesizes its own center-anchored + // touch sequence on the scroll view that can't be moved off the button + // column, so it reproduces the same accidental-tap problem we avoid in + // `swipeMainContent` by anchoring at the left gutter. Falling through to + // the swipe loop costs ~200ms but never taps a button. if (direction === 'down' && !isFlutterSDK) { if (platform === 'android') { await tryNativeScrollAndroid(identifier); - } else { + } else if (sdkType !== 'unity') { await tryNativeScrollIos(identifier); } } @@ -256,7 +269,12 @@ async function isVisibleInViewport( } } -async function scrollExtraIfNeeded }>( +async function scrollExtraIfNeeded< + T extends { + getLocation(): Promise<{ y: number }>; + getSize(): Promise<{ height: number }>; + }, +>( el: T, refetch: () => Promise, ): Promise { @@ -268,22 +286,39 @@ async function scrollExtraIfNeeded height - threshold) { - await swipeMainContent('down', 'small'); - return await refetch(); + for (let i = 0; i < 3; i++) { + const [{ y }, size, { height }] = await Promise.all([ + current.getLocation(), + current.getSize(), + driver.getWindowSize(), + ]); + const threshold = Math.round(height * 0.12); + if (y >= threshold && y + size.height <= height - threshold) return current; + + await swipeMainContent(y < threshold ? 'up' : 'down', 'small'); + current = await refetch(); } } catch { /* best-effort: if location read fails, return original ref */ } - return el; + return current; +} + +async function tapElementCenter(el: { + getLocation(): Promise<{ x: number; y: number }>; + getSize(): Promise<{ width: number; height: number }>; +}) { + const [loc, size] = await Promise.all([el.getLocation(), el.getSize()]); + const x = Math.round(loc.x + size.width / 2); + const y = Math.round(loc.y + size.height / 2); + await browser + .action('pointer', { parameters: { pointerType: 'touch' } }) + .move({ x, y }) + .down() + .up() + .perform(); } /** @@ -572,7 +607,11 @@ export async function openModal(triggerTestId: string, expectedTestId: string, f if (getSdkType() === 'unity') { await waitForStablePosition(trigger); } - await trigger.click(); + if (getSdkType() === 'unity') { + await tapElementCenter(trigger); + } else { + await trigger.click(); + } const expected = await byTestId(expectedTestId); await expected.waitForExist({ timeout: firstTryMs }); return expected; From df46b67c4c8d908c089ed48cf4c599240b6d8574 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 12 May 2026 00:08:48 -0700 Subject: [PATCH 13/31] refactor(appium): add waitForTestIdNotDisplayed helper --- appium/scripts/run-local.sh | 5 +++++ appium/tests/helpers/app.ts | 26 +++++++++++++++++--------- appium/tests/specs/07_tag.spec.ts | 10 ++++------ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 656aff3..359fe87 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -114,6 +114,11 @@ USAGE esac done +case "$SPEC" in + */*|*\**|*\?*|*.ts) ;; + *) SPEC="tests/specs/${SPEC}*.spec.ts" ;; +esac + # Ensure values set via CLI flags propagate to wdio (which reads them as env). export APPIUM_PORT [[ -n "$SYSTEM_PORT" ]] && export SYSTEM_PORT diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 504a6aa..781af2f 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -41,8 +41,7 @@ async function swipeMainContent(direction: 'up' | 'down', distance: 'small' | 'n // scroll` gestures sometimes report Down/Up without intermediate Move). // Other SDKs route swipes through native scroll containers that don't // dispatch into our element handlers, so center is fine. - const swipeX = - sdkType === 'unity' && getPlatform() === 'ios' ? 10 : Math.round(width / 2); + const swipeX = sdkType === 'unity' && getPlatform() === 'ios' ? 10 : Math.round(width / 2); const startY = Math.round(direction === 'down' ? height * 0.85 : height * 0.15); const endY = Math.round(direction === 'down' ? startY - swipeDistance : startY + swipeDistance); @@ -274,10 +273,7 @@ async function scrollExtraIfNeeded< getLocation(): Promise<{ y: number }>; getSize(): Promise<{ height: number }>; }, ->( - el: T, - refetch: () => Promise, -): Promise { +>(el: T, refetch: () => Promise): Promise { // Coordinate units differ by platform: iOS XCUITest reports points, Android // UiAutomator2 reports physical pixels. A fixed pixel threshold (e.g. 100) // is enough on iOS but only ~33dp on a density-3 Android phone — well inside @@ -588,9 +584,20 @@ export async function togglePushEnabled() { export async function confirmModal(buttonTestId: string, timeoutMs = 5_000) { const btn = await byTestId(buttonTestId); await btn.click(); - // waitForExist refetches by selector each poll; waitForDisplayed would - // hit stale-element warnings against the dismissed modal's cached id. - await btn.waitForExist({ timeout: timeoutMs, reverse: true }); + await waitForTestIdNotDisplayed(buttonTestId, timeoutMs); +} + +export async function waitForTestIdNotDisplayed(testId: string, timeoutMs = 5_000) { + await browser.waitUntil( + async () => { + const el = await byTestId(testId); + return !(await el.isDisplayed().catch(() => false)); + }, + { + timeout: timeoutMs, + timeoutMsg: `Element "${testId}" still displayed after ${timeoutMs}ms`, + }, + ); } /** @@ -1089,6 +1096,7 @@ export async function checkTooltip(buttonId: string, key: string) { const okButton = await byTestId('tooltip_ok_button'); await okButton.click(); + await waitForTestIdNotDisplayed('tooltip_ok_button'); } export async function withRetryDelay( diff --git a/appium/tests/specs/07_tag.spec.ts b/appium/tests/specs/07_tag.spec.ts index f20225e..b037bc3 100644 --- a/appium/tests/specs/07_tag.spec.ts +++ b/appium/tests/specs/07_tag.spec.ts @@ -5,6 +5,7 @@ import { openModal, scrollToEl, waitForAppReady, + waitForTestIdNotDisplayed, } from '../helpers/app'; import { byTestId } from '../helpers/selectors.js'; @@ -37,8 +38,7 @@ describe('Tags', () => { const removeButton = await byTestId(`tags_remove_test_tag`); await removeButton.click(); - const el = await byTestId('tags_pair_key_test_tag'); - await el.waitForDisplayed({ timeout: 5_000, reverse: true }); + await waitForTestIdNotDisplayed('tags_pair_key_test_tag'); }); it('can add and remove multiple tags', async () => { @@ -73,9 +73,7 @@ describe('Tags', () => { // wait for tags to be removed await scrollToEl('tags_section', { direction: 'up' }); - const tag2El = await byTestId('tags_pair_key_test_tag_2'); - const tag3El = await byTestId('tags_pair_key_test_tag_3'); - await tag2El.waitForDisplayed({ timeout: 5_000, reverse: true }); - await tag3El.waitForDisplayed({ timeout: 5_000, reverse: true }); + await waitForTestIdNotDisplayed('tags_pair_key_test_tag_2'); + await waitForTestIdNotDisplayed('tags_pair_key_test_tag_3'); }); }); From 623c375a20097acc034284590fb19ec640e4565d Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 12 May 2026 00:11:56 -0700 Subject: [PATCH 14/31] refactor(appium): rename waitForTestIdNotDisplayed to waitForDisappear --- appium/tests/helpers/app.ts | 6 +++--- appium/tests/specs/07_tag.spec.ts | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 781af2f..0a74f61 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -584,10 +584,10 @@ export async function togglePushEnabled() { export async function confirmModal(buttonTestId: string, timeoutMs = 5_000) { const btn = await byTestId(buttonTestId); await btn.click(); - await waitForTestIdNotDisplayed(buttonTestId, timeoutMs); + await waitForDisappear(buttonTestId, timeoutMs); } -export async function waitForTestIdNotDisplayed(testId: string, timeoutMs = 5_000) { +export async function waitForDisappear(testId: string, timeoutMs = 5_000) { await browser.waitUntil( async () => { const el = await byTestId(testId); @@ -1096,7 +1096,7 @@ export async function checkTooltip(buttonId: string, key: string) { const okButton = await byTestId('tooltip_ok_button'); await okButton.click(); - await waitForTestIdNotDisplayed('tooltip_ok_button'); + await waitForDisappear('tooltip_ok_button'); } export async function withRetryDelay( diff --git a/appium/tests/specs/07_tag.spec.ts b/appium/tests/specs/07_tag.spec.ts index b037bc3..5aabdad 100644 --- a/appium/tests/specs/07_tag.spec.ts +++ b/appium/tests/specs/07_tag.spec.ts @@ -5,7 +5,7 @@ import { openModal, scrollToEl, waitForAppReady, - waitForTestIdNotDisplayed, + waitForDisappear, } from '../helpers/app'; import { byTestId } from '../helpers/selectors.js'; @@ -38,7 +38,7 @@ describe('Tags', () => { const removeButton = await byTestId(`tags_remove_test_tag`); await removeButton.click(); - await waitForTestIdNotDisplayed('tags_pair_key_test_tag'); + await waitForDisappear('tags_pair_key_test_tag'); }); it('can add and remove multiple tags', async () => { @@ -73,7 +73,7 @@ describe('Tags', () => { // wait for tags to be removed await scrollToEl('tags_section', { direction: 'up' }); - await waitForTestIdNotDisplayed('tags_pair_key_test_tag_2'); - await waitForTestIdNotDisplayed('tags_pair_key_test_tag_3'); + await waitForDisappear('tags_pair_key_test_tag_2'); + await waitForDisappear('tags_pair_key_test_tag_3'); }); }); From bc118f4d49a14229650c8086ba17a860eb71109b Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 12 May 2026 00:36:30 -0700 Subject: [PATCH 15/31] fix(appium): improve Unity modal confirmation --- appium/tests/helpers/app.ts | 24 +------- appium/tests/helpers/selectors.ts | 76 +++++++++++++++----------- appium/tests/specs/09_trigger.spec.ts | 10 ++-- appium/tests/specs/12_activity.spec.ts | 2 + 4 files changed, 52 insertions(+), 60 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 0a74f61..03d1283 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -115,7 +115,7 @@ export async function scrollToEl( // Safety net for `direction: 'up'` and any case where a native fast path // didn't land the element. Flutter has no fast path and uses slower swipes // (see `swipeMainContent`), so it needs a higher cap. - const { direction = 'down', maxScrolls = isFlutterSDK ? 30 : 20 } = opts; + const { direction = 'down', maxScrolls = 30 } = opts; const platform = getPlatform(); if (isWebViewSDK) { @@ -302,21 +302,6 @@ async function scrollExtraIfNeeded< return current; } -async function tapElementCenter(el: { - getLocation(): Promise<{ x: number; y: number }>; - getSize(): Promise<{ width: number; height: number }>; -}) { - const [loc, size] = await Promise.all([el.getLocation(), el.getSize()]); - const x = Math.round(loc.x + size.width / 2); - const y = Math.round(loc.y + size.height / 2); - await browser - .action('pointer', { parameters: { pointerType: 'touch' } }) - .move({ x, y }) - .down() - .up() - .perform(); -} - /** * On Android the runtime permission dialog is rendered by a separate process * (the permission controller). Polling candidate selectors when no dialog @@ -583,6 +568,7 @@ export async function togglePushEnabled() { */ export async function confirmModal(buttonTestId: string, timeoutMs = 5_000) { const btn = await byTestId(buttonTestId); + await btn.waitForEnabled({ timeout: timeoutMs }); await btn.click(); await waitForDisappear(buttonTestId, timeoutMs); } @@ -614,11 +600,7 @@ export async function openModal(triggerTestId: string, expectedTestId: string, f if (getSdkType() === 'unity') { await waitForStablePosition(trigger); } - if (getSdkType() === 'unity') { - await tapElementCenter(trigger); - } else { - await trigger.click(); - } + await trigger.click(); const expected = await byTestId(expectedTestId); await expected.waitForExist({ timeout: firstTryMs }); return expected; diff --git a/appium/tests/helpers/selectors.ts b/appium/tests/helpers/selectors.ts index d3aa638..69ea7d9 100644 --- a/appium/tests/helpers/selectors.ts +++ b/appium/tests/helpers/selectors.ts @@ -194,33 +194,48 @@ export function getSdkType(): SdkType { ); } -/** - * On Flutter Android, two interactions need shimming: - * - * - `getText()` often returns empty because Flutter writes its text into the - * `content-desc` / `text` attributes rather than the property UiAutomator2's - * getText maps to. We fall back to those attributes. - * - `setValue()` doesn't focus the field first because Flutter renders inputs - * to a Skia canvas with Semantics shims (no native EditText), so W3C - * "send keys" lands without an IME binding and the keystrokes get dropped. - * We tap the element first to bind the IME, then forward to setValue. - * - * iOS XCUITest doesn't hit either problem in practice. - */ -function withFlutterAndroidFixes< - T extends { - getText(): Promise; - setValue(value: string): Promise; - click(): Promise; - }, ->(el: T): T { - if (!(getPlatform() === 'android' && getSdkType() === 'flutter')) { +type ElementWithInteractionMethods = { + click(): Promise; + getAttribute(name: string): Promise; + getLocation(): Promise<{ x: number; y: number }>; + getSize(): Promise<{ width: number; height: number }>; + getText(): Promise; + setValue(value: string): Promise; +}; + +async function tapElementCenter(el: { + getLocation(): Promise<{ x: number; y: number }>; + getSize(): Promise<{ width: number; height: number }>; +}) { + const [loc, size] = await Promise.all([el.getLocation(), el.getSize()]); + const x = Math.round(loc.x + size.width / 2); + const y = Math.round(loc.y + size.height / 2); + await browser + .action('pointer', { parameters: { pointerType: 'touch' } }) + .move({ x, y }) + .down() + .up() + .perform(); +} + +// Centralized element shims: Unity gets raw center taps, while Flutter Android +// keeps its text fallback and focus-before-setValue behavior. +function withElementInteractionFixes(el: T): T { + const isFlutterAndroid = getPlatform() === 'android' && getSdkType() === 'flutter'; + const isUnity = getSdkType() === 'unity'; + if (!isFlutterAndroid && !isUnity) { return el; } return new Proxy(el, { get(target, prop, receiver) { - if (prop === 'getText') { + if (prop === 'click' && isUnity) { + return async () => { + await tapElementCenter(target); + }; + } + + if (prop === 'getText' && isFlutterAndroid) { return async () => { const text = (await target.getText()).trim(); if (text) return text; @@ -228,11 +243,7 @@ function withFlutterAndroidFixes< const attrs = ['content-desc', 'contentDescription', 'text', 'name']; for (const attr of attrs) { try { - const val = ( - await ( - target as unknown as { getAttribute(n: string): Promise } - ).getAttribute(attr) - )?.trim(); + const val = (await target.getAttribute(attr))?.trim(); if (val) return val; } catch { /* best-effort */ @@ -243,7 +254,7 @@ function withFlutterAndroidFixes< }; } - if (prop === 'setValue') { + if (prop === 'setValue' && isFlutterAndroid) { return async (value: string) => { await target.click(); await target.setValue(value); @@ -282,11 +293,10 @@ export async function byTestId(id: string) { if (sdkType === 'capacitor' || sdkType === 'cordova') return $(`[data-testid="${id}"]`); if (platform === 'android') { - let el = await $(`id=${id}`); - if (sdkType === 'flutter') return withFlutterAndroidFixes(el); - return el; + const el = $(`id=${id}`); + return withElementInteractionFixes(el); } - return $(`~${id}`); + return withElementInteractionFixes($(`~${id}`)); } /** @@ -306,7 +316,7 @@ export async function byText(identifier: string, partial = false) { const xpath = partial ? `//*[contains(@content-desc, "${identifier}") or contains(@text, "${identifier}")]` : `//*[@content-desc="${identifier}" or @text="${identifier}"]`; - return withFlutterAndroidFixes(await $(xpath)); + return withElementInteractionFixes($(xpath)); } return partial ? $(`android=new UiSelector().textContains("${identifier}")`) diff --git a/appium/tests/specs/09_trigger.spec.ts b/appium/tests/specs/09_trigger.spec.ts index ffc86a0..bdff5b1 100644 --- a/appium/tests/specs/09_trigger.spec.ts +++ b/appium/tests/specs/09_trigger.spec.ts @@ -5,6 +5,7 @@ import { openModal, scrollToEl, waitForAppReady, + waitForDisappear, } from '../helpers/app'; import { byTestId } from '../helpers/selectors.js'; @@ -63,8 +64,7 @@ describe('Triggers', () => { const removeButton = await byTestId(`triggers_remove_test_trigger_key`); await removeButton.click(); - const el = await byTestId('triggers_pair_key_test_trigger_key'); - await el.waitForDisplayed({ timeout: 5_000, reverse: true }); + await waitForDisappear('triggers_pair_key_test_trigger_key'); }); it('can add and remove multiple triggers', async () => { @@ -85,10 +85,8 @@ describe('Triggers', () => { await scrollToEl('triggers_section', { direction: 'up' }); // wait for triggers to be removed - const trigger2El = await byTestId('triggers_pair_key_test_trigger_key_2'); - const trigger3El = await byTestId('triggers_pair_key_test_trigger_key_3'); - await trigger2El.waitForDisplayed({ timeout: 5_000, reverse: true }); - await trigger3El.waitForDisplayed({ timeout: 5_000, reverse: true }); + await waitForDisappear('triggers_pair_key_test_trigger_key_2'); + await waitForDisappear('triggers_pair_key_test_trigger_key_3'); }); it('can clear all triggers', async () => { diff --git a/appium/tests/specs/12_activity.spec.ts b/appium/tests/specs/12_activity.spec.ts index 1149373..1de1a15 100644 --- a/appium/tests/specs/12_activity.spec.ts +++ b/appium/tests/specs/12_activity.spec.ts @@ -42,6 +42,7 @@ describe('Live Activities', () => { if (isBrowserStackIos()) this.skip(); const startButton = await scrollToEl('start_live_activity_button'); + await startButton.waitForEnabled({ timeout: 15_000 }); await startButton.click(); const clickUpdateButton = async () => { @@ -66,6 +67,7 @@ describe('Live Activities', () => { // end live activity const endButton = await scrollToEl('end_live_activity_button'); + await endButton.waitForEnabled({ timeout: 15_000 }); await endButton.click(); await lockScreen(); From 21dd08b33479cd9a8fb4723ea3727407bdbcf9ff Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 12 May 2026 14:55:37 -0700 Subject: [PATCH 16/31] chore(appium): include *.java in Unity hash paths --- appium/scripts/run-local.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 359fe87..2dc79aa 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -1133,6 +1133,7 @@ unity_hash_paths() { -o -name "*.meta" -o -name "*.json" -o -name "*.xml" \ -o -name "*.plist" -o -name "*.strings" \ -o -name "*.h" -o -name "*.m" -o -name "*.mm" -o -name "*.swift" \ + -o -name "*.java" \ -o -name "*.a" -o -name "*.aar" -o -name "*.jar" \ -o -name "*.so" -o -name "*.dll" -o -name "*.dylib" \ -o -name "*.uxml" -o -name "*.uss" -o -name "*.unity" \ From a49343e29c4ad4837818ff296ace3d95589be548 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 12 May 2026 15:06:38 -0700 Subject: [PATCH 17/31] refactor(appium): extract isUnitySDK constant --- appium/tests/helpers/app.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 03d1283..649953e 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -41,7 +41,7 @@ async function swipeMainContent(direction: 'up' | 'down', distance: 'small' | 'n // scroll` gestures sometimes report Down/Up without intermediate Move). // Other SDKs route swipes through native scroll containers that don't // dispatch into our element handlers, so center is fine. - const swipeX = sdkType === 'unity' && getPlatform() === 'ios' ? 10 : Math.round(width / 2); + const swipeX = isUnitySDK ? 10 : Math.round(width / 2); const startY = Math.round(direction === 'down' ? height * 0.85 : height * 0.15); const endY = Math.round(direction === 'down' ? startY - swipeDistance : startY + swipeDistance); @@ -135,10 +135,10 @@ export async function scrollToEl( // column, so it reproduces the same accidental-tap problem we avoid in // `swipeMainContent` by anchoring at the left gutter. Falling through to // the swipe loop costs ~200ms but never taps a button. - if (direction === 'down' && !isFlutterSDK) { + if (direction === 'down' && !(isFlutterSDK || isUnitySDK)) { if (platform === 'android') { await tryNativeScrollAndroid(identifier); - } else if (sdkType !== 'unity') { + } else { await tryNativeScrollIos(identifier); } } @@ -597,7 +597,7 @@ export async function waitForDisappear(testId: string, timeoutMs = 5_000) { */ export async function openModal(triggerTestId: string, expectedTestId: string, firstTryMs = 5_000) { const trigger = await scrollToEl(triggerTestId); - if (getSdkType() === 'unity') { + if (isUnitySDK) { await waitForStablePosition(trigger); } await trigger.click(); From 0cd251856ab7d603dbb6d472046cba8f20fea439 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 12 May 2026 16:23:37 -0700 Subject: [PATCH 18/31] fix(appium): rename pod stamp var to avoid shadowing Inside build_unity_ios, the inner 'local stamp' for the Podfile.lock cache was shadowing the outer 'local stamp' for the Unity build cache. The trailing 'echo "$demo_hash" > "$stamp"' would then write the demo hash into .podfile.lock.stamp instead of .unity-build-ios.stamp, defeating the Unity build cache and corrupting the pod stamp. Also fix the --help text to reference Unity 6000.4.6f1 to match the actual default. Co-authored-by: Cursor --- appium/scripts/run-local.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 2dc79aa..995be30 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -94,7 +94,7 @@ Env vars (set in .env or export): DOTNET_ANDROID_ABI .NET Android ABI to pack (default: host arch) UNITY_DIR Unity SDK repo root (default: ../../OneSignal-Unity-SDK) UNITY_PATH Path to Unity Editor binary - (default: /Applications/Unity/Hub/Editor/6000.3.6f1/Unity.app/Contents/MacOS/Unity) + (default: /Applications/Unity/Hub/Editor/6000.4.6f1/Unity.app/Contents/MacOS/Unity) OS_VERSION Platform version (default: 26.2 / 16) IOS_SIMULATOR iOS simulator name (default: iPhone 17) IOS_RUNTIME simctl runtime id (default: iOS-26-2) @@ -1249,12 +1249,12 @@ build_unity_ios() { if [[ -f "$xcode_dir/Podfile" ]]; then local lock="$xcode_dir/Podfile.lock" - local stamp="$derived/.podfile.lock.stamp" - if [[ ! -f "$lock" ]] || [[ ! -f "$stamp" ]] || ! cmp -s "$lock" "$stamp"; then + local pod_stamp="$derived/.podfile.lock.stamp" + if [[ ! -f "$lock" ]] || [[ ! -f "$pod_stamp" ]] || ! cmp -s "$lock" "$pod_stamp"; then info "Installing CocoaPods..." (cd "$xcode_dir" && pod install) - mkdir -p "$(dirname "$stamp")" - cp "$lock" "$stamp" 2>/dev/null || true + mkdir -p "$(dirname "$pod_stamp")" + cp "$lock" "$pod_stamp" 2>/dev/null || true else info "Pods up to date, skipping pod install" fi From 511eb02e71714c1b4287d326e755f243947b56f3 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 12 May 2026 16:26:19 -0700 Subject: [PATCH 19/31] docs(appium): clarify openModal/tapIamTrigger scope comments Co-authored-by: Cursor --- appium/tests/helpers/app.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 649953e..3f0a359 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -588,12 +588,13 @@ export async function waitForDisappear(testId: string, timeoutMs = 5_000) { /** * Tap a button expected to open a modal/dialog and wait for one of its - * elements (`expectedTestId`) to appear. On iOS we briefly wait for the - * trigger to settle before tapping: Unity UI Toolkit relayouts the section - * after a previous test's teardown (dialog dismiss, list row removal), and - * that shift can land the queued tap on empty space, producing a 5s - * "modal element not found" timeout. Native iOS/Android views don't need - * this — their click dispatch already waits for layout to settle. + * elements (`expectedTestId`) to appear. On Unity (both platforms) we + * briefly wait for the trigger to settle before tapping: Unity UI Toolkit + * relayouts the section after a previous test's teardown (dialog dismiss, + * list row removal), and that shift can land the queued tap on empty space, + * producing a 5s "modal element not found" timeout. Native iOS/Android + * views don't need this — their click dispatch already waits for layout to + * settle. */ export async function openModal(triggerTestId: string, expectedTestId: string, firstTryMs = 5_000) { const trigger = await scrollToEl(triggerTestId); @@ -981,8 +982,9 @@ async function switchToIAMWebView(expectedTitle: string, timeoutMs: number) { } /** - * On Flutter the first tap is intermittently swallowed by a leftover IAM - * container window. If no WebView appears in 2.5s, re-tap. + * The first tap is intermittently swallowed on iOS (all SDKs) and on + * Flutter Android by a leftover IAM container window. If no WebView + * appears in 2.5s, re-tap. Native Android (non-Flutter) doesn't need this. */ async function tapIamTrigger(buttonId: string) { await (await scrollToEl(buttonId)).click(); From adccbbb7a055a7c7ec7561875b9fbdaceb064dde Mon Sep 17 00:00:00 2001 From: Fadi George Date: Tue, 12 May 2026 23:27:21 -0700 Subject: [PATCH 20/31] fix(appium): use ReleaseForRunning config for Unity iOS sim --- appium/scripts/run-local.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 995be30..c2e6f3e 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -281,7 +281,7 @@ elif [[ "$SDK_TYPE" == "unity" ]]; then # `Unity-iPhone.xcodeproj` (a fixed Unity convention), but the *product* # name is configured to `OneSignalDemo` in Player Settings, so xcodebuild # produces `OneSignalDemo.app`. - APP_PATH="${APP_PATH:-$DEMO_DIR/Build/iOS-DerivedData/Build/Products/Release-iphonesimulator/OneSignalDemo.app}" + APP_PATH="${APP_PATH:-$DEMO_DIR/Build/iOS-DerivedData/Build/Products/ReleaseForRunning-iphonesimulator/OneSignalDemo.app}" else APP_PATH="${APP_PATH:-$DEMO_DIR/Build/Android/onesignal-demo.apk}" fi @@ -1269,14 +1269,17 @@ build_unity_ios() { target_args=(-project "$xcode_dir/Unity-iPhone.xcodeproj") fi + local simulator_arch="${UNITY_IOS_SIM_ARCH:-x86_64}" + xcodebuild \ "${target_args[@]}" \ -scheme Unity-iPhone \ - -configuration Release \ + -configuration ReleaseForRunning \ -sdk iphonesimulator \ -derivedDataPath "$derived" \ -quiet \ ONLY_ACTIVE_ARCH=YES \ + ARCHS="$simulator_arch" \ CODE_SIGN_IDENTITY="-" \ CODE_SIGNING_ALLOWED=YES \ build @@ -1284,9 +1287,9 @@ build_unity_ios() { if [[ ! -d "$APP_PATH" ]]; then # Fallback: Unity's product name (and thus the .app filename) is set in # Player Settings, so it can drift from our default. Search the derived - # data Products dir for any .app, prefer Release-iphonesimulator/. + # data Products dir for any .app, prefer ReleaseForRunning-iphonesimulator/. local found - found=$(find "$derived/Build/Products/Release-iphonesimulator" \ + found=$(find "$derived/Build/Products/ReleaseForRunning-iphonesimulator" \ -maxdepth 1 -name "*.app" -not -name "*.appex" 2>/dev/null | head -1) [[ -z "$found" ]] && found=$(find "$derived" -path "*/Build/Products/*" \ -maxdepth 5 -name "*.app" \ From 5cfe9eea7d3c5ed34b7feca9926b7fb2fa5bf409 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:17:02 -0700 Subject: [PATCH 21/31] fix(appium): await chainable before wrapping in Proxy The Proxy returned by withElementInteractionFixes forwarded `then` to its target, which is a ChainablePromiseElement. Because the Proxy was itself thenable, awaiting byTestId/byText adopted the thenable and unwrapped past the Proxy down to the raw Element, silently bypassing the Unity center-tap shim and the Flutter Android getText/setValue fallbacks. Resolve the chainable first so the Proxy wraps a real Element. Co-authored-by: Cursor --- appium/tests/helpers/selectors.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/appium/tests/helpers/selectors.ts b/appium/tests/helpers/selectors.ts index 69ea7d9..48a11c7 100644 --- a/appium/tests/helpers/selectors.ts +++ b/appium/tests/helpers/selectors.ts @@ -292,11 +292,16 @@ export async function byTestId(id: string) { const platform = getPlatform(); if (sdkType === 'capacitor' || sdkType === 'cordova') return $(`[data-testid="${id}"]`); + // Await the chainable before wrapping. Otherwise the Proxy's `then` + // trap forwards to the underlying ChainablePromiseElement, so awaiting + // byTestId(...) adopts the thenable and unwraps past the Proxy down to + // the raw Element — silently bypassing every shim below. if (platform === 'android') { - const el = $(`id=${id}`); + const el = await $(`id=${id}`); return withElementInteractionFixes(el); } - return withElementInteractionFixes($(`~${id}`)); + const el = await $(`~${id}`); + return withElementInteractionFixes(el); } /** @@ -316,7 +321,8 @@ export async function byText(identifier: string, partial = false) { const xpath = partial ? `//*[contains(@content-desc, "${identifier}") or contains(@text, "${identifier}")]` : `//*[@content-desc="${identifier}" or @text="${identifier}"]`; - return withElementInteractionFixes($(xpath)); + const el = await $(xpath); + return withElementInteractionFixes(el); } return partial ? $(`android=new UiSelector().textContains("${identifier}")`) From 855d20e4bd38a5efd76ac9bac4574707fd2b1b8b Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:17:42 -0700 Subject: [PATCH 22/31] refactor(appium): drop redundant waitForDisplayed in 09_trigger openModal() already awaits waitForExist on the expected element before returning, so the extra wait was dead. Brings 09_trigger in line with the other migrated specs. Co-authored-by: Cursor --- appium/tests/specs/09_trigger.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/appium/tests/specs/09_trigger.spec.ts b/appium/tests/specs/09_trigger.spec.ts index bdff5b1..e9f2bec 100644 --- a/appium/tests/specs/09_trigger.spec.ts +++ b/appium/tests/specs/09_trigger.spec.ts @@ -50,7 +50,6 @@ describe('Triggers', () => { const keyInput = await openModal('add_trigger_button', 'trigger_key_input'); // add trigger - await keyInput.waitForDisplayed({ timeout: 5_000 }); await keyInput.setValue('test_trigger_key'); const valueInput = await byTestId('trigger_value_input'); From 543f6b0fe6f8bc32ac4bcf6cac98c51f01926d0a Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:17:59 -0700 Subject: [PATCH 23/31] docs(appium): shorten byTestId comment Co-authored-by: Cursor --- appium/tests/helpers/selectors.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/appium/tests/helpers/selectors.ts b/appium/tests/helpers/selectors.ts index 48a11c7..ef21c44 100644 --- a/appium/tests/helpers/selectors.ts +++ b/appium/tests/helpers/selectors.ts @@ -292,10 +292,7 @@ export async function byTestId(id: string) { const platform = getPlatform(); if (sdkType === 'capacitor' || sdkType === 'cordova') return $(`[data-testid="${id}"]`); - // Await the chainable before wrapping. Otherwise the Proxy's `then` - // trap forwards to the underlying ChainablePromiseElement, so awaiting - // byTestId(...) adopts the thenable and unwraps past the Proxy down to - // the raw Element — silently bypassing every shim below. + // Resolve the chainable first so awaiting the Proxy doesn't unwrap past it. if (platform === 'android') { const el = await $(`id=${id}`); return withElementInteractionFixes(el); From 9640b3792d8a91ecde744ed5d6aa1275787bd129 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:18:55 -0700 Subject: [PATCH 24/31] fix(appium): normalize --spec when bare basename has .ts suffix Previously the case statement's *.ts arm short-circuited normalization, so --spec=03_iam.spec.ts was passed verbatim to wdio and resolved against APPIUM_DIR instead of tests/specs/, producing 'No specs found'. Strip the optional .spec.ts/.ts suffix before re-prefixing so all three forms (03_iam, 03_iam.ts, 03_iam.spec.ts) resolve identically. Fully-qualified paths and explicit globs still bypass normalization. Co-authored-by: Cursor --- appium/scripts/run-local.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index c2e6f3e..9d41689 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -115,8 +115,12 @@ USAGE done case "$SPEC" in - */*|*\**|*\?*|*.ts) ;; - *) SPEC="tests/specs/${SPEC}*.spec.ts" ;; + */*|*\**|*\?*) ;; + *) + base="${SPEC%.spec.ts}" + base="${base%.ts}" + SPEC="tests/specs/${base}*.spec.ts" + ;; esac # Ensure values set via CLI flags propagate to wdio (which reads them as env). From 9b1c3a1f38123c8188f2793a9ee9a7fa2012ffef Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:20:22 -0700 Subject: [PATCH 25/31] fix(appium): short-circuit scrollExtraIfNeeded for tall elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The y >= threshold && y + height <= viewport - threshold predicate (threshold = 12% of viewport) is unsatisfiable whenever the element itself exceeds 76% of the viewport — exactly the case for populated section containers like triggers_section / aliases_section. That burned the full 3-iteration loop on every call. Accept tall elements as-is and fix the misleading catch-block comment, which referenced 'original ref' even though current is reassigned each miss. Co-authored-by: Cursor --- appium/tests/helpers/app.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 3f0a359..708c518 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -291,13 +291,16 @@ async function scrollExtraIfNeeded< driver.getWindowSize(), ]); const threshold = Math.round(height * 0.12); + // Elements taller than the safe area (e.g. a populated section + // container) can never satisfy both edges; accept them as-is. + if (size.height > height - 2 * threshold) return current; if (y >= threshold && y + size.height <= height - threshold) return current; await swipeMainContent(y < threshold ? 'up' : 'down', 'small'); current = await refetch(); } } catch { - /* best-effort: if location read fails, return original ref */ + /* best-effort: if a location read fails, return the most recent ref */ } return current; } From b1b616e232ab12dbacf1a7b65c0f8e583c477092 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:21:17 -0700 Subject: [PATCH 26/31] refactor(appium): rename openModal firstTryMs to timeoutMs The retry-era name no longer matches the simplified single-wait body and is inconsistent with confirmModal / waitForDisappear / waitForStablePosition. Co-authored-by: Cursor --- appium/tests/helpers/app.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 708c518..7c3c519 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -599,14 +599,14 @@ export async function waitForDisappear(testId: string, timeoutMs = 5_000) { * views don't need this — their click dispatch already waits for layout to * settle. */ -export async function openModal(triggerTestId: string, expectedTestId: string, firstTryMs = 5_000) { +export async function openModal(triggerTestId: string, expectedTestId: string, timeoutMs = 5_000) { const trigger = await scrollToEl(triggerTestId); if (isUnitySDK) { await waitForStablePosition(trigger); } await trigger.click(); const expected = await byTestId(expectedTestId); - await expected.waitForExist({ timeout: firstTryMs }); + await expected.waitForExist({ timeout: timeoutMs }); return expected; } From a2260f877df0ed3a4376ea70f2d760dc0ef2bc55 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:22:33 -0700 Subject: [PATCH 27/31] fix(appium): scope stale WDA cleanup to port 8100 holder The previous broad pkill -f patterns matched any WebDriverAgent or xcodebuild process on the host, so a developer's unrelated WDA session or parallel Xcode UI test would get SIGKILLed. Switch to lsof on port 8100 (WDA's hardcoded default in this repo) so we only kill the specific port-holder. Also move the cleanup after the Appium health check, so a healthy reused Appium session keeps its WDA child. Co-authored-by: Cursor --- appium/scripts/run-local.sh | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 9d41689..25d06f6 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -1500,28 +1500,26 @@ start_device() { } # ── 2. Start Appium ────────────────────────────────────────────────────────── -# Kill leftover WDA processes from prior runs. Appium aborts WDA with -# `SIGABRT` when it can't bind to port 8100 (its default), and the most -# common holder of 8100 is a stale `WebDriverAgentRunner-Runner` from an -# earlier crashed attempt or a Ctrl-C'd session. The accompanying -# `xcodebuild` wrapper also hangs onto its derived data lock. Killing -# both is cheap when nothing's running and prevents the cascading -# "Address already in use" → `xcodebuild exited with code 65` → wdio -# "Unable to start WebDriverAgent session" failure mode. +# Free port 8100 when a previous run left WDA bound to it. Scoped to the +# actual port-holder (not a broad pkill -f) so unrelated WDA sessions or +# other Xcode UI tests on the same host aren't collateral damage. Prevents +# the cascading "Address already in use" → `xcodebuild exited with code 65` +# → wdio "Unable to start WebDriverAgent session" failure mode. cleanup_stale_wda() { [[ "$PLATFORM" == "ios" ]] || return 0 - pkill -9 -f "WebDriverAgentRunner-Runner" 2>/dev/null || true - pkill -9 -f "xcodebuild.*WebDriverAgent" 2>/dev/null || true + local pids + pids=$(lsof -ti tcp:8100 2>/dev/null || true) + [[ -n "$pids" ]] && kill -9 $pids 2>/dev/null || true } start_appium() { - cleanup_stale_wda - if curl -s "http://localhost:$APPIUM_PORT/status" | grep -q '"ready":true' 2>/dev/null; then info "Appium already running on port $APPIUM_PORT" return fi + cleanup_stale_wda + info "Starting Appium on port $APPIUM_PORT..." appium --port "$APPIUM_PORT" --log-level error & local pid=$! From 92ecfa21f6489918ceb9b3d4453fc7473b3392b2 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:23:19 -0700 Subject: [PATCH 28/31] docs(appium): correct Unity scope on swipeMainContent/scrollToEl comments Both gates apply to Unity on both platforms but the comments described iOS-only XCUITest behavior. Update to reflect that the same gate fires on Unity Android for different reasons (UiScrollable doesn't traverse into the Unity SurfaceView). Co-authored-by: Cursor --- appium/tests/helpers/app.ts | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/appium/tests/helpers/app.ts b/appium/tests/helpers/app.ts index 7c3c519..531d6c2 100644 --- a/appium/tests/helpers/app.ts +++ b/appium/tests/helpers/app.ts @@ -34,13 +34,12 @@ async function swipeMainContent(direction: 'up' | 'down', distance: 'small' | 'n // Coordinates must be integers in WebView contexts (Capacitor/Cordova), // where chromedriver enforces W3C `actions` typing strictly. Native // UiAutomator2/XCUITest tolerate floats but rounding is harmless there. - // Unity iOS: anchor in the left section-padding gutter (x≈10pt; sections - // pad 16pt). XCUITest swipes can otherwise land PointerDown on a centered - // button and trigger AccessibilityBridge's E2E tap fallback before the - // drag generates enough PointerMove distance to cancel it (fast `mobile: - // scroll` gestures sometimes report Down/Up without intermediate Move). - // Other SDKs route swipes through native scroll containers that don't - // dispatch into our element handlers, so center is fine. + // Unity (both platforms): anchor in the left section-padding gutter + // (x≈10pt; sections pad 16pt). Center-anchored swipes can land + // PointerDown on a button and trigger AccessibilityBridge's E2E tap + // fallback before the drag generates enough PointerMove distance to + // cancel it. Other SDKs route swipes through native scroll containers + // that don't dispatch into our element handlers, so center is fine. const swipeX = isUnitySDK ? 10 : Math.round(width / 2); const startY = Math.round(direction === 'down' ? height * 0.85 : height * 0.15); const endY = Math.round(direction === 'down' ? startY - swipeDistance : startY + swipeDistance); @@ -129,12 +128,12 @@ export async function scrollToEl( } // Native fast path: pre-warms the scroll view so the loop below either - // returns immediately or has very little work left. - // Unity iOS opts out: `mobile: scroll` synthesizes its own center-anchored - // touch sequence on the scroll view that can't be moved off the button - // column, so it reproduces the same accidental-tap problem we avoid in - // `swipeMainContent` by anchoring at the left gutter. Falling through to - // the swipe loop costs ~200ms but never taps a button. + // returns immediately or has very little work left. Unity opts out on + // both platforms: iOS `mobile: scroll` synthesizes a center-anchored + // touch sequence that reproduces the accidental-tap problem we avoid in + // `swipeMainContent`, and on Android `UiScrollable` doesn't see UI + // Toolkit content rendered into the Unity SurfaceView. Falling through + // to the swipe loop costs ~200ms but is reliable. if (direction === 'down' && !(isFlutterSDK || isUnitySDK)) { if (platform === 'android') { await tryNativeScrollAndroid(identifier); From 8b2999f183e93ca4845273375535338a318706f0 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:24:02 -0700 Subject: [PATCH 29/31] fix(appium): auto-detect Unity iOS simulator arch by host Previous default of x86_64 forced Apple Silicon hosts through Rosetta on every Unity iOS build and test launch. Mirror the .NET branch's uname -m pickup so arm64 hosts get the native slice. UNITY_IOS_SIM_ARCH remains an override for the rare cross-arch case. Co-authored-by: Cursor --- appium/scripts/run-local.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 25d06f6..a2bb4e7 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -1273,7 +1273,14 @@ build_unity_ios() { target_args=(-project "$xcode_dir/Unity-iPhone.xcodeproj") fi - local simulator_arch="${UNITY_IOS_SIM_ARCH:-x86_64}" + # Match the host arch so Apple Silicon hosts run the sim natively instead + # of going through Rosetta. UNITY_IOS_SIM_ARCH still wins as an override. + local simulator_arch + case "$(uname -m)" in + arm64) simulator_arch="${UNITY_IOS_SIM_ARCH:-arm64}" ;; + x86_64) simulator_arch="${UNITY_IOS_SIM_ARCH:-x86_64}" ;; + *) error "Unsupported host arch for Unity iOS sim build: $(uname -m)" ;; + esac xcodebuild \ "${target_args[@]}" \ From 8faf45125b8651373de6886170c482f633b73468 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 11:40:42 -0700 Subject: [PATCH 30/31] refactor(appium): hoist simulator_arch before cache check --- appium/scripts/run-local.sh | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index a2bb4e7..7fccdaa 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -1222,6 +1222,16 @@ build_unity_ios() { [[ -x "$UNITY_PATH" ]] || error "Unity Editor not found at $UNITY_PATH — set UNITY_PATH in .env" + # Match the host arch so Apple Silicon hosts run the sim natively instead + # of going through Rosetta. UNITY_IOS_SIM_ARCH still wins as an override. + # Resolved before the cache check so the arch can scope the stamp filename. + local simulator_arch + case "$(uname -m)" in + arm64) simulator_arch="${UNITY_IOS_SIM_ARCH:-arm64}" ;; + x86_64) simulator_arch="${UNITY_IOS_SIM_ARCH:-x86_64}" ;; + *) error "Unsupported host arch for Unity iOS sim build: $(uname -m)" ;; + esac + # Top-level skip: if neither the demo nor the SDK changed and the .app is # still on disk, both stages (Unity batchmode 5-10min + xcodebuild 1-2min) # would otherwise reproduce identical output. Skip the whole thing. @@ -1229,7 +1239,7 @@ build_unity_ios() { sdk_hash=$(unity_sdk_inputs_hash ios) demo_hash=$(unity_demo_inputs_hash "$sdk_hash") - local stamp="$DEMO_DIR/Build/.unity-build-ios.stamp" + local stamp="$DEMO_DIR/Build/.unity-build-ios-${simulator_arch}.stamp" if unity_build_is_cached "$stamp" "$APP_PATH" "$demo_hash"; then info "Unity SDK + demo source unchanged, skipping iOS rebuild" info "App: $APP_PATH" @@ -1273,15 +1283,6 @@ build_unity_ios() { target_args=(-project "$xcode_dir/Unity-iPhone.xcodeproj") fi - # Match the host arch so Apple Silicon hosts run the sim natively instead - # of going through Rosetta. UNITY_IOS_SIM_ARCH still wins as an override. - local simulator_arch - case "$(uname -m)" in - arm64) simulator_arch="${UNITY_IOS_SIM_ARCH:-arm64}" ;; - x86_64) simulator_arch="${UNITY_IOS_SIM_ARCH:-x86_64}" ;; - *) error "Unsupported host arch for Unity iOS sim build: $(uname -m)" ;; - esac - xcodebuild \ "${target_args[@]}" \ -scheme Unity-iPhone \ From b654d938ac4ac9a25aadca79ffd5af5669adf520 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Wed, 13 May 2026 12:16:39 -0700 Subject: [PATCH 31/31] fix(appium): scope Unity iOS derived-data dir by arch --- appium/scripts/run-local.sh | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/appium/scripts/run-local.sh b/appium/scripts/run-local.sh index 7fccdaa..34f7343 100755 --- a/appium/scripts/run-local.sh +++ b/appium/scripts/run-local.sh @@ -95,6 +95,7 @@ Env vars (set in .env or export): UNITY_DIR Unity SDK repo root (default: ../../OneSignal-Unity-SDK) UNITY_PATH Path to Unity Editor binary (default: /Applications/Unity/Hub/Editor/6000.4.6f1/Unity.app/Contents/MacOS/Unity) + UNITY_IOS_SIM_ARCH Unity iOS simulator arch (default: host arch) OS_VERSION Platform version (default: 26.2 / 16) IOS_SIMULATOR iOS simulator name (default: iPhone 17) IOS_RUNTIME simctl runtime id (default: iOS-26-2) @@ -281,11 +282,19 @@ elif [[ "$SDK_TYPE" == "unity" ]]; then DEMO_DIR="$UNITY_DIR/examples/demo" UNITY_PATH="${UNITY_PATH:-/Applications/Unity/Hub/Editor/6000.4.6f1/Unity.app/Contents/MacOS/Unity}" if [[ "$PLATFORM" == "ios" ]]; then + # Match the host arch so Apple Silicon hosts run the sim natively instead + # of going through Rosetta. UNITY_IOS_SIM_ARCH still wins as an override. + case "$(uname -m)" in + arm64) UNITY_IOS_SIM_ARCH="${UNITY_IOS_SIM_ARCH:-arm64}" ;; + x86_64) UNITY_IOS_SIM_ARCH="${UNITY_IOS_SIM_ARCH:-x86_64}" ;; + *) error "Unsupported host arch for Unity iOS sim build: $(uname -m)" ;; + esac # Unity batchmode emits an Xcode project under Build/iOS named # `Unity-iPhone.xcodeproj` (a fixed Unity convention), but the *product* # name is configured to `OneSignalDemo` in Player Settings, so xcodebuild - # produces `OneSignalDemo.app`. - APP_PATH="${APP_PATH:-$DEMO_DIR/Build/iOS-DerivedData/Build/Products/ReleaseForRunning-iphonesimulator/OneSignalDemo.app}" + # produces `OneSignalDemo.app`. Scope the derived-data dir by arch so an + # arch flip doesn't return a stale wrong-arch binary from the cache. + APP_PATH="${APP_PATH:-$DEMO_DIR/Build/iOS-DerivedData-${UNITY_IOS_SIM_ARCH}/Build/Products/ReleaseForRunning-iphonesimulator/OneSignalDemo.app}" else APP_PATH="${APP_PATH:-$DEMO_DIR/Build/Android/onesignal-demo.apk}" fi @@ -1222,16 +1231,6 @@ build_unity_ios() { [[ -x "$UNITY_PATH" ]] || error "Unity Editor not found at $UNITY_PATH — set UNITY_PATH in .env" - # Match the host arch so Apple Silicon hosts run the sim natively instead - # of going through Rosetta. UNITY_IOS_SIM_ARCH still wins as an override. - # Resolved before the cache check so the arch can scope the stamp filename. - local simulator_arch - case "$(uname -m)" in - arm64) simulator_arch="${UNITY_IOS_SIM_ARCH:-arm64}" ;; - x86_64) simulator_arch="${UNITY_IOS_SIM_ARCH:-x86_64}" ;; - *) error "Unsupported host arch for Unity iOS sim build: $(uname -m)" ;; - esac - # Top-level skip: if neither the demo nor the SDK changed and the .app is # still on disk, both stages (Unity batchmode 5-10min + xcodebuild 1-2min) # would otherwise reproduce identical output. Skip the whole thing. @@ -1239,7 +1238,7 @@ build_unity_ios() { sdk_hash=$(unity_sdk_inputs_hash ios) demo_hash=$(unity_demo_inputs_hash "$sdk_hash") - local stamp="$DEMO_DIR/Build/.unity-build-ios-${simulator_arch}.stamp" + local stamp="$DEMO_DIR/Build/.unity-build-ios-${UNITY_IOS_SIM_ARCH}.stamp" if unity_build_is_cached "$stamp" "$APP_PATH" "$demo_hash"; then info "Unity SDK + demo source unchanged, skipping iOS rebuild" info "App: $APP_PATH" @@ -1247,7 +1246,7 @@ build_unity_ios() { fi local xcode_dir="$DEMO_DIR/Build/iOS" - local derived="$DEMO_DIR/Build/iOS-DerivedData" + local derived="$DEMO_DIR/Build/iOS-DerivedData-${UNITY_IOS_SIM_ARCH}" local log="$DEMO_DIR/Build/build-ios.log" mkdir -p "$xcode_dir" @@ -1291,7 +1290,7 @@ build_unity_ios() { -derivedDataPath "$derived" \ -quiet \ ONLY_ACTIVE_ARCH=YES \ - ARCHS="$simulator_arch" \ + ARCHS="$UNITY_IOS_SIM_ARCH" \ CODE_SIGN_IDENTITY="-" \ CODE_SIGNING_ALLOWED=YES \ build