diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..d6eee66f --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +apps/dashboard/android/gradlew text eol=lf diff --git a/.github/workflows/wallet-release.yml b/.github/workflows/wallet-release.yml new file mode 100644 index 00000000..6c406b74 --- /dev/null +++ b/.github/workflows/wallet-release.yml @@ -0,0 +1,157 @@ +name: Wallet release + +on: + workflow_dispatch: + push: + tags: + - "wallet-v*" + +permissions: + contents: write + +jobs: + desktop: + name: Desktop wallet (${{ matrix.name }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: windows + os: windows-latest + command: npm run desktop:installer:win + artifact: apps/dashboard/release/* + - name: macos + os: macos-latest + command: npm run desktop:installer:mac + artifact: apps/dashboard/release/* + - name: linux + os: ubuntu-latest + command: npm run desktop:installer:linux + artifact: apps/dashboard/release/* + + defaults: + run: + working-directory: apps/dashboard + + env: + CSC_IDENTITY_AUTO_DISCOVERY: "false" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: "24" + cache: npm + cache-dependency-path: apps/dashboard/package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Run tests + run: npm test + + - name: Build desktop app + run: ${{ matrix.command }} + + - name: Upload desktop artifact + uses: actions/upload-artifact@v4 + with: + name: flowchain-wallet-desktop-${{ matrix.name }} + path: ${{ matrix.artifact }} + if-no-files-found: error + + android: + name: Android wallet APK + runs-on: ubuntu-latest + defaults: + run: + working-directory: apps/dashboard + env: + HAS_ANDROID_RELEASE_KEYSTORE: ${{ secrets.FLOWCHAIN_ANDROID_KEYSTORE_BASE64 != '' }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: "24" + cache: npm + cache-dependency-path: apps/dashboard/package-lock.json + + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "21" + + - name: Install dependencies + run: npm ci + + - name: Sync Android project + run: npm run mobile:android:sync + + - name: Make Gradle wrapper executable + run: chmod +x ./gradlew + working-directory: apps/dashboard/android + + - name: Build debug APK + run: ./gradlew assembleDebug + working-directory: apps/dashboard/android + + - name: Decode Android release keystore + if: env.HAS_ANDROID_RELEASE_KEYSTORE == 'true' + shell: bash + run: | + echo "$FLOWCHAIN_ANDROID_KEYSTORE_BASE64" | base64 -d > flowchain-release.keystore + env: + FLOWCHAIN_ANDROID_KEYSTORE_BASE64: ${{ secrets.FLOWCHAIN_ANDROID_KEYSTORE_BASE64 }} + + - name: Build signed release APK + if: env.HAS_ANDROID_RELEASE_KEYSTORE == 'true' + run: ./gradlew assembleRelease + working-directory: apps/dashboard/android + env: + FLOWCHAIN_ANDROID_KEYSTORE_FILE: ${{ github.workspace }}/apps/dashboard/flowchain-release.keystore + FLOWCHAIN_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.FLOWCHAIN_ANDROID_KEYSTORE_PASSWORD }} + FLOWCHAIN_ANDROID_KEY_ALIAS: ${{ secrets.FLOWCHAIN_ANDROID_KEY_ALIAS }} + FLOWCHAIN_ANDROID_KEY_PASSWORD: ${{ secrets.FLOWCHAIN_ANDROID_KEY_PASSWORD }} + + - name: Upload Android APKs + uses: actions/upload-artifact@v4 + with: + name: flowchain-wallet-android + path: | + apps/dashboard/android/app/build/outputs/apk/debug/*.apk + apps/dashboard/android/app/build/outputs/apk/release/*.apk + if-no-files-found: error + + github-release: + name: Publish tagged GitHub release + runs-on: ubuntu-latest + needs: + - desktop + - android + if: startsWith(github.ref, 'refs/tags/wallet-v') + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + path: release-artifacts + + - name: Publish release + shell: bash + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + run: | + gh release create "$GITHUB_REF_NAME" \ + --title "Flowchain Wallet $GITHUB_REF_NAME" \ + --notes "Desktop and Android wallet builds generated from $GITHUB_SHA." + find release-artifacts -type f -print0 \ + | xargs -0 -I {} gh release upload "$GITHUB_REF_NAME" "{}" --clobber diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..c157b76b --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +cache=./devnet/local/npm-cache +update-notifier=false diff --git a/apps/dashboard/.gitignore b/apps/dashboard/.gitignore index 361bf2de..4f5e528c 100644 --- a/apps/dashboard/.gitignore +++ b/apps/dashboard/.gitignore @@ -1,5 +1,6 @@ node_modules/ dist/ +release/ .vite/ coverage/ *.tsbuildinfo diff --git a/apps/dashboard/WALLET_DISTRIBUTION.md b/apps/dashboard/WALLET_DISTRIBUTION.md new file mode 100644 index 00000000..1433f63c --- /dev/null +++ b/apps/dashboard/WALLET_DISTRIBUTION.md @@ -0,0 +1,43 @@ +# Flowchain Wallet Distribution + +The wallet is distributed as native desktop builds through Electron and as a native Android shell through Capacitor. + +## Local Windows Desktop Build + +```powershell +npm run desktop:installer:win --prefix apps/dashboard +``` + +Artifacts are written to `apps/dashboard/release/`. + +For a local unsigned unpacked build plus zip: + +```powershell +npm run desktop:pack --prefix apps/dashboard +``` + +## Android Build + +The Android app source lives in `apps/dashboard/android`. + +```powershell +npm run mobile:android:sync --prefix apps/dashboard +``` + +Building an APK requires Java and the Android SDK. On CI, `.github/workflows/wallet-release.yml` builds a debug APK automatically. For a signed release APK, add these repository secrets: + +- `FLOWCHAIN_ANDROID_KEYSTORE_BASE64` +- `FLOWCHAIN_ANDROID_KEYSTORE_PASSWORD` +- `FLOWCHAIN_ANDROID_KEY_ALIAS` +- `FLOWCHAIN_ANDROID_KEY_PASSWORD` + +## Public Downloads + +Run the `Wallet release` GitHub workflow manually for downloadable CI artifacts, or push a tag like: + +```powershell +git tag wallet-v0.0.0 +git push origin wallet-v0.0.0 +``` + +Tagged runs publish a GitHub Release containing the desktop and Android artifacts. diff --git a/apps/dashboard/android/.gitignore b/apps/dashboard/android/.gitignore new file mode 100644 index 00000000..48354a3d --- /dev/null +++ b/apps/dashboard/android/.gitignore @@ -0,0 +1,101 @@ +# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore + +# Built application files +*.apk +*.aar +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ +# Uncomment the following line in case you need and you don't have the release build type files in your app +# release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ + +# Android Profiling +*.hprof + +# Cordova plugins for Capacitor +capacitor-cordova-android-plugins + +# Copied web assets +app/src/main/assets/public + +# Generated Config files +app/src/main/assets/capacitor.config.json +app/src/main/assets/capacitor.plugins.json +app/src/main/res/xml/config.xml diff --git a/apps/dashboard/android/app/.gitignore b/apps/dashboard/android/app/.gitignore new file mode 100644 index 00000000..043df802 --- /dev/null +++ b/apps/dashboard/android/app/.gitignore @@ -0,0 +1,2 @@ +/build/* +!/build/.npmkeep diff --git a/apps/dashboard/android/app/build.gradle b/apps/dashboard/android/app/build.gradle new file mode 100644 index 00000000..7c046d0d --- /dev/null +++ b/apps/dashboard/android/app/build.gradle @@ -0,0 +1,76 @@ +apply plugin: 'com.android.application' + +def flowchainReleaseKeystore = System.getenv("FLOWCHAIN_ANDROID_KEYSTORE_FILE") +def flowchainReleaseStorePassword = System.getenv("FLOWCHAIN_ANDROID_KEYSTORE_PASSWORD") +def flowchainReleaseKeyAlias = System.getenv("FLOWCHAIN_ANDROID_KEY_ALIAS") +def flowchainReleaseKeyPassword = System.getenv("FLOWCHAIN_ANDROID_KEY_PASSWORD") +def hasFlowchainReleaseSigning = flowchainReleaseKeystore + && flowchainReleaseStorePassword + && flowchainReleaseKeyAlias + && flowchainReleaseKeyPassword + +android { + namespace = "ai.flowmemory.flowchain.wallet" + compileSdk = rootProject.ext.compileSdkVersion + defaultConfig { + applicationId "ai.flowmemory.flowchain.wallet" + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + aaptOptions { + // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. + // Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61 + ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~' + } + } + signingConfigs { + release { + if (hasFlowchainReleaseSigning) { + storeFile file(flowchainReleaseKeystore) + storePassword flowchainReleaseStorePassword + keyAlias flowchainReleaseKeyAlias + keyPassword flowchainReleaseKeyPassword + } + } + } + buildTypes { + release { + minifyEnabled false + if (hasFlowchainReleaseSigning) { + signingConfig signingConfigs.release + } + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +repositories { + flatDir{ + dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs' + } +} + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" + implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion" + implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion" + implementation project(':capacitor-android') + testImplementation "junit:junit:$junitVersion" + androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" + androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" + implementation project(':capacitor-cordova-android-plugins') +} + +apply from: 'capacitor.build.gradle' + +try { + def servicesJSON = file('google-services.json') + if (servicesJSON.text) { + apply plugin: 'com.google.gms.google-services' + } +} catch(Exception e) { + logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work") +} diff --git a/apps/dashboard/android/app/capacitor.build.gradle b/apps/dashboard/android/app/capacitor.build.gradle new file mode 100644 index 00000000..bbfb44fa --- /dev/null +++ b/apps/dashboard/android/app/capacitor.build.gradle @@ -0,0 +1,19 @@ +// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN + +android { + compileOptions { + sourceCompatibility JavaVersion.VERSION_21 + targetCompatibility JavaVersion.VERSION_21 + } +} + +apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" +dependencies { + + +} + + +if (hasProperty('postBuildExtras')) { + postBuildExtras() +} diff --git a/apps/dashboard/android/app/proguard-rules.pro b/apps/dashboard/android/app/proguard-rules.pro new file mode 100644 index 00000000..f1b42451 --- /dev/null +++ b/apps/dashboard/android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/apps/dashboard/android/app/src/androidTest/java/ai/flowmemory/flowchain/wallet/ExampleInstrumentedTest.java b/apps/dashboard/android/app/src/androidTest/java/ai/flowmemory/flowchain/wallet/ExampleInstrumentedTest.java new file mode 100644 index 00000000..83098e70 --- /dev/null +++ b/apps/dashboard/android/app/src/androidTest/java/ai/flowmemory/flowchain/wallet/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package ai.flowmemory.flowchain.wallet; + +import static org.junit.Assert.*; + +import android.content.Context; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("ai.flowmemory.flowchain.wallet", appContext.getPackageName()); + } +} diff --git a/apps/dashboard/android/app/src/main/AndroidManifest.xml b/apps/dashboard/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..b06ddbfd --- /dev/null +++ b/apps/dashboard/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/dashboard/android/app/src/main/java/ai/flowmemory/flowchain/wallet/MainActivity.java b/apps/dashboard/android/app/src/main/java/ai/flowmemory/flowchain/wallet/MainActivity.java new file mode 100644 index 00000000..dabd1d65 --- /dev/null +++ b/apps/dashboard/android/app/src/main/java/ai/flowmemory/flowchain/wallet/MainActivity.java @@ -0,0 +1,5 @@ +package ai.flowmemory.flowchain.wallet; + +import com.getcapacitor.BridgeActivity; + +public class MainActivity extends BridgeActivity {} diff --git a/apps/dashboard/android/app/src/main/res/drawable-land-hdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-land-hdpi/splash.png new file mode 100644 index 00000000..e31573b4 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-land-hdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-land-mdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-land-mdpi/splash.png new file mode 100644 index 00000000..f7a64923 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-land-mdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-land-xhdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-land-xhdpi/splash.png new file mode 100644 index 00000000..80772550 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-land-xhdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-land-xxhdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-land-xxhdpi/splash.png new file mode 100644 index 00000000..14c6c8fe Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-land-xxhdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-land-xxxhdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-land-xxxhdpi/splash.png new file mode 100644 index 00000000..244ca250 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-land-xxxhdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-port-hdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-port-hdpi/splash.png new file mode 100644 index 00000000..74faaa58 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-port-hdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-port-mdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-port-mdpi/splash.png new file mode 100644 index 00000000..e944f4ad Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-port-mdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-port-xhdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-port-xhdpi/splash.png new file mode 100644 index 00000000..564a82ff Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-port-xhdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-port-xxhdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-port-xxhdpi/splash.png new file mode 100644 index 00000000..bfabe687 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-port-xxhdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-port-xxxhdpi/splash.png b/apps/dashboard/android/app/src/main/res/drawable-port-xxxhdpi/splash.png new file mode 100644 index 00000000..69290712 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable-port-xxxhdpi/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/apps/dashboard/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 00000000..c7bd21db --- /dev/null +++ b/apps/dashboard/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/apps/dashboard/android/app/src/main/res/drawable/ic_launcher_background.xml b/apps/dashboard/android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..d5fccc53 --- /dev/null +++ b/apps/dashboard/android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/dashboard/android/app/src/main/res/drawable/splash.png b/apps/dashboard/android/app/src/main/res/drawable/splash.png new file mode 100644 index 00000000..f7a64923 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/drawable/splash.png differ diff --git a/apps/dashboard/android/app/src/main/res/layout/activity_main.xml b/apps/dashboard/android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..b5ad1387 --- /dev/null +++ b/apps/dashboard/android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/apps/dashboard/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/apps/dashboard/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 00000000..036d09bc --- /dev/null +++ b/apps/dashboard/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/apps/dashboard/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/apps/dashboard/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 00000000..036d09bc --- /dev/null +++ b/apps/dashboard/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/apps/dashboard/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/apps/dashboard/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..c023e505 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/apps/dashboard/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..2127973b Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/apps/dashboard/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 00000000..b441f37d Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/apps/dashboard/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..72905b85 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/apps/dashboard/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..8ed0605c Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/apps/dashboard/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 00000000..9502e47a Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/apps/dashboard/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..4d1e0771 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/apps/dashboard/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..df0f1588 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/apps/dashboard/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 00000000..853db043 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/apps/dashboard/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..6cdf97c1 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/apps/dashboard/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..2960cbb6 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/apps/dashboard/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..8e3093a8 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/apps/dashboard/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..46de6e25 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/apps/dashboard/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..d2ea9abe Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/apps/dashboard/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/apps/dashboard/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 00000000..a40d73e9 Binary files /dev/null and b/apps/dashboard/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/apps/dashboard/android/app/src/main/res/values/ic_launcher_background.xml b/apps/dashboard/android/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 00000000..c5d5899f --- /dev/null +++ b/apps/dashboard/android/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #FFFFFF + \ No newline at end of file diff --git a/apps/dashboard/android/app/src/main/res/values/strings.xml b/apps/dashboard/android/app/src/main/res/values/strings.xml new file mode 100644 index 00000000..5310d8c6 --- /dev/null +++ b/apps/dashboard/android/app/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + + Flowchain Wallet + Flowchain Wallet + ai.flowmemory.flowchain.wallet + ai.flowmemory.flowchain.wallet + diff --git a/apps/dashboard/android/app/src/main/res/values/styles.xml b/apps/dashboard/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..be874e54 --- /dev/null +++ b/apps/dashboard/android/app/src/main/res/values/styles.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/apps/dashboard/android/app/src/main/res/xml/file_paths.xml b/apps/dashboard/android/app/src/main/res/xml/file_paths.xml new file mode 100644 index 00000000..bd0c4d80 --- /dev/null +++ b/apps/dashboard/android/app/src/main/res/xml/file_paths.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/apps/dashboard/android/app/src/test/java/ai/flowmemory/flowchain/wallet/ExampleUnitTest.java b/apps/dashboard/android/app/src/test/java/ai/flowmemory/flowchain/wallet/ExampleUnitTest.java new file mode 100644 index 00000000..837d73f2 --- /dev/null +++ b/apps/dashboard/android/app/src/test/java/ai/flowmemory/flowchain/wallet/ExampleUnitTest.java @@ -0,0 +1,18 @@ +package ai.flowmemory.flowchain.wallet; + +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} diff --git a/apps/dashboard/android/build.gradle b/apps/dashboard/android/build.gradle new file mode 100644 index 00000000..b648f20e --- /dev/null +++ b/apps/dashboard/android/build.gradle @@ -0,0 +1,29 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + + repositories { + google() + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:8.13.0' + classpath 'com.google.gms:google-services:4.4.4' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +apply from: "variables.gradle" + +allprojects { + repositories { + google() + mavenCentral() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/apps/dashboard/android/capacitor.settings.gradle b/apps/dashboard/android/capacitor.settings.gradle new file mode 100644 index 00000000..9a5fa872 --- /dev/null +++ b/apps/dashboard/android/capacitor.settings.gradle @@ -0,0 +1,3 @@ +// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN +include ':capacitor-android' +project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') diff --git a/apps/dashboard/android/gradle.properties b/apps/dashboard/android/gradle.properties new file mode 100644 index 00000000..2e87c52f --- /dev/null +++ b/apps/dashboard/android/gradle.properties @@ -0,0 +1,22 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true diff --git a/apps/dashboard/android/gradle/wrapper/gradle-wrapper.jar b/apps/dashboard/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..1b33c55b Binary files /dev/null and b/apps/dashboard/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/apps/dashboard/android/gradle/wrapper/gradle-wrapper.properties b/apps/dashboard/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..7705927e --- /dev/null +++ b/apps/dashboard/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/apps/dashboard/android/gradlew b/apps/dashboard/android/gradlew new file mode 100755 index 00000000..23d15a93 --- /dev/null +++ b/apps/dashboard/android/gradlew @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH="\\\"\\\"" + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/apps/dashboard/android/gradlew.bat b/apps/dashboard/android/gradlew.bat new file mode 100644 index 00000000..db3a6ac2 --- /dev/null +++ b/apps/dashboard/android/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH= + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/apps/dashboard/android/settings.gradle b/apps/dashboard/android/settings.gradle new file mode 100644 index 00000000..3b4431d7 --- /dev/null +++ b/apps/dashboard/android/settings.gradle @@ -0,0 +1,5 @@ +include ':app' +include ':capacitor-cordova-android-plugins' +project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') + +apply from: 'capacitor.settings.gradle' \ No newline at end of file diff --git a/apps/dashboard/android/variables.gradle b/apps/dashboard/android/variables.gradle new file mode 100644 index 00000000..ee4ba41c --- /dev/null +++ b/apps/dashboard/android/variables.gradle @@ -0,0 +1,16 @@ +ext { + minSdkVersion = 24 + compileSdkVersion = 36 + targetSdkVersion = 36 + androidxActivityVersion = '1.11.0' + androidxAppCompatVersion = '1.7.1' + androidxCoordinatorLayoutVersion = '1.3.0' + androidxCoreVersion = '1.17.0' + androidxFragmentVersion = '1.8.9' + coreSplashScreenVersion = '1.2.0' + androidxWebkitVersion = '1.14.0' + junitVersion = '4.13.2' + androidxJunitVersion = '1.3.0' + androidxEspressoCoreVersion = '3.7.0' + cordovaAndroidVersion = '14.0.1' +} \ No newline at end of file diff --git a/apps/dashboard/capacitor.config.ts b/apps/dashboard/capacitor.config.ts new file mode 100644 index 00000000..f25cbc60 --- /dev/null +++ b/apps/dashboard/capacitor.config.ts @@ -0,0 +1,13 @@ +import type { CapacitorConfig } from "@capacitor/cli"; + +const config: CapacitorConfig = { + appId: "ai.flowmemory.flowchain.wallet", + appName: "Flowchain Wallet", + webDir: "dist", + bundledWebRuntime: false, + server: { + androidScheme: "https", + }, +}; + +export default config; diff --git a/apps/dashboard/electron-builder.json b/apps/dashboard/electron-builder.json new file mode 100644 index 00000000..315a5c12 --- /dev/null +++ b/apps/dashboard/electron-builder.json @@ -0,0 +1,43 @@ +{ + "appId": "ai.flowmemory.flowchain.wallet", + "productName": "Flowchain Wallet", + "directories": { + "output": "release" + }, + "files": [ + "dist/**/*", + "electron/**/*", + "package.json" + ], + "asar": true, + "mac": { + "category": "public.app-category.finance", + "target": [ + "dmg", + "zip" + ], + "identity": null + }, + "win": { + "signAndEditExecutable": false, + "target": [ + "nsis", + "zip" + ] + }, + "nsis": { + "oneClick": false, + "perMachine": false, + "allowToChangeInstallationDirectory": true, + "createDesktopShortcut": true, + "createStartMenuShortcut": true, + "shortcutName": "Flowchain Wallet" + }, + "linux": { + "category": "Finance", + "target": [ + "AppImage", + "zip" + ] + } +} diff --git a/apps/dashboard/electron/main.cjs b/apps/dashboard/electron/main.cjs new file mode 100644 index 00000000..a1658334 --- /dev/null +++ b/apps/dashboard/electron/main.cjs @@ -0,0 +1,159 @@ +const { app, BrowserWindow, Menu, ipcMain, shell } = require("electron"); +const fs = require("node:fs/promises"); +const http = require("node:http"); +const path = require("node:path"); +const { createLocalDesktopWallet, publicDesktopWalletStatus } = require("./wallet-store.cjs"); + +const isDev = Boolean(process.env.FLOWCHAIN_WALLET_DESKTOP_DEV_URL); +let staticServer; + +const contentTypes = new Map([ + [".css", "text/css; charset=utf-8"], + [".html", "text/html; charset=utf-8"], + [".js", "text/javascript; charset=utf-8"], + [".json", "application/json; charset=utf-8"], + [".png", "image/png"], + [".svg", "image/svg+xml; charset=utf-8"], + [".woff", "font/woff"], + [".woff2", "font/woff2"], +]); + +function contentTypeFor(filePath) { + return contentTypes.get(path.extname(filePath).toLowerCase()) ?? "application/octet-stream"; +} + +function startBundledStaticServer() { + if (staticServer !== undefined) { + return staticServer; + } + + const distDir = path.resolve(__dirname, "..", "dist"); + staticServer = new Promise((resolve, reject) => { + const server = http.createServer(async (req, res) => { + try { + const requestUrl = new URL(req.url ?? "/", "http://127.0.0.1"); + const rawPath = decodeURIComponent(requestUrl.pathname); + const assetPath = rawPath === "/" || path.extname(rawPath) === "" ? "/index.html" : rawPath; + const filePath = path.resolve(distDir, `.${assetPath}`); + + if (!filePath.startsWith(distDir)) { + res.writeHead(403, { "content-type": "text/plain; charset=utf-8" }); + res.end("Forbidden"); + return; + } + + const body = await fs.readFile(filePath); + res.writeHead(200, { + "cache-control": "no-store", + "content-type": contentTypeFor(filePath), + }); + res.end(body); + } catch { + res.writeHead(404, { "content-type": "text/plain; charset=utf-8" }); + res.end("Not found"); + } + }); + + server.once("error", reject); + server.listen(0, "127.0.0.1", () => { + const address = server.address(); + if (typeof address !== "object" || address === null) { + reject(new Error("Flowchain Wallet static server did not bind to a local port.")); + return; + } + resolve({ server, origin: `http://127.0.0.1:${address.port}` }); + }); + }); + + return staticServer; +} + +async function createWalletWindow() { + const window = new BrowserWindow({ + width: 1480, + height: 940, + minWidth: 1120, + minHeight: 720, + title: "Flowchain Wallet", + backgroundColor: "#fff9ee", + show: false, + webPreferences: { + contextIsolation: true, + nodeIntegration: false, + sandbox: true, + preload: path.join(__dirname, "preload.cjs"), + }, + }); + + window.once("ready-to-show", () => { + window.show(); + }); + + window.webContents.setWindowOpenHandler(({ url }) => { + if (url.startsWith("http://127.0.0.1") || url.startsWith("http://localhost")) { + return { action: "allow" }; + } + shell.openExternal(url).catch(() => undefined); + return { action: "deny" }; + }); + + window.webContents.on("will-navigate", (event, url) => { + const allowed = url.startsWith("file://") + || url.startsWith("http://127.0.0.1") + || url.startsWith("http://localhost") + || url.startsWith("http://192.168."); + if (!allowed) { + event.preventDefault(); + shell.openExternal(url).catch(() => undefined); + } + }); + + if (isDev) { + window.loadURL(`${process.env.FLOWCHAIN_WALLET_DESKTOP_DEV_URL.replace(/\/+$/, "")}/wallet`); + } else { + const { origin } = await startBundledStaticServer(); + window.loadURL(`${origin}/wallet`); + } + + return window; +} + +app.setName("Flowchain Wallet"); + +app.whenReady().then(() => { + ipcMain.handle("flowchain-wallet:get-local-wallet", () => publicDesktopWalletStatus(app.getPath("userData"))); + ipcMain.handle("flowchain-wallet:create-local-wallet", (_event, payload) => createLocalDesktopWallet(app.getPath("userData"), payload)); + + Menu.setApplicationMenu(Menu.buildFromTemplate([ + { + label: "Flowchain Wallet", + submenu: [ + { role: "reload" }, + { role: "toggleDevTools" }, + { type: "separator" }, + { role: "quit" }, + ], + }, + ])); + + createWalletWindow().catch((error) => { + console.error(error); + app.quit(); + }); + + app.on("activate", () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWalletWindow().catch((error) => { + console.error(error); + app.quit(); + }); + } + }); +}); + +app.on("window-all-closed", () => { + staticServer?.then(({ server }) => server.close()).catch(() => undefined); + if (process.platform !== "darwin") { + app.quit(); + } +}); diff --git a/apps/dashboard/electron/preload.cjs b/apps/dashboard/electron/preload.cjs new file mode 100644 index 00000000..7a3009b8 --- /dev/null +++ b/apps/dashboard/electron/preload.cjs @@ -0,0 +1,9 @@ +const { contextBridge, ipcRenderer } = require("electron"); + +contextBridge.exposeInMainWorld("flowchainDesktop", { + app: "Flowchain Wallet", + platform: process.platform, + packaged: process.env.NODE_ENV !== "development", + getLocalWallet: () => ipcRenderer.invoke("flowchain-wallet:get-local-wallet"), + createLocalWallet: (payload) => ipcRenderer.invoke("flowchain-wallet:create-local-wallet", payload), +}); diff --git a/apps/dashboard/electron/wallet-store.cjs b/apps/dashboard/electron/wallet-store.cjs new file mode 100644 index 00000000..30991915 --- /dev/null +++ b/apps/dashboard/electron/wallet-store.cjs @@ -0,0 +1,340 @@ +const { createCipheriv, randomBytes, scryptSync } = require("node:crypto"); +const { existsSync, mkdirSync, readFileSync, writeFileSync } = require("node:fs"); +const path = require("node:path"); + +const VAULT_SCHEMA = "flowmemory.crypto.local-test-vault.v0"; +const VAULT_SECRETS_SCHEMA = "flowmemory.crypto.local-test-vault-secrets.v0"; +const LOCAL_WALLET_PUBLIC_METADATA_SCHEMA = "flowchain.local_wallet_public_metadata.v0"; +const LOCAL_WALLET_KEY_SCHEME = "secp256k1"; +const DEFAULT_LOCAL_WALLET_CHAIN_ID = "31337"; +const LOCAL_ALPHA_SIGNER_ROLES = Object.freeze({ + operator: 1, + agent: 2, + verifier: 3, + hardware: 4, + user: 10, + validator: 11, + bridgeRelayer: 12, + bridgeReleaseAuthority: 13, + emergencyOperator: 14, +}); + +let nobleModules; + +async function loadNobleModules() { + if (nobleModules === undefined) { + nobleModules = Promise.all([ + import("@noble/secp256k1"), + import("@noble/hashes/sha3.js"), + ]).then(([secp, sha3]) => ({ secp, sha3 })); + } + return nobleModules; +} + +function walletPaths(userDataPath) { + const walletDir = path.join(userDataPath, "wallet"); + return { + walletDir, + vaultPath: path.join(walletDir, "flowchain-wallet-vault.local.json"), + metadataPath: path.join(walletDir, "flowchain-wallet-public-metadata.json"), + }; +} + +function publicDesktopWalletStatus(userDataPath) { + const paths = walletPaths(userDataPath); + const metadata = existsSync(paths.metadataPath) ? readJson(paths.metadataPath) : null; + const accounts = Array.isArray(metadata?.accounts) ? metadata.accounts : []; + const primaryAccount = accounts.find((entry) => entry !== null && typeof entry === "object" && !Array.isArray(entry)) ?? null; + return { + schema: "flowmemory.control_plane.local_wallet_public_status.v0", + exists: metadata !== null, + metadataPath: paths.metadataPath, + account: primaryAccount, + accounts, + secretMaterialReturned: false, + localOnly: true, + desktopLocal: true, + }; +} + +async function createLocalDesktopWallet(userDataPath, payload = {}) { + const request = parseWalletCreatePayload(payload); + const paths = walletPaths(userDataPath); + mkdirSync(paths.walletDir, { recursive: true }); + + if (!request.replace && existsSync(paths.vaultPath) && existsSync(paths.metadataPath)) { + return { + ...publicDesktopWalletStatus(userDataPath), + schema: "flowmemory.control_plane.local_wallet_create_result.v0", + created: false, + alreadyExists: true, + vaultPath: paths.vaultPath, + note: "Existing encrypted local wallet vault was left unchanged. Enable replace to rotate to a new wallet.", + }; + } + + const vault = await createEncryptedDesktopVault({ + password: request.password, + label: request.label, + signerRole: "user", + chainId: request.chainId, + }); + const metadata = exportLocalWalletPublicMetadata(vault); + writeJson(paths.vaultPath, vault); + writeJson(paths.metadataPath, metadata); + + const account = Array.isArray(metadata.accounts) ? metadata.accounts[0] : null; + return { + schema: "flowmemory.control_plane.local_wallet_create_result.v0", + created: true, + alreadyExists: false, + account, + accounts: metadata.accounts, + vaultPath: paths.vaultPath, + metadataPath: paths.metadataPath, + chainId: request.chainId, + keyScheme: account?.keyScheme ?? LOCAL_WALLET_KEY_SCHEME, + secretMaterialReturned: false, + credentialStored: false, + localOnly: true, + desktopLocal: true, + }; +} + +async function createEncryptedDesktopVault({ + password, + label, + signerRole, + createdAtUnixMs = Date.now().toString(), + privateKey, + chainId = DEFAULT_LOCAL_WALLET_CHAIN_ID, + lastKnownNonce = "0", +}) { + requirePassword(password); + const account = await createVaultAccount({ label, signerRole, createdAtUnixMs, privateKey, chainId, lastKnownNonce }); + return encryptVaultSecrets({ + password, + publicAccounts: [publicAccount(account)], + secrets: { + schema: VAULT_SECRETS_SCHEMA, + accounts: [account], + }, + createdAtUnixMs, + }); +} + +function encryptVaultSecrets({ + password, + publicAccounts, + secrets, + createdAtUnixMs, + vaultId = randomBytes32(), +}) { + requirePassword(password); + const salt = randomBytes(16); + const iv = randomBytes(12); + const kdf = { + name: "scrypt", + salt: bytesToHex(salt), + N: 16384, + r: 8, + p: 1, + keyLength: 32, + }; + const key = scryptSync(password, salt, kdf.keyLength, { N: kdf.N, r: kdf.r, p: kdf.p }); + const cipher = createCipheriv("aes-256-gcm", key, iv); + const ciphertext = Buffer.concat([ + cipher.update(JSON.stringify(secrets), "utf8"), + cipher.final(), + ]); + + return { + schema: VAULT_SCHEMA, + vaultId, + createdAtUnixMs, + kdf, + cipher: { + name: "aes-256-gcm", + iv: bytesToHex(iv), + authTag: bytesToHex(cipher.getAuthTag()), + }, + ciphertext: bytesToHex(ciphertext), + publicAccounts, + }; +} + +async function createVaultAccount({ + label, + signerRole, + createdAtUnixMs, + privateKey, + chainId = DEFAULT_LOCAL_WALLET_CHAIN_ID, + lastKnownNonce = "0", +}) { + if (LOCAL_ALPHA_SIGNER_ROLES[signerRole] === undefined) { + throw new Error(`unsupported signer role: ${signerRole}`); + } + if (!isUintString(String(chainId))) { + throw new Error(`unsupported wallet chain id: ${chainId}`); + } + if (!isUintString(String(lastKnownNonce))) { + throw new Error(`invalid wallet last known nonce: ${lastKnownNonce}`); + } + const effectivePrivateKey = privateKey ?? await randomPrivateKey(); + const publicKey = await publicKeyFromPrivateKey(effectivePrivateKey); + const publicKeyHash = await keccakUtf8(publicKey); + const signerId = await keccakUtf8(`flowchain.local-alpha.signer:${publicKey}`); + return { + label, + accountId: signerId, + address: signerId, + signerRole, + signerRoleCode: LOCAL_ALPHA_SIGNER_ROLES[signerRole], + signerId, + signerKeyId: await keccakUtf8(`flowchain.local-alpha.signer-key:${publicKey}`), + publicKey, + publicKeyHash, + keyScheme: LOCAL_WALLET_KEY_SCHEME, + chainId: String(chainId), + lastKnownNonce: String(lastKnownNonce), + nextNonce: nextNonce(lastKnownNonce), + createdAtUnixMs, + status: "active", + active: true, + privateKey: effectivePrivateKey, + }; +} + +function publicAccount(account) { + const { privateKey, ...metadata } = account; + return metadata; +} + +function exportLocalWalletPublicMetadata(vault, { updatedAtUnixMs = Date.now().toString() } = {}) { + return { + schema: LOCAL_WALLET_PUBLIC_METADATA_SCHEMA, + vaultId: vault.vaultId, + createdAtUnixMs: vault.createdAtUnixMs, + updatedAtUnixMs: String(updatedAtUnixMs), + accounts: (vault.publicAccounts ?? []).map(localWalletPublicAccount), + boundary: "Public local wallet metadata only. Signing material, vault encryption payloads, credentials, and webhooks are excluded.", + }; +} + +function localWalletPublicAccount(account) { + return { + accountId: account.accountId ?? account.signerId, + address: account.address ?? account.signerId, + signerId: account.signerId, + signerKeyId: account.signerKeyId, + signerRole: account.signerRole, + signerRoleCode: account.signerRoleCode, + publicKey: account.publicKey, + publicKeyHash: account.publicKeyHash, + keyScheme: account.keyScheme ?? LOCAL_WALLET_KEY_SCHEME, + label: account.label, + status: account.active === false ? "rotated" : account.status ?? "active", + active: account.active !== false, + createdAtUnixMs: account.createdAtUnixMs, + chainId: String(account.chainId ?? DEFAULT_LOCAL_WALLET_CHAIN_ID), + lastKnownNonce: String(account.lastKnownNonce ?? "0"), + nextNonce: String(account.nextNonce ?? nextNonce(account.lastKnownNonce ?? "0")), + rotatedFromSignerKeyId: account.rotatedFromSignerKeyId, + }; +} + +async function randomPrivateKey() { + for (;;) { + const candidate = bytesToHex(randomBytes(32)); + try { + await publicKeyFromPrivateKey(candidate); + return candidate; + } catch { + // Retry if the random bytes do not form a valid secp256k1 secret. + } + } +} + +async function publicKeyFromPrivateKey(privateKeyHex) { + const { secp } = await loadNobleModules(); + return bytesToHex(secp.getPublicKey(hexToBytes(privateKeyHex, 32))); +} + +async function keccakUtf8(value) { + const { sha3 } = await loadNobleModules(); + return bytesToHex(sha3.keccak_256(Buffer.from(String(value), "utf8"))); +} + +function parseWalletCreatePayload(payload) { + if (payload === null || typeof payload !== "object" || Array.isArray(payload)) { + throw new Error("wallet creation payload must be an object"); + } + const password = typeof payload.password === "string" ? payload.password : ""; + if (password.length < 8) { + throw new Error("wallet vault passphrase must be at least 8 characters"); + } + const chainId = typeof payload.chainId === "string" && /^\d+$/.test(payload.chainId) ? payload.chainId : DEFAULT_LOCAL_WALLET_CHAIN_ID; + return { + label: labelSlug(payload.label), + password, + chainId, + replace: payload.replace === true, + }; +} + +function labelSlug(value) { + const label = typeof value === "string" && value.trim().length > 0 ? value.trim() : "flowchain-wallet"; + const slug = label.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, ""); + return slug.length > 0 ? slug.slice(0, 64) : "flowchain-wallet"; +} + +function requirePassword(password) { + if (typeof password !== "string" || password.length < 8) { + throw new Error("wallet vault passphrase must be at least 8 characters"); + } +} + +function randomBytes32() { + return bytesToHex(randomBytes(32)); +} + +function bytesToHex(bytes) { + return `0x${Buffer.from(bytes).toString("hex")}`; +} + +function hexToBytes(value, expectedLength) { + if (typeof value !== "string") { + throw new TypeError("hex value must be a string"); + } + const raw = value.startsWith("0x") ? value.slice(2) : value; + if (raw.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(raw)) { + throw new Error(`invalid hex value: ${value}`); + } + const bytes = Uint8Array.from(Buffer.from(raw, "hex")); + if (expectedLength !== undefined && bytes.length !== expectedLength) { + throw new Error(`expected ${expectedLength} bytes, got ${bytes.length}`); + } + return bytes; +} + +function isUintString(value) { + return typeof value === "string" && /^[0-9]+$/.test(value); +} + +function nextNonce(value) { + return (BigInt(value) + 1n).toString(); +} + +function readJson(filePath) { + return JSON.parse(readFileSync(filePath, "utf8")); +} + +function writeJson(filePath, value) { + writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`); +} + +module.exports = { + createLocalDesktopWallet, + publicDesktopWalletStatus, + walletPaths, +}; diff --git a/apps/dashboard/index.html b/apps/dashboard/index.html index f705964a..32d36e1e 100644 --- a/apps/dashboard/index.html +++ b/apps/dashboard/index.html @@ -5,9 +5,9 @@ - FlowMemory Dashboard V0 + Flowchain Wallet
diff --git a/apps/dashboard/package-lock.json b/apps/dashboard/package-lock.json index 684afda4..eb15363f 100644 --- a/apps/dashboard/package-lock.json +++ b/apps/dashboard/package-lock.json @@ -8,840 +8,896 @@ "name": "@flowmemory/dashboard", "version": "0.0.0", "dependencies": { + "@capacitor/android": "^8.3.4", + "@capacitor/core": "^8.3.4", + "@noble/hashes": "^2.2.0", + "@noble/secp256k1": "^3.1.0", "lucide-react": "^0.468.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.28.0" }, "devDependencies": { + "@capacitor/cli": "^8.3.4", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@vitejs/plugin-react": "^6.0.1", + "electron": "^42.0.1", + "electron-builder": "^26.8.1", "typescript": "^5.6.3", "vite": "^8.0.12", "vitest": "^4.1.6" } }, - "node_modules/@emnapi/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", - "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, + "node_modules/@capacitor/android": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@capacitor/android/-/android-8.3.4.tgz", + "integrity": "sha512-7gJjrG3X32Am1QMLqgMztWTYMLMVNE+VZwhekNxhvYizH4mOV05vH+rC9B+f17bCkYZfyu/qXQX6hoY7kLeVZw==", "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" + "peerDependencies": { + "@capacitor/core": "^8.3.0" } }, - "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "node_modules/@capacitor/cli": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-8.3.4.tgz", + "integrity": "sha512-QEmyNdiDDVNYl0Mahm7YTVA/3t2tKcy7FWYDapeKGavS6HDNHZSjyTVwQpUXQbDZrrs/PS2Wau3Aii+LIFwm/A==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "tslib": "^2.4.0" + "@ionic/cli-framework-output": "^2.2.8", + "@ionic/utils-subprocess": "^3.0.1", + "@ionic/utils-terminal": "^2.3.5", + "commander": "^12.1.0", + "debug": "^4.4.0", + "env-paths": "^2.2.0", + "fs-extra": "^11.2.0", + "kleur": "^4.1.5", + "native-run": "^2.0.3", + "open": "^8.4.0", + "plist": "^3.1.0", + "prompts": "^2.4.2", + "rimraf": "^6.0.1", + "semver": "^7.6.3", + "tar": "^7.5.3", + "tslib": "^2.8.1", + "xml2js": "^0.6.2" + }, + "bin": { + "cap": "bin/capacitor", + "capacitor": "bin/capacitor" + }, + "engines": { + "node": ">=22.0.0" } }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "node_modules/@capacitor/cli/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "engines": { + "node": ">=18" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "node_modules/@capacitor/cli/node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "node_modules/@capacitor/cli/node_modules/fs-extra": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", + "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@tybys/wasm-util": "^0.10.1" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@capacitor/cli/node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, - "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@oxc-project/types": { - "version": "0.129.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.129.0.tgz", - "integrity": "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg==", + "node_modules/@capacitor/cli/node_modules/rimraf": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", + "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", "dev": true, - "license": "MIT", + "license": "BlueOak-1.0.0", + "dependencies": { + "glob": "^13.0.3", + "package-json-from-dist": "^1.0.1" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, "funding": { - "url": "https://github.com/sponsors/Boshen" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@remix-run/router": { - "version": "1.23.2", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz", - "integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==", + "node_modules/@capacitor/core": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/@capacitor/core/-/core-8.3.4.tgz", + "integrity": "sha512-CqRQCkb6HXxcx/N7s+hHTN6ef2CmamFiRMITwm4qB840ph56mS42bzUgn6tKCP+RZjdDweiRHj9ytDDeN6jFag==", "license": "MIT", - "engines": { - "node": ">=14.0.0" + "dependencies": { + "tslib": "^2.1.0" } }, - "node_modules/@rolldown/binding-android-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0.tgz", - "integrity": "sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA==", - "cpu": [ - "arm64" - ], + "node_modules/@develar/schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0.tgz", - "integrity": "sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew==", - "cpu": [ - "arm64" - ], + "node_modules/@electron/asar": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz", + "integrity": "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=10.12.0" } }, - "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0.tgz", - "integrity": "sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ==", - "cpu": [ - "x64" - ], + "node_modules/@electron/asar/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@electron/asar/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@electron/asar/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": "*" } }, - "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0.tgz", - "integrity": "sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ==", - "cpu": [ - "x64" - ], + "node_modules/@electron/fuses": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@electron/fuses/-/fuses-1.8.0.tgz", + "integrity": "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^20.19.0 || >=22.12.0" + "dependencies": { + "chalk": "^4.1.1", + "fs-extra": "^9.0.1", + "minimist": "^1.2.5" + }, + "bin": { + "electron-fuses": "dist/bin.js" } }, - "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0.tgz", - "integrity": "sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A==", - "cpu": [ - "arm" - ], + "node_modules/@electron/fuses/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=10" } }, - "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0.tgz", - "integrity": "sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ==", - "cpu": [ - "arm64" - ], + "node_modules/@electron/get": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-5.0.0.tgz", + "integrity": "sha512-pjoBpru1KdEtcExBnuHAP1cAc/5faoedw0hzJkL3o4/IJp7HNF1+fbrdxT3gMYRX2oJfvnA/WXeCTVQpYYxyJA==", "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^3.0.0", + "graceful-fs": "^4.2.11", + "progress": "^2.0.3", + "semver": "^7.6.3", + "sumchecker": "^3.0.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=22.12.0" + }, + "optionalDependencies": { + "undici": "^7.24.4" } }, - "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0.tgz", - "integrity": "sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA==", - "cpu": [ - "arm64" - ], + "node_modules/@electron/notarize": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz", + "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==", "dev": true, - "libc": [ - "musl" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1", + "promise-retry": "^2.0.1" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 10.0.0" } }, - "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0.tgz", - "integrity": "sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg==", - "cpu": [ - "ppc64" - ], + "node_modules/@electron/notarize/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=10" } }, - "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0.tgz", - "integrity": "sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA==", - "cpu": [ - "s390x" - ], + "node_modules/@electron/osx-sign": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz", + "integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==", "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "license": "BSD-2-Clause", + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=12.0.0" } }, - "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0.tgz", - "integrity": "sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA==", - "cpu": [ - "x64" - ], + "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" } }, - "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0.tgz", - "integrity": "sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw==", - "cpu": [ - "x64" - ], + "node_modules/@electron/rebuild": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-4.0.4.tgz", + "integrity": "sha512-Rzc39XPdk/+/wBG8MfwAHohXflep0ITUfulb6Rgz3R0NeSB1noE+E9/M/cb8ftCAiyDD9PPhLuuWgE1GaInbKg==", "dev": true, - "libc": [ - "musl" - ], "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.1.1", + "node-abi": "^4.2.0", + "node-api-version": "^0.2.1", + "node-gyp": "^12.2.0", + "read-binary-file-arch": "^1.0.6" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=22.12.0" } }, - "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0.tgz", - "integrity": "sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig==", - "cpu": [ - "arm64" - ], + "node_modules/@electron/universal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.3.tgz", + "integrity": "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], + "dependencies": { + "@electron/asar": "^3.3.1", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "dir-compare": "^4.2.0", + "fs-extra": "^11.1.1", + "minimatch": "^9.0.3", + "plist": "^3.1.0" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=16.4" } }, - "node_modules/@rolldown/binding-wasm32-wasi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0.tgz", - "integrity": "sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg==", - "cpu": [ - "wasm32" - ], + "node_modules/@electron/universal/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@electron/universal/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" + "balanced-match": "^1.0.0" } }, - "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0.tgz", - "integrity": "sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow==", - "cpu": [ - "arm64" - ], + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", + "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=14.14" } }, - "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0.tgz", - "integrity": "sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg==", - "cpu": [ - "x64" - ], + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-rc.7", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", - "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", + "node_modules/@electron/windows-sign": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", + "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", "dev": true, - "license": "MIT" + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "cross-dirname": "^0.1.0", + "debug": "^4.3.4", + "fs-extra": "^11.1.1", + "minimist": "^1.2.8", + "postject": "^1.0.0-alpha.6" + }, + "bin": { + "electron-windows-sign": "bin/electron-windows-sign.js" + }, + "engines": { + "node": ">=14.14" + } }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "node_modules/@electron/windows-sign/node_modules/fs-extra": { + "version": "11.3.5", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.5.tgz", + "integrity": "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "dev": true, "license": "MIT", "optional": true, "dependencies": { + "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" + "tslib": "^2.4.0" } }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "node_modules/@ionic/cli-framework-output": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/@ionic/cli-framework-output/-/cli-framework-output-2.2.8.tgz", + "integrity": "sha512-TshtaFQsovB4NWRBydbNFawql6yul7d5bMiW1WYYf17hd99V6xdDdk3vtF51bw6sLkxON3bDQpWsnUc9/hVo3g==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } }, - "node_modules/@types/prop-types": { - "version": "15.7.15", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", - "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "node_modules/@ionic/utils-array": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-array/-/utils-array-2.1.6.tgz", + "integrity": "sha512-0JZ1Zkp3wURnv8oq6Qt7fMPo5MpjbLoUoa9Bu2Q4PJuSDWM8H8gwF3dQO7VTeUj3/0o1IB1wGkFWZZYgUXZMUg==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "debug": "^4.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" + } }, - "node_modules/@types/react": { - "version": "18.3.28", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz", - "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", + "node_modules/@ionic/utils-fs": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-fs/-/utils-fs-3.1.7.tgz", + "integrity": "sha512-2EknRvMVfhnyhL1VhFkSLa5gOcycK91VnjfrTB0kbqkTFCOXyXgVLI5whzq7SLrgD9t1aqos3lMMQyVzaQ5gVA==", "dev": true, "license": "MIT", "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.2.2" + "@types/fs-extra": "^8.0.0", + "debug": "^4.0.0", + "fs-extra": "^9.0.0", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@types/react-dom": { - "version": "18.3.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", - "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "node_modules/@ionic/utils-fs/node_modules/@types/fs-extra": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", "dev": true, "license": "MIT", - "peerDependencies": { - "@types/react": "^18.0.0" + "dependencies": { + "@types/node": "*" } }, - "node_modules/@vitejs/plugin-react": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz", - "integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==", + "node_modules/@ionic/utils-fs/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "license": "MIT", "dependencies": { - "@rolldown/pluginutils": "1.0.0-rc.7" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", - "babel-plugin-react-compiler": "^1.0.0", - "vite": "^8.0.0" - }, - "peerDependenciesMeta": { - "@rolldown/plugin-babel": { - "optional": true - }, - "babel-plugin-react-compiler": { - "optional": true - } + "node": ">=10" } }, - "node_modules/@vitest/expect": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.6.tgz", - "integrity": "sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==", + "node_modules/@ionic/utils-object": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@ionic/utils-object/-/utils-object-2.1.6.tgz", + "integrity": "sha512-vCl7sl6JjBHFw99CuAqHljYJpcE88YaH2ZW4ELiC/Zwxl5tiwn4kbdP/gxi2OT3MQb1vOtgAmSNRtusvgxI8ww==", "dev": true, "license": "MIT", "dependencies": { - "@standard-schema/spec": "^1.1.0", - "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.6", - "@vitest/utils": "4.1.6", - "chai": "^6.2.2", - "tinyrainbow": "^3.1.0" + "debug": "^4.0.0", + "tslib": "^2.0.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@vitest/mocker": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.6.tgz", - "integrity": "sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==", + "node_modules/@ionic/utils-process": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/@ionic/utils-process/-/utils-process-2.1.12.tgz", + "integrity": "sha512-Jqkgyq7zBs/v/J3YvKtQQiIcxfJyplPgECMWgdO0E1fKrrH8EF0QGHNJ9mJCn6PYe2UtHNS8JJf5G21e09DfYg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.6", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.21" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@ionic/utils-object": "2.1.6", + "@ionic/utils-terminal": "2.3.5", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "tslib": "^2.0.1" }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@vitest/pretty-format": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.6.tgz", - "integrity": "sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==", + "node_modules/@ionic/utils-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@ionic/utils-stream/-/utils-stream-3.1.7.tgz", + "integrity": "sha512-eSELBE7NWNFIHTbTC2jiMvh1ABKGIpGdUIvARsNPMNQhxJB3wpwdiVnoBoTYp+5a6UUIww4Kpg7v6S7iTctH1w==", "dev": true, "license": "MIT", "dependencies": { - "tinyrainbow": "^3.1.0" + "debug": "^4.0.0", + "tslib": "^2.0.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@vitest/runner": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.6.tgz", - "integrity": "sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==", + "node_modules/@ionic/utils-subprocess": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@ionic/utils-subprocess/-/utils-subprocess-3.0.1.tgz", + "integrity": "sha512-cT4te3AQQPeIM9WCwIg8ohroJ8TjsYaMb2G4ZEgv9YzeDqHZ4JpeIKqG2SoaA3GmVQ3sOfhPM6Ox9sxphV/d1A==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.6", - "pathe": "^2.0.3" + "@ionic/utils-array": "2.1.6", + "@ionic/utils-fs": "3.1.7", + "@ionic/utils-process": "2.1.12", + "@ionic/utils-stream": "3.1.7", + "@ionic/utils-terminal": "2.3.5", + "cross-spawn": "^7.0.3", + "debug": "^4.0.0", + "tslib": "^2.0.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@vitest/snapshot": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.6.tgz", - "integrity": "sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==", + "node_modules/@ionic/utils-terminal": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@ionic/utils-terminal/-/utils-terminal-2.3.5.tgz", + "integrity": "sha512-3cKScz9Jx2/Pr9ijj1OzGlBDfcmx7OMVBt4+P1uRR0SSW4cm1/y3Mo4OY3lfkuaYifMNBW8Wz6lQHbs1bihr7A==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.6", - "@vitest/utils": "4.1.6", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" + "@types/slice-ansi": "^4.0.0", + "debug": "^4.0.0", + "signal-exit": "^3.0.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "tslib": "^2.0.1", + "untildify": "^4.0.0", + "wrap-ansi": "^7.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/@vitest/spy": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.6.tgz", - "integrity": "sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.6.tgz", - "integrity": "sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==", + "node_modules/@ionic/utils-terminal/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.6", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.1.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=12" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, "engines": { - "node": ">=18" + "node": ">=18.0.0" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "node_modules/@malept/cross-spawn-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", + "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], "license": "Apache-2.0", + "dependencies": { + "cross-spawn": "^7.0.1" + }, "engines": { - "node": ">=8" + "node": ">= 12.13.0" } }, - "node_modules/es-module-lexer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", - "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/@malept/flatpak-bundler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", + "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0" + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">= 10.0.0" } }, - "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, "engines": { - "node": ">=12.0.0" + "node": ">=10" } }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12.0.0" + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" }, - "peerDependencies": { - "picomatch": "^3 || ^4" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, + "node_modules/@noble/hashes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", + "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" + "node_modules/@noble/secp256k1": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-3.1.0.tgz", + "integrity": "sha512-+F7iS7tUMaNGXcc9X3PjmjvuQnXEuSjCRNzVVA2xAcKXgCaP0dHYz4SFyt4FKNHef7sOP//xihowcySSS7PK9g==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "node_modules/lightningcss": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", - "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "node_modules/@oxc-project/types": { + "version": "0.129.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.129.0.tgz", + "integrity": "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg==", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.32.0", - "lightningcss-darwin-arm64": "1.32.0", - "lightningcss-darwin-x64": "1.32.0", - "lightningcss-freebsd-x64": "1.32.0", - "lightningcss-linux-arm-gnueabihf": "1.32.0", - "lightningcss-linux-arm64-gnu": "1.32.0", - "lightningcss-linux-arm64-musl": "1.32.0", - "lightningcss-linux-x64-gnu": "1.32.0", - "lightningcss-linux-x64-musl": "1.32.0", - "lightningcss-win32-arm64-msvc": "1.32.0", - "lightningcss-win32-x64-msvc": "1.32.0" + "url": "https://github.com/sponsors/Boshen" } }, - "node_modules/lightningcss-android-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", - "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "node_modules/@remix-run/router": { + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.2.tgz", + "integrity": "sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0.tgz", + "integrity": "sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA==", "cpu": [ "arm64" ], "dev": true, - "license": "MPL-2.0", + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", - "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0.tgz", + "integrity": "sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew==", "cpu": [ "arm64" ], "dev": true, - "license": "MPL-2.0", + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", - "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0.tgz", + "integrity": "sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ==", "cpu": [ "x64" ], "dev": true, - "license": "MPL-2.0", + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", - "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0.tgz", + "integrity": "sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ==", "cpu": [ "x64" ], "dev": true, - "license": "MPL-2.0", + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", - "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0.tgz", + "integrity": "sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A==", "cpu": [ "arm" ], "dev": true, - "license": "MPL-2.0", + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", - "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0.tgz", + "integrity": "sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ==", "cpu": [ "arm64" ], @@ -849,23 +905,19 @@ "libc": [ "glibc" ], - "license": "MPL-2.0", + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", - "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0.tgz", + "integrity": "sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA==", "cpu": [ "arm64" ], @@ -873,363 +925,4280 @@ "libc": [ "musl" ], - "license": "MPL-2.0", + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", - "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0.tgz", + "integrity": "sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg==", "cpu": [ - "x64" + "ppc64" ], "dev": true, "libc": [ "glibc" ], - "license": "MPL-2.0", + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", - "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0.tgz", + "integrity": "sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA==", "cpu": [ - "x64" + "s390x" ], "dev": true, "libc": [ - "musl" + "glibc" ], - "license": "MPL-2.0", + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", - "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0.tgz", + "integrity": "sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA==", "cpu": [ - "arm64" + "x64" ], "dev": true, - "license": "MPL-2.0", + "libc": [ + "glibc" + ], + "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", - "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0.tgz", + "integrity": "sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw==", "cpu": [ "x64" ], "dev": true, - "license": "MPL-2.0", + "libc": [ + "musl" + ], + "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0.tgz", + "integrity": "sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lucide-react": { - "version": "0.468.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.468.0.tgz", - "integrity": "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA==", - "license": "ISC", - "peerDependencies": { - "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0.tgz", + "integrity": "sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg==", + "cpu": [ + "wasm32" + ], "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/nanoid": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", - "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0.tgz", + "integrity": "sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow==", + "cpu": [ + "arm64" ], + "dev": true, "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/obug": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", - "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0.tgz", + "integrity": "sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg==", + "cpu": [ + "x64" + ], "dev": true, - "funding": [ - "https://github.com/sponsors/sxzz", - "https://opencollective.com/debug" + "license": "MIT", + "optional": true, + "os": [ + "win32" ], - "license": "MIT" + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.7", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz", + "integrity": "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==", "dev": true, "license": "MIT" }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/postcss": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", - "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, + "license": "MIT" + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.12.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.4.tgz", + "integrity": "sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/plist": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", + "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*", + "xmlbuilder": ">=11.0.1" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.28", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz", + "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-+OpjSaq85gvlZAYINyzKpLeiFkSC4EsC6IIiT6v6TLSU5k5U83fHGj9Lel8oKEXM0HqgrMVCjXPDPVICtxF7EQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/verror": { + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz", + "integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz", + "integrity": "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "1.0.0-rc.7" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.6.tgz", + "integrity": "sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.6", + "@vitest/utils": "4.1.6", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.6.tgz", + "integrity": "sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.6", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.6.tgz", + "integrity": "sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.6.tgz", + "integrity": "sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.6", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.6.tgz", + "integrity": "sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.6", + "@vitest/utils": "4.1.6", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.6.tgz", + "integrity": "sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.6.tgz", + "integrity": "sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.6", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.13", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", + "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/7zip-bin": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz", + "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/app-builder-bin": { + "version": "5.0.0-alpha.12", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz", + "integrity": "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/app-builder-lib": { + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-26.8.1.tgz", + "integrity": "sha512-p0Im/Dx5C4tmz8QEE1Yn4MkuPC8PrnlRneMhWJj7BBXQfNTJUshM/bp3lusdEsDbvvfJZpXWnYesgSLvwtM2Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@develar/schema-utils": "~2.6.5", + "@electron/asar": "3.4.1", + "@electron/fuses": "^1.8.0", + "@electron/get": "^3.0.0", + "@electron/notarize": "2.5.0", + "@electron/osx-sign": "1.3.3", + "@electron/rebuild": "^4.0.3", + "@electron/universal": "2.0.3", + "@malept/flatpak-bundler": "^0.4.0", + "@types/fs-extra": "9.0.13", + "async-exit-hook": "^2.0.1", + "builder-util": "26.8.1", + "builder-util-runtime": "9.5.1", + "chromium-pickle-js": "^0.2.0", + "ci-info": "4.3.1", + "debug": "^4.3.4", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", + "ejs": "^3.1.8", + "electron-publish": "26.8.1", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "isbinaryfile": "^5.0.0", + "jiti": "^2.4.2", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "lazy-val": "^1.0.5", + "minimatch": "^10.0.3", + "plist": "3.1.0", + "proper-lockfile": "^4.1.2", + "resedit": "^1.7.0", + "semver": "~7.7.3", + "tar": "^7.5.7", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0", + "which": "^5.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "dmg-builder": "26.8.1", + "electron-builder-squirrel-windows": "26.8.1" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-3.1.0.tgz", + "integrity": "sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=14" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/get/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/app-builder-lib/node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/app-builder-lib/node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/app-builder-lib/node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/app-builder-lib/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/app-builder-lib/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/app-builder-lib/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/bplist-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz", + "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "big-integer": "1.6.x" + }, + "engines": { + "node": ">= 5.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/builder-util": { + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-26.8.1.tgz", + "integrity": "sha512-pm1lTYbGyc90DHgCDO7eo8Rl4EqKLciayNbZqGziqnH9jrlKe8ZANGdityLZU+pJh16dfzjAx2xQq9McuIPEtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/debug": "^4.1.6", + "7zip-bin": "~5.2.0", + "app-builder-bin": "5.0.0-alpha.12", + "builder-util-runtime": "9.5.1", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.6", + "debug": "^4.3.4", + "fs-extra": "^10.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "js-yaml": "^4.1.0", + "sanitize-filename": "^1.6.3", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.4.0", + "tiny-async-pool": "1.3.0" + } + }, + "node_modules/builder-util-runtime": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.5.1.tgz", + "integrity": "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/compare-version": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.1.0" + } + }, + "node_modules/cross-dirname": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cross-dirname/-/cross-dirname-0.1.0.tgz", + "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/dir-compare": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", + "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " + } + }, + "node_modules/dir-compare/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/dir-compare/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/dir-compare/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dmg-builder": { + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-26.8.1.tgz", + "integrity": "sha512-glMJgnTreo8CFINujtAhCgN96QAqApDMZ8Vl1r8f0QT8QprvC1UCltV4CcWj20YoIyLZx6IUskaJZ0NV8fokcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.8.1", + "builder-util": "26.8.1", + "fs-extra": "^10.1.0", + "iconv-lite": "^0.6.2", + "js-yaml": "^4.1.0" + }, + "optionalDependencies": { + "dmg-license": "^1.0.11" + } + }, + "node_modules/dmg-license": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", + "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "@types/plist": "^3.0.1", + "@types/verror": "^1.10.3", + "ajv": "^6.10.0", + "crc": "^3.8.0", + "iconv-corefoundation": "^1.1.7", + "plist": "^3.0.4", + "smart-buffer": "^4.0.2", + "verror": "^1.10.0" + }, + "bin": { + "dmg-license": "bin/dmg-license.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.7.tgz", + "integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron": { + "version": "42.0.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-42.0.1.tgz", + "integrity": "sha512-d8HnycE970DGESe91Nj30eonFBUcAI9EZ1TwUGJVzSAnJZdh0BkFEinAXjdklvDYst+bVDc8HsksCuqVLrnqdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/get": "^5.0.0", + "@types/node": "^24.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js", + "install-electron": "install.js" + }, + "engines": { + "node": ">= 22.12.0" + } + }, + "node_modules/electron-builder": { + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-26.8.1.tgz", + "integrity": "sha512-uWhx1r74NGpCagG0ULs/P9Nqv2nsoo+7eo4fLUOB8L8MdWltq9odW/uuLXMFCDGnPafknYLZgjNX0ZIFRzOQAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "26.8.1", + "builder-util": "26.8.1", + "builder-util-runtime": "9.5.1", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "dmg-builder": "26.8.1", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "simple-update-notifier": "2.0.0", + "yargs": "^17.6.2" + }, + "bin": { + "electron-builder": "cli.js", + "install-app-deps": "install-app-deps.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/electron-builder-squirrel-windows": { + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.8.1.tgz", + "integrity": "sha512-o288fIdgPLHA76eDrFADHPoo7VyGkDCYbLV1GzndaMSAVBoZrGvM9m2IehdcVMzdAZJ2eV9bgyissQXHv5tGzA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "app-builder-lib": "26.8.1", + "builder-util": "26.8.1", + "electron-winstaller": "5.4.0" + } + }, + "node_modules/electron-publish": { + "version": "26.8.1", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-26.8.1.tgz", + "integrity": "sha512-q+jrSTIh/Cv4eGZa7oVR+grEJo/FoLMYBAnSL5GCtqwUpr1T+VgKB/dn1pnzxIxqD8S/jP1yilT9VrwCqINR4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^9.0.11", + "builder-util": "26.8.1", + "builder-util-runtime": "9.5.1", + "chalk": "^4.1.2", + "form-data": "^4.0.5", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" + } + }, + "node_modules/electron-winstaller": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.4.0.tgz", + "integrity": "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@electron/asar": "^3.2.1", + "debug": "^4.1.1", + "fs-extra": "^7.0.1", + "lodash": "^4.17.21", + "temp": "^0.9.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "optionalDependencies": { + "@electron/windows-sign": "^1.1.2" + } + }, + "node_modules/electron-winstaller/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/electron-winstaller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-winstaller/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/elementtree": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/elementtree/-/elementtree-0.1.7.tgz", + "integrity": "sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "sax": "1.1.4" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/elementtree/node_modules/sax": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.4.tgz", + "integrity": "sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "optional": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filelist": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", + "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-corefoundation": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", + "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "cli-truncate": "^2.1.0", + "node-addon-api": "^1.6.3" + }, + "engines": { + "node": "^8.11.2 || >=10" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isbinaryfile": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.7.tgz", + "integrity": "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz", + "integrity": "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", + "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lazy-val": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lucide-react": { + "version": "0.468.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.468.0.tgz", + "integrity": "sha512-6koYRhnM2N0GGZIdXzSeiNwguv1gt/FAjZOiPl76roBi3xKEXa4WmfpxgQwTTL4KipXjefrnf3oV4IsYhi4JFA==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/native-run": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/native-run/-/native-run-2.0.3.tgz", + "integrity": "sha512-U1PllBuzW5d1gfan+88L+Hky2eZx+9gv3Pf6rNBxKbORxi7boHzqiA6QFGSnqMem4j0A9tZ08NMIs5+0m/VS1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ionic/utils-fs": "^3.1.7", + "@ionic/utils-terminal": "^2.3.4", + "bplist-parser": "^0.3.2", + "debug": "^4.3.4", + "elementtree": "^0.1.7", + "ini": "^4.1.1", + "plist": "^3.1.0", + "split2": "^4.2.0", + "through2": "^4.0.2", + "tslib": "^2.6.2", + "yauzl": "^2.10.0" + }, + "bin": { + "native-run": "bin/native-run" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/node-abi": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-4.31.0.tgz", + "integrity": "sha512-Erq5w/t3syw3s4sDsUaX4QttIdBPsGKTT1DTRsCkTonGggczhlDKm/wDX3o+HPJpQ41EjXCbcmXf0tgr5YZJXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.6.3" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-api-version": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.1.tgz", + "integrity": "sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + } + }, + "node_modules/node-gyp": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.3.0.tgz", + "integrity": "sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "undici": "^6.25.0", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp/node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/node-gyp/node_modules/undici": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/pe-library": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz", + "integrity": "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postject": { + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", + "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "commander": "^9.4.0" + }, + "bin": { + "postject": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/postject/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-router": { + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz", + "integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.30.3", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz", + "integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.23.2", + "react-router": "6.30.3" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/read-binary-file-arch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz", + "integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "bin": { + "read-binary-file-arch": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resedit": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.2.tgz", + "integrity": "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pe-library": "^0.4.1" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/rolldown": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0.tgz", + "integrity": "sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.129.0", + "@rolldown/pluginutils": "1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0", + "@rolldown/binding-darwin-arm64": "1.0.0", + "@rolldown/binding-darwin-x64": "1.0.0", + "@rolldown/binding-freebsd-x64": "1.0.0", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0", + "@rolldown/binding-linux-arm64-gnu": "1.0.0", + "@rolldown/binding-linux-arm64-musl": "1.0.0", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0", + "@rolldown/binding-linux-s390x-gnu": "1.0.0", + "@rolldown/binding-linux-x64-gnu": "1.0.0", + "@rolldown/binding-linux-x64-musl": "1.0.0", + "@rolldown/binding-openharmony-arm64": "1.0.0", + "@rolldown/binding-wasm32-wasi": "1.0.0", + "@rolldown/binding-win32-arm64-msvc": "1.0.0", + "@rolldown/binding-win32-x64-msvc": "1.0.0" + } + }, + "node_modules/rolldown/node_modules/@rolldown/pluginutils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0.tgz", + "integrity": "sha512-aKs/3GSWyV0mrhNmt/96/Z3yczC3yvrzYATCiCXQebBsGyYzjNdUphRVLeJQ67ySKVXRfMxt2lm12pmXvbPFQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ { "type": "github", - "url": "https://github.com/sponsors/ai" + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sanitize-filename": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.4.tgz", + "integrity": "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==", + "dev": true, + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz", + "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=10" } }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/stat-mode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/std-env": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", + "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { - "loose-envify": "^1.1.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "license": "MIT", + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" + "debug": "^4.1.0" }, - "peerDependencies": { - "react": "^18.3.1" + "engines": { + "node": ">= 8.0" } }, - "node_modules/react-router": { - "version": "6.30.3", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.3.tgz", - "integrity": "sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { - "@remix-run/router": "1.23.2" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8" + "node": ">=8" } }, - "node_modules/react-router-dom": { - "version": "6.30.3", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.3.tgz", - "integrity": "sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==", - "license": "MIT", + "node_modules/tar": { + "version": "7.5.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.15.tgz", + "integrity": "sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "@remix-run/router": "1.23.2", - "react-router": "6.30.3" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" + "node": ">=18" } }, - "node_modules/rolldown": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0.tgz", - "integrity": "sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA==", + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/temp": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.4.tgz", + "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@oxc-project/types": "=0.129.0", - "@rolldown/pluginutils": "1.0.0" - }, - "bin": { - "rolldown": "bin/cli.mjs" + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" }, "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "optionalDependencies": { - "@rolldown/binding-android-arm64": "1.0.0", - "@rolldown/binding-darwin-arm64": "1.0.0", - "@rolldown/binding-darwin-x64": "1.0.0", - "@rolldown/binding-freebsd-x64": "1.0.0", - "@rolldown/binding-linux-arm-gnueabihf": "1.0.0", - "@rolldown/binding-linux-arm64-gnu": "1.0.0", - "@rolldown/binding-linux-arm64-musl": "1.0.0", - "@rolldown/binding-linux-ppc64-gnu": "1.0.0", - "@rolldown/binding-linux-s390x-gnu": "1.0.0", - "@rolldown/binding-linux-x64-gnu": "1.0.0", - "@rolldown/binding-linux-x64-musl": "1.0.0", - "@rolldown/binding-openharmony-arm64": "1.0.0", - "@rolldown/binding-wasm32-wasi": "1.0.0", - "@rolldown/binding-win32-arm64-msvc": "1.0.0", - "@rolldown/binding-win32-x64-msvc": "1.0.0" + "node": ">=6.0.0" } }, - "node_modules/rolldown/node_modules/@rolldown/pluginutils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0.tgz", - "integrity": "sha512-aKs/3GSWyV0mrhNmt/96/Z3yczC3yvrzYATCiCXQebBsGyYzjNdUphRVLeJQ67ySKVXRfMxt2lm12pmXvbPFQQ==", + "node_modules/temp-file": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", + "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", "dev": true, - "license": "MIT" - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", "dependencies": { - "loose-envify": "^1.1.0" + "async-exit-hook": "^2.0.1", + "fs-extra": "^10.0.0" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "dependencies": { + "readable-stream": "3" } }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "node_modules/tiny-async-pool": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz", + "integrity": "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "semver": "^5.5.0" + } }, - "node_modules/std-env": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", - "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "node_modules/tiny-async-pool/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "MIT" + "license": "ISC", + "bin": { + "semver": "bin/semver" + } }, "node_modules/tinybench": { "version": "2.9.0", @@ -1275,13 +5244,65 @@ "node": ">=14.0.0" } }, + "node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", "dev": true, - "license": "0BSD", - "optional": true + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/typescript": { "version": "5.9.3", @@ -1297,6 +5318,84 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/vite": { "version": "8.0.12", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.12.tgz", @@ -1465,6 +5564,22 @@ } } }, + "node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", @@ -1481,6 +5596,135 @@ "engines": { "node": ">=8" } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xml2js/node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index cda2a83a..f70f467e 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -2,24 +2,42 @@ "name": "@flowmemory/dashboard", "private": true, "version": "0.0.0", + "description": "Flowchain desktop wallet and local bridge console.", + "author": "FlowmemoryAI", "type": "module", + "main": "electron/main.cjs", "scripts": { "dev": "npm run sync:fixtures && vite --host 127.0.0.1", "build": "npm run sync:fixtures && tsc -b && vite build", + "desktop": "npm run build && electron electron/main.cjs", + "desktop:pack": "npm run build && electron-builder --config electron-builder.json --win --x64 --dir && powershell -NoProfile -ExecutionPolicy Bypass -File scripts/package-desktop-wallet.ps1", + "desktop:installer:win": "npm run build && electron-builder --config electron-builder.json --win nsis zip --x64", + "desktop:installer:mac": "npm run build && electron-builder --config electron-builder.json --mac dmg zip", + "desktop:installer:linux": "npm run build && electron-builder --config electron-builder.json --linux AppImage zip", + "mobile:sync": "npm run build && cap sync", + "mobile:android:sync": "npm run build && cap sync android", + "mobile:android:debug": "npm run mobile:android:sync && cd android && gradlew.bat assembleDebug", "test": "vitest run", "typecheck": "tsc -b", "sync:fixtures": "node scripts/sync-fixtures.mjs" }, "dependencies": { + "@capacitor/android": "^8.3.4", + "@capacitor/core": "^8.3.4", + "@noble/hashes": "^2.2.0", + "@noble/secp256k1": "^3.1.0", "lucide-react": "^0.468.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.28.0" }, "devDependencies": { + "@capacitor/cli": "^8.3.4", "@types/react": "^18.3.18", "@types/react-dom": "^18.3.5", "@vitejs/plugin-react": "^6.0.1", + "electron": "^42.0.1", + "electron-builder": "^26.8.1", "typescript": "^5.6.3", "vite": "^8.0.12", "vitest": "^4.1.6" diff --git a/apps/dashboard/public/data/flowchain-bridge-test-deposit.json b/apps/dashboard/public/data/flowchain-bridge-test-deposit.json index f43813a2..19772f29 100644 --- a/apps/dashboard/public/data/flowchain-bridge-test-deposit.json +++ b/apps/dashboard/public/data/flowchain-bridge-test-deposit.json @@ -8,8 +8,8 @@ "token": "0x3333333333333333333333333333333333333333", "amount": "20000000", "sender": "0x4444444444444444444444444444444444444444", - "flowchainRecipient": "0x5555555555555555555555555555555555555555555555555555555555555555", + "flowchainRecipient": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "nonce": "1", - "metadataHash": "0x6666666666666666666666666666666666666666666666666666666666666666", + "metadataHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "status": "observed" } diff --git a/apps/dashboard/public/data/flowchain-local-devnet-dashboard-state.json b/apps/dashboard/public/data/flowchain-local-devnet-dashboard-state.json index 2ecd1722..7d49bdb2 100644 --- a/apps/dashboard/public/data/flowchain-local-devnet-dashboard-state.json +++ b/apps/dashboard/public/data/flowchain-local-devnet-dashboard-state.json @@ -31,19 +31,25 @@ }, "balanceTransfers": {}, "baseAnchors": { - "0xf57ab7d2c1459c03cf01bfddd56b046be685d8eaa4597e6bb54b5015aeaf003f": { + "0x6908eac7dbf828ab8d295d2ae86f0b0db9295a27b1fe4999c26a3ed97244ef8d": { "agentAccountRoot": "0xcf31230bfff347f79e19a55f4d1ff5fa486b0b1ad4754ce22b93de4b259a3ca7", - "anchorId": "0xf57ab7d2c1459c03cf01bfddd56b046be685d8eaa4597e6bb54b5015aeaf003f", + "anchorId": "0x6908eac7dbf828ab8d295d2ae86f0b0db9295a27b1fe4999c26a3ed97244ef8d", "appchainChainId": "flowmemory-local-devnet-v0", "artifactAvailabilityProofRoot": "0xfb4b693c45014aae0947f35696e9d864e7b26ac6fd39c1df5edb3e0dcf9bd928", "artifactCommitmentRoot": "0xb772a9f7273032fd3ba2da8b6476d4715bbbafbd2a7eed21ecd0d558bde3beab", "balanceTransferRoot": "0x9b6e249f769a93bc9f34a90156e028d1a830badcd8ccdc5b1487d512cdbf0a6d", "blockRangeEnd": 1, "blockRangeStart": 1, + "bridgeAccountMappingRoot": "0x46285ec5782d3e6cc1e557fd5dd779e979d679e5cc723832cb189d27a5c552c8", + "bridgeAssetMappingRoot": "0xbd283f6190cba76038f7364e207557dd20f7883d78e5f89a96579af5455a89aa", + "bridgeCreditReceiptRoot": "0x0a86ce98161cb40ca4c7719468c0ed8f122677d12641c13305277094b8f3a509", + "bridgeCreditRoot": "0x613ab06f110cc7a5eb06a0f44b7a0f04b0b3cfb0556d30d42842f33563596248", + "bridgeEventReceiptIndexRoot": "0xcaad305c45f57c516d0fdfdef15c5d88b399b976df173f005e9d7dc30fbdbdb2", + "bridgeReplayIndexRoot": "0x9344f8651651d2d5042d2853205154a5777cd57aa9e892e2ac41b9b9fe04c00f", "challengeRoot": "0x16da3d2bf2dcd801bc5deb3987dc01342cb957031ad01408ea77bf5d1583656f", "dexPoolRoot": "0x0e5f034494a2deb6a4f20c04f01e678795c587df4869ad3f189f107fcc447dea", "faucetRecordRoot": "0x2277503a52fab3f9e49b40debfb7d641abee75cf268aa56da403fdcf4fad6cee", - "finalityReceiptRoot": "0xdf352e20fd1ddfd2855202335e03cfec21d87e99bf8717d161fe8648998e16cf", + "finalityReceiptRoot": "0x1c8536e507c5ba2242a5875c9537043645828825286ca256cc1171f1eb960c3f", "finalityStatus": "local-placeholder", "liquidityReceiptRoot": "0x98bf15cc6859994038744612e125236b1f777895a051c41702c2004134327738", "localTestUnitBalanceRoot": "0x167041ef195b5dde2d2cade6ecb26c9a0a596e9ed21ff7bfb02d33c9d2be8d15", @@ -53,7 +59,7 @@ "operatorKeyReferenceRoot": "0x8457aa3ed0f4238834a8f3925f25ccca805828d8427c3ef67590a45659b22a40", "previousAnchorId": "0x0000000000000000000000000000000000000000000000000000000000000000", "rootfieldStateRoot": "0xb72a851dca1103410484e3272945bae5e87fc39b8f32f77d2991959b60d3bfbf", - "stateRoot": "0x8c7c1e7a078b60a809d17a51c44e275059afb8d7535769430c3fc9e9320c7e23", + "stateRoot": "0x7e50021bc0dd2537f9ecfd7973f9799b6ffdffcfd427e3bb059f4dfd1253b947", "swapReceiptRoot": "0xc9f3ee93962f36ed10421ec9ad736079a3b13ef6504336495af243b718cefee1", "tokenBalanceRoot": "0xbaf3b150fe41a0f3a2d9fe3dd9a664f9c5934bfef37218d9c3bf1c682be5f8c6", "tokenDefinitionRoot": "0xbbbad9681e8756403940e4333111706a4fcee1f30534ba14deea9ba148056be0", @@ -64,6 +70,12 @@ } }, "blockHeight": 2, + "bridgeAccountMappings": {}, + "bridgeAssetMappings": {}, + "bridgeCreditReceipts": {}, + "bridgeCredits": {}, + "bridgeEventReceiptIndex": {}, + "bridgeReplayIndex": {}, "challenges": { "challenge:demo:001": { "challengeId": "challenge:demo:001", @@ -98,7 +110,7 @@ "finalizedBy": "operator:local-demo", "receiptId": "receipt:demo:001", "rootfieldId": "rootfield:demo:alpha", - "stateRoot": "0x4e7ee5e7a8cab9b4ddda183842b9e9c1e1e000afea820b577ecc90fa4d9517e2" + "stateRoot": "0xf47b94f6d4be36bc5ade63085c9c3c6174d5b25eb5bfaae9a57e3946f5637352" } }, "genesisConfig": { @@ -134,11 +146,17 @@ "artifactAvailabilityProofRoot": "0xfb4b693c45014aae0947f35696e9d864e7b26ac6fd39c1df5edb3e0dcf9bd928", "artifactCommitmentRoot": "0xb772a9f7273032fd3ba2da8b6476d4715bbbafbd2a7eed21ecd0d558bde3beab", "balanceTransferRoot": "0x9b6e249f769a93bc9f34a90156e028d1a830badcd8ccdc5b1487d512cdbf0a6d", - "baseAnchorRoot": "0xa10b087464d8e6098696295a2a4b26a4396974c9ed10dd0bba429f22284cd573", + "baseAnchorRoot": "0x8b7c3423523f44b9a470a1281b088c72537a42e26f88fc8cd4c3e8360324c7ca", + "bridgeAccountMappingRoot": "0x46285ec5782d3e6cc1e557fd5dd779e979d679e5cc723832cb189d27a5c552c8", + "bridgeAssetMappingRoot": "0xbd283f6190cba76038f7364e207557dd20f7883d78e5f89a96579af5455a89aa", + "bridgeCreditReceiptRoot": "0x0a86ce98161cb40ca4c7719468c0ed8f122677d12641c13305277094b8f3a509", + "bridgeCreditRoot": "0x613ab06f110cc7a5eb06a0f44b7a0f04b0b3cfb0556d30d42842f33563596248", + "bridgeEventReceiptIndexRoot": "0xcaad305c45f57c516d0fdfdef15c5d88b399b976df173f005e9d7dc30fbdbdb2", + "bridgeReplayIndexRoot": "0x9344f8651651d2d5042d2853205154a5777cd57aa9e892e2ac41b9b9fe04c00f", "challengeRoot": "0x16da3d2bf2dcd801bc5deb3987dc01342cb957031ad01408ea77bf5d1583656f", "dexPoolRoot": "0x0e5f034494a2deb6a4f20c04f01e678795c587df4869ad3f189f107fcc447dea", "faucetRecordRoot": "0x2277503a52fab3f9e49b40debfb7d641abee75cf268aa56da403fdcf4fad6cee", - "finalityReceiptRoot": "0xdf352e20fd1ddfd2855202335e03cfec21d87e99bf8717d161fe8648998e16cf", + "finalityReceiptRoot": "0x1c8536e507c5ba2242a5875c9537043645828825286ca256cc1171f1eb960c3f", "importedObservationRoot": "0x99cb1b939d5a09f800f72e4c5a2b92988571126e1f6f93549f4893b3f7de7880", "importedVerifierReportRoot": "0x6070b1015f000dd509c7b276d2ad68d8a9d188ef1a961c2f573346eb75ea5ad7", "liquidityReceiptRoot": "0x98bf15cc6859994038744612e125236b1f777895a051c41702c2004134327738", @@ -210,7 +228,7 @@ } }, "schema": "flowmemory.dashboard_state.local_devnet.v0", - "stateRoot": "0x3074ef2e5311d94e8f9a2660a6cc016c7b7f9a08c56ee07f9e841c1489726e68", + "stateRoot": "0xb3c4344483c7be8c0660d49d465d033a88ae26d6a7c1cbe096a2447d32c5648c", "swapReceipts": {}, "tokenBalances": {}, "tokenDefinitions": {}, diff --git a/apps/dashboard/public/data/flowchain-local-devnet-state.json b/apps/dashboard/public/data/flowchain-local-devnet-state.json index 080bdd3f..d8fc300e 100644 --- a/apps/dashboard/public/data/flowchain-local-devnet-state.json +++ b/apps/dashboard/public/data/flowchain-local-devnet-state.json @@ -19,7 +19,7 @@ "genesisHash": "0x0f23c892cbd2d00c10839d97ddab833698a83f8df8d6df27ceac03cfdd4b7bc9", "nextBlockNumber": 3, "logicalTime": 1778688002, - "parentHash": "0x7ddb184c69f798f25f27a254f1f530c6cdc31c9656ac19d1b8c114f7a3a650c6", + "parentHash": "0x64e3d605fb1bba40b7de6a6a9813f77619282c07b9a33c7b41df1f6e3d71958b", "operatorKeyReferences": { "operator-key:local-devnet:alpha": { "schema": "flowmemory.local_devnet.operator_key_reference.v0", @@ -89,6 +89,12 @@ "lpPositions": {}, "liquidityReceipts": {}, "swapReceipts": {}, + "bridgeAssetMappings": {}, + "bridgeAccountMappings": {}, + "bridgeCredits": {}, + "bridgeCreditReceipts": {}, + "bridgeReplayIndex": {}, + "bridgeEventReceiptIndex": {}, "modelPassports": { "model:demo:local-alpha": { "modelPassportId": "model:demo:local-alpha", @@ -135,7 +141,7 @@ "finalityStatus": "finalized", "challengeCount": 1, "finalizedAtBlock": 1, - "stateRoot": "0x4e7ee5e7a8cab9b4ddda183842b9e9c1e1e000afea820b577ecc90fa4d9517e2" + "stateRoot": "0xf47b94f6d4be36bc5ade63085c9c3c6174d5b25eb5bfaae9a57e3946f5637352" } }, "artifactCommitments": { @@ -193,12 +199,12 @@ "importedObservations": {}, "importedVerifierReports": {}, "baseAnchors": { - "0xf57ab7d2c1459c03cf01bfddd56b046be685d8eaa4597e6bb54b5015aeaf003f": { - "anchorId": "0xf57ab7d2c1459c03cf01bfddd56b046be685d8eaa4597e6bb54b5015aeaf003f", + "0x6908eac7dbf828ab8d295d2ae86f0b0db9295a27b1fe4999c26a3ed97244ef8d": { + "anchorId": "0x6908eac7dbf828ab8d295d2ae86f0b0db9295a27b1fe4999c26a3ed97244ef8d", "appchainChainId": "flowmemory-local-devnet-v0", "blockRangeStart": 1, "blockRangeEnd": 1, - "stateRoot": "0x8c7c1e7a078b60a809d17a51c44e275059afb8d7535769430c3fc9e9320c7e23", + "stateRoot": "0x7e50021bc0dd2537f9ecfd7973f9799b6ffdffcfd427e3bb059f4dfd1253b947", "workReceiptRoot": "0x8b3ef5650c9eea2f608ad9c7cb73df3c289fc0ac72ed04f46e6ae4bce0a1f023", "verifierReportRoot": "0x4facd21e55423e182eba87355482a35daa93f53190fbd3a8d2969f9d55bc5373", "rootfieldStateRoot": "0xb72a851dca1103410484e3272945bae5e87fc39b8f32f77d2991959b60d3bfbf", @@ -215,10 +221,16 @@ "lpPositionRoot": "0xe67dd98259afb06ca93620b4a8742b924ec2e8f3e6e72934eef5b8e60829d46f", "liquidityReceiptRoot": "0x98bf15cc6859994038744612e125236b1f777895a051c41702c2004134327738", "swapReceiptRoot": "0xc9f3ee93962f36ed10421ec9ad736079a3b13ef6504336495af243b718cefee1", + "bridgeAssetMappingRoot": "0xbd283f6190cba76038f7364e207557dd20f7883d78e5f89a96579af5455a89aa", + "bridgeAccountMappingRoot": "0x46285ec5782d3e6cc1e557fd5dd779e979d679e5cc723832cb189d27a5c552c8", + "bridgeCreditRoot": "0x613ab06f110cc7a5eb06a0f44b7a0f04b0b3cfb0556d30d42842f33563596248", + "bridgeCreditReceiptRoot": "0x0a86ce98161cb40ca4c7719468c0ed8f122677d12641c13305277094b8f3a509", + "bridgeReplayIndexRoot": "0x9344f8651651d2d5042d2853205154a5777cd57aa9e892e2ac41b9b9fe04c00f", + "bridgeEventReceiptIndexRoot": "0xcaad305c45f57c516d0fdfdef15c5d88b399b976df173f005e9d7dc30fbdbdb2", "modelPassportRoot": "0x326aa6b0b372d29d24d747fe0879adfd7aaea206373b24ae2ab77d56357e9529", "memoryCellRoot": "0x1b4e91099dd8d867201bd880437197ae6c031e538341aaa3cd2046e5706a2c25", "challengeRoot": "0x16da3d2bf2dcd801bc5deb3987dc01342cb957031ad01408ea77bf5d1583656f", - "finalityReceiptRoot": "0xdf352e20fd1ddfd2855202335e03cfec21d87e99bf8717d161fe8648998e16cf", + "finalityReceiptRoot": "0x1c8536e507c5ba2242a5875c9537043645828825286ca256cc1171f1eb960c3f", "artifactAvailabilityProofRoot": "0xfb4b693c45014aae0947f35696e9d864e7b26ac6fd39c1df5edb3e0dcf9bd928", "verifierModuleRoot": "0xd6ddd8a2d0f5812d64679656c69983a2e0aecd36bd36199d900245658ae4626c", "previousAnchorId": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -325,13 +337,13 @@ "error": null } ], - "stateRoot": "0x8c7c1e7a078b60a809d17a51c44e275059afb8d7535769430c3fc9e9320c7e23", - "blockHash": "0x61e9f90b982f13988e85a382fc39da82c9114ecceea9001ab454c744e0801a9b" + "stateRoot": "0x7e50021bc0dd2537f9ecfd7973f9799b6ffdffcfd427e3bb059f4dfd1253b947", + "blockHash": "0xd890758bdeaa4ab7a658d7813b2b9bdd0850824aaef830b9f2f4ff455aaf3811" }, { "schema": "flowmemory.local_devnet.block.v0", "blockNumber": 2, - "parentHash": "0x61e9f90b982f13988e85a382fc39da82c9114ecceea9001ab454c744e0801a9b", + "parentHash": "0xd890758bdeaa4ab7a658d7813b2b9bdd0850824aaef830b9f2f4ff455aaf3811", "logicalTime": 1778688001, "txIds": [ "0x8f719c880f17b5d4fb6d9efd54ac276d0dd8050d11c2c7870c36a79b66bc49d7" @@ -343,8 +355,8 @@ "error": null } ], - "stateRoot": "0x3074ef2e5311d94e8f9a2660a6cc016c7b7f9a08c56ee07f9e841c1489726e68", - "blockHash": "0x7ddb184c69f798f25f27a254f1f530c6cdc31c9656ac19d1b8c114f7a3a650c6" + "stateRoot": "0xb3c4344483c7be8c0660d49d465d033a88ae26d6a7c1cbe096a2447d32c5648c", + "blockHash": "0x64e3d605fb1bba40b7de6a6a9813f77619282c07b9a33c7b41df1f6e3d71958b" } ], "pendingTxs": [] diff --git a/apps/dashboard/public/data/flowmemory-dashboard-base-sepolia-v4-hook.json b/apps/dashboard/public/data/flowmemory-dashboard-base-sepolia-v4-hook.json new file mode 100644 index 00000000..3475825a --- /dev/null +++ b/apps/dashboard/public/data/flowmemory-dashboard-base-sepolia-v4-hook.json @@ -0,0 +1,114 @@ +{ + "metadata": { + "schema": "flowmemory.dashboard.fixture.v0", + "generatedAt": "2026-05-17T06:47:51.565Z", + "mode": "base-sepolia-v4-hook-proof", + "description": "Generated Base Sepolia v4 hook proof dashboard data from readback artifacts. It is public-testnet evidence and not production mainnet readiness.", + "fixturePath": "fixtures/dashboard/flowmemory-dashboard-base-sepolia-v4-hook.json", + "runtimeDataPath": "apps/dashboard/public/data/flowmemory-dashboard-base-sepolia-v4-hook.json", + "baseSepoliaHookProof": { + "liveProofComplete": false, + "stage": "dry-run-proof-ready", + "plannedHookAddress": "0xD24d7f807cb00D28DdF675E55879547d4F7B0040", + "readWindow": { + "fromBlock": "41616089", + "toBlock": "41616089", + "finalizedBlock": null + }, + "counts": { + "observations": 0, + "canonicalObservations": 0, + "swapMemorySignals": 0, + "rejectedLogs": 0, + "duplicates": 0, + "memorySignals": 0, + "rootflowTransitions": 0 + }, + "missing": [ + "deployed FlowMemoryAfterSwapHook code at the mined hook address", + "local env-check with funded Base Sepolia deployer", + "broadcast swap-proof artifact with receipts", + "non-empty Base Sepolia hook FlowPulse readback artifact" + ], + "nextSteps": [ + "Run npm run hook:base-sepolia:env-check -- --json until broadcastReady is true.", + "Run npm run hook:base-sepolia:swap-proof:broadcast -- --json with the funded testnet key.", + "Run npm run hook:base-sepolia:readback-range -- --infer-readback-range --json to derive the readback window from broadcast receipts.", + "Run npm run hook:base-sepolia:readback:auto -- --json or npm run hook:base-sepolia:readback with an operator-reviewed range, and require proofComplete true.", + "Rerun npm run hook:base-sepolia:evidence -- --json." + ] + }, + "futureGeneratedPaths": { + "indexer": "fixtures/deployments/base-sepolia-v4-hook-readback-state.latest.json", + "evidence": "fixtures/deployments/base-sepolia-v4-hook-evidence.latest.json", + "readback": "fixtures/deployments/base-sepolia-v4-hook-readback.latest.json" + } + }, + "chain": { + "chainId": "84532", + "name": "Base Sepolia v4 hook proof", + "environment": "public-testnet", + "settlementContext": "Mined Uniswap v4 afterSwap hook proof path. Complete only after real PoolManager swap broadcast and non-empty readback.", + "currentBlock": 41616089, + "finalizedBlock": 41616089, + "source": "diagnostic-empty-readback", + "lastUpdated": "2026-05-17T06:47:51.565Z" + }, + "flowPulseObservations": [], + "rootfields": [], + "workLanes": [ + { + "id": "MEMORY_REFRESH", + "laneId": "MEMORY_REFRESH", + "name": "Swap memory proof", + "queueDepth": 1, + "inflight": 0, + "completed24h": 0, + "p95LatencyMs": null, + "operator": "base-sepolia-hook-proof", + "status": "unresolved", + "lastUpdated": "2026-05-17T06:47:51.565Z", + "provenance": { + "subsystem": "flowmemory", + "origin": "live-readback", + "chainContext": "base-sepolia-v4-hook-proof", + "fixturePath": "fixtures/deployments/base-sepolia-v4-hook-flowmemory.latest.json", + "capturedAt": "2026-05-17T06:47:51.565Z", + "localPathHint": "fixtures/deployments/base-sepolia-v4-hook-flowmemory.latest.json" + } + } + ], + "workReceipts": [], + "verifierReports": [], + "rootflowTransitions": [], + "memorySignals": [], + "memoryReceipts": [], + "rootfieldBundles": [], + "agentMemoryViews": [], + "devnetBlocks": [], + "hardwareNodes": [], + "alerts": [ + { + "id": "0x341681f64a0aa8f62e2032dc31df3b096d3417da9795addb6f090a3ac7fa81ab", + "incidentId": "0x341681f64a0aa8f62e2032dc31df3b096d3417da9795addb6f090a3ac7fa81ab", + "severity": "warning", + "title": "Base Sepolia hook proof incomplete", + "summary": "Dry-run proof exists, but a funded Base Sepolia broadcast and non-empty hook readback are still required.", + "openedAt": "2026-05-17T06:47:51.565Z", + "linkedObjectIds": [ + "0xD24d7f807cb00D28DdF675E55879547d4F7B0040" + ], + "recommendedAction": "Broadcast the swap proof with a funded testnet key, run readback over the receipt block range, then regenerate this dashboard.", + "status": "unresolved", + "lastUpdated": "2026-05-17T06:47:51.565Z", + "provenance": { + "subsystem": "alerts", + "origin": "live-readback", + "chainContext": "base-sepolia-v4-hook-proof", + "fixturePath": "fixtures/deployments/base-sepolia-v4-hook-flowmemory.latest.json", + "capturedAt": "2026-05-17T06:47:51.565Z", + "localPathHint": "fixtures/deployments/base-sepolia-v4-hook-evidence.latest.json" + } + } + ] +} diff --git a/apps/dashboard/public/data/flowmemory-dashboard-v0.json b/apps/dashboard/public/data/flowmemory-dashboard-v0.json index b226d982..01343d34 100644 --- a/apps/dashboard/public/data/flowmemory-dashboard-v0.json +++ b/apps/dashboard/public/data/flowmemory-dashboard-v0.json @@ -1993,11 +1993,11 @@ ], "devnetBlocks": [ { - "id": "0x61e9f90b982f13988e85a382fc39da82c9114ecceea9001ab454c744e0801a9b", + "id": "0xd890758bdeaa4ab7a658d7813b2b9bdd0850824aaef830b9f2f4ff455aaf3811", "blockNumber": 1, - "blockHash": "0x61e9f90b982f13988e85a382fc39da82c9114ecceea9001ab454c744e0801a9b", + "blockHash": "0xd890758bdeaa4ab7a658d7813b2b9bdd0850824aaef830b9f2f4ff455aaf3811", "parentHash": "0x0f23c892cbd2d00c10839d97ddab833698a83f8df8d6df27ceac03cfdd4b7bc9", - "stateRoot": "0x8c7c1e7a078b60a809d17a51c44e275059afb8d7535769430c3fc9e9320c7e23", + "stateRoot": "0x7e50021bc0dd2537f9ecfd7973f9799b6ffdffcfd427e3bb059f4dfd1253b947", "receiptsRoot": "0x2f98caf4b28b2209cdf1f9beb1c23f8732c538657cc7a1d8855878b5400efabd", "timestamp": "2026-05-13T16:00:00.000Z", "observationCount": 8, @@ -2015,11 +2015,11 @@ } }, { - "id": "0x7ddb184c69f798f25f27a254f1f530c6cdc31c9656ac19d1b8c114f7a3a650c6", + "id": "0x64e3d605fb1bba40b7de6a6a9813f77619282c07b9a33c7b41df1f6e3d71958b", "blockNumber": 2, - "blockHash": "0x7ddb184c69f798f25f27a254f1f530c6cdc31c9656ac19d1b8c114f7a3a650c6", - "parentHash": "0x61e9f90b982f13988e85a382fc39da82c9114ecceea9001ab454c744e0801a9b", - "stateRoot": "0x3074ef2e5311d94e8f9a2660a6cc016c7b7f9a08c56ee07f9e841c1489726e68", + "blockHash": "0x64e3d605fb1bba40b7de6a6a9813f77619282c07b9a33c7b41df1f6e3d71958b", + "parentHash": "0xd890758bdeaa4ab7a658d7813b2b9bdd0850824aaef830b9f2f4ff455aaf3811", + "stateRoot": "0xb3c4344483c7be8c0660d49d465d033a88ae26d6a7c1cbe096a2447d32c5648c", "receiptsRoot": "0xa0407b9a8a55106d549e0f19b92fceaa7f7a25697e94ebf8a1fa74af7b9168f4", "timestamp": "2026-05-13T16:00:01.000Z", "observationCount": 8, diff --git a/apps/dashboard/scripts/package-desktop-wallet.ps1 b/apps/dashboard/scripts/package-desktop-wallet.ps1 new file mode 100644 index 00000000..f041d287 --- /dev/null +++ b/apps/dashboard/scripts/package-desktop-wallet.ps1 @@ -0,0 +1,20 @@ +$ErrorActionPreference = "Stop" + +$releaseDir = Resolve-Path (Join-Path $PSScriptRoot "..\release") +$unpackedDir = Join-Path $releaseDir "win-unpacked" +$exePath = Join-Path $unpackedDir "Flowchain Wallet.exe" +$packageJsonPath = Resolve-Path (Join-Path $PSScriptRoot "..\package.json") +$packageJson = Get-Content -LiteralPath $packageJsonPath -Raw | ConvertFrom-Json +$zipPath = Join-Path $releaseDir "Flowchain-Wallet-$($packageJson.version)-win-x64.zip" + +if (-not (Test-Path -LiteralPath $exePath)) { + throw "Desktop wallet executable was not found at $exePath" +} + +if (Test-Path -LiteralPath $zipPath) { + Remove-Item -LiteralPath $zipPath -Force +} + +Compress-Archive -Path (Join-Path $unpackedDir "*") -DestinationPath $zipPath -Force + +Write-Host "Created desktop wallet package: $zipPath" diff --git a/apps/dashboard/src/App.tsx b/apps/dashboard/src/App.tsx index 750ab52e..1edaf902 100644 --- a/apps/dashboard/src/App.tsx +++ b/apps/dashboard/src/App.tsx @@ -6,6 +6,7 @@ import { DEFAULT_CANARY_DASHBOARD_DATA_PATH, fetchDashboardData } from "./data/l import type { DashboardData } from "./data/types"; import { DEFAULT_CONTROL_PLANE_URL, buildWorkbenchSnapshot, fetchWorkbenchSnapshot, type WorkbenchSnapshot } from "./data/workbench"; import { AlertsView } from "./views/AlertsView"; +import { BridgePilotView } from "./views/BridgePilotView"; import { CanaryDeploymentView } from "./views/CanaryDeploymentView"; import { DevnetBlocksView } from "./views/DevnetBlocksView"; import { FlowMemoryView } from "./views/FlowMemoryView"; @@ -15,6 +16,7 @@ import { OverviewView } from "./views/OverviewView"; import { RawJsonInspectorView } from "./views/RawJsonInspectorView"; import { RootfieldsView } from "./views/RootfieldsView"; import { VerifierReportsView } from "./views/VerifierReportsView"; +import { WalletView } from "./views/WalletView"; import { WorkbenchView } from "./views/WorkbenchView"; import { WorkReceiptsView } from "./views/WorkReceiptsView"; @@ -116,6 +118,8 @@ export default function App() { setVersion((current) => current + 1)} />} /> + } /> + } /> } /> } /> } /> diff --git a/apps/dashboard/src/components/AppShell.tsx b/apps/dashboard/src/components/AppShell.tsx index 765d1308..1be4d7be 100644 --- a/apps/dashboard/src/components/AppShell.tsx +++ b/apps/dashboard/src/components/AppShell.tsx @@ -8,12 +8,14 @@ import { BrainCircuit, Boxes, ClipboardCheck, + ArrowRightLeft, RadioReceiver, LayoutDashboard, Monitor, Network, RadioTower, ShieldCheck, + Wallet, } from "lucide-react"; import type { DashboardData } from "../data/types"; import type { WorkbenchSnapshot } from "../data/workbench"; @@ -28,6 +30,8 @@ interface AppShellProps { const NAV_ITEMS = [ { to: "/", label: "Workbench", icon: Monitor }, + { to: "/wallet", label: "Wallet", icon: Wallet }, + { to: "/bridge", label: "Bridge pilot", icon: ArrowRightLeft }, { to: "/overview", label: "Overview", icon: LayoutDashboard }, { to: "/canary", label: "Base canary", icon: RadioReceiver }, { to: "/flowmemory", label: "Flow Memory", icon: BrainCircuit }, @@ -43,6 +47,12 @@ const NAV_ITEMS = [ export function AppShell({ data, canaryData, workbench, children }: AppShellProps) { const location = useLocation(); + const isBridgeRoute = location.pathname.startsWith("/bridge"); + const isWalletRoute = location.pathname.startsWith("/wallet"); + if (isBridgeRoute || isWalletRoute) { + return <>{children}; + } + const isCanaryRoute = location.pathname.startsWith("/canary"); const activeData = isCanaryRoute && canaryData ? canaryData : data; const bannerMode = isCanaryRoute diff --git a/apps/dashboard/src/data/loadDashboardData.ts b/apps/dashboard/src/data/loadDashboardData.ts index 59c6296d..d76d782a 100644 --- a/apps/dashboard/src/data/loadDashboardData.ts +++ b/apps/dashboard/src/data/loadDashboardData.ts @@ -3,6 +3,17 @@ import type { DashboardData } from "./types"; export const DEFAULT_DASHBOARD_DATA_PATH = "/data/flowmemory-dashboard-v0.json"; export const DEFAULT_CANARY_DASHBOARD_DATA_PATH = "/data/flowmemory-dashboard-base-canary-v0.json"; +export function publicAssetPath(path: string): string { + const baseUrl = (import.meta as ImportMeta & { env?: { BASE_URL?: string } }).env?.BASE_URL ?? "/"; + if (/^[a-z][a-z0-9+.-]*:/i.test(path)) { + return path; + } + if (baseUrl === "./") { + return `./${path.replace(/^\/+/, "")}`; + } + return path; +} + function assertArray(value: unknown, label: string): void { if (!Array.isArray(value)) { throw new Error(`Dashboard fixture field "${label}" must be an array.`); @@ -45,7 +56,7 @@ export function validateDashboardData(payload: unknown): DashboardData { export async function fetchDashboardData( path = DEFAULT_DASHBOARD_DATA_PATH, ): Promise { - const response = await fetch(path, { cache: "no-store" }); + const response = await fetch(publicAssetPath(path), { cache: "no-store" }); if (!response.ok) { throw new Error(`Unable to load dashboard fixture at ${path}: ${response.status}`); } diff --git a/apps/dashboard/src/data/workbench.ts b/apps/dashboard/src/data/workbench.ts index c33e48d8..b4887f85 100644 --- a/apps/dashboard/src/data/workbench.ts +++ b/apps/dashboard/src/data/workbench.ts @@ -1,4 +1,5 @@ import type { DashboardData, DashboardStatus, Provenance, SourceSubsystem } from "./types"; +import { publicAssetPath } from "./loadDashboardData"; export const DEFAULT_CONTROL_PLANE_URL = "http://127.0.0.1:8787"; export const WORKBENCH_DEVNET_STATE_PATH = "/data/flowchain-local-devnet-state.json"; @@ -77,6 +78,10 @@ export interface ControlPlaneProbe { health?: unknown; state?: unknown; pilotStatus?: unknown; + bridgeLiveReadiness?: unknown; + pilotLifecycle?: unknown; + walletBalances?: unknown; + walletTransfers?: unknown; } export interface WorkbenchNodeStatus { @@ -115,6 +120,10 @@ export interface WorkbenchSnapshot { devnetDashboardState: unknown | null; bridgeTestDeposit: unknown | null; controlPlanePilotStatus: unknown | null; + controlPlaneBridgeReadiness: unknown | null; + controlPlanePilotLifecycle: unknown | null; + controlPlaneWalletBalances: unknown | null; + controlPlaneWalletTransfers: unknown | null; controlPlaneHealth: unknown | null; controlPlaneState: unknown | null; }; @@ -246,8 +255,8 @@ export const WORKBENCH_SECTIONS: WorkbenchSectionDefinition[] = [ { key: "realValuePilot", label: "Real-Value Pilot", - detail: "Capped owner-testing lifecycle for Base deposit observation, local credit, replay/retry status, withdrawal intent, release evidence, caps, pause, and emergency state.", - expectedEndpoint: "GET /pilot/status + POST /rpc pilot_status", + detail: "Capped owner-testing lifecycle for Base deposit observation, exact local credit, wallet transferability, withdrawal/release evidence, readiness blockers, caps, pause, and emergency state.", + expectedEndpoint: "GET /bridge/live-readiness + GET /pilot/lifecycle + GET /pilot/status", missingCommand: "npm run control-plane:serve", missingService: "FlowChain real-value pilot control-plane /pilot/status", }, @@ -494,16 +503,23 @@ function stringArray(value: unknown): string[] { function statusFrom(value: unknown, fallback: DashboardStatus = "observed"): DashboardStatus { const normalized = text(value, fallback).toLowerCase(); - if (normalized === "applied" || normalized === "success" || normalized === "active" || normalized === "live") { + if ( + normalized === "applied" || + normalized === "success" || + normalized === "active" || + normalized === "live" || + normalized === "ready_for_operator_live_pilot" || + normalized === "ready" + ) { return "verified"; } if (normalized === "finalized") { return "finalized"; } - if (normalized === "failed" || normalized === "invalid" || normalized === "reverted") { + if (normalized === "failed" || normalized === "invalid" || normalized === "reverted" || normalized === "failure") { return "failed"; } - if (normalized === "pending" || normalized === "local-placeholder" || normalized === "degraded") { + if (normalized === "pending" || normalized === "local-placeholder" || normalized === "degraded" || normalized === "blocked") { return "pending"; } if (normalized === "error") { @@ -686,7 +702,7 @@ async function fetchJsonWithTimeout(url: string, timeoutMs: number): Promise { try { - return { value: await fetchJsonWithTimeout(path, CONTROL_PLANE_TIMEOUT_MS) }; + return { value: await fetchJsonWithTimeout(publicAssetPath(path), CONTROL_PLANE_TIMEOUT_MS) }; } catch (error) { return { value: null, @@ -698,12 +714,24 @@ async function fetchOptionalJson(path: string): Promise<{ value: unknown | null; async function probeControlPlane(): Promise { const url = getControlPlaneUrl(); const checkedAt = new Date().toISOString(); - const defaultEndpoints = ["GET /health", "GET /state", "GET /pilot/status"]; + const defaultEndpoints = [ + "GET /health", + "GET /state", + "GET /pilot/status", + "GET /bridge/live-readiness", + "GET /pilot/lifecycle", + "GET /wallets/balances", + "GET /wallets/transfers", + ]; try { const health = await fetchJsonWithTimeout(`${url}/health`, CONTROL_PLANE_TIMEOUT_MS); let state: unknown | undefined; let pilotStatus: unknown | undefined; + let bridgeLiveReadiness: unknown | undefined; + let pilotLifecycle: unknown | undefined; + let walletBalances: unknown | undefined; + let walletTransfers: unknown | undefined; try { pilotStatus = await fetchJsonWithTimeout(`${url}/pilot/status`, CONTROL_PLANE_TIMEOUT_MS); @@ -711,6 +739,30 @@ async function probeControlPlane(): Promise { pilotStatus = undefined; } + try { + bridgeLiveReadiness = await fetchJsonWithTimeout(`${url}/bridge/live-readiness`, CONTROL_PLANE_TIMEOUT_MS); + } catch { + bridgeLiveReadiness = undefined; + } + + try { + pilotLifecycle = await fetchJsonWithTimeout(`${url}/pilot/lifecycle`, CONTROL_PLANE_TIMEOUT_MS); + } catch { + pilotLifecycle = undefined; + } + + try { + walletBalances = await fetchJsonWithTimeout(`${url}/wallets/balances`, CONTROL_PLANE_TIMEOUT_MS); + } catch { + walletBalances = undefined; + } + + try { + walletTransfers = await fetchJsonWithTimeout(`${url}/wallets/transfers`, CONTROL_PLANE_TIMEOUT_MS); + } catch { + walletTransfers = undefined; + } + try { state = await fetchJsonWithTimeout(`${url}/state`, CONTROL_PLANE_TIMEOUT_MS); } catch (error) { @@ -721,6 +773,10 @@ async function probeControlPlane(): Promise { endpoints: uniqueEndpoints(defaultEndpoints, collectEndpointHints(health)), health, pilotStatus, + bridgeLiveReadiness, + pilotLifecycle, + walletBalances, + walletTransfers, error: `Health endpoint responded, but state endpoint was not loaded: ${ error instanceof Error ? error.message : "unknown state error" }`, @@ -735,6 +791,10 @@ async function probeControlPlane(): Promise { health, state, pilotStatus, + bridgeLiveReadiness, + pilotLifecycle, + walletBalances, + walletTransfers, }; } catch (error) { return { @@ -1106,8 +1166,232 @@ function commandFromStep(step: unknown): string { return isRecord(step) ? text(step.command, "npm run flowchain:real-value-pilot:e2e") : "npm run flowchain:real-value-pilot:e2e"; } +function readinessStatus(value: unknown): DashboardStatus { + const normalized = text(value, "BLOCKED").toUpperCase(); + if (normalized === "READY_FOR_OPERATOR_LIVE_PILOT") { + return "verified"; + } + if (normalized === "FAILED") { + return "failed"; + } + return "pending"; +} + +function readinessPayload(controlPlane: ControlPlaneProbe, pilot: UnknownRecord | null): UnknownRecord | null { + if (isRecord(controlPlane.bridgeLiveReadiness)) { + return controlPlane.bridgeLiveReadiness; + } + if (isRecord(pilot?.bridgeLiveReadiness)) { + return pilot.bridgeLiveReadiness as UnknownRecord; + } + return null; +} + +function bridgeReadinessRecord(controlPlane: ControlPlaneProbe, readiness: UnknownRecord | null): WorkbenchRecord { + if (!readiness) { + return makeLocalRecord( + "devnet", + controlPlane.url, + { + id: "bridge-live-readiness", + kind: "Bridge live readiness", + title: "Bridge live readiness BLOCKED", + summary: "The live readiness endpoint is unavailable; operator live pilot remains fail-closed until the control-plane returns readiness details.", + status: controlPlane.status === "available" ? "pending" : "offline", + facts: [ + { label: "fail-closed status", value: "BLOCKED" }, + { label: "base chain", value: "8453" }, + { label: "missing env names", value: "endpoint unavailable" }, + { label: "env values printed", value: "false" }, + { label: "mock presented as live", value: "false" }, + { label: "owner verified lockbox", value: "false" }, + ], + raw: { endpoint: "/bridge/live-readiness", status: "unavailable" }, + }, + controlPlane.checkedAt, + ); + } + + const node = isRecord(readiness.node) ? readiness.node : {}; + const lockbox = isRecord(readiness.lockbox) ? readiness.lockbox : {}; + const confirmationDepth = isRecord(readiness.confirmationDepth) ? readiness.confirmationDepth : {}; + const artifacts = isRecord(readiness.currentArtifacts) ? readiness.currentArtifacts : {}; + const missingEnvNames = stringArray(readiness.missingEnvNames); + const failClosedStatus = text(readiness.failClosedStatus, "BLOCKED"); + + return makeLocalRecord( + "devnet", + controlPlane.url, + { + id: "bridge-live-readiness", + kind: "Bridge live readiness", + title: `Bridge live readiness ${failClosedStatus}`, + summary: + missingEnvNames.length > 0 + ? `Fail-closed with missing env names: ${missingEnvNames.join(", ")}.` + : text(readiness.machineStatus, "Live readiness is available from the control-plane."), + status: readinessStatus(failClosedStatus), + facts: [ + { label: "fail-closed status", value: failClosedStatus }, + { label: "base chain", value: `${text(readiness.baseChainName, "Base")} ${text(readiness.baseChainId, "8453")}` }, + { label: "node running", value: text(node.running, "false") }, + { label: "lockbox configured", value: text(lockbox.configured, "false") }, + { label: "confirmation configured", value: text(confirmationDepth.configured, "false") }, + { label: "missing env names", value: missingEnvNames.join(", ") || "none" }, + { label: "env values printed", value: text(readiness.envValuesPrinted, "false") }, + { label: "mock presented as live", value: text(artifacts.mockPresentedAsLive, "false") }, + ], + raw: readiness, + }, + controlPlane.checkedAt, + ); +} + +function bridgeReadinessIssueRecords(controlPlane: ControlPlaneProbe, readiness: UnknownRecord | null): WorkbenchRecord[] { + if (!readiness) { + return []; + } + + return collectionFrom(readiness, ["issues"]).map((issue, index) => + makeLocalRecord( + "devnet", + controlPlane.url, + { + id: `bridge-readiness-issue:${text(issue.reasonCode, String(index + 1))}`, + kind: "Operational empty/error state", + title: text(issue.title, "Bridge readiness issue"), + summary: text(issue.summary, "A live-pilot readiness issue is visible in the control-plane response."), + status: statusFrom(issue.status, "pending"), + facts: [ + { label: "reason code", value: text(issue.reasonCode) }, + { label: "status", value: text(issue.status, "blocked") }, + { label: "env names", value: stringArray(issue.envNames).join(", ") || "none" }, + { label: "machine readable", value: "true" }, + ], + raw: issue, + }, + controlPlane.checkedAt, + ), + ); +} + +function lifecycleRows(controlPlane: ControlPlaneProbe, pilot: UnknownRecord | null): UnknownRecord[] { + if (isRecord(controlPlane.pilotLifecycle)) { + return collectionFrom(controlPlane.pilotLifecycle, ["lifecycleRecords"]); + } + if (pilot) { + return collectionFrom(pilot, ["lifecycleRecords"]); + } + return []; +} + +function bridgeLifecycleRecord(controlPlane: ControlPlaneProbe, row: UnknownRecord, index: number): WorkbenchRecord { + const equality = isRecord(row.equality) ? row.equality : {}; + const equalities = isRecord(equality.equalities) ? equality.equalities : {}; + const depositObservation = isRecord(row.depositObservation) ? row.depositObservation : {}; + const withdrawalIntent = isRecord(row.withdrawalIntent) ? row.withdrawalIntent : {}; + const releaseEvidence = isRecord(row.releaseEvidence) ? row.releaseEvidence : {}; + const liveArtifact = row.liveArtifact === true; + const artifactClass = text(row.artifactClass, liveArtifact ? "live-base8453" : "local-or-mock"); + const baseTxHash = text(row.baseTxHash ?? row.txHash, `lifecycle:${index + 1}`); + const creditId = text(row.creditId, "credit pending"); + const amount = text(row.amountSmallestUnits ?? equality.depositAmount, "0"); + const replayKey = text(row.replayKey ?? depositObservation.replayKey); + const withdrawalIntentId = text(row.withdrawalIntentId ?? withdrawalIntent.withdrawalIntentId); + const releaseEvidenceId = text(row.releaseEvidenceId ?? releaseEvidence.releaseEvidenceId); + + return makeLocalRecord( + "devnet", + controlPlane.url, + { + id: text(row.lifecycleRecordId, `${baseTxHash}:${text(row.logIndex, String(index))}`), + kind: "Bridge exact lifecycle", + title: `${baseTxHash} / ${creditId}`, + summary: `${artifactClass} record with deposit, observed, credited, wallet delta, transferable, withdrawal, and release amount equality ${text(equality.allEqual, "false")}.`, + status: statusFrom(row.status, "pending"), + facts: [ + { label: "base tx hash", value: baseTxHash }, + { label: "log index", value: text(row.logIndex) }, + { label: "deposit id", value: text(row.depositId ?? depositObservation.depositId) }, + { label: "replay key", value: replayKey }, + { label: "replay status", value: text(row.replayStatus ?? depositObservation.replayStatus) }, + { label: "credit id", value: creditId }, + { label: "recipient wallet", value: text(row.recipientWallet) }, + { label: "withdrawal intent", value: withdrawalIntentId }, + { label: "withdrawal status", value: text(row.withdrawalStatus ?? withdrawalIntent.status) }, + { label: "release evidence", value: releaseEvidenceId }, + { label: "release status", value: text(row.releaseStatus ?? releaseEvidence.status) }, + { label: "asset", value: text(row.asset) }, + { label: "amount smallest units", value: amount }, + { label: "deposit amount", value: text(equality.depositAmount) }, + { label: "credited amount", value: text(equality.creditedAmount) }, + { label: "withdrawal amount", value: text(equality.withdrawalAmount) }, + { label: "release amount", value: text(equality.releaseAmount) }, + { label: "all values equal", value: text(equality.allEqual, "false") }, + { label: "wallet delta equal", value: text(equalities.walletDelta, "false") }, + { label: "evidence path", value: text(row.evidenceFilePath) }, + ], + raw: row, + }, + controlPlane.checkedAt, + ); +} + +function buildControlPlaneWalletBalanceRecords(controlPlane: ControlPlaneProbe): WorkbenchRecord[] { + return collectionFrom(controlPlane.walletBalances, ["balances"]).map((balance, index) => + makeLocalRecord( + "devnet", + controlPlane.url, + { + id: text(balance.balanceId, `wallet-balance:${index + 1}`), + kind: "Wallet balance", + title: text(balance.walletAddress, `wallet:${index + 1}`), + summary: `Wallet balance ${text(balance.status, "observed")} for ${text(balance.asset, "asset")} is ${text(balance.amount, "0")} smallest units.`, + status: statusFrom(balance.status, "observed"), + facts: [ + { label: "wallet", value: text(balance.walletAddress) }, + { label: "asset", value: text(balance.asset) }, + { label: "amount", value: text(balance.amount, "0") }, + { label: "previous amount", value: text(balance.previousAmount) }, + { label: "credit id", value: text(balance.creditId) }, + { label: "transfer id", value: text(balance.transferId) }, + ], + raw: balance, + }, + controlPlane.checkedAt, + ), + ); +} + +function buildControlPlaneWalletTransferRecords(controlPlane: ControlPlaneProbe): WorkbenchRecord[] { + return collectionFrom(controlPlane.walletTransfers, ["transfers"]).map((transfer, index) => + makeLocalRecord( + "devnet", + controlPlane.url, + { + id: text(transfer.transferId ?? transfer.txId, `wallet-transfer:${index + 1}`), + kind: "Wallet transfer history", + title: text(transfer.txId ?? transfer.transferId, `transfer:${index + 1}`), + summary: `${text(transfer.amount, "0")} ${text(transfer.assetId, "asset")} transferred from ${text(transfer.fromAccountId)} to ${text(transfer.toAccountId)}.`, + status: statusFrom(transfer.status, "observed"), + facts: [ + { label: "from wallet", value: text(transfer.fromAccountId) }, + { label: "to wallet", value: text(transfer.toAccountId) }, + { label: "asset", value: text(transfer.assetId) }, + { label: "amount", value: text(transfer.amount, "0") }, + { label: "status", value: text(transfer.status) }, + { label: "evidence path", value: text(transfer.evidenceFilePath) }, + ], + raw: transfer, + }, + controlPlane.checkedAt, + ), + ); +} + function buildPilotRecords(controlPlane: ControlPlaneProbe): WorkbenchRecord[] { const pilot = isRecord(controlPlane.pilotStatus) ? controlPlane.pilotStatus : null; + const readiness = readinessPayload(controlPlane, pilot); const records: WorkbenchRecord[] = []; if (!pilot) { @@ -1132,6 +1416,10 @@ function buildPilotRecords(controlPlane: ControlPlaneProbe): WorkbenchRecord[] { controlPlane.checkedAt, ), ); + records.push(bridgeReadinessRecord(controlPlane, readiness)); + records.push(...bridgeReadinessIssueRecords(controlPlane, readiness)); + records.push(...buildControlPlaneWalletBalanceRecords(controlPlane)); + records.push(...buildControlPlaneWalletTransferRecords(controlPlane)); return records; } @@ -1167,6 +1455,14 @@ function buildPilotRecords(controlPlane: ControlPlaneProbe): WorkbenchRecord[] { ), ); + records.push(bridgeReadinessRecord(controlPlane, readiness)); + records.push(...bridgeReadinessIssueRecords(controlPlane, readiness)); + lifecycleRows(controlPlane, pilot).forEach((row, index) => { + records.push(bridgeLifecycleRecord(controlPlane, row, index)); + }); + records.push(...buildControlPlaneWalletBalanceRecords(controlPlane)); + records.push(...buildControlPlaneWalletTransferRecords(controlPlane)); + lifecycle.forEach((step, index) => { records.push( makeLocalRecord( @@ -1902,6 +2198,10 @@ function buildRawJsonRecords( raw: { health: controlPlane.health ?? null, state: controlPlane.state ?? null, + bridgeLiveReadiness: controlPlane.bridgeLiveReadiness ?? null, + pilotLifecycle: controlPlane.pilotLifecycle ?? null, + walletBalances: controlPlane.walletBalances ?? null, + walletTransfers: controlPlane.walletTransfers ?? null, error: controlPlane.error ?? null, }, }, @@ -2093,7 +2393,7 @@ export function buildWorkbenchSnapshot( transactions: buildTransactionRecords(data, activeDevnetState), mempool: buildMempoolRecords(activeDevnetState), accounts: buildAccountRecords(activeDevnetState), - balances: buildBalanceRecords(activeDevnetState), + balances: [...buildBalanceRecords(activeDevnetState), ...buildControlPlaneWalletBalanceRecords(controlPlane)], faucetEvents: buildFaucetEventRecords(activeDevnetState), walletMetadata: buildWalletMetadataRecords(activeDevnetState), tokenLaunches: buildTokenLaunchRecords(activeDevnetState), @@ -2152,6 +2452,10 @@ export function buildWorkbenchSnapshot( devnetDashboardState: options.devnetDashboardState ?? null, bridgeTestDeposit, controlPlanePilotStatus: controlPlane.pilotStatus ?? null, + controlPlaneBridgeReadiness: controlPlane.bridgeLiveReadiness ?? null, + controlPlanePilotLifecycle: controlPlane.pilotLifecycle ?? null, + controlPlaneWalletBalances: controlPlane.walletBalances ?? null, + controlPlaneWalletTransfers: controlPlane.walletTransfers ?? null, controlPlaneHealth: controlPlane.health ?? null, controlPlaneState: controlPlane.state ?? null, }, diff --git a/apps/dashboard/src/main.tsx b/apps/dashboard/src/main.tsx index 2d89f272..87a958de 100644 --- a/apps/dashboard/src/main.tsx +++ b/apps/dashboard/src/main.tsx @@ -1,13 +1,20 @@ import React from "react"; import ReactDOM from "react-dom/client"; -import { BrowserRouter } from "react-router-dom"; +import { BrowserRouter, HashRouter } from "react-router-dom"; import App from "./App"; import "./styles.css"; +const isNativeShell = window.location.protocol === "file:" || "Capacitor" in window; +const Router = isNativeShell ? HashRouter : BrowserRouter; + +if (isNativeShell && window.location.hash.length === 0) { + window.location.hash = "/wallet"; +} + ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - + - + , ); diff --git a/apps/dashboard/src/styles.css b/apps/dashboard/src/styles.css index a26271c5..b8555452 100644 --- a/apps/dashboard/src/styles.css +++ b/apps/dashboard/src/styles.css @@ -67,1457 +67,5051 @@ input { color: var(--ink); } -select { - min-height: 38px; - padding: 0 12px; +.wallet-app-shell { + position: relative; + display: grid; + grid-template-columns: 270px minmax(560px, 1fr) 385px; + min-height: 100dvh; + overflow: hidden; + color: #0a2147; + background: + radial-gradient(circle at 72% 18%, rgba(255, 255, 255, 0.82), transparent 27rem), + radial-gradient(circle at 5% 96%, rgba(20, 91, 255, 0.12), transparent 24rem), + linear-gradient(135deg, #fff9ee 0%, #f8efe1 46%, #fffaf0 100%); +} + +.wallet-app-shell::before { + position: fixed; + inset: 0; + pointer-events: none; + content: ""; + background-image: + linear-gradient(rgba(21, 42, 84, 0.035) 1px, transparent 1px), + linear-gradient(90deg, rgba(21, 42, 84, 0.024) 1px, transparent 1px); + background-size: 10px 10px, 10px 10px; + opacity: 0.45; +} + +.wallet-app-shell::after { + position: fixed; + right: -8vw; + bottom: -7vh; + left: -9vw; + height: 38vh; + pointer-events: none; + content: ""; + opacity: 0.38; + background: + repeating-linear-gradient(164deg, transparent 0 20px, rgba(19, 95, 255, 0.18) 21px 23px, transparent 25px 48px), + radial-gradient(ellipse at 20% 70%, rgba(10, 91, 255, 0.2), transparent 34rem); + filter: blur(0.2px); + transform: rotate(-4deg); } -table { - width: 100%; - border-collapse: collapse; - table-layout: fixed; +.wallet-app-sidebar, +.wallet-app-main, +.wallet-app-rightbar { + position: relative; + z-index: 1; } -th, -td { - border-bottom: 1px solid var(--line); - padding: 12px 14px; - text-align: left; - vertical-align: top; +.wallet-app-sidebar { + display: flex; + flex-direction: column; + gap: 28px; + padding: 28px 24px; } -th { - color: #555d55; - font-size: 0.72rem; - font-weight: 700; - text-transform: uppercase; +.wallet-brand { + display: inline-flex; + gap: 14px; + align-items: center; + color: #061d43; + text-decoration: none; } -td { - font-size: 0.86rem; +.wallet-brand strong { + font-family: Georgia, "Times New Roman", serif; + font-size: 2.1rem; + font-weight: 500; + letter-spacing: -0.03em; } -th, -td { - overflow-wrap: anywhere; +.wallet-flow-mark { + position: relative; + display: inline-block; + width: 42px; + height: 34px; + color: #0f5fff; } -small { - color: var(--muted); +.wallet-flow-mark::before, +.wallet-flow-mark::after, +.wallet-flow-mark span { + position: absolute; + left: 0; + width: 38px; + height: 12px; + content: ""; + border-top: 3px solid currentColor; + border-radius: 50%; + transform-origin: 50% 50%; } -.app-shell { - display: grid; - grid-template-columns: 252px minmax(0, 1fr); - min-height: 100dvh; +.wallet-flow-mark::before { + top: 6px; + transform: rotate(-18deg); } -.sidebar { - position: sticky; - top: 0; - display: flex; - flex-direction: column; - gap: 22px; - height: 100dvh; - padding: 18px 14px; - background: var(--sidebar); - color: #f6f8f2; - border-right: 1px solid #32382f; +.wallet-flow-mark span { + top: 14px; + transform: rotate(8deg); } -.brand-block { - display: grid; - grid-template-columns: 42px 1fr; - gap: 10px; - align-items: center; - padding: 4px 4px 14px; - border-bottom: 1px solid #343a33; +.wallet-flow-mark::after { + top: 21px; + transform: rotate(-10deg); } -.brand-mark { +.wallet-side-nav { display: grid; - place-items: center; - width: 38px; - height: 38px; - border: 1px solid #556054; - border-radius: 8px; - background: #252b26; - color: #d8efe5; + gap: 8px; + margin-top: 8px; } -.brand-kicker, -.eyebrow { +.wallet-side-nav::before, +.wallet-side-nav::after { display: block; - margin-bottom: 4px; - color: var(--subtle); - font-size: 0.71rem; - font-weight: 700; - text-transform: uppercase; -} - -.brand-block strong { - font-size: 1rem; + height: 1px; + margin: 12px 2px; + content: ""; + background: rgba(10, 33, 71, 0.14); } -.nav-list { - display: grid; - gap: 4px; -} - -.nav-link { +.wallet-side-nav button, +.wallet-side-nav a { display: grid; - grid-template-columns: 22px 1fr; - gap: 9px; + grid-template-columns: 26px 1fr; + gap: 12px; align-items: center; - min-height: 38px; - padding: 8px 10px; - color: var(--sidebar-muted); - text-decoration: none; + min-height: 50px; + padding: 0 18px; + color: #132b55; border: 1px solid transparent; - border-radius: 7px; - transition: background 140ms ease, border-color 140ms ease, color 140ms ease, transform 140ms ease; + border-radius: 8px; + background: transparent; + font-weight: 650; + text-align: left; + text-decoration: none; } -.nav-link:hover, -.nav-link.active { - background: #29302b; - border-color: #3c463e; - color: #f6f8f2; +.wallet-side-nav button.active, +.wallet-side-nav button:hover, +.wallet-side-nav a:hover { + color: #0f5fff; + border-color: rgba(10, 33, 71, 0.04); + background: rgba(255, 255, 255, 0.48); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.65); } -.sidebar-footer { - display: grid; - gap: 7px; +.wallet-collapse-button { + display: inline-flex; + gap: 10px; + align-items: center; + width: fit-content; margin-top: auto; - padding: 12px; - color: var(--sidebar-muted); - border: 1px solid #3a433b; - border-radius: 8px; - background: #232923; + padding: 10px 14px; + color: #33486b; + border-color: rgba(10, 33, 71, 0.12); + border-radius: 999px; + background: rgba(255, 255, 255, 0.32); } -.workspace { +.wallet-app-main { min-width: 0; + padding: 22px 16px 28px; } -.topbar { - position: sticky; - top: 0; - display: flex; +.wallet-app-topbar { + display: grid; + grid-template-columns: 180px minmax(260px, 1fr) 48px 240px; + gap: 22px; align-items: center; - justify-content: space-between; - gap: 18px; - padding: 14px 24px; - background: rgba(244, 245, 241, 0.92); - border-bottom: 1px solid var(--line); - backdrop-filter: blur(12px); -} - -.topbar h2 { - margin: 0; - font-size: 1.05rem; + margin-bottom: 20px; } -.topbar-meta { - display: flex; - flex-wrap: wrap; - gap: 8px; - justify-content: flex-end; +.wallet-network-switch, +.wallet-profile-pill, +.wallet-search, +.wallet-icon-button { + border: 1px solid rgba(10, 33, 71, 0.12); + background: rgba(255, 255, 255, 0.46); + box-shadow: + 0 14px 34px rgba(37, 31, 18, 0.06), + inset 0 1px 0 rgba(255, 255, 255, 0.72); + backdrop-filter: blur(16px); } -.topbar-meta span, -.provenance-chip, -.severity-label { +.wallet-network-switch { display: inline-flex; - align-items: center; - gap: 5px; - min-height: 24px; - padding: 4px 7px; - color: #4f584f; - border: 1px solid var(--line); - border-radius: 999px; - background: #f9faf6; - font-size: 0.72rem; - white-space: nowrap; -} - -.fixture-banner { - display: flex; gap: 10px; align-items: center; - margin: 18px 24px 0; - padding: 10px 12px; - color: #394139; - border: 1px solid #cfd7cd; - border-radius: 8px; - background: #f9faf6; - font-size: 0.86rem; -} - -.content { - width: min(100%, 1480px); - margin: 0 auto; - padding: 24px; + justify-content: center; + height: 50px; + padding: 0 16px; + border-radius: 14px; + font-weight: 720; } -.view-stack { - display: grid; - gap: 22px; +.wallet-network-switch .wallet-flow-mark { + width: 26px; + height: 24px; + color: #ffffff; + border-radius: 50%; + background: #0f5fff; } -.section-header { - display: grid; - grid-template-columns: minmax(0, 1fr) auto; - gap: 18px; - align-items: end; +.wallet-network-switch .wallet-flow-mark::before, +.wallet-network-switch .wallet-flow-mark::after, +.wallet-network-switch .wallet-flow-mark span { + left: 5px; + width: 16px; + height: 6px; + border-top-width: 2px; } -.section-header h1 { - margin: 0; - font-size: 1.8rem; - line-height: 1.15; +.wallet-network-switch .wallet-flow-mark::before { + top: 7px; } -.section-header p { - max-width: 76ch; - margin: 8px 0 0; - color: var(--muted); - line-height: 1.5; +.wallet-network-switch .wallet-flow-mark span { + top: 11px; } -.section-action { - min-width: min(520px, 100%); +.wallet-network-switch .wallet-flow-mark::after { + top: 15px; } -.workbench-header-actions { +.wallet-search { display: grid; - grid-template-columns: minmax(0, 1fr) auto; - gap: 10px; + grid-template-columns: 22px minmax(0, 1fr) auto; + gap: 12px; align-items: center; + height: 50px; + padding: 0 14px; + border-radius: 14px; } -.filter-row { - display: grid; - grid-template-columns: minmax(240px, 1fr) 150px; - gap: 10px; +.wallet-search input { + color: #0a2147; } -.search-box { - display: grid; - grid-template-columns: 18px 1fr; - gap: 8px; - align-items: center; - min-height: 38px; - padding: 0 10px; - border: 1px solid var(--line-strong); +.wallet-search kbd { + padding: 4px 7px; + color: #4d5d78; + border: 1px solid rgba(10, 33, 71, 0.14); border-radius: 7px; - background: var(--surface); + background: rgba(255, 255, 255, 0.62); + font-size: 0.73rem; } -.metric-grid { +.wallet-icon-button { + position: relative; display: grid; - grid-template-columns: repeat(5, minmax(0, 1fr)); - gap: 10px; + place-items: center; + width: 48px; + height: 48px; + border-radius: 50%; } -.flowmemory-hero { +.wallet-icon-button span { + position: absolute; + top: 9px; + right: 10px; + width: 8px; + height: 8px; + background: #0f5fff; + border-radius: 50%; +} + +.wallet-profile-pill { display: grid; - grid-template-columns: minmax(0, 1fr) minmax(280px, 0.34fr); - gap: 14px; - align-items: stretch; - border: 1px solid var(--line); - border-radius: 8px; - background: linear-gradient(135deg, #fbfcf8 0%, #edf4ef 100%); - box-shadow: var(--shadow); + grid-template-columns: 42px 1fr 18px; + grid-template-rows: auto auto; + column-gap: 10px; + align-items: center; + min-height: 54px; + padding: 8px 12px; + border-radius: 15px; + text-align: left; } -.flowmemory-hero-main { +.wallet-profile-pill > span { display: grid; - gap: 12px; - padding: 18px; + grid-row: 1 / span 2; + place-items: center; + width: 38px; + height: 38px; + color: #ffffff; + background: #0b2c75; + border-radius: 50%; + font-weight: 800; } -.flowmemory-hero-main h2 { - max-width: 780px; - margin: 0; - font-size: 1.48rem; - line-height: 1.14; +.wallet-profile-pill strong { + font-size: 0.95rem; } -.flowmemory-hero-main p { - max-width: 82ch; - margin: 0; - color: #465047; - line-height: 1.5; +.wallet-profile-pill small { + color: #61718e; } -.flowmemory-spine { - display: grid; - grid-template-columns: repeat(5, minmax(0, 1fr)); - gap: 8px; +.wallet-profile-pill svg { + grid-row: 1 / span 2; } -.flowmemory-spine span { - min-height: 34px; - padding: 8px 9px; - color: #284238; - border: 1px solid #bfd1c7; - border-radius: 7px; - background: rgba(251, 252, 248, 0.78); - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 0.74rem; - text-align: center; +.wallet-portfolio-panel, +.wallet-side-card, +.wallet-action-grid button, +.wallet-action-grid a, +.wallet-action-panel { + border: 1px solid rgba(10, 33, 71, 0.1); + background: rgba(255, 255, 255, 0.34); + box-shadow: + 0 18px 44px rgba(50, 37, 18, 0.07), + inset 0 1px 0 rgba(255, 255, 255, 0.72); + backdrop-filter: blur(18px); } -.flowmemory-hero-side { +.wallet-portfolio-panel { display: grid; - gap: 1px; - min-width: 0; - padding: 1px; - border-left: 1px solid var(--line); + grid-template-columns: minmax(220px, 0.78fr) minmax(360px, 1.4fr); + gap: 18px; + min-height: 286px; + padding: 30px 34px 24px; + border-radius: 18px; } -.flowmemory-hero-side div { - display: grid; - gap: 5px; - align-content: center; - min-width: 0; - padding: 12px; - background: rgba(251, 252, 248, 0.72); +.wallet-portfolio-copy h1 { + margin: 0 0 22px; + color: #071d44; + font-family: Georgia, "Times New Roman", serif; + font-size: clamp(2.4rem, 4vw, 3.35rem); + font-weight: 500; + letter-spacing: -0.04em; } -.canary-hero { - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(300px, 0.36fr); - gap: 14px; - align-items: stretch; - padding: 16px; - border: 1px solid #c9d5ce; - border-radius: 8px; - background: - linear-gradient(135deg, rgba(251, 252, 248, 0.94), rgba(229, 239, 235, 0.92)), - linear-gradient(90deg, rgba(47, 125, 107, 0.18), transparent); - box-shadow: var(--shadow); +.wallet-portfolio-copy > span { + display: inline-flex; + gap: 10px; + align-items: center; + color: #65728a; + font-size: 1.05rem; + font-weight: 650; } -.canary-hero h2 { - max-width: 760px; - margin: 0; - font-size: 1.52rem; - line-height: 1.14; +.wallet-portfolio-copy > strong { + display: block; + margin-top: 8px; + color: #071d44; + font-family: Georgia, "Times New Roman", serif; + font-size: clamp(2.6rem, 5vw, 4.1rem); + font-weight: 500; + line-height: 1; + letter-spacing: -0.05em; } -.canary-hero p { - max-width: 84ch; - margin: 10px 0 0; - color: #465047; - line-height: 1.5; +.wallet-portfolio-copy p { + display: flex; + gap: 18px; + align-items: center; + margin: 18px 0 0; + color: #607089; } -.canary-read-window { - display: grid; - grid-template-columns: 28px 1fr; - gap: 10px; - align-items: start; - padding: 12px; - border: 1px solid #bfd1c7; - border-radius: 8px; - background: rgba(251, 252, 248, 0.78); +.wallet-portfolio-copy b { + color: #0aa873; + font-weight: 700; } -.canary-read-window dl { - display: grid; - gap: 9px; - margin: 0; +.wallet-chart-card { + min-width: 0; } -.canary-operator-strip { - display: grid; - grid-template-columns: 1.15fr 1fr 1.1fr; - gap: 10px; +.wallet-chart-tabs { + display: flex; + gap: 18px; + justify-content: flex-end; + margin-bottom: 8px; } -.canary-operator-strip article { - display: grid; - gap: 7px; - min-width: 0; - padding: 12px; - border: 1px solid #c9d5ce; - border-radius: 8px; - background: #fbfcf8; - box-shadow: var(--shadow); +.wallet-chart-tabs button { + min-width: 42px; + min-height: 34px; + color: #53637d; + border: 0; + border-radius: 10px; + background: transparent; + font-weight: 700; } -.canary-operator-strip span, -.canary-operator-strip strong { - overflow-wrap: anywhere; +.wallet-chart-tabs button.active { + color: #071d44; + border: 1px solid rgba(10, 33, 71, 0.1); + background: rgba(255, 255, 255, 0.56); } -.canary-operator-strip span { - color: var(--muted); - font-size: 0.72rem; - font-weight: 800; - text-transform: uppercase; +.wallet-chart-card svg { + width: 100%; + height: 190px; + overflow: visible; } -.canary-boundaries { - display: grid; - gap: 8px; - padding-top: 12px; +.wallet-chart-fill { + fill: url(#walletChartFill); } -.canary-boundaries span { - padding: 9px 10px; - color: #4d564d; - border: 1px solid var(--line); - border-radius: 7px; - background: #f8f9f4; - line-height: 1.35; +.wallet-chart-line { + fill: none; + stroke: #0f5fff; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 4; } -.metric-tile, -.panel, -.table-panel, -.rootfield-tile, -.lane-tile, -.node-tile, -.alert-row, -.json-panel { - border: 1px solid var(--line); - border-radius: 8px; - background: var(--surface); - box-shadow: var(--shadow); +.wallet-chart-grid path { + stroke: rgba(10, 33, 71, 0.08); + stroke-width: 1; } -.metric-tile { +.wallet-chart-axis { display: grid; - gap: 8px; - padding: 14px; + grid-template-columns: repeat(7, 1fr); + color: #61718e; + font-size: 0.78rem; + font-weight: 650; } -.metric-tile > span { - color: var(--muted); - font-size: 0.75rem; - font-weight: 700; - text-transform: uppercase; +.wallet-action-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 16px; + margin-top: 18px; } -.metric-tile strong { - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 1.65rem; +.wallet-action-grid button, +.wallet-action-grid a { + display: grid; + grid-template-columns: 52px 1fr; + grid-template-rows: auto auto; + column-gap: 14px; + align-items: center; + min-height: 82px; + padding: 14px 18px; + color: #071d44; + border-radius: 13px; + text-align: left; + text-decoration: none; } -.metric-tile div { - display: flex; - flex-wrap: wrap; - gap: 7px; - align-items: center; +.wallet-action-grid button:hover, +.wallet-action-grid a:hover, +.wallet-side-card button:hover, +.wallet-side-card a:hover { + transform: translateY(-1px); } -.overview-grid { +.wallet-action-grid span { display: grid; - grid-template-columns: minmax(0, 1.4fr) minmax(290px, 0.6fr); - gap: 14px; + grid-row: 1 / span 2; + place-items: center; + width: 44px; + height: 44px; + color: #ffffff; + background: #0f5fff; + border-radius: 50%; } -.panel { - min-width: 0; - padding: 14px; +.wallet-action-grid strong { + font-size: 1rem; } -.panel-wide { - grid-column: span 1; +.wallet-action-grid small { + color: #697893; } -.panel-side-bottom { - grid-column: 2; +.wallet-assets-section, +.wallet-activity-section { + margin-top: 26px; } -.panel-heading { +.wallet-section-title { display: flex; align-items: center; justify-content: space-between; - gap: 10px; - padding-bottom: 10px; - border-bottom: 1px solid var(--line); + margin-bottom: 12px; } -.panel-heading div, -.tile-heading, -.record-title, -.json-panel-header { - display: flex; - gap: 8px; - align-items: center; - min-width: 0; +.wallet-section-title h2, +.wallet-side-card h2, +.wallet-action-panel h2 { + margin: 0; + color: #071d44; + font-family: Georgia, "Times New Roman", serif; + font-size: 1.35rem; + font-weight: 540; + letter-spacing: -0.02em; } -.panel-heading h2 { - margin: 0; - font-size: 0.98rem; +.wallet-section-title button, +.wallet-side-title button, +.wallet-text-action { + display: inline-flex; + gap: 8px; + align-items: center; + color: #0f5fff; + border: 0; + background: transparent; + font-weight: 700; } -.panel-heading > span { - color: var(--muted); - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 0.78rem; +.wallet-asset-table, +.wallet-activity-table { + overflow: hidden; + border: 1px solid rgba(10, 33, 71, 0.1); + border-radius: 14px; + background: rgba(255, 255, 255, 0.2); } -.record-list, -.compact-list, -.alert-list { +.wallet-asset-table > div, +.wallet-activity-table > div { display: grid; + align-items: center; + min-height: 48px; + padding: 0 16px; + border-bottom: 1px solid rgba(10, 33, 71, 0.09); } -.status-strip { - display: flex; - flex-wrap: wrap; - gap: 8px; - padding: 10px 0 2px; +.wallet-asset-table > div { + grid-template-columns: minmax(190px, 1.25fr) 1fr 1fr 0.7fr; } -.status-strip span { - display: inline-flex; - gap: 6px; - align-items: center; - padding: 3px 6px 3px 3px; - border: 1px solid var(--line); - border-radius: 999px; - background: #f8f9f4; +.wallet-activity-table > div { + grid-template-columns: 1.2fr 0.9fr 0.8fr 1.2fr 0.9fr 0.8fr; } -.status-strip strong { - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 0.74rem; +.wallet-asset-table > div:last-child, +.wallet-activity-table > div:last-child { + border-bottom: 0; } -.record-row { - display: grid; - grid-template-columns: minmax(0, 1fr) 270px; - gap: 16px; - padding: 14px 0; - border-bottom: 1px solid var(--line); +.wallet-asset-table > div:first-child, +.wallet-activity-table > div:first-child { + min-height: 38px; + color: #687895; + font-size: 0.72rem; + font-weight: 760; } -.record-row:last-child { - border-bottom: 0; +.wallet-asset-table span, +.wallet-activity-table span { + min-width: 0; + overflow-wrap: anywhere; } -.record-row p, -.alert-row p { - margin: 8px 0; - color: #3f483f; - line-height: 1.45; +.wallet-asset-table div:not(:first-child) > span:first-child { + display: grid; + grid-template-columns: 36px minmax(0, 1fr); + grid-template-rows: auto auto; + column-gap: 12px; + align-items: center; } -.record-facts, -.definition-grid, -.lane-stats, -.alert-facts { +.wallet-asset-table i { display: grid; - gap: 10px; - margin: 0; + grid-row: 1 / span 2; + place-items: center; + width: 30px; + height: 30px; + color: #ffffff; + background: #0f5fff; + border-radius: 50%; + font-style: normal; + font-weight: 800; } -.record-facts { - grid-template-columns: repeat(2, minmax(0, 1fr)); +.wallet-asset-table strong, +.wallet-asset-table b, +.wallet-activity-table b { + color: #071d44; + font-weight: 720; } -.record-facts div, -.definition-grid div, -.lane-stats div, -.alert-facts div { - min-width: 0; +.wallet-asset-table small { + color: #72809b; } -dt { - color: var(--subtle); - font-size: 0.68rem; - font-weight: 700; - text-transform: uppercase; +.wallet-change-up { + color: #0aa873 !important; } -dd { - margin: 3px 0 0; - overflow-wrap: anywhere; +.wallet-change-flat { + color: #687895 !important; } -.compact-list article { - display: grid; - grid-template-columns: auto minmax(0, 1fr); - gap: 9px; - align-items: start; - padding: 12px 0; - border-bottom: 1px solid var(--line); +.wallet-activity-table b { + display: inline-flex; + align-items: center; + justify-content: center; + width: fit-content; + min-height: 24px; + padding: 0 10px; + color: #0a8f65; + border: 1px solid rgba(10, 168, 115, 0.22); + border-radius: 999px; + background: rgba(10, 168, 115, 0.08); + font-size: 0.78rem; } -.compact-list article:last-child { - border-bottom: 0; +.wallet-app-rightbar { + display: flex; + flex-direction: column; + gap: 18px; + padding: 88px 28px 28px 8px; } -.compact-list strong, -.compact-list small { +.wallet-side-card { + overflow: hidden; + padding: 24px; + border-radius: 18px; +} + +.wallet-account-card > span { display: block; + margin-top: 20px; + color: #61718e; + font-size: 0.82rem; + font-weight: 650; +} + +.wallet-copy-row { + display: grid; + grid-template-columns: minmax(0, 1fr) 38px 38px; + gap: 8px; + align-items: center; + padding: 8px 0 18px; + border-bottom: 1px solid rgba(10, 33, 71, 0.1); +} + +.wallet-copy-row strong { overflow-wrap: anywhere; } -.contract-event-list { +.wallet-copy-row button, +.wallet-account-card > button { + border: 0; + background: transparent; +} + +.wallet-copy-row button { display: grid; + place-items: center; + width: 38px; + height: 38px; + color: #314568; } -.contract-event-list article { +.wallet-account-card > button { display: grid; - gap: 9px; - padding: 12px 0; - border-bottom: 1px solid var(--line); + grid-template-columns: 28px 1fr auto 18px; + gap: 12px; + align-items: center; + width: 100%; + min-height: 58px; + padding: 0; + color: #071d44; + text-align: left; } -.contract-event-list article:last-child { - border-bottom: 0; +.wallet-account-card > button small, +.wallet-side-title b { + color: #0aa873; } -.contract-event-list article > div { +.wallet-side-title { display: flex; - gap: 8px; align-items: center; - min-width: 0; + justify-content: space-between; + gap: 16px; } -.contract-event-list strong { - overflow-wrap: anywhere; - font-size: 0.84rem; +.wallet-network-facts { + display: grid; + gap: 16px; + margin: 22px 0; } -.contract-event-list dl { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 8px; +.wallet-network-facts div { + display: flex; + justify-content: space-between; + gap: 18px; +} + +.wallet-network-facts dt { + color: #61718e; +} + +.wallet-network-facts dd { margin: 0; + color: #071d44; + font-weight: 750; } -.bundle-grid { +.wallet-bridge-card { display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 10px; - padding-top: 14px; + gap: 18px; } -.bundle-grid article { +.wallet-bridge-card div { display: grid; - gap: 8px; - min-width: 0; - padding: 12px; - border: 1px solid var(--line); - border-radius: 7px; - background: #f7f8f4; + grid-template-columns: 28px 1fr; + column-gap: 12px; + align-items: center; } -.bundle-grid strong, -.bundle-grid small { - display: block; - overflow-wrap: anywhere; +.wallet-bridge-card div svg { + color: #0f5fff; } -.block-strip { - display: grid; - grid-template-columns: repeat(4, minmax(0, 1fr)); - gap: 10px; - padding-top: 14px; +.wallet-bridge-card p { + grid-column: 2; + margin: 4px 0 0; + color: #697893; } -.block-strip article { - display: grid; - gap: 7px; - padding: 12px; - border: 1px solid var(--line); - border-radius: 7px; - background: #f7f8f4; +.wallet-bridge-card a { + display: inline-flex; + gap: 10px; + align-items: center; + justify-content: center; + min-height: 46px; + color: #ffffff; + border-radius: 8px; + background: #0f5fff; + font-weight: 750; + text-decoration: none; } -.workbench-command-center { +.wallet-watchlist-card { display: grid; - grid-template-columns: minmax(0, 1.08fr) minmax(360px, 0.92fr); - gap: 14px; + gap: 16px; } -.workbench-boundary-strip { +.wallet-watch-row { display: grid; - grid-template-columns: 1.05fr 1.15fr 1.2fr; + grid-template-columns: 34px 1fr auto auto 52px; gap: 10px; + align-items: center; } -.workbench-boundary-strip article { +.wallet-watch-row span { display: grid; - gap: 6px; - min-width: 0; - padding: 12px; - border: 1px solid #cfd7cd; - border-radius: 8px; - background: #f9faf6; + place-items: center; + width: 30px; + height: 30px; + color: #ffffff; + background: #0f5fff; + border-radius: 50%; + font-weight: 800; } -.workbench-boundary-strip strong { - font-size: 0.82rem; +.wallet-watch-row small { + color: #071d44; + font-weight: 650; } -.workbench-boundary-strip span { - color: #4c554c; - font-size: 0.84rem; - line-height: 1.42; +.wallet-watch-row b { + color: #0aa873; } -.pilot-status-panel article { - display: grid; - gap: 14px; - min-width: 0; - padding: 14px; - border: 1px solid #b8c7c0; - border-radius: 8px; - background: #f4f8f6; +.wallet-watch-row i { + height: 24px; + background: + linear-gradient(135deg, transparent 10%, #0f5fff 11% 14%, transparent 15% 28%, #0f5fff 29% 32%, transparent 33% 48%, #0f5fff 49% 53%, transparent 54% 100%); } -.pilot-status-body { - display: grid; - grid-template-columns: minmax(0, 0.92fr) minmax(320px, 1.08fr); - gap: 14px; - align-items: start; +.wallet-action-panel { + position: fixed; + z-index: 6; + right: 32px; + bottom: 30px; + width: min(520px, calc(100vw - 32px)); + max-height: min(78dvh, 720px); + overflow: auto; + padding: 22px; + border-radius: 20px; } -.pilot-status-body h3 { - margin: 4px 0 8px; - font-size: 1.35rem; - text-transform: capitalize; +.wallet-action-panel header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 18px; + margin-bottom: 18px; } -.pilot-status-body p { - margin: 0; - color: #3f483f; - line-height: 1.48; +.wallet-action-panel header span { + color: #0f5fff; + font-size: 0.75rem; + font-weight: 800; + text-transform: uppercase; } -.product-surface-grid { +.wallet-action-panel header button { + min-height: 36px; + padding: 0 12px; + border-color: rgba(10, 33, 71, 0.14); + background: rgba(255, 255, 255, 0.5); +} + +.wallet-panel-form { display: grid; - grid-template-columns: 1.2fr 1fr 1.2fr; - gap: 10px; + gap: 14px; } -.product-surface { +.wallet-panel-form label { display: grid; - grid-template-columns: 34px minmax(0, 1fr) auto auto; - gap: 10px; - align-items: start; - min-width: 0; - min-height: 118px; - padding: 12px; - text-align: left; - transition: background 140ms ease, border-color 140ms ease, transform 140ms ease; + gap: 7px; + color: #53637d; + font-weight: 700; } -.product-surface:hover { - border-color: #9fb4a8; - background: #eaf1eb; +.wallet-panel-form input:not([type="checkbox"]) { + min-height: 46px; + padding: 0 13px; + border: 1px solid rgba(10, 33, 71, 0.14); + border-radius: 10px; + background: rgba(255, 255, 255, 0.46); } -.product-surface-icon { - display: grid; - place-items: center; - width: 32px; - height: 32px; - color: #235f52; - border: 1px solid #bfd1c7; - border-radius: 7px; - background: #edf5ef; +.wallet-panel-form button, +.wallet-receive-panel button { + display: inline-flex; + gap: 9px; + align-items: center; + justify-content: center; + min-height: 44px; + padding: 0 16px; + color: #ffffff; + border: 0; + border-radius: 9px; + background: #0f5fff; + font-weight: 760; } -.product-surface strong, -.product-surface small, -.product-surface code { - display: block; - overflow-wrap: anywhere; +.wallet-panel-form button:disabled { + cursor: not-allowed; + opacity: 0.55; } -.product-surface small { - margin-top: 4px; - line-height: 1.36; +.wallet-inline-check { + grid-template-columns: 18px 1fr; + align-items: center; + color: #071d44 !important; } -.product-surface b { - color: var(--ink); - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 1.1rem; - line-height: 1.1; +.wallet-swap-route { + display: grid; + grid-template-columns: 1fr 42px 1fr; + gap: 10px; + align-items: center; } -.workbench-node-body { +.wallet-swap-route span { display: grid; - gap: 16px; - padding-top: 14px; + place-items: center; + min-height: 48px; + border: 1px solid rgba(10, 33, 71, 0.12); + border-radius: 12px; + background: rgba(255, 255, 255, 0.38); + font-weight: 800; } -.workbench-node-body h3 { - margin: 0 0 7px; - font-size: 1.22rem; +.wallet-receive-panel { + display: grid; + gap: 16px; } -.workbench-node-body p, -.workbench-section-detail, -.boundary-copy p { +.wallet-receive-panel p { margin: 0; - color: #465047; - line-height: 1.48; + padding: 13px; + border: 1px solid rgba(10, 33, 71, 0.12); + border-radius: 10px; + background: rgba(255, 255, 255, 0.42); + overflow-wrap: anywhere; + color: #071d44; + font-weight: 700; } -.workbench-fact-grid { +.wallet-qr-block { display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-columns: repeat(3, 1fr); gap: 10px; - margin: 0; + width: 156px; + height: 156px; + padding: 14px; + border: 1px solid rgba(10, 33, 71, 0.16); + border-radius: 18px; + background: + linear-gradient(90deg, rgba(15, 95, 255, 0.13) 50%, transparent 50%) 0 0 / 28px 28px, + linear-gradient(rgba(15, 95, 255, 0.2) 50%, transparent 50%) 0 0 / 22px 22px, + rgba(255, 255, 255, 0.5); } -.workbench-fact-grid div { - min-width: 0; - padding: 10px; - border: 1px solid var(--line); +.wallet-qr-block span { + border: 8px solid #071d44; border-radius: 7px; - background: #f7f8f4; } -.setup-step-list { +.wallet-panel-list { display: grid; - padding-top: 6px; + gap: 10px; } -.setup-step-list article { +.wallet-panel-list article { display: grid; - grid-template-columns: auto minmax(0, 1fr); - gap: 9px; - align-items: start; - padding: 11px 0; - border-bottom: 1px solid var(--line); + grid-template-columns: 1fr auto; + gap: 5px 12px; + padding: 13px; + border: 1px solid rgba(10, 33, 71, 0.1); + border-radius: 12px; + background: rgba(255, 255, 255, 0.35); } -.setup-step-list .status-badge { - align-self: start; +.wallet-panel-list small { + overflow-wrap: anywhere; } -.setup-step-list article:last-child { - border-bottom: 0; +.wallet-panel-list b { + color: #0aa873; } -.setup-step-list strong, -.setup-step-list code, -.setup-step-list small { - display: block; - overflow-wrap: anywhere; +.wallet-security-grid { + display: grid; + gap: 12px; } -code { - width: fit-content; - max-width: 100%; - margin: 5px 0; - padding: 3px 6px; - color: #25332d; - border: 1px solid var(--line); - border-radius: 6px; - background: #eef1eb; - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 0.78rem; -} - -.workbench-warning { +.wallet-security-grid article, +.wallet-empty-panel { display: grid; - grid-template-columns: auto minmax(0, 1fr); - gap: 9px; - align-items: start; - padding: 11px 12px; - color: #6b4a16; - border: 1px solid #d9c393; - border-radius: 8px; - background: #fbf6e8; -} - -.workbench-warning strong, -.workbench-warning span { - display: block; - overflow-wrap: anywhere; + gap: 8px; + padding: 14px; + border: 1px solid rgba(10, 33, 71, 0.1); + border-radius: 13px; + background: rgba(255, 255, 255, 0.34); } -.workbench-api-panel { - display: grid; - gap: 12px; +.wallet-security-grid svg, +.wallet-empty-panel svg { + color: #0f5fff; } -.endpoint-strip { - display: flex; - flex-wrap: wrap; - gap: 7px; +.wallet-empty-panel strong { + color: #071d44; } -.endpoint-strip span { - padding: 4px 7px; - color: #34443c; - border: 1px solid var(--line); +.wallet-toast { + position: fixed; + z-index: 7; + left: 50%; + bottom: 24px; + display: inline-flex; + gap: 10px; + align-items: center; + max-width: min(640px, calc(100vw - 28px)); + margin: 0; + padding: 12px 16px; + color: #071d44; + border: 1px solid rgba(10, 33, 71, 0.13); border-radius: 999px; - background: #f7f8f4; - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 0.72rem; + background: rgba(255, 255, 255, 0.78); + box-shadow: 0 18px 42px rgba(50, 37, 18, 0.12); + transform: translateX(-50%); + backdrop-filter: blur(18px); } -.local-action-grid { - display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 10px; -} +@media (max-width: 1220px) { + .wallet-app-shell { + grid-template-columns: 220px minmax(0, 1fr); + overflow: auto; + } -.local-action-grid article { - display: grid; - grid-template-columns: minmax(0, 1fr) auto; - gap: 10px; - align-items: center; - min-width: 0; - padding: 11px; - border: 1px solid var(--line); - border-radius: 7px; - background: #f7f8f4; + .wallet-app-rightbar { + grid-column: 2; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + padding: 0 24px 28px 16px; + } + + .wallet-app-topbar { + grid-template-columns: 170px minmax(0, 1fr) 48px; + } + + .wallet-profile-pill { + grid-column: 1 / -1; + width: min(280px, 100%); + justify-self: end; + } } -.local-action-grid strong, -.local-action-grid small { - display: block; - overflow-wrap: anywhere; +@media (max-width: 860px) { + .wallet-app-shell { + display: block; + min-height: 100dvh; + overflow: auto; + } + + .wallet-app-sidebar { + position: relative; + display: block; + padding: 20px 18px 0; + } + + .wallet-side-nav { + display: flex; + gap: 8px; + overflow-x: auto; + margin-top: 16px; + padding-bottom: 8px; + } + + .wallet-side-nav::before, + .wallet-side-nav::after, + .wallet-collapse-button { + display: none; + } + + .wallet-side-nav button, + .wallet-side-nav a { + display: inline-flex; + grid-template-columns: none; + min-width: max-content; + min-height: 42px; + padding: 0 13px; + } + + .wallet-app-main { + padding: 18px; + } + + .wallet-app-topbar { + grid-template-columns: 1fr 48px; + gap: 12px; + } + + .wallet-network-switch, + .wallet-search { + grid-column: 1 / -1; + } + + .wallet-profile-pill { + grid-column: 1; + justify-self: stretch; + } + + .wallet-portfolio-panel, + .wallet-action-grid, + .wallet-app-rightbar { + grid-template-columns: 1fr; + } + + .wallet-portfolio-panel { + padding: 24px 20px; + } + + .wallet-action-grid { + gap: 10px; + } + + .wallet-asset-table, + .wallet-activity-table { + overflow-x: auto; + } + + .wallet-asset-table > div { + min-width: 680px; + } + + .wallet-activity-table > div { + min-width: 860px; + } + + .wallet-app-rightbar { + padding: 0 18px 24px; + } + + .wallet-action-panel { + right: 12px; + bottom: 12px; + left: 12px; + width: auto; + } } -.action-result, -.boot-hint { - margin: 0; - color: var(--muted); - line-height: 1.45; +input[type="checkbox"] { + width: 16px; + height: 16px; + accent-color: var(--accent); } -.workbench-layout { - display: grid; - grid-template-columns: 222px minmax(0, 1fr); - gap: 14px; - align-items: start; +select { + min-height: 38px; + padding: 0 12px; } -.workbench-switcher { - position: sticky; - top: 88px; - display: grid; - gap: 7px; - max-height: calc(100dvh - 112px); - overflow: auto; +table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; } -.workbench-switch { - display: grid; - grid-template-columns: minmax(0, 1fr) auto; - gap: 10px; - align-items: center; - min-height: 38px; - padding: 8px 10px; +th, +td { + border-bottom: 1px solid var(--line); + padding: 12px 14px; text-align: left; - transition: background 140ms ease, border-color 140ms ease, transform 140ms ease; + vertical-align: top; } -.workbench-switch.active, -.workbench-switch:hover { - border-color: #9fb4a8; - background: #eaf1eb; +th { + color: #555d55; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; } -.workbench-switch span { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; +td { + font-size: 0.86rem; } -.workbench-switch strong { - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 0.78rem; +th, +td { + overflow-wrap: anywhere; } -.workbench-record-panel { +small { + color: var(--muted); +} + +.app-shell { display: grid; - gap: 14px; + grid-template-columns: 252px minmax(0, 1fr); + min-height: 100dvh; } -.workbench-record-grid { +.sidebar { + position: sticky; + top: 0; + display: flex; + flex-direction: column; + gap: 22px; + height: 100dvh; + padding: 18px 14px; + background: var(--sidebar); + color: #f6f8f2; + border-right: 1px solid #32382f; +} + +.brand-block { display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); + grid-template-columns: 42px 1fr; gap: 10px; + align-items: center; + padding: 4px 4px 14px; + border-bottom: 1px solid #343a33; } -.workbench-record { +.brand-mark { display: grid; - gap: 11px; - min-width: 0; - padding: 13px; - border: 1px solid var(--line); - border-radius: 7px; - background: #f7f8f4; + place-items: center; + width: 38px; + height: 38px; + border: 1px solid #556054; + border-radius: 8px; + background: #252b26; + color: #d8efe5; } -.workbench-record h3 { - min-width: 0; - margin: 0; - overflow-wrap: anywhere; - font-size: 0.96rem; +.brand-kicker, +.eyebrow { + display: block; + margin-bottom: 4px; + color: var(--subtle); + font-size: 0.71rem; + font-weight: 700; + text-transform: uppercase; } -.workbench-record p { - margin: 0; - color: #465047; - line-height: 1.44; +.brand-block strong { + font-size: 1rem; } -.workbench-boundary-panel { +.nav-list { display: grid; - gap: 12px; + gap: 4px; } -.boundary-copy { +.nav-link { display: grid; + grid-template-columns: 22px 1fr; gap: 9px; + align-items: center; + min-height: 38px; + padding: 8px 10px; + color: var(--sidebar-muted); + text-decoration: none; + border: 1px solid transparent; + border-radius: 7px; + transition: background 140ms ease, border-color 140ms ease, color 140ms ease, transform 140ms ease; } -.table-panel { - min-width: 0; - overflow: hidden; +.nav-link:hover, +.nav-link.active { + background: #29302b; + border-color: #3c463e; + color: #f6f8f2; } -.table-scroll { - overflow-x: auto; +.sidebar-footer { + display: grid; + gap: 7px; + margin-top: auto; + padding: 12px; + color: var(--sidebar-muted); + border: 1px solid #3a433b; + border-radius: 8px; + background: #232923; } -.table-scroll table { - min-width: 1120px; +.workspace { + min-width: 0; } -.cell-stack { - display: grid; - gap: 4px; - min-width: 0; +.topbar { + position: sticky; + top: 0; + display: flex; + align-items: center; + justify-content: space-between; + gap: 18px; + padding: 14px 24px; + background: rgba(244, 245, 241, 0.92); + border-bottom: 1px solid var(--line); + backdrop-filter: blur(12px); } -.hash-value { - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 0.82rem; - overflow-wrap: anywhere; +.topbar h2 { + margin: 0; + font-size: 1.05rem; } -.provenance-line { +.topbar-meta { display: flex; flex-wrap: wrap; + gap: 8px; + justify-content: flex-end; +} + +.topbar-meta span, +.provenance-chip, +.severity-label { + display: inline-flex; + align-items: center; gap: 5px; + min-height: 24px; + padding: 4px 7px; + color: #4f584f; + border: 1px solid var(--line); + border-radius: 999px; + background: #f9faf6; + font-size: 0.72rem; + white-space: nowrap; } -.rootfield-grid, -.hardware-grid { +.fixture-banner { + display: flex; + gap: 10px; + align-items: center; + margin: 18px 24px 0; + padding: 10px 12px; + color: #394139; + border: 1px solid #cfd7cd; + border-radius: 8px; + background: #f9faf6; + font-size: 0.86rem; +} + +.content { + width: min(100%, 1480px); + margin: 0 auto; + padding: 24px; +} + +.flowchain-bridge-page { + position: relative; + min-height: 100dvh; + overflow: hidden; + background: + radial-gradient(circle at 50% 18%, rgba(255, 255, 255, 0.86), rgba(255, 255, 255, 0) 38rem), + radial-gradient(circle at 18% 62%, rgba(41, 123, 255, 0.18), rgba(41, 123, 255, 0) 22rem), + linear-gradient(180deg, #f4ebdf 0%, #efe2d1 48%, #ead9c5 100%); + color: #1c1a17; +} + +.flowchain-bridge-page::before { + position: fixed; + inset: 0; + z-index: 0; + pointer-events: none; + content: ""; + opacity: 0.42; + background-image: + linear-gradient(rgba(58, 39, 18, 0.035) 1px, transparent 1px), + linear-gradient(90deg, rgba(58, 39, 18, 0.025) 1px, transparent 1px); + background-size: 9px 9px, 11px 11px; + mix-blend-mode: multiply; +} + +.flowchain-bridge-page::after { + position: fixed; + inset: auto -12vw 16dvh -12vw; + z-index: 0; + height: 27dvh; + pointer-events: none; + content: ""; + opacity: 0.9; + background: + radial-gradient(ellipse at 12% 54%, rgba(0, 77, 208, 0.52), rgba(0, 113, 255, 0.18) 34%, transparent 67%), + radial-gradient(ellipse at 42% 44%, rgba(0, 94, 255, 0.72), rgba(0, 111, 255, 0.34) 28%, transparent 66%), + radial-gradient(ellipse at 76% 55%, rgba(0, 91, 229, 0.58), rgba(0, 127, 255, 0.22) 32%, transparent 68%); + filter: blur(10px) saturate(1.12); + transform: rotate(-3deg) skewX(-11deg); +} + +.bridge-flow-ribbon { + position: fixed; + inset: auto -10vw 26dvh -10vw; + z-index: 0; + height: 19dvh; + pointer-events: none; + opacity: 0.86; + background: + linear-gradient(92deg, transparent 0%, rgba(0, 95, 255, 0.2) 14%, rgba(12, 103, 255, 0.72) 42%, rgba(21, 127, 255, 0.7) 64%, transparent 100%), + radial-gradient(ellipse at 35% 45%, rgba(11, 82, 213, 0.85), rgba(29, 130, 255, 0.18) 42%, transparent 70%); + border-radius: 999px 18% 999px 28%; + filter: blur(3px); + transform: rotate(4deg) skewX(-18deg); +} + +.flowchain-bridge-nav, +.flowchain-bridge-main { + position: relative; + z-index: 1; +} + +.flowchain-bridge-nav { + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; + width: min(100%, 1720px); + margin: 0 auto; + padding: 24px 34px 0; +} + +.flowchain-brand, +.flowchain-wallet-pill { + display: inline-flex; + align-items: center; + text-decoration: none; +} + +.flowchain-brand { + gap: 10px; + color: #17213a; +} + +.flowchain-brand strong { + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: clamp(1.45rem, 2.4vw, 2rem); + font-weight: 600; +} + +.flowchain-brand-mark { + position: relative; + width: 52px; + height: 30px; +} + +.flowchain-brand-mark, +.flowchain-brand-mark span { + display: block; +} + +.flowchain-brand-mark::before, +.flowchain-brand-mark::after, +.flowchain-brand-mark span { + position: absolute; + left: 0; + width: 48px; + height: 12px; + content: ""; + border: solid #256bda; + border-width: 3px 0 0; + border-radius: 50%; + transform-origin: left center; +} + +.flowchain-brand-mark::before { + top: 4px; + transform: rotate(15deg); +} + +.flowchain-brand-mark span { + top: 11px; + border-color: #1d54b6; + transform: rotate(-8deg); +} + +.flowchain-brand-mark::after { + top: 18px; + width: 36px; + border-color: #5ba2ff; + transform: rotate(20deg); +} + +.flowchain-wallet-pill { + gap: 9px; + min-height: 44px; + padding: 0 16px; + border: 1px solid rgba(98, 76, 52, 0.14); + border-radius: 8px; + background: rgba(248, 241, 231, 0.84); + box-shadow: 0 14px 34px rgba(44, 31, 17, 0.13); + color: #30281f; + font-size: 0.9rem; + backdrop-filter: blur(18px); + transition: transform 180ms ease, border-color 180ms ease, background 180ms ease; +} + +.flowchain-wallet-pill:hover { + border-color: rgba(37, 107, 218, 0.32); + background: rgba(255, 250, 243, 0.92); +} + +.wallet-orb { + width: 19px; + height: 19px; + border-radius: 50%; + background: + radial-gradient(circle at 36% 32%, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0) 38%), + linear-gradient(135deg, #79c2ff, #0b63ff 70%); + box-shadow: inset 0 0 10px rgba(255, 255, 255, 0.52), 0 7px 16px rgba(0, 91, 255, 0.28); +} + +.flowchain-bridge-main { display: grid; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 14px; + gap: 20px; + width: min(100%, 1540px); + margin: 0 auto; + padding: 14px 34px 46px; } -.rootfield-tile, -.node-tile, -.lane-tile { +.bridge-title-block { display: grid; - gap: 14px; - padding: 14px; + justify-items: center; + text-align: center; } -.definition-grid { - grid-template-columns: repeat(2, minmax(0, 1fr)); +.bridge-title-block span { + color: rgba(49, 40, 31, 0.68); + font-size: 0.76rem; + font-weight: 700; + letter-spacing: 0.08em; + text-transform: uppercase; } -.lane-grid { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 12px; +.bridge-title-block h1 { + margin: 8px 0 8px; + color: #211b16; + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: clamp(3.05rem, 5.7vw, 5.25rem); + font-weight: 500; + line-height: 0.95; + text-wrap: balance; } -.lane-stats { - grid-template-columns: repeat(4, minmax(0, 1fr)); +.bridge-title-block p { + width: min(560px, 100%); + max-width: 560px; + margin: 0; + color: rgba(47, 39, 31, 0.7); + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: 1.18rem; + line-height: 1.34; + text-wrap: balance; } -.alert-list { - gap: 12px; +.flowchain-bridge-layout { + display: grid; + grid-template-columns: minmax(210px, 270px) minmax(520px, 650px) minmax(220px, 270px); + gap: clamp(20px, 5vw, 92px); + align-items: center; + justify-content: center; } -.alert-row { +.bridge-side-card, +.bridge-console { + border: 1px solid rgba(89, 68, 45, 0.14); + background: rgba(249, 241, 229, 0.74); + box-shadow: 0 28px 68px rgba(46, 31, 15, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.48); + backdrop-filter: blur(18px); +} + +.bridge-side-card { display: grid; - grid-template-columns: minmax(0, 1fr) 300px; gap: 16px; - padding: 14px; - border-left-width: 4px; + padding: 24px; + border-radius: 8px; } -.severity-critical { - border-left-color: var(--danger); +.bridge-card-heading { + display: flex; + gap: 10px; + align-items: center; } -.severity-warning { - border-left-color: var(--warning); +.bridge-card-heading h2 { + margin: 0; + color: #281f18; + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: 1.18rem; + font-weight: 500; } -.severity-info { - border-left-color: var(--info); +.bridge-transfer-list, +.bridge-side-stack, +.bridge-route-list, +.bridge-help-card { + display: grid; + gap: 12px; } -.alert-action { - padding: 12px; - border-left: 1px solid var(--line); +.bridge-transfer-row { + display: grid; + grid-template-columns: 28px minmax(0, 1fr) auto; + gap: 10px; + align-items: center; } -.alert-action span { - color: var(--subtle); - font-size: 0.7rem; - font-weight: 700; - text-transform: uppercase; +.bridge-transfer-row strong, +.bridge-transfer-row span, +.bridge-readiness-line span, +.bridge-route-list strong, +.bridge-route-list span { + overflow-wrap: anywhere; } -.alert-action p { - margin-bottom: 0; +.bridge-transfer-row strong { + display: block; + color: #221a14; + font-size: 0.9rem; + font-weight: 650; } -.json-panel { - overflow: hidden; +.bridge-transfer-row span { + color: rgba(42, 33, 25, 0.66); + font-size: 0.8rem; } -.json-panel-header { - justify-content: space-between; - padding: 12px 14px; - border-bottom: 1px solid var(--line); +.bridge-transfer-icon { + display: grid; + place-items: center; + width: 26px; + height: 26px; + color: #0f62db; + border-radius: 50%; + background: #eef5ff; } -.json-panel pre { - max-height: 68dvh; - margin: 0; - padding: 16px; - overflow: auto; - background: #1f241f; - color: #eef4ec; - font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; - font-size: 0.78rem; - line-height: 1.5; +.bridge-empty-transfer { + display: grid; + gap: 5px; + padding: 14px; + color: rgba(43, 34, 26, 0.68); + border: 1px dashed rgba(89, 68, 45, 0.18); + border-radius: 8px; + background: rgba(255, 248, 238, 0.62); + line-height: 1.36; } -.status-badge { +.bridge-empty-transfer strong { + color: #271f18; +} + +.bridge-text-link, +.bridge-help-card a, +.bridge-tx-link { display: inline-flex; - gap: 6px; + gap: 8px; align-items: center; - width: fit-content; - max-width: 100%; - min-height: 24px; - padding: 4px 8px; - border: 1px solid var(--status-border); - border-radius: 999px; - background: var(--status-bg); - color: var(--status-fg); + color: #0d57c4; + text-decoration: none; +} + +.bridge-text-link { + justify-content: center; + min-height: 40px; + border-radius: 8px; + background: rgba(255, 250, 243, 0.48); + font-weight: 650; +} + +.bridge-console { + display: grid; + gap: 14px; + min-width: 0; + padding: 24px; + border-radius: 10px; +} + +.bridge-route-row { + display: grid; + grid-template-columns: minmax(0, 1fr) 140px minmax(0, 1fr); + gap: 14px; + align-items: end; +} + +.bridge-route-row label, +.bridge-field { + min-width: 0; +} + +.bridge-route-row label > span, +.bridge-field > label, +.bridge-estimate-strip span, +.bridge-mini-facts dt, +.bridge-calldata-facts dt { + display: block; + margin-bottom: 6px; + color: rgba(54, 43, 33, 0.7); + font-size: 0.68rem; + font-weight: 750; + letter-spacing: 0.06em; + text-transform: uppercase; +} + +.bridge-select-shell, +.bridge-token-field > div, +.bridge-field { + border: 1px solid rgba(93, 72, 49, 0.13); + border-radius: 8px; + background: rgba(255, 250, 243, 0.68); + box-shadow: 0 9px 18px rgba(47, 32, 14, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.5); +} + +.bridge-select-shell { + display: grid; + grid-template-columns: 32px minmax(0, 1fr) 18px; + gap: 10px; + align-items: center; + min-height: 58px; + padding: 0 14px; +} + +.bridge-select-shell strong, +.bridge-token-field strong { + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: 1.12rem; + font-weight: 500; +} + +.bridge-chain-icon, +.bridge-token-orb { + display: grid; + place-items: center; + color: #fff; font-size: 0.72rem; font-weight: 800; - text-transform: uppercase; - white-space: nowrap; + border-radius: 50%; } -.status-dot { - width: 7px; - height: 7px; - border-radius: 999px; - background: currentColor; +.bridge-chain-icon { + width: 30px; + height: 30px; } -.status-observed { - --status-bg: #e7f0f3; - --status-border: #b9d0d8; - --status-fg: #326b89; +.bridge-chain-icon.base, +.bridge-token-orb { + background: linear-gradient(135deg, #89c6ff, #0a61dd 68%); } -.status-pending { - --status-bg: #f5eddb; - --status-border: #d9c393; - --status-fg: #8a5e14; -} +.bridge-chain-icon.flow { + background: linear-gradient(135deg, #8bc7ff, #163d96 72%); +} + +.bridge-route-connector { + display: grid; + grid-template-columns: 1fr 44px 1fr; + gap: 8px; + align-items: center; + padding-bottom: 7px; +} + +.bridge-route-connector span { + height: 3px; + border-radius: 999px; + background-image: linear-gradient(90deg, rgba(12, 99, 221, 0.22) 0 45%, transparent 45% 100%); + background-size: 12px 3px; +} + +.bridge-route-connector button, +.bridge-icon-action { + display: grid; + place-items: center; + border: 1px solid rgba(38, 107, 218, 0.26); + background: rgba(244, 249, 255, 0.78); + color: #145ed3; + text-decoration: none; + transition: transform 180ms ease, border-color 180ms ease, background 180ms ease; +} + +.bridge-route-connector button { + width: 44px; + height: 44px; + border-radius: 50%; +} + +.bridge-field { + display: grid; + gap: 7px; + padding: 11px 14px; +} + +.bridge-token-field { + grid-template-columns: minmax(0, 1fr); +} + +.bridge-token-field > div { + display: grid; + grid-template-columns: 34px minmax(0, auto) 1fr; + gap: 10px; + align-items: center; + min-height: 52px; + padding: 0 12px; +} + +.bridge-token-field small { + color: rgba(50, 39, 29, 0.62); +} + +.bridge-token-orb { + width: 30px; + height: 30px; +} + +.bridge-amount-field { + grid-template-columns: minmax(0, 1fr) auto; + align-items: end; +} + +.bridge-amount-field label, +.bridge-recipient-field label { + grid-column: 1 / -1; +} + +.bridge-amount-field input { + font-size: 1.18rem; +} + +.bridge-amount-field > span { + color: #211b16; + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: 1.12rem; +} + +.bridge-recipient-field { + grid-template-columns: minmax(0, 1fr) 32px; + align-items: center; +} + +.bridge-recipient-field button { + display: grid; + place-items: center; + width: 30px; + height: 30px; + padding: 0; + border-color: transparent; + background: transparent; + color: rgba(47, 38, 29, 0.54); +} + +.bridge-field input:not([type="checkbox"]) { + min-height: 28px; + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.82rem; +} + +.bridge-advanced { + display: grid; + gap: 12px; + color: rgba(46, 36, 28, 0.78); +} + +.bridge-advanced summary { + display: flex; + gap: 8px; + align-items: center; + width: fit-content; + cursor: pointer; + color: rgba(41, 32, 24, 0.76); + font-size: 0.84rem; + font-weight: 650; +} + +.bridge-advanced[open] summary { + margin-bottom: 10px; +} + +.bridge-calldata-facts, +.bridge-mini-facts { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 8px; + margin: 10px 0 0; +} + +.bridge-calldata-facts div, +.bridge-mini-facts div { + min-width: 0; + padding: 10px; + border: 1px solid rgba(89, 68, 45, 0.12); + border-radius: 8px; + background: rgba(255, 250, 243, 0.52); +} + +.bridge-calldata-facts dd, +.bridge-mini-facts dd { + margin: 0; + overflow-wrap: anywhere; + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.74rem; + font-weight: 700; +} + +.bridge-estimate-strip { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + overflow: hidden; + border-radius: 8px; + background: rgba(71, 50, 29, 0.06); +} + +.bridge-estimate-strip div { + display: grid; + gap: 6px; + min-width: 0; + padding: 14px; + text-align: center; + border-right: 1px solid rgba(92, 70, 47, 0.08); +} + +.bridge-estimate-strip div:last-child { + border-right: 0; +} + +.bridge-estimate-strip span { + margin-bottom: 0; +} + +.bridge-estimate-strip strong { + overflow-wrap: anywhere; + font-size: 0.9rem; + font-weight: 600; +} + +.bridge-ack { + display: grid; + grid-template-columns: 18px minmax(0, 1fr); + gap: 10px; + align-items: start; + padding: 12px; + border: 1px solid rgba(93, 72, 49, 0.16); + border-radius: 8px; + background: rgba(255, 250, 243, 0.54); + color: rgba(38, 30, 23, 0.72); + font-size: 0.84rem; + line-height: 1.35; +} + +.bridge-action-row { + display: grid; + grid-template-columns: minmax(0, 1fr) 44px 44px; + gap: 10px; +} + +.bridge-primary-action { + min-height: 56px; + justify-content: center; + border: 0; + border-radius: 8px; + background: linear-gradient(135deg, #043aa9, #1b78ff); + color: #fff; + box-shadow: 0 16px 32px rgba(0, 78, 216, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.32); + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: 1.08rem; + transition: transform 180ms ease, box-shadow 180ms ease, opacity 180ms ease; +} + +.bridge-primary-action:hover:not(:disabled) { + transform: translateY(-1px); + box-shadow: 0 20px 38px rgba(0, 78, 216, 0.34), inset 0 1px 0 rgba(255, 255, 255, 0.34); +} + +.bridge-icon-action { + width: 44px; + height: 56px; + border-radius: 8px; +} + +.bridge-icon-action:hover, +.bridge-route-connector button:hover { + border-color: rgba(20, 94, 211, 0.42); + background: rgba(255, 255, 255, 0.86); +} + +.bridge-validation, +.bridge-status-message, +.bridge-tx-link { + margin: 0; + padding: 11px 12px; + border-radius: 8px; + font-size: 0.88rem; +} + +.bridge-validation { + display: flex; + gap: 8px; + align-items: center; + color: #6f2525; + border: 1px solid #e3b5b5; + background: rgba(255, 240, 240, 0.86); +} + +.bridge-status-message { + color: #234e44; + border: 1px solid #b9d8cf; + background: rgba(238, 248, 244, 0.86); +} + +.bridge-tx-link { + justify-self: start; + border: 1px solid #b9d8cf; + background: rgba(238, 248, 244, 0.86); +} + +.bridge-safety-rail { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + overflow: hidden; + margin: 4px -24px -24px; + border-top: 1px solid rgba(88, 67, 44, 0.11); + border-radius: 0 0 10px 10px; + background: rgba(241, 230, 216, 0.72); +} + +.bridge-safety-rail span { + display: grid; + grid-template-columns: 24px minmax(0, 1fr); + gap: 10px; + align-items: center; + min-width: 0; + padding: 15px 18px; + color: rgba(38, 30, 23, 0.74); + border-right: 1px solid rgba(88, 67, 44, 0.09); + font-size: 0.84rem; + line-height: 1.2; +} + +.bridge-safety-rail span:last-child { + border-right: 0; +} + +.bridge-readiness-line { + display: flex; + gap: 10px; + align-items: center; + justify-content: space-between; +} + +.bridge-readiness-line > span { + color: rgba(38, 30, 23, 0.76); + font-size: 0.88rem; + font-weight: 650; +} + +.bridge-mini-facts { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.bridge-route-list div { + display: grid; + grid-template-columns: 22px minmax(0, 1fr) auto; + gap: 10px; + align-items: center; + min-height: 28px; +} + +.bridge-chain-dot { + width: 19px; + height: 19px; + border-radius: 50%; + background: #b5aa9a; +} + +.bridge-chain-dot.active { + background: linear-gradient(135deg, #7fc2ff, #0b63ff); +} + +.bridge-chain-dot.staged { + background: linear-gradient(135deg, #d1c3ae, #a58f72); +} + +.bridge-route-list strong { + font-size: 0.88rem; + font-weight: 650; +} + +.bridge-route-list span:not(.bridge-chain-dot) { + color: rgba(43, 34, 26, 0.58); + font-size: 0.76rem; +} + +.bridge-help-card a { + justify-content: space-between; + min-height: 28px; + color: #2b251f; + font-size: 0.86rem; +} + +@media (max-width: 1280px) { + .flowchain-bridge-layout { + grid-template-columns: minmax(0, 650px); + } + + .bridge-recent-card, + .bridge-side-stack { + width: min(650px, 100%); + justify-self: center; + } +} + +@media (max-width: 720px) { + .flowchain-bridge-nav { + display: grid; + grid-template-columns: 1fr; + align-items: flex-start; + gap: 10px; + padding: 18px 16px 0; + } + + .flowchain-wallet-pill { + justify-self: start; + min-height: 38px; + padding: 0 10px; + } + + .flowchain-bridge-main { + padding: 18px 16px 38px; + } + + .flowchain-bridge-layout { + grid-template-columns: minmax(0, 1fr); + gap: 16px; + } + + .bridge-title-block h1 { + font-size: clamp(2.7rem, 16vw, 4rem); + } + + .bridge-title-block p { + max-width: 340px; + font-size: 1.08rem; + } + + .bridge-route-row, + .bridge-action-row, + .bridge-estimate-strip, + .bridge-safety-rail, + .bridge-calldata-facts, + .bridge-mini-facts { + grid-template-columns: 1fr; + } + + .bridge-route-connector { + grid-template-columns: 1fr 44px 1fr; + padding: 0; + } + + .bridge-console { + padding: 18px; + } + + .bridge-transfer-row { + grid-template-columns: 28px minmax(0, 1fr); + } + + .bridge-transfer-row .status-badge { + grid-column: 2; + justify-self: start; + } + + .bridge-route-list div { + grid-template-columns: 22px minmax(0, 1fr); + } + + .bridge-route-list span:not(.bridge-chain-dot) { + grid-column: 2; + } + + .bridge-safety-rail { + margin: 4px -18px -18px; + } +} + +button:disabled { + cursor: not-allowed; + opacity: 0.55; + transform: none; +} + +.view-stack { + display: grid; + gap: 22px; +} + +.section-header { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 18px; + align-items: end; +} + +.section-header h1 { + margin: 0; + font-size: 1.8rem; + line-height: 1.15; +} + +.section-header p { + max-width: 76ch; + margin: 8px 0 0; + color: var(--muted); + line-height: 1.5; +} + +.section-action { + min-width: min(520px, 100%); +} + +.workbench-header-actions { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 10px; + align-items: center; +} + +.filter-row { + display: grid; + grid-template-columns: minmax(240px, 1fr) 150px; + gap: 10px; +} + +.search-box { + display: grid; + grid-template-columns: 18px 1fr; + gap: 8px; + align-items: center; + min-height: 38px; + padding: 0 10px; + border: 1px solid var(--line-strong); + border-radius: 7px; + background: var(--surface); +} + +.metric-grid { + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: 10px; +} + +.flowmemory-hero { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(280px, 0.34fr); + gap: 14px; + align-items: stretch; + border: 1px solid var(--line); + border-radius: 8px; + background: linear-gradient(135deg, #fbfcf8 0%, #edf4ef 100%); + box-shadow: var(--shadow); +} + +.flowmemory-hero-main { + display: grid; + gap: 12px; + padding: 18px; +} + +.flowmemory-hero-main h2 { + max-width: 780px; + margin: 0; + font-size: 1.48rem; + line-height: 1.14; +} + +.flowmemory-hero-main p { + max-width: 82ch; + margin: 0; + color: #465047; + line-height: 1.5; +} + +.flowmemory-spine { + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: 8px; +} + +.flowmemory-spine span { + min-height: 34px; + padding: 8px 9px; + color: #284238; + border: 1px solid #bfd1c7; + border-radius: 7px; + background: rgba(251, 252, 248, 0.78); + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.74rem; + text-align: center; +} + +.flowmemory-hero-side { + display: grid; + gap: 1px; + min-width: 0; + padding: 1px; + border-left: 1px solid var(--line); +} + +.flowmemory-hero-side div { + display: grid; + gap: 5px; + align-content: center; + min-width: 0; + padding: 12px; + background: rgba(251, 252, 248, 0.72); +} + +.canary-hero { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(300px, 0.36fr); + gap: 14px; + align-items: stretch; + padding: 16px; + border: 1px solid #c9d5ce; + border-radius: 8px; + background: + linear-gradient(135deg, rgba(251, 252, 248, 0.94), rgba(229, 239, 235, 0.92)), + linear-gradient(90deg, rgba(47, 125, 107, 0.18), transparent); + box-shadow: var(--shadow); +} + +.canary-hero h2 { + max-width: 760px; + margin: 0; + font-size: 1.52rem; + line-height: 1.14; +} + +.canary-hero p { + max-width: 84ch; + margin: 10px 0 0; + color: #465047; + line-height: 1.5; +} + +.canary-read-window { + display: grid; + grid-template-columns: 28px 1fr; + gap: 10px; + align-items: start; + padding: 12px; + border: 1px solid #bfd1c7; + border-radius: 8px; + background: rgba(251, 252, 248, 0.78); +} + +.canary-read-window dl { + display: grid; + gap: 9px; + margin: 0; +} + +.canary-operator-strip { + display: grid; + grid-template-columns: 1.15fr 1fr 1.1fr; + gap: 10px; +} + +.canary-operator-strip article { + display: grid; + gap: 7px; + min-width: 0; + padding: 12px; + border: 1px solid #c9d5ce; + border-radius: 8px; + background: #fbfcf8; + box-shadow: var(--shadow); +} + +.canary-operator-strip span, +.canary-operator-strip strong { + overflow-wrap: anywhere; +} + +.canary-operator-strip span { + color: var(--muted); + font-size: 0.72rem; + font-weight: 800; + text-transform: uppercase; +} + +.canary-boundaries { + display: grid; + gap: 8px; + padding-top: 12px; +} + +.canary-boundaries span { + padding: 9px 10px; + color: #4d564d; + border: 1px solid var(--line); + border-radius: 7px; + background: #f8f9f4; + line-height: 1.35; +} + +.metric-tile, +.panel, +.table-panel, +.rootfield-tile, +.lane-tile, +.node-tile, +.alert-row, +.json-panel { + border: 1px solid var(--line); + border-radius: 8px; + background: var(--surface); + box-shadow: var(--shadow); +} + +.metric-tile { + display: grid; + gap: 8px; + padding: 14px; +} + +.metric-tile > span { + color: var(--muted); + font-size: 0.75rem; + font-weight: 700; + text-transform: uppercase; +} + +.metric-tile strong { + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 1.65rem; +} + +.metric-tile div { + display: flex; + flex-wrap: wrap; + gap: 7px; + align-items: center; +} + +.overview-grid { + display: grid; + grid-template-columns: minmax(0, 1.4fr) minmax(290px, 0.6fr); + gap: 14px; +} + +.panel { + min-width: 0; + padding: 14px; +} + +.panel-wide { + grid-column: span 1; +} + +.panel-side-bottom { + grid-column: 2; +} + +.panel-heading { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + padding-bottom: 10px; + border-bottom: 1px solid var(--line); +} + +.panel-heading div, +.tile-heading, +.record-title, +.json-panel-header { + display: flex; + gap: 8px; + align-items: center; + min-width: 0; +} + +.panel-heading h2 { + margin: 0; + font-size: 0.98rem; +} + +.panel-heading > span { + color: var(--muted); + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.78rem; +} + +.record-list, +.compact-list, +.alert-list { + display: grid; +} + +.status-strip { + display: flex; + flex-wrap: wrap; + gap: 8px; + padding: 10px 0 2px; +} + +.status-strip span { + display: inline-flex; + gap: 6px; + align-items: center; + padding: 3px 6px 3px 3px; + border: 1px solid var(--line); + border-radius: 999px; + background: #f8f9f4; +} + +.status-strip strong { + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.74rem; +} + +.record-row { + display: grid; + grid-template-columns: minmax(0, 1fr) 270px; + gap: 16px; + padding: 14px 0; + border-bottom: 1px solid var(--line); +} + +.record-row:last-child { + border-bottom: 0; +} + +.record-row p, +.alert-row p { + margin: 8px 0; + color: #3f483f; + line-height: 1.45; +} + +.record-facts, +.definition-grid, +.lane-stats, +.alert-facts { + display: grid; + gap: 10px; + margin: 0; +} + +.record-facts { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.record-facts div, +.definition-grid div, +.lane-stats div, +.alert-facts div { + min-width: 0; +} + +dt { + color: var(--subtle); + font-size: 0.68rem; + font-weight: 700; + text-transform: uppercase; +} + +dd { + margin: 3px 0 0; + overflow-wrap: anywhere; +} + +.compact-list article { + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 9px; + align-items: start; + padding: 12px 0; + border-bottom: 1px solid var(--line); +} + +.compact-list article:last-child { + border-bottom: 0; +} + +.compact-list strong, +.compact-list small { + display: block; + overflow-wrap: anywhere; +} + +.contract-event-list { + display: grid; +} + +.contract-event-list article { + display: grid; + gap: 9px; + padding: 12px 0; + border-bottom: 1px solid var(--line); +} + +.contract-event-list article:last-child { + border-bottom: 0; +} + +.contract-event-list article > div { + display: flex; + gap: 8px; + align-items: center; + min-width: 0; +} + +.contract-event-list strong { + overflow-wrap: anywhere; + font-size: 0.84rem; +} + +.contract-event-list dl { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 8px; + margin: 0; +} + +.bundle-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 10px; + padding-top: 14px; +} + +.bundle-grid article { + display: grid; + gap: 8px; + min-width: 0; + padding: 12px; + border: 1px solid var(--line); + border-radius: 7px; + background: #f7f8f4; +} + +.bundle-grid strong, +.bundle-grid small { + display: block; + overflow-wrap: anywhere; +} + +.block-strip { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + padding-top: 14px; +} + +.block-strip article { + display: grid; + gap: 7px; + padding: 12px; + border: 1px solid var(--line); + border-radius: 7px; + background: #f7f8f4; +} + +.workbench-command-center { + display: grid; + grid-template-columns: minmax(0, 1.08fr) minmax(360px, 0.92fr); + gap: 14px; +} + +.workbench-boundary-strip { + display: grid; + grid-template-columns: 1.05fr 1.15fr 1.2fr; + gap: 10px; +} + +.workbench-boundary-strip article { + display: grid; + gap: 6px; + min-width: 0; + padding: 12px; + border: 1px solid #cfd7cd; + border-radius: 8px; + background: #f9faf6; +} + +.workbench-boundary-strip strong { + font-size: 0.82rem; +} + +.workbench-boundary-strip span { + color: #4c554c; + font-size: 0.84rem; + line-height: 1.42; +} + +.pilot-status-panel article { + display: grid; + gap: 14px; + min-width: 0; + padding: 14px; + border: 1px solid #b8c7c0; + border-radius: 8px; + background: #f4f8f6; +} + +.pilot-status-body { + display: grid; + grid-template-columns: minmax(0, 0.92fr) minmax(320px, 1.08fr); + gap: 14px; + align-items: start; +} + +.pilot-status-body h3 { + margin: 4px 0 8px; + font-size: 1.35rem; + text-transform: capitalize; +} + +.pilot-status-body p { + margin: 0; + color: #3f483f; + line-height: 1.48; +} + +.product-surface-grid { + display: grid; + grid-template-columns: 1.2fr 1fr 1.2fr; + gap: 10px; +} + +.product-surface { + display: grid; + grid-template-columns: 34px minmax(0, 1fr) auto auto; + gap: 10px; + align-items: start; + min-width: 0; + min-height: 118px; + padding: 12px; + text-align: left; + transition: background 140ms ease, border-color 140ms ease, transform 140ms ease; +} + +.product-surface:hover { + border-color: #9fb4a8; + background: #eaf1eb; +} + +.product-surface-icon { + display: grid; + place-items: center; + width: 32px; + height: 32px; + color: #235f52; + border: 1px solid #bfd1c7; + border-radius: 7px; + background: #edf5ef; +} + +.product-surface strong, +.product-surface small, +.product-surface code { + display: block; + overflow-wrap: anywhere; +} + +.product-surface small { + margin-top: 4px; + line-height: 1.36; +} + +.product-surface b { + color: var(--ink); + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 1.1rem; + line-height: 1.1; +} + +.workbench-node-body { + display: grid; + gap: 16px; + padding-top: 14px; +} + +.workbench-node-body h3 { + margin: 0 0 7px; + font-size: 1.22rem; +} + +.workbench-node-body p, +.workbench-section-detail, +.boundary-copy p { + margin: 0; + color: #465047; + line-height: 1.48; +} + +.workbench-fact-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + margin: 0; +} + +.workbench-fact-grid div { + min-width: 0; + padding: 10px; + border: 1px solid var(--line); + border-radius: 7px; + background: #f7f8f4; +} + +.setup-step-list { + display: grid; + padding-top: 6px; +} + +.setup-step-list article { + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 9px; + align-items: start; + padding: 11px 0; + border-bottom: 1px solid var(--line); +} + +.setup-step-list .status-badge { + align-self: start; +} + +.setup-step-list article:last-child { + border-bottom: 0; +} + +.setup-step-list strong, +.setup-step-list code, +.setup-step-list small { + display: block; + overflow-wrap: anywhere; +} + +code { + width: fit-content; + max-width: 100%; + margin: 5px 0; + padding: 3px 6px; + color: #25332d; + border: 1px solid var(--line); + border-radius: 6px; + background: #eef1eb; + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.78rem; +} + +.workbench-warning { + display: grid; + grid-template-columns: auto minmax(0, 1fr); + gap: 9px; + align-items: start; + padding: 11px 12px; + color: #6b4a16; + border: 1px solid #d9c393; + border-radius: 8px; + background: #fbf6e8; +} + +.workbench-warning strong, +.workbench-warning span { + display: block; + overflow-wrap: anywhere; +} + +.workbench-api-panel { + display: grid; + gap: 12px; +} + +.endpoint-strip { + display: flex; + flex-wrap: wrap; + gap: 7px; +} + +.endpoint-strip span { + padding: 4px 7px; + color: #34443c; + border: 1px solid var(--line); + border-radius: 999px; + background: #f7f8f4; + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.72rem; +} + +.local-action-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; +} + +.local-action-grid article { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 10px; + align-items: center; + min-width: 0; + padding: 11px; + border: 1px solid var(--line); + border-radius: 7px; + background: #f7f8f4; +} + +.local-action-grid strong, +.local-action-grid small { + display: block; + overflow-wrap: anywhere; +} + +.action-result, +.boot-hint { + margin: 0; + color: var(--muted); + line-height: 1.45; +} + +.workbench-layout { + display: grid; + grid-template-columns: 222px minmax(0, 1fr); + gap: 14px; + align-items: start; +} + +.workbench-switcher { + position: sticky; + top: 88px; + display: grid; + gap: 7px; + max-height: calc(100dvh - 112px); + overflow: auto; +} + +.workbench-switch { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 10px; + align-items: center; + min-height: 38px; + padding: 8px 10px; + text-align: left; + transition: background 140ms ease, border-color 140ms ease, transform 140ms ease; +} + +.workbench-switch.active, +.workbench-switch:hover { + border-color: #9fb4a8; + background: #eaf1eb; +} + +.workbench-switch span { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.workbench-switch strong { + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.78rem; +} + +.workbench-record-panel { + display: grid; + gap: 14px; +} + +.workbench-record-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; +} + +.workbench-record { + display: grid; + gap: 11px; + min-width: 0; + padding: 13px; + border: 1px solid var(--line); + border-radius: 7px; + background: #f7f8f4; +} + +.workbench-record h3 { + min-width: 0; + margin: 0; + overflow-wrap: anywhere; + font-size: 0.96rem; +} + +.workbench-record p { + margin: 0; + color: #465047; + line-height: 1.44; +} + +.workbench-boundary-panel { + display: grid; + gap: 12px; +} + +.boundary-copy { + display: grid; + gap: 9px; +} + +.table-panel { + min-width: 0; + overflow: hidden; +} + +.table-scroll { + overflow-x: auto; +} + +.table-scroll table { + min-width: 1120px; +} + +.cell-stack { + display: grid; + gap: 4px; + min-width: 0; +} + +.hash-value { + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.82rem; + overflow-wrap: anywhere; +} + +.provenance-line { + display: flex; + flex-wrap: wrap; + gap: 5px; +} + +.rootfield-grid, +.hardware-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 14px; +} + +.rootfield-tile, +.node-tile, +.lane-tile { + display: grid; + gap: 14px; + padding: 14px; +} + +.definition-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +.lane-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 12px; +} + +.lane-stats { + grid-template-columns: repeat(4, minmax(0, 1fr)); +} + +.alert-list { + gap: 12px; +} + +.alert-row { + display: grid; + grid-template-columns: minmax(0, 1fr) 300px; + gap: 16px; + padding: 14px; + border-left-width: 4px; +} + +.severity-critical { + border-left-color: var(--danger); +} + +.severity-warning { + border-left-color: var(--warning); +} + +.severity-info { + border-left-color: var(--info); +} + +.alert-action { + padding: 12px; + border-left: 1px solid var(--line); +} + +.alert-action span { + color: var(--subtle); + font-size: 0.7rem; + font-weight: 700; + text-transform: uppercase; +} + +.alert-action p { + margin-bottom: 0; +} + +.json-panel { + overflow: hidden; +} + +.json-panel-header { + justify-content: space-between; + padding: 12px 14px; + border-bottom: 1px solid var(--line); +} + +.json-panel pre { + max-height: 68dvh; + margin: 0; + padding: 16px; + overflow: auto; + background: #1f241f; + color: #eef4ec; + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.78rem; + line-height: 1.5; +} + +.status-badge { + display: inline-flex; + gap: 6px; + align-items: center; + width: fit-content; + max-width: 100%; + min-height: 24px; + padding: 4px 8px; + border: 1px solid var(--status-border); + border-radius: 999px; + background: var(--status-bg); + color: var(--status-fg); + font-size: 0.72rem; + font-weight: 800; + text-transform: uppercase; + white-space: nowrap; +} + +.status-dot { + width: 7px; + height: 7px; + border-radius: 999px; + background: currentColor; +} + +.status-observed { + --status-bg: #e7f0f3; + --status-border: #b9d0d8; + --status-fg: #326b89; +} + +.status-pending { + --status-bg: #f5eddb; + --status-border: #d9c393; + --status-fg: #8a5e14; +} + +.status-finalized { + --status-bg: #e9eee8; + --status-border: #bdcabc; + --status-fg: #3e6541; +} + +.status-verified { + --status-bg: #e2f0e8; + --status-border: #a8ceb7; + --status-fg: #1f6a45; +} + +.status-unresolved { + --status-bg: #f3e7dc; + --status-border: #d4b495; + --status-fg: #8c5527; +} + +.status-failed { + --status-bg: #f5e2e2; + --status-border: #d4a0a0; + --status-fg: #963b3b; +} + +.status-unsupported { + --status-bg: #ece7f1; + --status-border: #c1b6d0; + --status-fg: #665283; +} + +.status-reorged { + --status-bg: #eee6dd; + --status-border: #c6b19e; + --status-fg: #714f35; +} + +.status-offline { + --status-bg: #e7e8e3; + --status-border: #b9beb5; + --status-fg: #555d55; +} + +.status-stale { + --status-bg: #f0ecdc; + --status-border: #cfc38c; + --status-fg: #766a23; +} + +.empty-state { + display: flex; + gap: 12px; + align-items: flex-start; + padding: 22px; + color: var(--muted); + border: 1px dashed var(--line-strong); + border-radius: 8px; + background: #f8f9f4; +} + +.empty-state h3 { + margin: 0 0 5px; + color: var(--ink); + font-size: 1rem; +} + +.empty-state p { + margin: 0; + line-height: 1.45; +} + +.boot-screen { + display: grid; + place-items: center; + min-height: 100dvh; + padding: 24px; + background: #f4f5f1; +} + +.boot-panel, +.error-panel { + width: min(620px, 100%); + border: 1px solid var(--line); + border-radius: 8px; + background: var(--surface); + box-shadow: var(--shadow); +} + +.boot-panel { + display: grid; + gap: 14px; + padding: 24px; +} + +.skeleton-line { + height: 14px; + border-radius: 999px; + background: linear-gradient(90deg, #e1e6de 0%, #f5f6f0 45%, #e1e6de 100%); + background-size: 220% 100%; + animation: shimmer 1.4s ease-in-out infinite; +} + +.skeleton-title { + width: 70%; + height: 24px; +} + +.skeleton-short { + width: 46%; +} + +.boot-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 10px; + margin-top: 8px; +} + +.boot-grid div { + height: 92px; + border-radius: 8px; + background: #edf0e9; +} + +.error-panel { + display: grid; + grid-template-columns: 42px 1fr; + gap: 14px; + padding: 22px; + color: #873a3a; +} + +.error-panel h1 { + margin: 0 0 8px; + color: var(--ink); + font-size: 1.25rem; +} + +.error-panel p { + margin: 0 0 14px; + color: #6f4c4c; +} + +.button { + display: inline-flex; + gap: 8px; + align-items: center; + min-height: 36px; + padding: 0 12px; +} + +.button-primary { + border-color: #1f6a45; + background: #2f7d6b; + color: #f9fcf7; +} + +.wallet-view { + display: grid; + gap: 18px; +} + +.wallet-heading { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 16px; +} + +.wallet-heading h1, +.wallet-heading p, +.wallet-panel-title h2 { + margin: 0; +} + +.wallet-heading p { + color: var(--muted); +} + +.wallet-grid { + display: grid; + grid-template-columns: minmax(0, 1.45fr) minmax(320px, 0.75fr); + gap: 18px; + align-items: start; +} + +.wallet-primary-panel, +.wallet-create-panel { + display: grid; + gap: 18px; + padding: 18px; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--surface); + box-shadow: var(--shadow); +} + +.wallet-account-topline { + display: grid; + grid-template-columns: 52px minmax(0, 1fr); + gap: 14px; + align-items: center; +} + +.wallet-account-icon { + display: grid; + place-items: center; + width: 52px; + height: 52px; + border: 1px solid #a7b8b1; + border-radius: 8px; + background: #e3eee8; + color: var(--accent-strong); +} + +.wallet-account-topline span, +.wallet-form-field span, +.wallet-toggle-row span, +.wallet-fact-grid dt { + color: var(--muted); + font-size: 0.75rem; + font-weight: 700; + text-transform: uppercase; +} + +.wallet-account-topline strong { + display: block; + margin-top: 4px; + overflow-wrap: anywhere; + font-size: clamp(1.25rem, 2vw, 1.9rem); + letter-spacing: 0; +} + +.wallet-fact-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + margin: 0; +} + +.wallet-fact-grid div { + min-width: 0; + padding: 12px; + border: 1px solid var(--line); + border-radius: 7px; + background: var(--surface-2); +} + +.wallet-fact-grid dd { + margin: 6px 0 0; + overflow-wrap: anywhere; + color: var(--ink); + font-size: 0.86rem; +} + +.wallet-action-row { + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +.wallet-action-row a { + text-decoration: none; +} + +.wallet-panel-title { + display: flex; + gap: 10px; + align-items: center; +} + +.wallet-form-field { + display: grid; + gap: 8px; +} + +.wallet-form-field input { + min-height: 42px; + padding: 0 12px; + border: 1px solid var(--line-strong); + border-radius: 7px; + background: #ffffff; +} + +.wallet-toggle-row { + display: flex; + gap: 10px; + align-items: center; +} + +.wallet-create-button { + justify-content: center; +} + +.wallet-message { + display: flex; + gap: 9px; + align-items: center; + margin: 0; + padding: 12px 14px; + border: 1px solid #dfc184; + border-radius: 8px; + background: #fff7df; + color: #6e4a13; +} + +@keyframes shimmer { + 0% { + background-position: 100% 0; + } + 100% { + background-position: -100% 0; + } +} + +@media (max-width: 1180px) { + .metric-grid, + .block-strip { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .overview-grid, + .rootfield-grid, + .hardware-grid, + .lane-grid, + .canary-operator-strip, + .workbench-boundary-strip, + .product-surface-grid, + .pilot-status-body, + .local-action-grid, + .workbench-command-center, + .workbench-record-grid { + grid-template-columns: 1fr; + } + + .wallet-grid { + grid-template-columns: 1fr; + } + + .flowmemory-hero, + .canary-hero, + .flowmemory-spine, + .contract-event-list dl, + .bundle-grid { + grid-template-columns: 1fr; + } + + .flowmemory-hero-side, + .panel-side-bottom { + grid-column: auto; + } + + .flowmemory-hero-side { + border-left: 0; + border-top: 1px solid var(--line); + } + + .workbench-layout { + grid-template-columns: 1fr; + } + + .workbench-switcher { + position: static; + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 860px) { + .app-shell { + grid-template-columns: 1fr; + } + + .sidebar { + position: static; + height: auto; + } + + .nav-list { + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .topbar, + .section-header, + .fixture-banner, + .record-row, + .alert-row { + display: grid; + grid-template-columns: 1fr; + } + + .content { + padding: 18px 14px 28px; + } + + .section-action, + .filter-row { + min-width: 0; + grid-template-columns: 1fr; + } + + .fixture-banner { + margin: 14px 14px 0; + } + + .alert-action { + border-left: 0; + border-top: 1px solid var(--line); + } + + .workbench-fact-grid { + grid-template-columns: 1fr; + } +} + +@media (max-width: 560px) { + .nav-list, + .metric-grid, + .block-strip, + .definition-grid, + .lane-stats, + .record-facts, + .workbench-switcher { + grid-template-columns: 1fr; + } + + .topbar { + padding: 12px 14px; + } + + th, + td { + padding: 10px; + } +} + +/* Flowchain bridge reference layout */ +.flowchain-bridge-page { + min-height: 100dvh; + overflow-x: hidden; + overflow-y: auto; + background: + radial-gradient(circle at 38% 25%, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0) 34rem), + radial-gradient(circle at 8% 86%, rgba(255, 255, 255, 0.58), rgba(255, 255, 255, 0) 20rem), + linear-gradient(180deg, #f5ebdc 0%, #f0dfc7 100%); + color: #0d1b35; +} + +.flowchain-bridge-page::before { + opacity: 0.36; + background-image: + linear-gradient(rgba(77, 56, 34, 0.035) 1px, transparent 1px), + linear-gradient(90deg, rgba(77, 56, 34, 0.025) 1px, transparent 1px), + radial-gradient(circle at 28% 18%, rgba(107, 78, 42, 0.06), transparent 22rem); + background-size: 8px 8px, 10px 10px, auto; +} + +.flowchain-bridge-page::after { + inset: auto -14vw -7dvh -14vw; + height: 32dvh; + opacity: 0.52; + background: + radial-gradient(ellipse at 18% 50%, rgba(1, 88, 224, 0.66), rgba(16, 112, 255, 0.26) 34%, transparent 70%), + radial-gradient(ellipse at 44% 40%, rgba(0, 91, 255, 0.9), rgba(0, 105, 255, 0.32) 36%, transparent 74%), + radial-gradient(ellipse at 79% 54%, rgba(1, 95, 236, 0.68), rgba(38, 132, 255, 0.22) 40%, transparent 76%); + filter: blur(14px) saturate(1.22); + transform: rotate(-4deg) skewX(-14deg); +} + +.bridge-flow-ribbon { + inset: auto -12vw 5dvh -12vw; + height: 18dvh; + opacity: 0.58; + background: + linear-gradient(92deg, transparent 0%, rgba(0, 93, 255, 0.16) 10%, rgba(1, 83, 221, 0.74) 38%, rgba(44, 145, 255, 0.48) 72%, transparent 100%), + radial-gradient(ellipse at 36% 40%, rgba(1, 79, 220, 0.88), rgba(36, 130, 255, 0.26) 48%, transparent 72%); + filter: blur(9px); + transform: rotate(-8deg) skewX(-18deg); +} + +.flowchain-bridge-nav { + align-items: flex-start; + width: min(100%, 1700px); + padding: 24px 66px 0; +} + +.flowchain-brand { + gap: 14px; + color: #071831; +} + +.flowchain-brand strong { + color: #071831; + font-size: clamp(1.75rem, 2.3vw, 2.35rem); + letter-spacing: 0; +} + +.flowchain-brand-mark { + width: 48px; + height: 38px; +} + +.flowchain-brand-mark::before, +.flowchain-brand-mark::after, +.flowchain-brand-mark span { + width: 44px; + height: 15px; + border-color: #1b6fff; + border-width: 5px 0 0; +} + +.flowchain-brand-mark::before { + top: 2px; + transform: rotate(-10deg); +} + +.flowchain-brand-mark span { + top: 13px; + width: 36px; + border-color: #246de0; + transform: rotate(-12deg); +} + +.flowchain-brand-mark::after { + top: 24px; + width: 28px; + border-color: #73adff; + transform: rotate(-12deg); +} + +.bridge-system-rail { + display: grid; + grid-template-columns: minmax(190px, 1fr) minmax(185px, 1fr) minmax(210px, 1.08fr) 48px; + align-items: stretch; + width: min(730px, 100%); + min-height: 78px; + border: 1px solid rgba(70, 48, 25, 0.14); + border-radius: 10px; + background: rgba(249, 240, 227, 0.8); + box-shadow: 0 18px 45px rgba(48, 32, 14, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.58); + backdrop-filter: blur(18px); +} + +.bridge-system-item, +.bridge-system-info { + min-width: 0; + border: 0; + background: transparent; + color: #162138; +} + +.bridge-system-item { + display: grid; + grid-template-columns: 42px minmax(0, 1fr) 10px; + gap: 12px; + align-items: center; + padding: 15px 20px; + text-align: left; + border-right: 1px solid rgba(85, 64, 39, 0.12); +} + +.bridge-system-wallet { + cursor: pointer; +} + +.bridge-system-item strong, +.bridge-system-item small { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.bridge-system-item strong { + font-size: 0.88rem; + font-weight: 750; +} + +.bridge-system-item small { + margin-top: 4px; + color: rgba(22, 33, 56, 0.62); + font-size: 0.82rem; +} + +.bridge-system-icon { + display: grid; + place-items: center; + width: 40px; + height: 40px; + color: #171a21; + border-radius: 50%; + background: rgba(73, 54, 34, 0.08); +} + +.bridge-system-item i { + width: 7px; + height: 7px; + border-radius: 50%; +} + +.bridge-system-item i.is-green { + background: #1a9c68; +} + +.bridge-system-item i.is-amber { + background: #d79916; +} + +.bridge-system-item i.is-red { + background: #b74638; +} + +.bridge-system-info { + display: grid; + place-items: center; + text-decoration: none; +} + +.flowchain-bridge-main { + display: grid; + grid-template-columns: minmax(420px, 660px) minmax(650px, 820px); + gap: clamp(48px, 6vw, 96px); + align-items: start; + width: min(100%, 1700px); + min-height: calc(100dvh - 104px); + padding: 16px 66px 38px; +} + +.bridge-title-block { + justify-items: start; + align-self: start; + max-width: 620px; + padding-bottom: 80px; + text-align: left; +} + +.bridge-title-block > span { + display: inline-flex; + min-height: 28px; + align-items: center; + padding: 0 15px; + border-radius: 999px; + background: rgba(101, 76, 45, 0.08); + color: rgba(31, 25, 20, 0.72); + font-size: 0.75rem; + font-weight: 800; + letter-spacing: 0.22em; + text-transform: uppercase; +} + +.bridge-title-block h1 { + max-width: 610px; + margin: 28px 0 18px; + color: #081a36; + font-size: clamp(4.2rem, 6.25vw, 6.25rem); + font-weight: 500; + line-height: 0.88; + letter-spacing: 0; +} + +.bridge-title-block p { + width: min(520px, 100%); + max-width: 520px; + color: rgba(31, 27, 24, 0.82); + font-family: Geist, Satoshi, "Segoe UI", system-ui, sans-serif; + font-size: clamp(1.24rem, 1.55vw, 1.55rem); + line-height: 1.36; +} + +.bridge-benefit-list { + display: grid; + gap: 26px; + margin-top: 38px; +} + +.bridge-benefit-list article { + display: grid; + grid-template-columns: 50px minmax(0, 1fr); + gap: 16px; + align-items: center; +} + +.bridge-benefit-list article > span { + display: grid; + place-items: center; + width: 44px; + height: 44px; + color: #1d1c18; + border-radius: 50%; + background: rgba(57, 41, 23, 0.12); +} + +.bridge-benefit-list strong, +.bridge-benefit-list small { + display: block; +} + +.bridge-benefit-list strong { + color: #111923; + font-size: 0.95rem; +} + +.bridge-benefit-list small { + margin-top: 4px; + color: rgba(33, 28, 23, 0.72); + font-size: 0.85rem; + line-height: 1.35; +} + +.flowchain-bridge-layout { + display: block; + width: 100%; +} + +.bridge-console { + width: 100%; + min-width: 0; + gap: 12px; + padding: 26px 32px 22px; + border: 1px solid rgba(72, 50, 27, 0.16); + border-radius: 14px; + background: rgba(250, 241, 229, 0.82); + box-shadow: 0 28px 78px rgba(46, 31, 15, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.62); +} + +.bridge-route-row { + grid-template-columns: minmax(0, 1fr) 52px minmax(0, 1fr); + gap: 24px; + align-items: center; +} + +.bridge-route-row label > span, +.bridge-field > label, +.bridge-label-row label, +.bridge-estimate-grid span, +.bridge-calldata-facts dt { + color: rgba(42, 32, 22, 0.78); + font-size: 0.72rem; + font-weight: 800; + letter-spacing: 0.12em; +} + +.bridge-route-row label > small { + display: block; + margin: 5px 0 8px; + color: rgba(42, 32, 22, 0.7); + font-size: 0.9rem; +} + +.bridge-route-connector { + display: grid; + place-items: center; + padding: 30px 0 0; + color: #101820; +} + +.bridge-route-connector span, +.bridge-route-connector button { + display: none; +} + +.bridge-select-shell, +.bridge-token-field > div, +.bridge-field { + border: 1px solid rgba(83, 61, 37, 0.18); + border-radius: 8px; + background: rgba(255, 250, 243, 0.58); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5); +} + +.bridge-select-shell { + grid-template-columns: 36px minmax(0, 1fr) 18px; + min-height: 56px; + padding: 0 16px; +} + +.bridge-select-shell strong, +.bridge-token-field strong { + font-family: Geist, Satoshi, "Segoe UI", system-ui, sans-serif; + font-size: 1.02rem; + font-weight: 700; +} + +.bridge-chain-icon, +.bridge-token-orb { + width: 32px; + height: 32px; +} + +.bridge-token-amount-row { + display: grid; + grid-template-columns: minmax(220px, 0.78fr) minmax(300px, 1.42fr); + gap: 30px; +} + +.bridge-field { + padding: 0; + background: transparent; + border: 0; + box-shadow: none; +} + +.bridge-token-field > div { + grid-template-columns: 36px auto minmax(0, 1fr) 18px; + min-height: 56px; + padding: 0 14px; +} + +.bridge-token-field small { + color: rgba(43, 34, 26, 0.64); + font-size: 0.82rem; +} + +.bridge-amount-field { + grid-template-columns: minmax(0, 1fr) auto; + align-items: center; + min-height: 56px; + padding: 10px 14px; + border: 1px solid rgba(83, 61, 37, 0.18); + border-radius: 8px; + background: rgba(255, 250, 243, 0.58); +} + +.bridge-amount-field label { + grid-column: 1 / -1; + margin: 0; +} + +.bridge-amount-field input { + min-height: 30px; + font-family: Geist, Satoshi, "Segoe UI", system-ui, sans-serif; + font-size: 1.55rem; + font-weight: 600; +} + +.bridge-amount-field > span { + font-family: Geist, Satoshi, "Segoe UI", system-ui, sans-serif; + font-size: 0.95rem; + font-weight: 800; +} + +.bridge-amount-field small { + grid-column: 1; + color: rgba(43, 34, 26, 0.62); + font-size: 0.82rem; +} + +.bridge-amount-field .bridge-usd-note { + color: #0b62df; + font-weight: 750; +} + +.bridge-amount-field button { + grid-column: 2; + justify-self: end; + border: 0; + background: transparent; + color: #125bd8; + font-size: 0.82rem; + font-weight: 800; +} + +.bridge-recipient-field { + display: grid; + grid-template-columns: minmax(0, 1fr) 34px; + gap: 8px; + align-items: center; + min-height: 56px; + padding: 10px 14px; + border: 1px solid rgba(83, 61, 37, 0.18); + border-radius: 8px; + background: rgba(255, 250, 243, 0.58); +} + +.bridge-label-row { + display: flex; + grid-column: 1 / -1; + align-items: center; + justify-content: space-between; + gap: 10px; +} + +.bridge-label-row button { + display: inline-flex; + gap: 6px; + align-items: center; + width: auto; + height: auto; + padding: 0; + border: 0; + background: transparent; + color: #125bd8; + font-size: 0.84rem; + white-space: nowrap; +} + +.bridge-recipient-field input { + font-family: Geist, Satoshi, "Segoe UI", system-ui, sans-serif; + font-size: 1.02rem; +} + +.bridge-recipient-field button[title="Copy recipient"] { + color: rgba(42, 32, 22, 0.52); +} + +.bridge-recipient-field button[title="Copy recipient"]:disabled { + cursor: not-allowed; + opacity: 0.42; +} + +.bridge-recipient-options { + display: flex; + grid-column: 1 / -1; + flex-wrap: wrap; + gap: 7px; +} + +.bridge-recipient-options button { + display: inline-flex; + align-items: center; + width: auto; + min-height: 30px; + height: auto; + gap: 7px; + padding: 5px 8px; + border: 1px solid rgba(83, 61, 37, 0.16); + border-radius: 8px; + background: rgba(255, 255, 255, 0.62); + color: #2d231a; + font-size: 0.76rem; +} + +.bridge-recipient-options span { + max-width: 150px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.bridge-recipient-options small { + color: rgba(45, 35, 26, 0.6); + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; +} + +.bridge-estimate-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + overflow: hidden; + border: 1px solid rgba(83, 61, 37, 0.15); + border-radius: 8px; + background: rgba(235, 222, 205, 0.34); +} + +.bridge-estimate-grid > div { + display: grid; + gap: 4px; + min-height: 54px; + padding: 9px 16px; + border-right: 1px solid rgba(83, 61, 37, 0.12); + border-bottom: 1px solid rgba(83, 61, 37, 0.12); +} + +.bridge-estimate-grid > div:nth-child(2n) { + border-right: 0; +} + +.bridge-estimate-grid > div:nth-last-child(-n + 2) { + border-bottom: 0; +} + +.bridge-estimate-grid span { + display: inline-flex; + gap: 6px; + align-items: center; +} + +.bridge-estimate-grid strong { + color: #151a21; + font-size: 1rem; + font-weight: 650; +} + +.bridge-estimate-grid small { + color: rgba(33, 28, 23, 0.62); + font-size: 0.82rem; +} + +.bridge-estimate-primary strong { + color: #0b62df; + font-size: 1.12rem; +} + +.bridge-advanced { + border: 1px solid rgba(83, 61, 37, 0.16); + border-radius: 8px; + background: rgba(255, 250, 243, 0.5); +} + +.bridge-advanced summary { + display: flex; + justify-content: space-between; + width: 100%; + min-height: 42px; + padding: 0 16px; + font-size: 0.95rem; +} + +.bridge-advanced-body { + padding: 0 14px 12px; +} + +.bridge-advanced[open] summary { + margin: 0; +} + +.bridge-calldata-facts { + grid-template-columns: repeat(3, minmax(0, 1fr)); + padding: 0 14px 14px; +} + +.bridge-action-row { + grid-template-columns: 1fr; +} + +.bridge-primary-action { + display: flex; + gap: 10px; + align-items: center; + justify-content: center; + min-height: 54px; + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: 1.26rem; +} + +.bridge-terms-row { + display: grid; + grid-template-columns: 18px minmax(0, 1fr); + gap: 8px; + align-items: center; + color: rgba(35, 30, 25, 0.64); + font-size: 0.82rem; + line-height: 1.35; +} + +.bridge-safety-rail { + grid-template-columns: minmax(0, 1fr) auto auto; + gap: 24px; + align-items: center; + margin: 4px 0 0; + padding-top: 10px; + border-top: 1px solid rgba(83, 61, 37, 0.14); + border-radius: 0; + background: transparent; +} + +.bridge-safety-rail span, +.bridge-safety-rail a { + display: inline-flex; + gap: 8px; + align-items: center; + min-width: 0; + padding: 0; + color: rgba(35, 30, 25, 0.64); + border: 0; + font-size: 0.82rem; + text-decoration: none; +} + +.bridge-safety-rail a { + color: rgba(29, 24, 20, 0.82); +} + +.bridge-validation, +.bridge-status-message, +.bridge-tx-link { + padding: 10px 12px; +} + +@media (max-width: 1280px) { + .flowchain-bridge-nav { + display: grid; + grid-template-columns: 1fr; + gap: 18px; + padding: 32px 28px 0; + } + + .bridge-system-rail { + width: 100%; + } + + .flowchain-bridge-main { + grid-template-columns: 1fr; + gap: 28px; + padding: 28px; + } + + .bridge-title-block { + max-width: 760px; + padding-bottom: 0; + } +} + +@media (max-width: 760px) { + .flowchain-bridge-nav, + .flowchain-bridge-main { + width: 100%; + max-width: 100vw; + padding-left: 16px; + padding-right: 16px; + } + + .bridge-system-rail { + grid-template-columns: 1fr; + } + + .bridge-system-item { + border-right: 0; + border-bottom: 1px solid rgba(85, 64, 39, 0.12); + } + + .bridge-title-block h1 { + font-size: clamp(3.25rem, 16vw, 4.6rem); + } + + .bridge-title-block { + width: calc(100vw - 32px) !important; + max-width: calc(100vw - 32px) !important; + overflow: hidden; + } + + .bridge-title-block p { + width: calc(100vw - 32px) !important; + max-width: calc(100vw - 32px) !important; + font-size: 1.08rem; + overflow-wrap: break-word; + text-wrap: pretty; + } + + .bridge-benefit-list { + gap: 16px; + } + + .bridge-benefit-list article { + grid-template-columns: 50px minmax(0, 1fr); + } + + .bridge-benefit-list small, + .bridge-benefit-list strong { + max-width: calc(100vw - 98px); + overflow-wrap: break-word; + } + + .bridge-console { + padding: 18px; + } + + .bridge-route-row, + .bridge-token-amount-row, + .bridge-estimate-grid, + .bridge-calldata-facts, + .bridge-safety-rail { + grid-template-columns: 1fr; + } + + .bridge-route-connector { + padding: 0; + } + + .bridge-estimate-grid > div, + .bridge-estimate-grid > div:nth-child(2n), + .bridge-estimate-grid > div:nth-last-child(-n + 2) { + border-right: 0; + border-bottom: 1px solid rgba(83, 61, 37, 0.12); + } + + .bridge-estimate-grid > div:last-child { + border-bottom: 0; + } + + .bridge-safety-rail { + gap: 12px; + } +} + +.flowchain-mobile-wallet { + display: none; +} + +@media (max-width: 760px) { + .flowchain-bridge-page { + min-height: 100dvh; + overflow-x: hidden; + overflow-y: auto; + background: + radial-gradient(circle at 50% 12%, rgba(255, 255, 255, 0.76), rgba(255, 255, 255, 0) 18rem), + linear-gradient(180deg, #f7eddc 0%, #f1e2cb 56%, #efe0c8 100%); + } + + .flowchain-bridge-page::after, + .bridge-flow-ribbon { + display: none; + } + + .flowchain-bridge-nav, + .flowchain-bridge-main { + display: none; + } + + .flowchain-mobile-wallet { + position: relative; + z-index: 1; + display: block; + box-sizing: border-box; + width: 100vw; + max-width: min(390px, 100vw); + min-height: 100dvh; + margin: 0 auto; + padding: 12px 17px 96px; + color: #10203a; + font-family: Geist, Satoshi, "Segoe UI", system-ui, sans-serif; + } + + .flowchain-mobile-wallet *, + .flowchain-mobile-wallet *::before, + .flowchain-mobile-wallet *::after { + box-sizing: border-box; + } + + .flowchain-mobile-wallet::before { + position: fixed; + inset: 0; + z-index: -2; + pointer-events: none; + content: ""; + opacity: 0.34; + background-image: + linear-gradient(rgba(86, 63, 38, 0.045) 1px, transparent 1px), + linear-gradient(90deg, rgba(86, 63, 38, 0.026) 1px, transparent 1px), + radial-gradient(circle at 50% 8%, rgba(255, 255, 255, 0.76), transparent 15rem); + background-size: 8px 8px, 10px 10px, auto; + } + + .mobile-wallet-statusbar { + display: flex; + align-items: center; + justify-content: space-between; + height: 34px; + padding: 0 20px; + color: #131313; + font-size: 0.95rem; + font-weight: 800; + } + + .mobile-wallet-statusbar > div { + display: inline-flex; + gap: 8px; + align-items: center; + } + + .mobile-signal-bars { + width: 20px; + height: 13px; + background: + linear-gradient(#151515, #151515) 0 8px / 3px 5px no-repeat, + linear-gradient(#151515, #151515) 6px 5px / 3px 8px no-repeat, + linear-gradient(#151515, #151515) 12px 2px / 3px 11px no-repeat, + linear-gradient(#151515, #151515) 18px 0 / 3px 13px no-repeat; + border-radius: 2px; + } + + .mobile-wifi-mark { + width: 19px; + height: 13px; + border-top: 4px solid #151515; + border-radius: 50% 50% 0 0; + transform: scaleX(1.08); + } + + .mobile-battery-mark { + position: relative; + width: 25px; + height: 12px; + border: 2px solid #151515; + border-radius: 4px; + } + + .mobile-battery-mark::before { + position: absolute; + top: 2px; + right: -5px; + width: 3px; + height: 5px; + content: ""; + background: #151515; + border-radius: 0 2px 2px 0; + } + + .mobile-battery-mark::after { + position: absolute; + inset: 2px 4px 2px 2px; + content: ""; + background: #151515; + border-radius: 2px; + } + + .mobile-wallet-header { + position: relative; + display: grid; + grid-template-columns: 42px minmax(0, 1fr) 42px; + align-items: center; + margin-top: 8px; + } + + .mobile-wallet-brand { + display: inline-flex; + gap: 12px; + align-items: center; + justify-self: center; + color: #071831; + text-decoration: none; + } + + .mobile-wallet-brand .flowchain-brand-mark { + width: 46px; + height: 34px; + } + + .mobile-wallet-brand .flowchain-brand-mark::before, + .mobile-wallet-brand .flowchain-brand-mark::after, + .mobile-wallet-brand .flowchain-brand-mark span { + width: 42px; + height: 13px; + border-width: 5px 0 0; + } + + .mobile-wallet-brand strong { + color: #071831; + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: 2rem; + font-weight: 550; + line-height: 1; + } + + .mobile-bell-button { + position: relative; + display: grid; + place-items: center; + justify-self: end; + width: 40px; + height: 40px; + padding: 0; + border: 0; + color: #101820; + background: transparent; + } + + .mobile-bell-button i { + position: absolute; + top: 4px; + right: 4px; + width: 8px; + height: 8px; + background: #1f6df0; + border-radius: 50%; + } + + .mobile-wallet-pills { + display: grid; + grid-template-columns: minmax(0, 1fr) 1px minmax(0, 1.18fr); + gap: 13px; + align-items: center; + width: min(100%, 292px); + margin: 24px auto 0; + } + + .mobile-wallet-pills > button { + display: inline-flex; + gap: 9px; + align-items: center; + justify-content: center; + min-height: 44px; + padding: 0 14px; + color: #2a251f; + border: 1px solid rgba(72, 50, 27, 0.14); + border-radius: 999px; + background: rgba(255, 250, 243, 0.52); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.62); + backdrop-filter: blur(14px); + font-size: 0.95rem; + white-space: nowrap; + } + + .mobile-wallet-pills > i { + width: 1px; + height: 26px; + background: rgba(86, 63, 38, 0.18); + } + + .mobile-blue-dot { + width: 12px; + height: 12px; + background: #1e6df0; + border-radius: 50%; + } + + .mobile-wallet-orb { + width: 34px; + height: 34px; + margin-left: -6px; + background: + radial-gradient(circle at 34% 30%, rgba(255, 255, 255, 0.82), transparent 18%), + linear-gradient(135deg, #81c5ff 0%, #175fdf 70%, #0a318d 100%); + border-radius: 50%; + } + + .mobile-portfolio-hero { + position: relative; + z-index: 2; + display: grid; + justify-items: center; + margin-top: 34px; + text-align: center; + } + + .mobile-portfolio-hero p { + display: inline-flex; + gap: 8px; + align-items: center; + margin: 0 0 8px; + color: rgba(55, 48, 40, 0.64); + font-size: 0.79rem; + font-weight: 800; + letter-spacing: 0.16em; + text-transform: uppercase; + } + + .mobile-portfolio-hero strong { + display: block; + width: 100%; + color: #24201d; + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: clamp(2.9rem, 12.9vw, 3.8rem); + font-weight: 400; + line-height: 0.98; + text-align: center; + } + + .mobile-portfolio-hero > span { + display: inline-flex; + gap: 14px; + align-items: center; + margin-top: 8px; + color: #4b4339; + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.98rem; + } + + .mobile-portfolio-hero b, + .mobile-asset-row .is-up, + .mobile-activity-row:last-child small { + color: #20936b; + } + + .mobile-flow-smoke { + position: absolute; + top: 276px; + right: -78px; + left: -86px; + z-index: 1; + height: 182px; + pointer-events: none; + opacity: 0.48; + background: + radial-gradient(ellipse at 4% 52%, transparent 0 21%, rgba(15, 101, 240, 0.34) 36%, transparent 62%), + radial-gradient(ellipse at 38% 54%, rgba(28, 111, 239, 0.18), rgba(14, 98, 224, 0.42) 33%, transparent 67%), + radial-gradient(ellipse at 78% 48%, rgba(0, 82, 219, 0.56), rgba(61, 153, 255, 0.18) 38%, transparent 72%); + filter: blur(12px) saturate(1.16); + transform: rotate(-6deg) skewX(-13deg); + } + + .mobile-flow-smoke::before, + .mobile-flow-smoke::after { + position: absolute; + inset: 42px -20px auto; + height: 66px; + content: ""; + background: + linear-gradient(90deg, transparent, rgba(34, 121, 255, 0.38), rgba(0, 82, 219, 0.8), rgba(84, 170, 255, 0.22), transparent); + filter: blur(5px); + border-radius: 50%; + } + + .mobile-flow-smoke::after { + inset: 96px -34px auto; + height: 48px; + opacity: 0.64; + transform: rotate(8deg); + } + + .mobile-chart-card, + .mobile-action-card, + .mobile-assets-card, + .mobile-activity-card { + position: relative; + z-index: 2; + border: 1px solid rgba(82, 61, 37, 0.18); + background: rgba(249, 241, 229, 0.62); + box-shadow: 0 18px 48px rgba(53, 35, 18, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.62); + backdrop-filter: blur(14px); + } + + .mobile-chart-card { + display: grid; + grid-template-columns: minmax(0, 1fr) 42px; + gap: 8px; + margin-top: 68px; + padding: 24px 16px 14px; + border-radius: 24px; + } + + .mobile-chart-card svg { + width: 100%; + min-height: 118px; + overflow: visible; + } + + .mobile-chart-grid-line { + stroke: rgba(88, 66, 41, 0.1); + stroke-width: 1; + } + + .mobile-chart-line { + fill: none; + stroke: url("#mobileChartGlow"); + stroke-linecap: round; + stroke-width: 3; + } + + .mobile-chart-card circle { + fill: #1e62d9; + stroke: #f7eddc; + stroke-width: 2; + } + + .mobile-chart-scale { + display: grid; + align-content: space-between; + padding: 4px 0 28px; + color: rgba(69, 58, 45, 0.56); + font-size: 0.8rem; + font-weight: 700; + } + + .mobile-chart-tabs { + display: grid; + grid-column: 1 / -1; + grid-template-columns: repeat(6, minmax(0, 1fr)); + gap: 4px; + min-height: 36px; + margin-top: -3px; + } + + .mobile-chart-tabs button { + border: 0; + color: rgba(67, 59, 50, 0.58); + background: transparent; + font-size: 0.78rem; + font-weight: 750; + } + + .mobile-chart-tabs button[aria-current="true"] { + color: #22201d; + border: 1px solid rgba(91, 67, 40, 0.09); + border-radius: 999px; + background: rgba(234, 222, 206, 0.7); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5); + } + + .mobile-action-card { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + margin-top: 24px; + overflow: hidden; + border-radius: 22px; + } + + .mobile-action-card button { + display: grid; + justify-items: center; + min-width: 0; + min-height: 104px; + padding: 16px 5px 14px; + border: 0; + border-right: 1px solid rgba(82, 61, 37, 0.12); + color: #241f1a; + background: transparent; + } + + .mobile-action-card button:last-child { + border-right: 0; + } + + .mobile-action-card button > span { + display: grid; + place-items: center; + width: 47px; + height: 47px; + margin-bottom: 8px; + color: #145de0; + border: 1px solid rgba(30, 100, 215, 0.15); + border-radius: 50%; + background: rgba(219, 228, 242, 0.82); + } + + .mobile-action-card strong, + .mobile-action-card small { + display: block; + max-width: 100%; + overflow: hidden; + text-align: center; + text-overflow: ellipsis; + white-space: nowrap; + } + + .mobile-action-card strong { + color: #221d18; + font-family: ui-serif, Georgia, "Times New Roman", serif; + font-size: 1.16rem; + font-weight: 520; + } -.status-finalized { - --status-bg: #e9eee8; - --status-border: #bdcabc; - --status-fg: #3e6541; -} + .mobile-action-card small { + margin-top: 3px; + color: rgba(65, 55, 45, 0.55); + font-size: 0.72rem; + } -.status-verified { - --status-bg: #e2f0e8; - --status-border: #a8ceb7; - --status-fg: #1f6a45; -} + .mobile-assets-card, + .mobile-activity-card { + margin-top: 24px; + overflow: hidden; + border-radius: 23px; + } -.status-unresolved { - --status-bg: #f3e7dc; - --status-border: #d4b495; - --status-fg: #8c5527; -} + .mobile-section-header { + display: grid; + grid-template-columns: minmax(0, 1fr) 92px 74px; + gap: 8px; + padding: 14px 14px 10px; + color: rgba(62, 53, 44, 0.58); + border-bottom: 1px solid rgba(82, 61, 37, 0.13); + font-size: 0.72rem; + font-weight: 800; + letter-spacing: 0.16em; + text-transform: uppercase; + } -.status-failed { - --status-bg: #f5e2e2; - --status-border: #d4a0a0; - --status-fg: #963b3b; -} + .mobile-section-header span:nth-child(2), + .mobile-section-header span:nth-child(3) { + text-align: right; + } -.status-unsupported { - --status-bg: #ece7f1; - --status-border: #c1b6d0; - --status-fg: #665283; -} + .mobile-asset-row { + display: grid; + grid-template-columns: 48px minmax(0, 1fr) minmax(84px, 95px) minmax(62px, 76px) 16px; + gap: 8px; + align-items: center; + min-height: 74px; + padding: 10px 12px; + border-bottom: 1px solid rgba(82, 61, 37, 0.13); + } -.status-reorged { - --status-bg: #eee6dd; - --status-border: #c6b19e; - --status-fg: #714f35; -} + .mobile-asset-row:last-of-type { + border-bottom: 0; + } -.status-offline { - --status-bg: #e7e8e3; - --status-border: #b9beb5; - --status-fg: #555d55; -} + .mobile-asset-icon { + display: grid; + place-items: center; + width: 46px; + height: 46px; + color: #fff; + border-radius: 50%; + font-size: 1.05rem; + font-weight: 850; + } -.status-stale { - --status-bg: #f0ecdc; - --status-border: #cfc38c; - --status-fg: #766a23; -} + .mobile-asset-icon.flow { + background: linear-gradient(135deg, #5da7ff, #1052cc 72%); + } -.empty-state { - display: flex; - gap: 12px; - align-items: flex-start; - padding: 22px; - color: var(--muted); - border: 1px dashed var(--line-strong); - border-radius: 8px; - background: #f8f9f4; -} + .mobile-asset-icon.eth { + background: linear-gradient(135deg, #b9caff, #5d81e7 76%); + } -.empty-state h3 { - margin: 0 0 5px; - color: var(--ink); - font-size: 1rem; -} + .mobile-asset-icon.usdc { + background: linear-gradient(135deg, #62bdff, #2370cf 76%); + } -.empty-state p { - margin: 0; - line-height: 1.45; -} + .mobile-asset-icon.btc { + color: #f39920; + border: 3px solid #20253b; + background: #fff5e3; + } -.boot-screen { - display: grid; - place-items: center; - min-height: 100dvh; - padding: 24px; - background: #f4f5f1; -} + .mobile-asset-row strong, + .mobile-asset-row small, + .mobile-activity-row strong, + .mobile-activity-row small { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } -.boot-panel, -.error-panel { - width: min(620px, 100%); - border: 1px solid var(--line); - border-radius: 8px; - background: var(--surface); - box-shadow: var(--shadow); -} + .mobile-asset-row > div:nth-child(2) strong { + color: #202020; + font-size: 1.06rem; + letter-spacing: 0.12em; + } -.boot-panel { - display: grid; - gap: 14px; - padding: 24px; -} + .mobile-asset-row > div:nth-child(2) small { + margin-top: 2px; + color: rgba(65, 55, 45, 0.56); + font-size: 0.8rem; + } -.skeleton-line { - height: 14px; - border-radius: 999px; - background: linear-gradient(90deg, #e1e6de 0%, #f5f6f0 45%, #e1e6de 100%); - background-size: 220% 100%; - animation: shimmer 1.4s ease-in-out infinite; -} + .mobile-asset-row > div:nth-child(3) { + text-align: right; + } -.skeleton-title { - width: 70%; - height: 24px; -} + .mobile-asset-row > div:nth-child(3) strong { + color: #25221e; + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.86rem; + } -.skeleton-short { - width: 46%; -} + .mobile-asset-row > div:nth-child(3) small { + margin-top: 3px; + color: rgba(65, 55, 45, 0.55); + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.72rem; + } -.boot-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 10px; - margin-top: 8px; -} + .mobile-asset-row b { + text-align: right; + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.78rem; + font-weight: 750; + white-space: nowrap; + } -.boot-grid div { - height: 92px; - border-radius: 8px; - background: #edf0e9; -} + .mobile-asset-row .is-down { + color: #c74b46; + } -.error-panel { - display: grid; - grid-template-columns: 42px 1fr; - gap: 14px; - padding: 22px; - color: #873a3a; -} + .mobile-asset-row svg { + color: rgba(65, 55, 45, 0.42); + } -.error-panel h1 { - margin: 0 0 8px; - color: var(--ink); - font-size: 1.25rem; -} + .mobile-assets-link { + display: inline-flex; + gap: 8px; + align-items: center; + justify-content: center; + width: 100%; + min-height: 52px; + border: 0; + color: #155ad8; + background: transparent; + font-size: 1rem; + font-weight: 650; + } -.error-panel p { - margin: 0 0 14px; - color: #6f4c4c; -} + .mobile-section-title { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 46px; + padding: 0 15px; + border-bottom: 1px solid rgba(82, 61, 37, 0.13); + } -.button { - display: inline-flex; - gap: 8px; - align-items: center; - min-height: 36px; - padding: 0 12px; -} + .mobile-section-title span, + .mobile-section-title button { + color: rgba(62, 53, 44, 0.62); + font-size: 0.72rem; + font-weight: 850; + letter-spacing: 0.16em; + text-transform: uppercase; + } -.button-primary { - border-color: #1f6a45; - background: #2f7d6b; - color: #f9fcf7; -} + .mobile-section-title button { + border: 0; + color: #155ad8; + background: transparent; + } -@keyframes shimmer { - 0% { - background-position: 100% 0; + .mobile-activity-row { + display: grid; + grid-template-columns: 48px minmax(0, 1fr) minmax(102px, auto); + gap: 13px; + align-items: center; + min-height: 72px; + padding: 10px 14px; + border-bottom: 1px solid rgba(82, 61, 37, 0.13); } - 100% { - background-position: -100% 0; + + .mobile-activity-row:last-child { + border-bottom: 0; } -} -@media (max-width: 1180px) { - .metric-grid, - .block-strip { - grid-template-columns: repeat(2, minmax(0, 1fr)); + .mobile-activity-icon { + display: grid; + place-items: center; + width: 44px; + height: 44px; + border-radius: 50%; } - .overview-grid, - .rootfield-grid, - .hardware-grid, - .lane-grid, - .canary-operator-strip, - .workbench-boundary-strip, - .product-surface-grid, - .pilot-status-body, - .local-action-grid, - .workbench-command-center, - .workbench-record-grid { - grid-template-columns: 1fr; + .mobile-activity-icon.receive { + color: #198e68; + background: rgba(49, 149, 112, 0.13); } - .flowmemory-hero, - .canary-hero, - .flowmemory-spine, - .contract-event-list dl, - .bundle-grid { - grid-template-columns: 1fr; + .mobile-activity-icon.swap { + color: #135bdc; + background: rgba(31, 104, 224, 0.12); } - .flowmemory-hero-side, - .panel-side-bottom { - grid-column: auto; + .mobile-activity-row > div:nth-child(2) strong { + color: #221f1b; + font-size: 0.97rem; } - .flowmemory-hero-side { - border-left: 0; - border-top: 1px solid var(--line); + .mobile-activity-row > div:nth-child(2) small { + margin-top: 3px; + color: rgba(65, 55, 45, 0.55); + font-size: 0.78rem; } - .workbench-layout { - grid-template-columns: 1fr; + .mobile-activity-row > div:nth-child(3) { + text-align: right; } - .workbench-switcher { - position: static; - grid-template-columns: repeat(2, minmax(0, 1fr)); + .mobile-activity-row > div:nth-child(3) strong, + .mobile-activity-row > div:nth-child(3) small { + font-family: "JetBrains Mono", "SFMono-Regular", Consolas, monospace; + font-size: 0.8rem; } -} -@media (max-width: 860px) { - .app-shell { - grid-template-columns: 1fr; + .mobile-activity-row:first-of-type > div:nth-child(3) strong { + color: #20936b; } - .sidebar { - position: static; - height: auto; + .mobile-activity-row > div:nth-child(3) small { + margin-top: 3px; + color: rgba(65, 55, 45, 0.58); } - .nav-list { - grid-template-columns: repeat(3, minmax(0, 1fr)); + .mobile-bottom-nav { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 8; + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + width: 100vw; + max-width: min(390px, 100vw); + min-height: 75px; + margin: 0 auto; + padding: 9px 10px calc(12px + env(safe-area-inset-bottom)); + border-top: 1px solid rgba(83, 61, 37, 0.13); + background: rgba(247, 238, 225, 0.88); + box-shadow: 0 -16px 36px rgba(53, 35, 18, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.62); + backdrop-filter: blur(18px); } - .topbar, - .section-header, - .fixture-banner, - .record-row, - .alert-row { + .mobile-bottom-nav a { display: grid; - grid-template-columns: 1fr; + gap: 3px; + justify-items: center; + align-content: center; + color: rgba(54, 48, 42, 0.62); + font-size: 0.73rem; + font-weight: 650; + text-decoration: none; } - .content { - padding: 18px 14px 28px; + .mobile-bottom-nav a[aria-current="page"] { + color: #165dda; } +} - .section-action, - .filter-row { - min-width: 0; - grid-template-columns: 1fr; +@media (max-width: 370px) { + .flowchain-mobile-wallet { + padding-right: 12px; + padding-left: 12px; } - .fixture-banner { - margin: 14px 14px 0; + .mobile-wallet-brand strong { + font-size: 1.72rem; } - .alert-action { - border-left: 0; - border-top: 1px solid var(--line); + .mobile-wallet-pills { + gap: 8px; } - .workbench-fact-grid { - grid-template-columns: 1fr; + .mobile-wallet-pills > button { + padding: 0 10px; + font-size: 0.84rem; } -} -@media (max-width: 560px) { - .nav-list, - .metric-grid, - .block-strip, - .definition-grid, - .lane-stats, - .record-facts, - .workbench-switcher { - grid-template-columns: 1fr; + .mobile-section-header { + grid-template-columns: minmax(0, 1fr) 84px 66px; + font-size: 0.64rem; } - .topbar { - padding: 12px 14px; + .mobile-asset-row { + grid-template-columns: 42px minmax(0, 1fr) 82px 58px 12px; + gap: 6px; + padding-right: 8px; + padding-left: 8px; } - th, - td { - padding: 10px; + .mobile-asset-icon { + width: 40px; + height: 40px; + } + + .mobile-asset-row > div:nth-child(2) strong { + font-size: 0.93rem; + } + + .mobile-asset-row b, + .mobile-asset-row > div:nth-child(3) strong, + .mobile-asset-row > div:nth-child(3) small { + font-size: 0.68rem; } } diff --git a/apps/dashboard/src/test/dashboardData.test.ts b/apps/dashboard/src/test/dashboardData.test.ts index f4e16394..4defe200 100644 --- a/apps/dashboard/src/test/dashboardData.test.ts +++ b/apps/dashboard/src/test/dashboardData.test.ts @@ -250,6 +250,96 @@ describe("dashboard fixture", () => { lifecycle: [], }); } + if (url.endsWith("/bridge/live-readiness")) { + return Response.json({ + schema: "flowmemory.control_plane.bridge_live_readiness.v0", + baseChainId: 8453, + baseChainName: "Base", + failClosedStatus: "BLOCKED", + readyForOperatorLivePilot: false, + lockbox: { configured: false, envName: "FLOWCHAIN_BASE8453_LOCKBOX_ADDRESS", ownerVerified: false }, + node: { running: true, chainId: "flowmemory-local-devnet-v0" }, + confirmationDepth: { configured: false, envName: "FLOWCHAIN_BASE8453_CONFIRMATION_DEPTH" }, + missingEnvNames: ["FLOWCHAIN_BASE8453_RPC_URL", "FLOWCHAIN_BASE8453_LOCKBOX_ADDRESS"], + currentArtifacts: { base8453DepositCount: 0, localOrMockDepositCount: 1, mockPresentedAsLive: false }, + issues: [{ + reasonCode: "missing_env", + status: "blocked", + title: "Missing live pilot env", + summary: "Live readiness is blocked until all required env names are present.", + envNames: ["FLOWCHAIN_BASE8453_RPC_URL", "FLOWCHAIN_BASE8453_LOCKBOX_ADDRESS"], + }], + envValuesPrinted: false, + localOnly: true, + productionReady: false, + }); + } + if (url.endsWith("/pilot/lifecycle")) { + return Response.json({ + schema: "flowmemory.control_plane.bridge_lifecycle_record_list.v0", + count: 1, + lifecycleRecords: [{ + lifecycleRecordId: "lifecycle:1", + baseTxHash: `0x${"1".repeat(64)}`, + logIndex: 0, + depositId: "deposit:1", + replayKey: "replay:1", + replayStatus: "accepted", + creditId: "credit:1", + recipientWallet: "wallet:credited", + withdrawalIntentId: "withdrawal:1", + withdrawalStatus: "requested", + releaseEvidenceId: "release:1", + releaseStatus: "recorded", + asset: "local-test-unit", + amountSmallestUnits: "100", + status: "credited", + artifactClass: "local-or-mock", + liveArtifact: false, + evidenceFilePath: "fixtures/bridge/local-runtime-bridge-handoff.json", + equality: { + depositAmount: "100", + observedAmount: "100", + creditedAmount: "100", + walletDelta: "100", + transferableAmount: "100", + withdrawalAmount: "100", + releaseAmount: "100", + allEqual: true, + equalities: { walletDelta: true }, + }, + }], + }); + } + if (url.endsWith("/wallets/balances")) { + return Response.json({ + schema: "flowmemory.control_plane.wallet_balance_list.v0", + count: 1, + balances: [{ + balanceId: "balance:credited", + walletAddress: "wallet:credited", + asset: "local-test-unit", + amount: "100", + status: "credited", + creditId: "credit:1", + }], + }); + } + if (url.endsWith("/wallets/transfers")) { + return Response.json({ + schema: "flowmemory.control_plane.wallet_transfer_history.v0", + count: 1, + transfers: [{ + transferId: "transfer:1", + txId: "tx:transfer:1", + fromAccountId: "wallet:credited", + toAccountId: "wallet:recipient", + assetId: "local-test-unit", + amount: "100", + status: "applied", + }], + }); + } if (url === WORKBENCH_DEVNET_STATE_PATH) { return Response.json(devnetState); } @@ -270,15 +360,87 @@ describe("dashboard fixture", () => { expect(workbench.raw.controlPlaneHealth).toEqual({ status: "ok" }); expect(workbench.raw.controlPlaneState).toEqual({ state: devnetState }); expect(workbench.raw.controlPlanePilotStatus).toMatchObject({ state: "degraded" }); + expect(workbench.raw.controlPlaneBridgeReadiness).toMatchObject({ failClosedStatus: "BLOCKED" }); + expect(workbench.raw.controlPlanePilotLifecycle).toMatchObject({ count: 1 }); + expect(workbench.sections.realValuePilot.some((record) => record.kind === "Bridge live readiness")).toBe(true); + expect(workbench.sections.realValuePilot.some((record) => record.kind === "Bridge exact lifecycle")).toBe(true); + expect(workbench.sections.realValuePilot.some((record) => record.kind === "Wallet transfer history")).toBe(true); + const lifecycleRecord = workbench.sections.realValuePilot.find((record) => record.kind === "Bridge exact lifecycle"); + expect(lifecycleRecord?.facts.find((fact) => fact.label === "replay key")?.value).toBe("replay:1"); + expect(lifecycleRecord?.facts.find((fact) => fact.label === "withdrawal intent")?.value).toBe("withdrawal:1"); + expect(lifecycleRecord?.facts.find((fact) => fact.label === "release evidence")?.value).toBe("release:1"); + expect(lifecycleRecord?.facts.find((fact) => fact.label === "withdrawal amount")?.value).toBe("100"); + expect(lifecycleRecord?.facts.find((fact) => fact.label === "release amount")?.value).toBe("100"); expect(workbench.raw.devnetState).toEqual(devnetState); expect(workbench.raw.bridgeTestDeposit).toEqual(bridgeTestDeposit); expect(workbench.loadIssues).toEqual([]); expect(fetchMock).toHaveBeenCalledWith("http://127.0.0.1:8787/health", expect.any(Object)); expect(fetchMock).toHaveBeenCalledWith("http://127.0.0.1:8787/pilot/status", expect.any(Object)); + expect(fetchMock).toHaveBeenCalledWith("http://127.0.0.1:8787/bridge/live-readiness", expect.any(Object)); + expect(fetchMock).toHaveBeenCalledWith("http://127.0.0.1:8787/pilot/lifecycle", expect.any(Object)); expect(fetchMock).toHaveBeenCalledWith(WORKBENCH_DEVNET_STATE_PATH, expect.any(Object)); expect(fetchMock).toHaveBeenCalledWith(WORKBENCH_BRIDGE_TEST_DEPOSIT_PATH, expect.any(Object)); }); + it("renders bridge readiness live-blocked without env values", () => { + const configuredButHidden = "https://example.invalid/rpc-redacted"; + const workbench = buildWorkbenchSnapshot(data, { + controlPlane: { + url: "http://127.0.0.1:8787", + status: "available", + checkedAt: "2026-05-14T15:00:00.000Z", + endpoints: ["GET /health", "GET /state", "GET /bridge/live-readiness", "GET /pilot/lifecycle"], + health: { status: "ok" }, + state: devnetState, + pilotStatus: { + schema: "flowmemory.control_plane.real_value_pilot_status.v0", + state: "degraded", + stateReason: "Waiting for Base 8453 deposit.", + baseChainId: 8453, + cappedOwnerTesting: true, + broadPublicReadiness: false, + productionReady: false, + browserStoresSecrets: false, + nextOperatorStep: { command: "npm run control-plane:serve" }, + lifecycle: [], + }, + bridgeLiveReadiness: { + schema: "flowmemory.control_plane.bridge_live_readiness.v0", + baseChainId: 8453, + baseChainName: "Base", + failClosedStatus: "BLOCKED", + readyForOperatorLivePilot: false, + lockbox: { configured: false, envName: "FLOWCHAIN_BASE8453_LOCKBOX_ADDRESS", ownerVerified: false }, + node: { running: true, chainId: "flowmemory-local-devnet-v0" }, + confirmationDepth: { configured: false, envName: "FLOWCHAIN_BASE8453_CONFIRMATION_DEPTH" }, + missingEnvNames: ["FLOWCHAIN_BASE8453_RPC_URL", "FLOWCHAIN_BASE8453_LOCKBOX_ADDRESS"], + currentArtifacts: { base8453DepositCount: 0, localOrMockDepositCount: 1, mockPresentedAsLive: false }, + issues: [{ + reasonCode: "missing_env", + status: "blocked", + title: "Missing live pilot env", + summary: "Live readiness is blocked until all required env names are present.", + envNames: ["FLOWCHAIN_BASE8453_RPC_URL", "FLOWCHAIN_BASE8453_LOCKBOX_ADDRESS"], + }], + envValuesPrinted: false, + localOnly: true, + productionReady: false, + }, + }, + devnetState, + devnetDashboardState, + }); + const html = renderToStaticMarkup(createElement(WorkbenchView, { data, workbench })); + + expect(html).toContain("Bridge live readiness"); + expect(html).toContain("BLOCKED"); + expect(html).toContain("FLOWCHAIN_BASE8453_RPC_URL"); + expect(html).toContain("FLOWCHAIN_BASE8453_LOCKBOX_ADDRESS"); + expect(html).toContain("env values printed"); + expect(html).toContain("false"); + expect(html).not.toContain(configuredButHidden); + }); + it("renders the critical workbench view labels from fixture fallback", () => { const workbench = buildWorkbenchSnapshot(data, { devnetState, @@ -291,6 +453,7 @@ describe("dashboard fixture", () => { expect(html).toContain("Node and API status"); expect(html).toContain("Control-plane offline"); expect(html).toContain("Real-value pilot"); + expect(html).toContain("Bridge live readiness"); expect(html).toContain("capped owner testing"); expect(html).toContain("public readiness"); expect(html).toContain("Wallet Metadata"); diff --git a/apps/dashboard/src/views/BridgePilotView.tsx b/apps/dashboard/src/views/BridgePilotView.tsx new file mode 100644 index 00000000..9a734b92 --- /dev/null +++ b/apps/dashboard/src/views/BridgePilotView.tsx @@ -0,0 +1,987 @@ +import { useEffect, useMemo, useState } from "react"; +import { + AlertTriangle, + ArrowRightLeft, + Bell, + ChevronDown, + ChevronRight, + CircleDollarSign, + Copy, + Download, + ExternalLink, + Home, + Info, + Lock, + Send, + ShieldCheck, + UserRound, + Wallet, + Zap, +} from "lucide-react"; +import { StatusBadge } from "../components/StatusBadge"; +import type { DashboardStatus } from "../data/types"; +import type { WorkbenchSnapshot } from "../data/workbench"; + +type EthereumProvider = { + request(args: { method: string; params?: unknown[] | Record }): Promise; +}; + +declare global { + interface Window { + ethereum?: EthereumProvider; + } +} + +interface BridgePilotViewProps { + workbench: WorkbenchSnapshot; +} + +type BridgeReadiness = { + failClosedStatus?: string; + readyForOperatorLivePilot?: boolean; + missingEnvNames?: string[]; + issues?: Array<{ reasonCode?: string; status?: string; title?: string; summary?: string }>; + lockbox?: { configured?: boolean; ownerVerified?: boolean }; + currentArtifacts?: { base8453DepositCount?: number }; + envValuesPrinted?: boolean; + productionReady?: boolean; +}; + +const BASE_CHAIN_ID_DECIMAL = 8453; +const BASE_CHAIN_ID_HEX = "0x2105"; +const BASE_RPC_URL = "https://mainnet.base.org"; +const BASE_EXPLORER_URL = "https://basescan.org"; +const LOCKBOX_ADDRESS = "0xe731Bc6b117d92deDCA40a7ccAec11d16205026a"; +const LOCK_NATIVE_SELECTOR = "0x1326d1ec"; +const MAX_DEPOSIT_WEI = 100000000000000n; +const ETH_USD_RATE_URL = "https://api.coinbase.com/v2/exchange-rates?currency=ETH"; +const ZERO_BYTES32 = "0x0000000000000000000000000000000000000000000000000000000000000000"; +const BLOCKED_RECIPIENT_PLACEHOLDER = "0x5555555555555555555555555555555555555555555555555555555555555555"; +const BLOCKED_METADATA_PLACEHOLDER = "0x6666666666666666666666666666666666666666666666666666666666666666"; +const RECIPIENT_CANDIDATE_FIELDS = new Set(["accountId", "signerId", "address", "flowchainRecipient", "recipient"]); + +type BridgeRecipientOption = { + value: string; + label: string; + source: string; +}; + +function asReadiness(value: unknown): BridgeReadiness | null { + if (value === null || typeof value !== "object" || Array.isArray(value)) { + return null; + } + + return value as BridgeReadiness; +} + +function statusFromReadiness(readiness: BridgeReadiness | null): DashboardStatus { + if (!readiness) { + return "pending"; + } + + if (readiness.readyForOperatorLivePilot || readiness.failClosedStatus === "READY_FOR_OPERATOR_LIVE_PILOT") { + return "verified"; + } + + if (readiness.failClosedStatus === "FAILED") { + return "failed"; + } + + return "pending"; +} + +function isBytes32(value: string): boolean { + return /^0x[0-9a-fA-F]{64}$/.test(value); +} + +function isZeroBytes32(value: string): boolean { + return /^0x0{64}$/i.test(value); +} + +function normalizeInput(value: string): string { + return value.trim(); +} + +function isRecord(value: unknown): value is Record { + return value !== null && typeof value === "object" && !Array.isArray(value); +} + +function blockedPlaceholderLabel(value: string): string | null { + const normalized = value.toLowerCase(); + if (normalized === BLOCKED_RECIPIENT_PLACEHOLDER) { + return "old 0x555... placeholder"; + } + if (normalized === BLOCKED_METADATA_PLACEHOLDER) { + return "old 0x666... placeholder"; + } + return null; +} + +function addRecipientOption( + options: BridgeRecipientOption[], + seen: Set, + value: unknown, + label: string, + source: string, +): void { + if (typeof value !== "string") { + return; + } + const normalized = normalizeInput(value); + if (!isBytes32(normalized) || isZeroBytes32(normalized) || blockedPlaceholderLabel(normalized)) { + return; + } + const key = normalized.toLowerCase(); + if (seen.has(key)) { + return; + } + seen.add(key); + options.push({ value: normalized, label, source }); +} + +function collectRecipientOptionsFromRaw( + value: unknown, + options: BridgeRecipientOption[], + seen: Set, + source: string, + label: string, + depth = 0, +): void { + if (depth > 3) { + return; + } + if (Array.isArray(value)) { + value.forEach((item, index) => { + collectRecipientOptionsFromRaw(item, options, seen, source, `${label} ${index + 1}`, depth + 1); + }); + return; + } + if (!isRecord(value)) { + return; + } + + for (const [key, nestedValue] of Object.entries(value)) { + if (RECIPIENT_CANDIDATE_FIELDS.has(key)) { + addRecipientOption(options, seen, nestedValue, label, source); + } + if (Array.isArray(nestedValue) || isRecord(nestedValue)) { + collectRecipientOptionsFromRaw(nestedValue, options, seen, source, label, depth + 1); + } + } +} + +function collectRecipientOptions(workbench: WorkbenchSnapshot): BridgeRecipientOption[] { + const options: BridgeRecipientOption[] = []; + const seen = new Set(); + const records = [ + ...workbench.sections.walletMetadata, + ...workbench.sections.accounts, + ...workbench.sections.bridgeCredits, + ...workbench.sections.bridgeDeposits, + ]; + + for (const record of records) { + collectRecipientOptionsFromRaw(record.raw, options, seen, record.kind, record.title); + } + + return options.slice(0, 6); +} + +function validateRecipient(value: string): string | null { + if (value.length === 0) { + return "Enter a real Flowchain account id before bridging."; + } + if (!isBytes32(value)) { + return "Recipient must be a 32-byte Flowchain account id."; + } + if (isZeroBytes32(value)) { + return "Recipient cannot be the zero account id."; + } + const blockedLabel = blockedPlaceholderLabel(value); + if (blockedLabel) { + return `Recipient cannot be the ${blockedLabel}.`; + } + return null; +} + +function validateMetadataHash(value: string): string | null { + if (value.length === 0) { + return null; + } + if (!isBytes32(value)) { + return "Metadata hash must be blank or a bytes32 value."; + } + const blockedLabel = blockedPlaceholderLabel(value); + if (blockedLabel) { + return `Metadata hash cannot be the ${blockedLabel}.`; + } + return null; +} + +function shorten(value: string): string { + return `${value.slice(0, 6)}...${value.slice(-4)}`; +} + +function parseEthToWei(value: string): { wei: bigint | null; error: string | null } { + const trimmed = value.trim(); + if (!/^\d+(\.\d{0,18})?$/.test(trimmed)) { + return { wei: null, error: "Use a decimal ETH amount with up to 18 decimals." }; + } + + const [wholePart, fractionPart = ""] = trimmed.split("."); + const whole = BigInt(wholePart.length > 0 ? wholePart : "0"); + const fraction = BigInt(fractionPart.padEnd(18, "0")); + const wei = whole * 10n ** 18n + fraction; + + if (wei <= 0n) { + return { wei: null, error: "Amount must be greater than zero." }; + } + + if (wei > MAX_DEPOSIT_WEI) { + return { wei: null, error: "Amount exceeds the 0.0001 ETH pilot cap." }; + } + + return { wei, error: null }; +} + +function parseEthDecimal(value: string): number | null { + const trimmed = value.trim(); + if (!/^\d+(\.\d*)?$/.test(trimmed)) { + return null; + } + + const parsed = Number(trimmed); + return Number.isFinite(parsed) ? parsed : null; +} + +function formatUsd(value: number): string { + return new Intl.NumberFormat("en-US", { + style: "currency", + currency: "USD", + maximumFractionDigits: value < 1 ? 4 : 2, + }).format(value); +} + +function usdEstimateFromEth(value: string, rate: number | null): string | null { + const parsed = parseEthDecimal(value); + if (parsed === null || rate === null) { + return null; + } + + return `~ ${formatUsd(parsed * rate)} USD`; +} + +function toQuantityHex(value: bigint): string { + return `0x${value.toString(16)}`; +} + +function buildLockNativeData(flowchainRecipient: string, metadataHash: string): string { + return `${LOCK_NATIVE_SELECTOR}${flowchainRecipient.slice(2)}${metadataHash.slice(2)}`; +} + +async function switchToBase(provider: EthereumProvider): Promise { + try { + await provider.request({ + method: "wallet_switchEthereumChain", + params: [{ chainId: BASE_CHAIN_ID_HEX }], + }); + } catch (error) { + const code = typeof error === "object" && error !== null && "code" in error ? Number((error as { code?: unknown }).code) : 0; + if (code !== 4902) { + throw error; + } + + await provider.request({ + method: "wallet_addEthereumChain", + params: [ + { + chainId: BASE_CHAIN_ID_HEX, + chainName: "Base", + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + rpcUrls: [BASE_RPC_URL], + blockExplorerUrls: [BASE_EXPLORER_URL], + }, + ], + }); + } +} + +function errorMessage(error: unknown): string { + if (error instanceof Error && error.message.trim().length > 0) { + return error.message; + } + + return "Wallet request failed or was rejected."; +} + +export function BridgePilotView({ workbench }: BridgePilotViewProps) { + const readiness = asReadiness(workbench.controlPlane.bridgeLiveReadiness); + const [walletAddress, setWalletAddress] = useState(null); + const [chainId, setChainId] = useState(null); + const [amountEth, setAmountEth] = useState("0.00001"); + const [recipient, setRecipient] = useState(""); + const [metadataHash, setMetadataHash] = useState(""); + const [ethUsdRate, setEthUsdRate] = useState(null); + const [priceStatus, setPriceStatus] = useState<"loading" | "ready" | "unavailable">("loading"); + const [statusMessage, setStatusMessage] = useState(null); + const [txHash, setTxHash] = useState(null); + + const normalizedRecipient = normalizeInput(recipient); + const normalizedMetadataHash = normalizeInput(metadataHash); + const effectiveMetadataHash = normalizedMetadataHash.length === 0 ? ZERO_BYTES32 : normalizedMetadataHash; + const amount = useMemo(() => parseEthToWei(amountEth), [amountEth]); + const usdEstimate = useMemo(() => usdEstimateFromEth(amountEth, ethUsdRate), [amountEth, ethUsdRate]); + const pilotCapUsdEstimate = useMemo(() => usdEstimateFromEth("0.0001", ethUsdRate), [ethUsdRate]); + const recipientOptions = useMemo(() => collectRecipientOptions(workbench), [workbench]); + const hardIssues = useMemo( + () => + (readiness?.issues ?? []).filter( + (issue) => issue.status === "blocked" && issue.reasonCode !== "no_deposits_observed", + ), + [readiness], + ); + const missingEnvNames = readiness?.missingEnvNames ?? []; + const validationIssue = + amount.error ?? + validateRecipient(normalizedRecipient) ?? + validateMetadataHash(normalizedMetadataHash) ?? + (missingEnvNames.length > 0 ? `Control-plane is missing ${missingEnvNames.join(", ")}.` : null) ?? + (hardIssues.length > 0 ? hardIssues.map((issue) => issue.reasonCode ?? issue.title ?? "blocked").join(", ") : null); + const sendDisabled = !walletAddress || validationIssue !== null; + const readinessStatus = statusFromReadiness(readiness); + const chainLabel = chainId === BASE_CHAIN_ID_HEX ? `Base ${BASE_CHAIN_ID_DECIMAL}` : chainId ?? "Connect wallet"; + const routeLabel = readinessStatus === "verified" ? "Verified" : "Pilot route"; + const receivedAmount = amount.wei === null ? "0 ETH" : `${amountEth || "0"} ETH`; + const usdEstimateLabel = + usdEstimate ?? + (priceStatus === "loading" ? "Loading ETH/USD quote" : "USD quote unavailable"); + const mobileAccountLabel = walletAddress ? shorten(walletAddress) : "0x4F...A7F3"; + const mobileNetworkLabel = chainId && chainId !== BASE_CHAIN_ID_HEX ? chainLabel : "Mainnet"; + + useEffect(() => { + const controller = new AbortController(); + + async function loadEthUsdRate() { + try { + const response = await fetch(ETH_USD_RATE_URL, { signal: controller.signal }); + if (!response.ok) { + throw new Error(`ETH/USD quote failed with ${response.status}`); + } + + const payload = (await response.json()) as { data?: { rates?: { USD?: string } } }; + const parsed = Number(payload.data?.rates?.USD); + if (!Number.isFinite(parsed) || parsed <= 0) { + throw new Error("ETH/USD quote payload did not include a positive USD rate."); + } + + setEthUsdRate(parsed); + setPriceStatus("ready"); + } catch (error) { + if (error instanceof DOMException && error.name === "AbortError") { + return; + } + setPriceStatus("unavailable"); + } + } + + void loadEthUsdRate(); + + return () => controller.abort(); + }, []); + + const connectWallet = async () => { + const provider = window.ethereum; + if (!provider) { + setStatusMessage("No browser wallet detected."); + return; + } + + try { + const accounts = await provider.request({ method: "eth_requestAccounts" }); + const nextChainId = await provider.request({ method: "eth_chainId" }); + const accountList = Array.isArray(accounts) ? accounts : []; + setWalletAddress(typeof accountList[0] === "string" ? accountList[0] : null); + setChainId(typeof nextChainId === "string" ? nextChainId : null); + setStatusMessage(null); + } catch (error) { + setStatusMessage(errorMessage(error)); + } + }; + + const sendDeposit = async () => { + const provider = window.ethereum; + if (!provider || !walletAddress || amount.wei === null || validationIssue !== null) { + return; + } + + try { + setStatusMessage("Waiting for wallet confirmation."); + setTxHash(null); + await switchToBase(provider); + const transactionHash = await provider.request({ + method: "eth_sendTransaction", + params: [ + { + from: walletAddress, + to: LOCKBOX_ADDRESS, + value: toQuantityHex(amount.wei), + data: buildLockNativeData(normalizedRecipient, effectiveMetadataHash), + }, + ], + }); + if (typeof transactionHash === "string") { + setTxHash(transactionHash); + setStatusMessage("Transaction submitted on Base."); + } else { + setStatusMessage("Wallet returned without a transaction hash."); + } + const nextChainId = await provider.request({ method: "eth_chainId" }); + setChainId(typeof nextChainId === "string" ? nextChainId : null); + } catch (error) { + setStatusMessage(errorMessage(error)); + } + }; + + const handlePrimaryAction = walletAddress ? sendDeposit : connectWallet; + const primaryActionLabel = walletAddress ? "Bridge to Flowchain" : "Connect wallet"; + + return ( +
+