diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..8020ffa --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,17 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + env: { + node: true, + }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + ], + ignorePatterns: ['dist', 'node_modules', 'lib', 'dev-start.js'], + rules: { + 'quotes': ['error', 'single'], + 'indent': ['error', 2, { 'SwitchCase': 1 }], + }, +}; \ No newline at end of file diff --git a/.firebaserc b/.firebaserc new file mode 100644 index 0000000..9d33ffd --- /dev/null +++ b/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "genesis-super-pool" + } +} diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index a12225a..b3a114a 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -42,14 +42,7 @@ jobs: # Direct prompt for automated review (no @claude mention needed) direct_prompt: | - Please review this pull request and provide feedback on: - - Code quality and best practices - - Potential bugs or issues - - Performance considerations - - Security concerns - - Test coverage - - Be constructive and helpful in your feedback. + Please review this pull request and look specifically for bugs and security issues. Only provide feedback on potential bugs and vulnerabilities. Be concise and to the point. # Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR # use_sticky_comment: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2c5c77 --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Dependencies +node_modules + +# IDE +.vscode/ + +# Debug +firebase-debug.log +firestore-debug.log + +# Env Variables +.env +.env.* + +# Ngrok config (contains personal authtoken) +ngrok.yml + +# Claude Code files +CLAUDE.md +**/CLAUDE.md +.claude/ \ No newline at end of file diff --git a/README.md b/README.md index 869f013..977309b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ๐Ÿš€ **SuperPool: Decentralized Micro-Lending Pools on Polygon** +# ๐Ÿš€ **SuperPool: Decentralized Micro-Lending Pools** ![GitHub repo size](https://img.shields.io/github/repo-size/rafamiziara/superpool) ![GitHub last commit](https://img.shields.io/github/last-commit/rafamiziara/superpool) @@ -12,6 +12,17 @@ This project serves as a comprehensive portfolio piece demonstrating expertise a ### Key Features: +#### โœ… **Completed Features:** + +- **๐Ÿ” Wallet-Based Authentication:** Secure signature-based login system supporting multiple wallet providers (MetaMask, WalletConnect, Coinbase, etc.). +- **๐ŸŒ Multi-Chain Support:** Compatible with Mainnet, Polygon, Arbitrum, Base, BSC, and Polygon Amoy networks. +- **๐Ÿ“ฑ Cross-Platform Mobile App:** React Native/Expo application with comprehensive user onboarding flow. +- **๐Ÿ›ก๏ธ Robust Error Handling:** Advanced error categorization, user-friendly feedback, and graceful failure recovery. +- **๐Ÿ”” Toast Notification System:** Real-time user feedback for connection states, authentication progress, and error scenarios. +- **โš™๏ธ Global State Management:** Sophisticated wallet connection and logout state management with race condition prevention. + +#### ๐Ÿšง **Planned Features:** + - **Multi-Pool Architecture:** Supports the creation of multiple independent lending pools, each with its own members and potentially unique parameters. - **Permissioned Membership:** Pool administrators (initially controlled by a multi-sig Safe) approve members before they can contribute or borrow. - **Liquidity Contribution:** Pool members can contribute MATIC (or a custom ERC-20 token) to provide liquidity for loans. @@ -35,13 +46,15 @@ This project serves as a comprehensive portfolio piece demonstrating expertise a - **TypeScript:** Type-safe JavaScript. - **Wagmi:** React Hooks for Ethereum. - **Viem:** TypeScript interface for Ethereum. -- **WalletConnect:** For connecting user wallets (e.g., MetaMask Mobile, Trust Wallet). +- **Reown AppKit:** Multi-wallet connection with WalletConnect protocol support. +- **Multi-Chain Support:** Mainnet, Polygon, Arbitrum, Base, BSC, and Polygon Amoy. +- **Comprehensive Error Handling:** Robust error categorization and user feedback systems. **Backend / Cloud Infrastructure:** - **Firebase / Google Cloud Functions:** Serverless functions for off-chain logic (e.g., AI loan assessment, sending notifications, database interactions, bridging on-chain events). - **Firebase Firestore:** NoSQL database for off-chain data storage (e.g., user profiles, pool metadata, pending loan requests, AI assessment results). -- **Firebase Authentication:** User authentication (email/password, social logins). +- **Firebase Authentication:** Wallet-based signature authentication with custom token generation. **Monorepo Management:** @@ -54,9 +67,10 @@ The project is structured as a monorepo, allowing for seamless development and t ``` superpool-dapp/ +โ”œโ”€โ”€ apps/ +โ”‚ โ””โ”€โ”€ mobile/ # React Native / Expo application โ”œโ”€โ”€ packages/ โ”‚ โ”œโ”€โ”€ contracts/ # Solidity smart contracts (PoolFactory, LendingPool) -โ”‚ โ”œโ”€โ”€ mobile-app/ # React Native / Expo application โ”‚ โ””โ”€โ”€ backend/ # Firebase Cloud Functions & backend logic โ”œโ”€โ”€ .gitignore โ”œโ”€โ”€ pnpm-workspace.yaml @@ -67,8 +81,15 @@ superpool-dapp/ **Workflow:** 1. **Smart Contracts:** Deployed on Polygon, managing core lending logic, liquidity, and membership. The `PoolFactory` is controlled by a multi-sig Safe, which deploys upgradable `LendingPool` instances. -2. **Backend (Cloud Functions):** Acts as a bridge between the mobile app and smart contracts. It handles user authentication, stores off-chain data, processes loan assessment requests (AI agent), sends notifications, and interacts with smart contracts for specific admin-controlled actions (via multi-sig). -3. **Mobile App:** Provides the user interface for interacting with the platform, connecting wallets, initiating transactions, and viewing data fetched from the backend. +2. **Backend (Cloud Functions):** Acts as a bridge between the mobile app and smart contracts. It handles wallet-based authentication through signature verification, stores off-chain data, processes loan assessment requests (AI agent), sends notifications, and interacts with smart contracts for specific admin-controlled actions (via multi-sig). +3. **Mobile App:** Provides the user interface for interacting with the platform. Features a comprehensive wallet connection system supporting multiple providers (MetaMask, WalletConnect, Coinbase, etc.), signature-based authentication, multi-chain support, and robust error handling with user-friendly feedback. + +**Authentication Flow:** +1. User connects wallet via Reown AppKit (supports 100+ wallets) +2. App requests authentication message from backend Cloud Function +3. User signs message with their wallet (cryptographic proof of ownership) +4. Backend verifies signature and issues Firebase custom token +5. User is authenticated and can access protected features ## ๐Ÿš€ Getting Started @@ -81,6 +102,8 @@ Follow these steps to set up and run the SuperPool project locally. - Git - A Polygon (Amoy Testnet recommended) wallet with some MATIC for gas. - A Firebase project set up with Firestore, Authentication, and Cloud Functions enabled. +- A Reown Cloud account and project ID for wallet connections (sign up at [cloud.reown.com](https://cloud.reown.com)). +- **ngrok account and authtoken** (sign up at [ngrok.com](https://ngrok.com) for local development with mobile devices). ### 1. Clone the Repository @@ -117,15 +140,8 @@ POLYGONSCAN_API_KEY=[YOUR_POLYGONSCAN_API_KEY] # For contract verification - `packages/backend/.env` ``` -# For Firebase Admin SDK if needed, or other backend-specific secrets -# Typically, Firebase Admin SDK works via service account files, -# or you'll use Firebase Functions environment config directly. - -# For local functions emulator: -GOOGLE_APPLICATION_CREDENTIALS=/path/to/your/firebase-adminsdk.json - -# Or for other APIs your Cloud Functions might call -AI_API_KEY=[YOUR_AI_SERVICE_API_KEY] +# For appCheck.createToken +APP_ID_FIREBASE=[YOUR_FIREBASE_APP_ID] # Contract addresses deployed to Amoy POOL_FACTORY_ADDRESS=[DEPLOYED_POOL_FACTORY_ADDRESS_ON_AMOY] @@ -133,7 +149,7 @@ POOL_FACTORY_ADDRESS=[DEPLOYED_POOL_FACTORY_ADDRESS_ON_AMOY] _Note: For actual Firebase Functions deployment, you should use `firebase functions:config:set` for secrets, not `.env`._ -- `packages/mobile-app/.env` +- `apps/mobile/.env` ``` # Public Firebase config (safe to be here, but still use .env for consistency) @@ -145,8 +161,16 @@ EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=... EXPO_PUBLIC_FIREBASE_APP_ID=... EXPO_PUBLIC_FIREBASE_MEASUREMENT_ID=... +# Reown/WalletConnect Project ID (required for wallet connections) +EXPO_PUBLIC_REOWN_PROJECT_ID=[YOUR_REOWN_PROJECT_ID] + +# Ngrok URL for Firebase Emulators (for local development) +EXPO_PUBLIC_NGROK_URL_AUTH=... +EXPO_PUBLIC_NGROK_URL_FUNCTIONS=... +EXPO_PUBLIC_NGROK_URL_FIRESTORE=... + # Cloud Functions Base URL -EXPO_PUBLIC_CLOUD_FUNCTIONS_BASE_URL=https://[YOUR_REGION]-[YOUR_PROJECT_ID].cloudfunctions.net/api +EXPO_PUBLIC_CLOUD_FUNCTIONS_BASE_URL=https://[HOST]:[PORT]/[YOUR_PROJECT_ID]/[YOUR_REGION]/ # Contract addresses deployed to Amoy EXPO_PUBLIC_POOL_FACTORY_ADDRESS=[DEPLOYED_POOL_FACTORY_ADDRESS_ON_AMOY] @@ -161,12 +185,42 @@ cd packages/contracts pnpm deploy:amoy # This command should be defined in your package.json scripts ``` -- **Important:** Note the deployed `PoolFactory` address. You will need this for your `backend` and `mobile-app` `.env` files. +- **Important:** Note the deployed `PoolFactory` address. You will need this for your `backend` and `mobile` `.env` files. - **Multi-sig Setup:** After `PoolFactory` is deployed, set up your multi-sig Safe (e.g., Gnosis Safe on Polygon Amoy) and transfer ownership of the `PoolFactory` to your Safe. All subsequent calls to `createPool` from your backend should be initiated via the Safe. ### 5. Deploy Backend Cloud Functions +--- + +To run the backend functions locally, you need to provide the Firebase Admin SDK with credentials via a service account key. + +1. **Generate a Service Account Key:** + + - Navigate to your Firebase Console. + - Go to **Project settings > Service accounts**. + - Click the **Generate new private key** button and download the JSON file. + +2. **Add the Key to the Project:** + + - Rename the downloaded JSON file to `service-account-key.json`. + - Place this file in the **`packages/backend/`** directory. + +3. **Secure the Key:** + + - **Crucially**, add `service-account-key.json` to the `.gitignore` file in your `packages/backend` directory. This prevents sensitive credentials from being committed to the repository. + + ``` + # packages/backend/.gitignore + + # Firebase Service Account Key + service-account-key.json + ``` + +After completing these steps, the Firebase Functions emulator will be able to start and run your backend functions locally. + +--- + Navigate to the `backend` package and deploy your Firebase Functions: ```bash @@ -176,24 +230,121 @@ cd packages/backend firebase use [YOUR_FIREBASE_PROJECT_ID] # Set config variables (e.g., contract addresses, any private API keys) -firebase functions:config:set contracts.pool_factory_address="[DEPLOYED_POOL_FACTORY_ADDRESS_ON_AMOY]" ai.api_key="[YOUR_AI_SERVICE_API_KEY]" +firebase functions:config:set contracts.pool_factory_address="[DEPLOYED_POOL_FACTORY_ADDRESS_ON_AMOY]" # Deploy firebase deploy --only functions ``` -- **Important:** Note the base URL for your deployed Cloud Functions. Update `EXPO_PUBLIC_CLOUD_FUNCTIONS_BASE_URL` in `packages/mobile-app/.env`. +- **Important:** Note the base URL for your deployed Cloud Functions. Update `EXPO_PUBLIC_CLOUD_FUNCTIONS_BASE_URL` in `packages/mobile/.env`. + +--- + +### Development & Testing Tools + +To facilitate local testing of the authentication and signature verification flow, we use two utility scripts located in the `packages/backend/scripts` directory. + +#### 1. Generating a Key Pair + +The `generateKey` script creates a new public/private key pair used for signing messages during local development. + +- **Purpose**: Generates `privateKey.pem` and `publicKey.pem` files in the `scripts` directory. The private key is used by the `signMessage` script, and the public key is used by the backend to verify signatures. +- **Usage**: + ```bash + pnpm generateKey + ``` +- **Note**: These files are automatically added to `.gitignore` and should **never** be committed to the repository. + +#### 2. Signing a Message -### 6. Run the Mobile Application +The `signMessage` script signs a message using the generated private key and the `nonce` and `timestamp` from your backend. -Navigate to the `mobile-app` package and start the Expo development server: +- **Purpose**: Creates a cryptographic signature that you can use to test the `verifySignatureAndLogin` backend function. +- **Usage**: + ```bash + pnpm signMessage + ``` +- **Output**: The script will print the generated signature, which you can then use in your test requests (e.g., Postman). +#### 3. Testing Workflow + +Here is the complete workflow to test your authentication functions: + +1. Call your `generateAuthMessage` backend function to get a unique `nonce` and `timestamp`. +2. Run the `signMessage` script with the `nonce` and `timestamp` values from the previous step. +3. Use the `signature` from the script's output, along with the original `walletAddress`, to call the `verifySignatureAndLogin` backend function. + +--- + +### 6. Set Up Wallet Connection (Reown Cloud) + +Before running the mobile app, you need to set up wallet connection capabilities: + +1. **Create a Reown Cloud Account:** + - Visit [cloud.reown.com](https://cloud.reown.com) and create an account. + - Create a new project and note your **Project ID**. + +2. **Update Environment Variables:** + - Add your Reown Project ID to `apps/mobile/.env`: + ``` + EXPO_PUBLIC_REOWN_PROJECT_ID=your_project_id_here + ``` + +3. **Configure Supported Networks:** + - The app currently supports: Mainnet, Polygon, Arbitrum, Base, BSC, and Polygon Amoy. + - Networks are configured in `apps/mobile/src/app/_layout.tsx`. + +### 7. Set Up Ngrok for Local Development (Mobile Device Testing) + +For testing the mobile app on a physical device with local Firebase emulators, you'll need ngrok: + +1. **Configure Ngrok:** + ```bash + # Copy the template + cp ngrok.yml.template ngrok.yml + + # Edit ngrok.yml and add your authtoken + # Get your authtoken from: https://dashboard.ngrok.com/get-started/your-authtoken + ``` + +2. **Add your authtoken to `ngrok.yml`:** + ```yaml + authtoken: your_ngrok_authtoken_here + ``` + +### 8. Run the Development Environment + +Use the automated development script that handles all local setup: + +```bash +# Start everything with one command +pnpm dev +``` + +This command will: +- โœ… Start Firebase emulators (auth, functions, firestore) +- โœ… Launch ngrok tunnels for mobile device access +- โœ… Automatically update mobile app environment variables with ngrok URLs +- โœ… Start the Expo development server + +**Manual alternative (if needed):** ```bash -cd packages/mobile-app +# Start Firebase emulators +firebase emulators:start + +# In another terminal, start ngrok +ngrok start --all + +# Update mobile/.env with ngrok URLs, then start mobile app +cd apps/mobile pnpm start ``` -- This will open the Expo Dev Tools in your browser. You can then scan the QR code with your phone (using the Expo Go app) or run it on an Android/iOS simulator. +**Testing the App:** +- **Mobile Device:** Scan the QR code with Expo Go app on your phone +- **Simulator:** Use Android/iOS simulator from your development machine +- **Testing Wallet Connection:** Try connecting with MetaMask Mobile, Coinbase Wallet, or other WalletConnect-compatible wallets +- **Authentication Flow:** After connecting, you'll be prompted to sign an authentication message to access the dashboard ## ๐Ÿค Multi-Sig Administration @@ -201,6 +352,35 @@ This project utilizes a multi-signature wallet (Safe) to control critical protoc To interact with actions requiring multi-sig approval (e.g., initiating a `createPool` call via the backend), the transaction will be proposed on your Safe. The configured owners will then need to confirm the transaction via the Safe web or mobile app. +## โœ… Completed Features Details + +### ๐Ÿ” Wallet-Based Authentication System + +The SuperPool app features a production-ready wallet authentication system that demonstrates advanced Web3 UX patterns: + +- **Multi-Wallet Support:** Integrates with 100+ wallets through Reown AppKit (MetaMask, WalletConnect, Coinbase Wallet, Trust Wallet, etc.) +- **Cross-Platform Compatibility:** Works seamlessly on iOS, Android, and web platforms +- **Multi-Chain Support:** Supports Mainnet, Polygon, Arbitrum, Base, BSC, and Polygon Amoy networks +- **Signature-Based Authentication:** Cryptographically secure login without passwords using wallet signatures +- **Session Management:** Robust session handling with automatic cleanup and state persistence + +### ๐Ÿ›ก๏ธ Advanced Error Handling & User Experience + +- **Comprehensive Error Categorization:** Intelligent error classification (wallet, network, authentication, signature rejection) +- **User-Friendly Feedback:** Context-aware error messages that guide users toward resolution +- **Toast Notification System:** Real-time feedback for all user actions and system states +- **Race Condition Prevention:** Sophisticated state management prevents common Web3 UX issues +- **Graceful Failure Recovery:** Automatic retry logic and fallback mechanisms +- **Offline Handling:** Robust handling of network connectivity issues + +### ๐Ÿ”ง Technical Implementation Highlights + +- **Global State Management:** Centralized wallet connection and authentication state management +- **Connection Trigger Logic:** Precise detection of wallet connection vs. disconnection events +- **Multi-Layer Error Handling:** Defensive programming with error boundaries at multiple levels +- **TypeScript Integration:** Full type safety across wallet interactions and error handling +- **Modular Architecture:** Reusable hooks and components for wallet integration + ## ๐Ÿ›ก๏ธ Security Disclaimer **This project is a personal portfolio piece and proof-of-concept. It is NOT intended for production use without comprehensive security audits, bug bounties, and significant hardening.** diff --git a/SPRINT_1_IMPLEMENTATION.md b/SPRINT_1_IMPLEMENTATION.md new file mode 100644 index 0000000..825e4e8 --- /dev/null +++ b/SPRINT_1_IMPLEMENTATION.md @@ -0,0 +1,172 @@ +# ๐Ÿƒโ€โ™€๏ธ Sprint 1 Implementation Tracker +## Create a New Lending Pool Feature + +This document tracks the GitHub issues and implementation progress for Sprint 1's "Create a New Lending Pool" feature from the [SPRINT_PLAN.md](./SPRINT_PLAN.md). + +--- + +## ๐ŸŽฏ Sprint 1 Goal +Enable designated pool creators/admins to successfully deploy new lending pools on Polygon Amoy via the dApp, with verified contracts owned by multi-sig Safe. + +--- + +## โœ… User Onboarding & Wallet Connection (COMPLETED) + +### Infrastructure & Setup +- **[#1 โœ… CLOSED]** chore: PNPM Monorepo Initialization +- **[#2 โœ… CLOSED]** setup: Configure Firebase project and services +- **[#3 โœ… CLOSED]** setup: Configure environment variables across workspaces +- **[#18 โœ… CLOSED]** setup: Initialize the Expo mobile app +- **[#19 โœ… CLOSED]** chore: Configure Monorepo tsconfig and ESLint +- **[#20 โœ… CLOSED]** refactor: Backend Directory Refactoring + +### Backend Authentication System +- **[#4 โœ… CLOSED]** feat: Implement 'generateAuthMessage' Cloud Function +- **[#5 โœ… CLOSED]** feat: Implement 'verifySignatureAndLogin' Cloud Function +- **[#6 โœ… CLOSED]** feat: Implement Firestore user profile creation/update +- **[#7 โœ… CLOSED]** feat: Implement Custom App Check Provider +- **[#8 โœ… CLOSED]** test: Add unit tests for backend auth functions + +### Mobile App Wallet Integration +- **[#9 โœ… CLOSED]** feat: Install wallet connection libraries (wagmi/viem) +- **[#10 โœ… CLOSED]** feat: Implement 'Connect Wallet' UI component +- **[#11 โœ… CLOSED]** feat: Integrate wallet connection and state management logic +- **[#12 โœ… CLOSED]** feat: Integrate Firebase SDK and authentication logic +- **[#13 โœ… CLOSED]** feat: Implement basic routing based on auth status + +### Quality Assurance & Refinement +- **[#14 โœ… CLOSED]** feat: Add error handling and user feedback to the flow +- **[#15 โœ… CLOSED]** test: Conduct manual end-to-end testing of the onboarding flow +- **[#16 โœ… CLOSED]** refactor: Refine user feedback and error messages + +**Completed Features Summary:** +- โœ… Multi-wallet connection (MetaMask, WalletConnect, etc.) via Reown AppKit +- โœ… Multi-chain support (Mainnet, Polygon, Arbitrum, Base, BSC, Polygon Amoy) +- โœ… Firebase Authentication with wallet-based signature login +- โœ… Comprehensive error handling and user feedback systems +- โœ… Auth-based routing and session management +- โœ… Toast notifications and connection state tracking +- โœ… WalletConnect session management with automatic error recovery +- โœ… Development automation with Firebase emulators and ngrok integration +- โœ… Enhanced user feedback with context-aware error messages +- โœ… One-command development environment setup (pnpm dev) + +--- + +## ๐Ÿ—๏ธ Smart Contracts (packages/contracts/) + +### [#22 - Set up Hardhat development environment for contracts](https://github.com/rafamiziara/superpool/issues/22) +**Status**: ๐Ÿ”„ Open +**Scope**: Infrastructure setup for contract development +**Priority**: High (Prerequisite for all contract work) + +### [#23 - Develop PoolFactory.sol smart contract](https://github.com/rafamiziara/superpool/issues/23) +**Status**: ๐Ÿ”„ Open +**Scope**: Core factory contract for pool creation +**Dependencies**: #22 + +### [#24 - Develop LendingPool.sol implementation contract](https://github.com/rafamiziara/superpool/issues/24) +**Status**: ๐Ÿ”„ Open +**Scope**: Upgradeable pool implementation template +**Dependencies**: #22 + +### [#25 - Create deployment scripts for Polygon Amoy](https://github.com/rafamiziara/superpool/issues/25) +**Status**: ๐Ÿ”„ Open +**Scope**: Automated deployment to testnet +**Dependencies**: #23, #24 + +### [#26 - Add contract verification automation](https://github.com/rafamiziara/superpool/issues/26) +**Status**: ๐Ÿ”„ Open +**Scope**: Polygonscan verification integration +**Dependencies**: #25 + +### [#27 - Transfer PoolFactory ownership to multi-sig Safe](https://github.com/rafamiziara/superpool/issues/27) +**Status**: ๐Ÿ”„ Open +**Scope**: Security handover to multi-sig governance +**Dependencies**: #25, #26 + +--- + +## โšก Backend (packages/backend/) + +### [#28 - Create Cloud Function for pool creation via PoolFactory](https://github.com/rafamiziara/superpool/issues/28) +**Status**: ๐Ÿ”„ Open +**Scope**: API endpoint for pool creation requests +**Dependencies**: #23, #27 + +### [#29 - Add contract interaction service for Safe integration](https://github.com/rafamiziara/superpool/issues/29) +**Status**: ๐Ÿ”„ Open +**Scope**: Service layer for multi-sig transactions +**Dependencies**: #27 + +### [#30 - Set up event listeners for pool creation events](https://github.com/rafamiziara/superpool/issues/30) +**Status**: ๐Ÿ”„ Open +**Scope**: Blockchain event monitoring and Firestore sync +**Dependencies**: #23, #28 + +--- + +## ๐Ÿ“ฑ Mobile App (apps/mobile/) + +### [#31 - Design and implement pool creation UI](https://github.com/rafamiziara/superpool/issues/31) +**Status**: ๐Ÿ”„ Open +**Scope**: User interface for pool creation form +**Dependencies**: None (can start in parallel) + +### [#32 - Integrate pool creation with backend API](https://github.com/rafamiziara/superpool/issues/32) +**Status**: ๐Ÿ”„ Open +**Scope**: Connect UI to backend services +**Dependencies**: #28, #31 + +### [#33 - Add form validation for pool parameters](https://github.com/rafamiziara/superpool/issues/33) +**Status**: ๐Ÿ”„ Open +**Scope**: Client/server-side validation +**Dependencies**: #31 + +--- + +## ๐Ÿ“Š Progress Tracking + +### Overall Sprint 1 Progress: 17/26 issues completed (65%) + +**By Feature:** +- โœ… **User Onboarding & Wallet Connection**: 14/14 issues (100%) โœ… COMPLETED + - Infrastructure & Setup: 6/6 issues โœ… + - Backend Authentication: 5/5 issues โœ… + - Mobile App Integration: 5/5 issues โœ… + - Quality Assurance: 3/3 issues โœ… COMPLETED +- ๐Ÿ”„ **Create a New Lending Pool**: 0/12 issues (0%) + - ๐Ÿ—๏ธ Smart Contracts: 0/6 issues (0%) + - โšก Backend: 0/3 issues (0%) + - ๐Ÿ“ฑ Mobile App: 0/3 issues (0%) + +### Critical Path +1. **#22** (Hardhat setup) โ†’ **#23, #24** (Contracts) โ†’ **#25** (Deployment) โ†’ **#27** (Safe transfer) +2. **#28** (Cloud Function) depends on completed contracts +3. **#31** (UI) can start immediately in parallel +4. **#32** (Integration) brings everything together + +--- + +## ๐ŸŽฏ Sprint 1 Expected Deliverables + +- [x] **User can successfully connect wallet and log in** โœ… COMPLETED + - Multi-wallet support (MetaMask, WalletConnect, etc.) + - Firebase authentication with signature verification + - Multi-chain support and proper session management +- [ ] **Pool creator can deploy new lending pool via dApp** ๐Ÿ”„ IN PROGRESS +- [ ] **PoolFactory contract verified on Polygonscan** โณ PENDING +- [ ] **PoolFactory ownership transferred to multi-sig Safe** โณ PENDING +- [ ] **End-to-end pool creation flow functional** โณ PENDING + +--- + +## ๐Ÿ“ Notes + +- All issues include comprehensive acceptance criteria and technical requirements +- Dependencies are clearly mapped to enable parallel work where possible +- Critical path focuses on smart contract foundation first +- Mobile UI work can start immediately while contracts are being developed +- Integration phase (#32) will bring all components together + +**Last Updated**: 2025-08-17 \ No newline at end of file diff --git a/apps/mobile/.eslintrc.js b/apps/mobile/.eslintrc.js new file mode 100644 index 0000000..9b40982 --- /dev/null +++ b/apps/mobile/.eslintrc.js @@ -0,0 +1,54 @@ +module.exports = { + env: { + node: true, + es6: true, + }, + extends: ['eslint:recommended'], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + parserOptions: { + ecmaVersion: 2020, + sourceType: 'module', + }, + ignorePatterns: ['dist', 'node_modules', 'lib', '.expo', 'coverage'], + globals: { + __DEV__: 'readonly', + React: 'readonly', + NodeJS: 'readonly', + }, + rules: { + 'quotes': ['error', 'single'], + 'indent': ['error', 2, { 'SwitchCase': 1 }], + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': ['error', { 'argsIgnorePattern': '^_', 'varsIgnorePattern': '^_' }], + '@typescript-eslint/no-explicit-any': 'warn', + }, + overrides: [ + { + // Jest configuration for test files and mocks + files: ['**/__tests__/**/*', '**/*.test.*', '**/*.spec.*', '**/__mocks__/**/*', '**/setupTests.*'], + env: { + jest: true, + node: true, + }, + globals: { + jest: 'readonly', + }, + }, + { + // TypeScript files + files: ['**/*.ts', '**/*.tsx'], + rules: { + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-unused-vars': ['error', { 'argsIgnorePattern': '^_', 'varsIgnorePattern': '^_' }], + }, + }, + { + // Enum values are exported for external use + files: ['**/errorHandling.ts'], + rules: { + '@typescript-eslint/no-unused-vars': 'off', + }, + }, + ], +}; \ No newline at end of file diff --git a/apps/mobile/.gitignore b/apps/mobile/.gitignore new file mode 100644 index 0000000..20aefd7 --- /dev/null +++ b/apps/mobile/.gitignore @@ -0,0 +1,40 @@ +# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files + +# dependencies +node_modules/ + +# Expo +.expo/ +dist/ +web-build/ +expo-env.d.ts + +# Native +.kotlin/ +*.orig.* +*.jks +*.p8 +*.p12 +*.key +*.mobileprovision + +# Metro +.metro-health-check* + +# debug +npm-debug.* +yarn-debug.* +yarn-error.* + +# macOS +.DS_Store +*.pem + +# local env files +.env*.local + +# typescript +*.tsbuildinfo + +# Test coverage reports +/coverage diff --git a/apps/mobile/__mocks__/asyncStorage.js b/apps/mobile/__mocks__/asyncStorage.js new file mode 100644 index 0000000..e3e99d2 --- /dev/null +++ b/apps/mobile/__mocks__/asyncStorage.js @@ -0,0 +1,10 @@ +export default { + getItem: jest.fn(() => Promise.resolve(null)), + setItem: jest.fn(() => Promise.resolve()), + removeItem: jest.fn(() => Promise.resolve()), + clear: jest.fn(() => Promise.resolve()), + getAllKeys: jest.fn(() => Promise.resolve([])), + multiGet: jest.fn(() => Promise.resolve([])), + multiSet: jest.fn(() => Promise.resolve()), + multiRemove: jest.fn(() => Promise.resolve()), +}; \ No newline at end of file diff --git a/apps/mobile/__mocks__/expoApplication.js b/apps/mobile/__mocks__/expoApplication.js new file mode 100644 index 0000000..b1273d0 --- /dev/null +++ b/apps/mobile/__mocks__/expoApplication.js @@ -0,0 +1,4 @@ +export default { + getAndroidId: jest.fn(() => Promise.resolve('mock-android-id')), + getIosIdForVendorAsync: jest.fn(() => Promise.resolve('mock-ios-id')), +}; \ No newline at end of file diff --git a/apps/mobile/__mocks__/expoSecureStore.js b/apps/mobile/__mocks__/expoSecureStore.js new file mode 100644 index 0000000..c0a1d08 --- /dev/null +++ b/apps/mobile/__mocks__/expoSecureStore.js @@ -0,0 +1,5 @@ +export default { + getItemAsync: jest.fn(() => Promise.resolve(null)), + setItemAsync: jest.fn(() => Promise.resolve()), + deleteItemAsync: jest.fn(() => Promise.resolve()), +}; \ No newline at end of file diff --git a/apps/mobile/app.json b/apps/mobile/app.json new file mode 100644 index 0000000..405d25b --- /dev/null +++ b/apps/mobile/app.json @@ -0,0 +1,45 @@ +{ + "expo": { + "name": "mobile", + "slug": "mobile", + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "userInterfaceStyle": "light", + "newArchEnabled": true, + "splash": { + "image": "./assets/splash-icon.png", + "resizeMode": "contain", + "backgroundColor": "#ffffff" + }, + "ios": { + "supportsTablet": true, + "infoPlist": { + "LSApplicationQueriesSchemes": [ + "metamask", + "trust", + "safe", + "rainbow", + "uniswap" + // Add other wallet schemes names here + ] + } + }, + "android": { + "adaptiveIcon": { + "foregroundImage": "./assets/adaptive-icon.png", + "backgroundColor": "#ffffff" + }, + "edgeToEdgeEnabled": true + }, + "web": { + "favicon": "./assets/favicon.png", + "bundler": "metro" + }, + "plugins": [ + "expo-secure-store", + "expo-router" + ], + "scheme": "superpool" + } +} diff --git a/apps/mobile/assets/adaptive-icon.png b/apps/mobile/assets/adaptive-icon.png new file mode 100644 index 0000000..03d6f6b Binary files /dev/null and b/apps/mobile/assets/adaptive-icon.png differ diff --git a/apps/mobile/assets/favicon.png b/apps/mobile/assets/favicon.png new file mode 100644 index 0000000..e75f697 Binary files /dev/null and b/apps/mobile/assets/favicon.png differ diff --git a/apps/mobile/assets/icon.png b/apps/mobile/assets/icon.png new file mode 100644 index 0000000..a0b1526 Binary files /dev/null and b/apps/mobile/assets/icon.png differ diff --git a/apps/mobile/assets/splash-icon.png b/apps/mobile/assets/splash-icon.png new file mode 100644 index 0000000..03d6f6b Binary files /dev/null and b/apps/mobile/assets/splash-icon.png differ diff --git a/apps/mobile/babel.config.js b/apps/mobile/babel.config.js new file mode 100644 index 0000000..70e9845 --- /dev/null +++ b/apps/mobile/babel.config.js @@ -0,0 +1,6 @@ +module.exports = function (api) { + api.cache(true); + return { + presets: [['babel-preset-expo', { unstable_transformImportMeta: true }]], + }; +}; \ No newline at end of file diff --git a/apps/mobile/index.ts b/apps/mobile/index.ts new file mode 100644 index 0000000..67000cc --- /dev/null +++ b/apps/mobile/index.ts @@ -0,0 +1 @@ +import 'expo-router/entry' diff --git a/apps/mobile/jest.babel.config.js b/apps/mobile/jest.babel.config.js new file mode 100644 index 0000000..a00de4a --- /dev/null +++ b/apps/mobile/jest.babel.config.js @@ -0,0 +1,10 @@ +module.exports = { + presets: [ + ['@babel/preset-env', { targets: { node: 'current' } }], + '@babel/preset-typescript', + ['@babel/preset-react', { runtime: 'automatic' }], + ], + plugins: [ + '@babel/plugin-transform-modules-commonjs', + ], +}; \ No newline at end of file diff --git a/apps/mobile/jest.config.js b/apps/mobile/jest.config.js new file mode 100644 index 0000000..adeb327 --- /dev/null +++ b/apps/mobile/jest.config.js @@ -0,0 +1,50 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'jsdom', + setupFilesAfterEnv: ['/src/setupTests.ts'], + + // File patterns + testPathIgnorePatterns: [ + '/node_modules/', + '/android/', + '/ios/', + '/.expo/', + '/src/app/', // Exclude Expo Router app directory + ], + + // TypeScript transformation + transform: { + '^.+\\.(ts|tsx)$': ['ts-jest', { + tsconfig: 'tsconfig.json', + }], + '^.+\\.(js|jsx)$': ['babel-jest', { configFile: './jest.babel.config.js' }], + }, + + // File extensions + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], + + // Coverage settings - exclude problematic files + collectCoverageFrom: [ + 'src/**/*.{ts,tsx}', + '!src/**/*.d.ts', + '!src/setupTests.ts', + '!src/**/*.test.{ts,tsx}', + '!src/**/*.spec.{ts,tsx}', + '!src/app/**', // Exclude Expo Router app directory + '!src/**/+*.tsx', // Exclude Expo Router files like +not-found.tsx + '!src/firebase.config.ts', // Exclude Firebase config that imports Expo modules + '!src/utils/appCheckProvider.ts', // Exclude App Check provider that imports Expo modules + ], + coverageDirectory: 'coverage', + coverageReporters: ['text', 'lcov', 'html'], + + // Module mapping for mocks + moduleNameMapper: { + '^@/(.*)$': '/src/$1', + }, + + // Ignore transform for certain files + transformIgnorePatterns: [ + 'node_modules/(?!(expo|@expo|expo-router|@react-native|react-native|@react-navigation)/)', + ], +}; \ No newline at end of file diff --git a/apps/mobile/package.json b/apps/mobile/package.json new file mode 100644 index 0000000..6f4799e --- /dev/null +++ b/apps/mobile/package.json @@ -0,0 +1,59 @@ +{ + "name": "mobile", + "version": "1.0.0", + "main": "index.ts", + "scripts": { + "start": "expo start", + "android": "expo start --android", + "ios": "expo start --ios", + "web": "expo start --web", + "test": "jest", + "test:watch": "jest --watch", + "test:coverage": "jest --coverage" + }, + "dependencies": { + "@react-native-async-storage/async-storage": "2.1.2", + "@react-native-community/netinfo": "11.4.1", + "@reown/appkit-wagmi-react-native": "^1.3.0", + "@tanstack/react-query": "^5.85.0", + "@walletconnect/react-native-compat": "^2.21.8", + "expo": "~53.0.20", + "expo-application": "~6.1.5", + "expo-router": "^5.1.4", + "expo-secure-store": "~14.2.3", + "expo-status-bar": "~2.2.3", + "firebase": "^12.1.0", + "react": "19.0.0", + "react-native": "0.79.5", + "react-native-get-random-values": "^1.11.0", + "react-native-modal": "14.0.0-rc.1", + "react-native-svg": "15.11.2", + "react-native-toast-message": "^2.3.3", + "uuid": "^11.1.0", + "viem": "^2.33.3", + "wagmi": "^2.16.3" + }, + "devDependencies": { + "@babel/core": "^7.25.2", + "@babel/plugin-transform-modules-commonjs": "^7.26.2", + "@babel/preset-env": "^7.26.0", + "@babel/preset-react": "^7.25.9", + "@babel/preset-typescript": "^7.26.0", + "@testing-library/react-hooks": "^8.0.1", + "@testing-library/react-native": "^12.4.3", + "@types/jest": "^29.5.12", + "@types/react": "~19.0.10", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "babel-jest": "^29.7.0", + "eslint": "^8.57.1", + "eslint-plugin-jest": "^29.0.1", + "eslint-plugin-react-native": "^5.0.0", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "react-test-renderer": "19.0.0", + "ts-jest": "^29.1.1", + "typescript": "~5.8.3" + }, + "private": true +} \ No newline at end of file diff --git a/apps/mobile/src/app/+not-found.tsx b/apps/mobile/src/app/+not-found.tsx new file mode 100644 index 0000000..96da1a8 --- /dev/null +++ b/apps/mobile/src/app/+not-found.tsx @@ -0,0 +1,38 @@ +import { Link, Stack } from 'expo-router'; +import { StyleSheet, Text, View } from 'react-native'; + +export default function NotFoundScreen() { + return ( + <> + + + This screen doesn't exist. + + Go to home screen! + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + padding: 20, + }, + title: { + fontSize: 20, + fontWeight: 'bold', + marginBottom: 20, + }, + link: { + marginTop: 15, + paddingVertical: 15, + }, + linkText: { + fontSize: 14, + color: '#2e78b7', + }, +}); \ No newline at end of file diff --git a/apps/mobile/src/app/_layout.tsx b/apps/mobile/src/app/_layout.tsx new file mode 100644 index 0000000..52b574b --- /dev/null +++ b/apps/mobile/src/app/_layout.tsx @@ -0,0 +1,98 @@ +import '@walletconnect/react-native-compat'; +import { EventEmitter } from 'events'; + +// Increase max listeners to prevent memory leak warnings from multiple WalletConnect sessions +EventEmitter.defaultMaxListeners = 20; + +import { + AppKit, + createAppKit, + defaultWagmiConfig, +} from '@reown/appkit-wagmi-react-native'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { arbitrum, base, bsc, mainnet, polygon, polygonAmoy } from '@wagmi/core/chains'; +import { Stack } from 'expo-router'; +import { useEffect } from 'react'; +import Toast from 'react-native-toast-message'; +import { WagmiProvider } from 'wagmi'; +import { useGlobalLogoutState } from '../hooks/useLogoutState'; +import { useWalletToasts } from '../hooks/useWalletToasts'; +import { SessionManager } from '../utils/sessionManager'; + +const queryClient = new QueryClient(); + +const projectId = process.env.EXPO_PUBLIC_REOWN_PROJECT_ID; + +if (!projectId) { + throw new Error('EXPO_PUBLIC_REOWN_PROJECT_ID is required!'); +} + +const metadata = { + name: 'SuperPool', + description: 'Decentralized Micro-Lending Pools', + url: 'https://superpool.app', + icons: ['https://avatars.githubusercontent.com/u/179229932'], + redirect: { + native: 'superpool://', + universal: 'https://superpool.app', + }, +}; + +const chains = [mainnet, polygon, polygonAmoy, arbitrum, base, bsc] as const; + +const wagmiConfig = defaultWagmiConfig({ chains, projectId, metadata }); + +// Clear stale sessions before AppKit initialization to prevent "No matching key" errors +SessionManager.preventiveSessionCleanup().catch(console.warn); + +createAppKit({ + projectId, + metadata, + wagmiConfig, + defaultChain: polygon, + enableAnalytics: true, +}); + +function AppContent() { + useWalletToasts() // Global wallet toast notifications + useGlobalLogoutState() // Global logout state management + + // Debug session state on app start (no aggressive cleanup) + useEffect(() => { + if (__DEV__) { + SessionManager.getSessionDebugInfo() + .then(debugInfo => { + console.log('๐Ÿš€ App startup - Session debug info:', { + totalKeys: debugInfo.totalKeys, + walletConnectKeysCount: debugInfo.walletConnectKeys.length, + walletConnectKeys: debugInfo.walletConnectKeys.slice(0, 5) // Show first 5 + }) + console.log('โœ… Session state preserved - no aggressive cleanup on startup') + }) + .catch(error => { + console.warn('โš ๏ธ Failed to get session debug info on startup:', error) + }) + } + }, []) + + return ( + <> + + + + + + + + ) +} + +export default function RootLayout() { + return ( + + + + + + ); +} \ No newline at end of file diff --git a/apps/mobile/src/app/dashboard.tsx b/apps/mobile/src/app/dashboard.tsx new file mode 100644 index 0000000..e48fe7c --- /dev/null +++ b/apps/mobile/src/app/dashboard.tsx @@ -0,0 +1,167 @@ +import { AppKitButton } from '@reown/appkit-wagmi-react-native'; +import { router } from 'expo-router'; +import { StatusBar } from 'expo-status-bar'; +import { signOut } from 'firebase/auth'; +import { useEffect } from 'react'; +import { Alert, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { useAccount, useDisconnect } from 'wagmi'; +import { FIREBASE_AUTH } from '../firebase.config'; +import { getGlobalLogoutState } from '../hooks/useLogoutState'; + +export default function DashboardScreen() { + const { address, chain, isConnected } = useAccount(); + const { disconnect } = useDisconnect(); + + useEffect(() => { + if (!isConnected) { + signOut(FIREBASE_AUTH).catch(console.error); + router.replace('/'); + } + }, [isConnected]); + + const handleLogout = async () => { + const { startLogout, finishLogout } = getGlobalLogoutState() + + try { + // Set logout state to prevent authentication hook from processing + startLogout() + + // Disconnect wallet first + disconnect(); + + // Then sign out of Firebase + await signOut(FIREBASE_AUTH); + + router.replace('/'); + } catch (error) { + console.error('Logout error:', error); + Alert.alert('Error', 'Failed to logout. Please try again.'); + } finally { + // Always clear logout state + finishLogout() + } + }; + + if (!isConnected) { + return null; + } + + return ( + + Dashboard + + + Welcome to SuperPool! + Connected Wallet: + {address} + + {chain && ( + <> + Network: + {chain.name} + + )} + + + + + + + Logout + + + + + + ๐Ÿšง Coming Soon: Lending Pools, Loan Management, and More! + + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#fff', + alignItems: 'center', + justifyContent: 'center', + padding: 32 + }, + title: { + fontSize: 32, + marginBottom: 32, + fontWeight: '800', + color: '#333' + }, + welcomeText: { + fontSize: 20, + fontWeight: '600', + marginBottom: 24, + color: '#333' + }, + infoContainer: { + alignItems: 'center', + marginBottom: 32, + backgroundColor: '#f8f9fa', + padding: 20, + borderRadius: 12, + width: '100%' + }, + label: { + fontSize: 14, + fontWeight: '600', + color: '#666', + marginTop: 16, + marginBottom: 4 + }, + addressText: { + fontSize: 14, + fontFamily: 'monospace', + color: '#333', + textAlign: 'center', + backgroundColor: '#e9ecef', + padding: 8, + borderRadius: 6, + width: '100%' + }, + networkText: { + fontSize: 16, + fontWeight: '500', + color: '#007bff', + textAlign: 'center' + }, + buttonContainer: { + alignItems: 'center', + gap: 16, + marginBottom: 32, + width: '100%' + }, + logoutButton: { + backgroundColor: '#dc3545', + paddingHorizontal: 24, + paddingVertical: 12, + borderRadius: 8, + alignSelf: 'stretch', + alignItems: 'center' + }, + logoutButtonText: { + color: '#fff', + fontSize: 16, + fontWeight: '600' + }, + placeholderContainer: { + backgroundColor: '#fff3cd', + padding: 16, + borderRadius: 8, + borderWidth: 1, + borderColor: '#ffeaa7' + }, + placeholderText: { + fontSize: 14, + color: '#856404', + textAlign: 'center' + } +}); \ No newline at end of file diff --git a/apps/mobile/src/app/index.tsx b/apps/mobile/src/app/index.tsx new file mode 100644 index 0000000..f1aa570 --- /dev/null +++ b/apps/mobile/src/app/index.tsx @@ -0,0 +1,92 @@ +import { AppKitButton } from '@reown/appkit-wagmi-react-native'; +import { StatusBar } from 'expo-status-bar'; +import { StyleSheet, Text, View } from 'react-native'; +import { useAccount } from 'wagmi'; +import { useAuthentication } from '../hooks/useAuthentication'; + +export default function WalletConnectionScreen() { + const { isConnected, chain, address } = useAccount() + const { authError } = useAuthentication() + + return ( + + SuperPool + + + {isConnected ? ( + + โœ… Connected + {chain && ( + + You are on the {chain.name} network. + + )} + {address && ( + + {address.slice(0, 6)}...{address.slice(-4)} + + )} + {authError ? ( + + Authentication failed: {authError.userFriendlyMessage} + + ) : ( + + Authentication in progress... Please check your wallet app for signature requests and follow the toast notifications. + + )} + + ) : ( + + Please connect your wallet to continue. + + )} + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#fff', + alignItems: 'center', + justifyContent: 'center', + padding: 32 + }, + infoContainer: { + marginTop: 20, + alignItems: 'center', + }, + subText: { + fontSize: 14, + color: '#666', + textAlign: 'center', + marginTop: 8, + fontStyle: 'italic', + }, + title: { + fontSize: 32, + marginBottom: 32, + fontWeight: '800' + }, + infoText: { + fontSize: 16, + marginTop: 8, + textAlign: 'center', + }, + addressText: { + fontSize: 14, + marginTop: 4, + textAlign: 'center', + color: '#666', + fontFamily: 'monospace', + }, + errorText: { + fontSize: 14, + color: '#ff4444', + textAlign: 'center', + marginTop: 8, + fontWeight: '500', + }, +}); \ No newline at end of file diff --git a/apps/mobile/src/firebase.config.ts b/apps/mobile/src/firebase.config.ts new file mode 100644 index 0000000..dd9e2ae --- /dev/null +++ b/apps/mobile/src/firebase.config.ts @@ -0,0 +1,48 @@ +// apps/mobile-app/src/firebase.config.ts + +import ReactNativeAsyncStorage from '@react-native-async-storage/async-storage' +import { initializeApp } from 'firebase/app' +import { initializeAppCheck } from 'firebase/app-check' +import { connectAuthEmulator, getReactNativePersistence, initializeAuth } from 'firebase/auth' +import { connectFirestoreEmulator, getFirestore } from 'firebase/firestore' +import { connectFunctionsEmulator, getFunctions } from 'firebase/functions' +import { customAppCheckProviderFactory } from './utils/appCheckProvider' + +// Firebase Project Configuration +const firebaseConfig = { + apiKey: process.env.EXPO_PUBLIC_FIREBASE_API_KEY, + authDomain: process.env.EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN, + projectId: process.env.EXPO_PUBLIC_FIREBASE_PROJECT_ID, + storageBucket: process.env.EXPO_PUBLIC_FIREBASE_STORAGE_BUCKET, + messagingSenderId: process.env.EXPO_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, + appId: process.env.EXPO_PUBLIC_FIREBASE_APP_ID, + measurementId: process.env.EXPO_PUBLIC_FIREBASE_MEASUREMENT_ID, +} + +// Initialize Firebase App +const FIREBASE_APP = initializeApp(firebaseConfig) + +// Initialize App Check with the custom provider +initializeAppCheck(FIREBASE_APP, { + provider: customAppCheckProviderFactory(), +}) + +// Initialize Firebase Auth with AsyncStorage persistence +export const FIREBASE_AUTH = initializeAuth(FIREBASE_APP, { + persistence: getReactNativePersistence(ReactNativeAsyncStorage), +}) +export const FIREBASE_FIRESTORE = getFirestore(FIREBASE_APP) +export const FIREBASE_FUNCTIONS = getFunctions(FIREBASE_APP) + +// --- Connect to Emulators in Development --- +if (__DEV__) { + console.log('Connecting to Firebase Emulators...') + + const ngrokAuthUrl = process.env.EXPO_PUBLIC_NGROK_URL_AUTH + const ngrokFirestoreUrl = process.env.EXPO_PUBLIC_NGROK_URL_FIRESTORE + const ngrokFunctionsUrl = process.env.EXPO_PUBLIC_NGROK_URL_FUNCTIONS + + if (ngrokAuthUrl) connectAuthEmulator(FIREBASE_AUTH, ngrokAuthUrl) + if (ngrokFirestoreUrl) connectFirestoreEmulator(FIREBASE_FIRESTORE, ngrokFirestoreUrl, 80) + if (ngrokFunctionsUrl) connectFunctionsEmulator(FIREBASE_FUNCTIONS, ngrokFunctionsUrl, 80) +} diff --git a/apps/mobile/src/globals.d.ts b/apps/mobile/src/globals.d.ts new file mode 100644 index 0000000..404c55f --- /dev/null +++ b/apps/mobile/src/globals.d.ts @@ -0,0 +1 @@ +declare const __DEV__: boolean diff --git a/apps/mobile/src/hooks/useAuthentication.ts b/apps/mobile/src/hooks/useAuthentication.ts new file mode 100644 index 0000000..25126c3 --- /dev/null +++ b/apps/mobile/src/hooks/useAuthentication.ts @@ -0,0 +1,67 @@ +import { useCallback } from 'react' +import { useAccount, useDisconnect, useSignMessage, useSignTypedData } from 'wagmi' +import { AuthenticationContext, AuthenticationOrchestrator } from '../services/authenticationOrchestrator' +import { createAppError, ErrorType } from '../utils/errorHandling' +import { useAuthenticationState } from './useAuthenticationState' +import { useWalletConnectionTrigger } from './useWalletConnectionTrigger' + +export const useAuthentication = () => { + const { chain, connector } = useAccount() + const { signTypedDataAsync } = useSignTypedData() + const { signMessageAsync } = useSignMessage() + const { disconnect } = useDisconnect() + + // Use the new modular state management + const authState = useAuthenticationState() + + // Create the authentication orchestrator + const orchestrator = new AuthenticationOrchestrator(authState.getAuthLock()) + + const handleAuthentication = useCallback( + async (walletAddress: string) => { + // Clear any previous errors + authState.setAuthError(null) + + // Create the authentication context + const context: AuthenticationContext = { + walletAddress, + connector, + chainId: chain?.id, + signatureFunctions: { + signTypedDataAsync, + signMessageAsync, + }, + disconnect, + } + + try { + // Delegate to the orchestrator + await orchestrator.authenticate(context) + } catch (error) { + // Error handling is already done by the orchestrator and recovery service + // Just set the error state for the UI + if (error instanceof Error) { + authState.setAuthError(createAppError(ErrorType.UNKNOWN_ERROR, error.message, error)) + } + } + }, + [authState, orchestrator, connector, chain?.id, signTypedDataAsync, signMessageAsync, disconnect] + ) + + const handleDisconnection = useCallback(() => { + authState.setAuthError(null) + orchestrator.cleanup() + }, [authState, orchestrator]) + + // Use the connection trigger to only authenticate on new connections + useWalletConnectionTrigger({ + onNewConnection: handleAuthentication, + onDisconnection: handleDisconnection, + }) + + return { + authError: authState.authError, + isAuthenticating: authState.isAuthenticating, + authWalletAddress: authState.authWalletAddress, + } +} diff --git a/apps/mobile/src/hooks/useAuthenticationState.test.ts b/apps/mobile/src/hooks/useAuthenticationState.test.ts new file mode 100644 index 0000000..4c9bc4f --- /dev/null +++ b/apps/mobile/src/hooks/useAuthenticationState.test.ts @@ -0,0 +1,110 @@ +import { createAppError, ErrorType, AppError } from '../utils/errorHandling' + +// Simple test for the authentication state logic without React hooks complexity +describe('useAuthenticationState Logic', () => { + // Test the state management logic directly + it('should manage authentication state properly', () => { + // Simulate the state management logic + let authError: AppError | null = null + + const setAuthError = (error: AppError | null) => { + authError = error + } + + // Test setting error + const testError = createAppError(ErrorType.UNKNOWN_ERROR, 'Test error', new Error('Test')) + setAuthError(testError) + + expect(authError).toBe(testError) + expect(authError).toHaveProperty('type', ErrorType.UNKNOWN_ERROR) + expect(authError).toHaveProperty('userFriendlyMessage', 'Something went wrong. Please try again.') + + // Test clearing error + setAuthError(null) + expect(authError).toBeNull() + }) + + it('should handle authentication lock state', () => { + // Simulate authentication lock logic + const authLock: { + isLocked: boolean + startTime: number + walletAddress: string | null + abortController: { abort: jest.Mock } | null + } = { + isLocked: false, + startTime: 0, + walletAddress: null, + abortController: null, + } + + // Test acquiring lock + const acquireLock = (walletAddress: string) => { + authLock.isLocked = true + authLock.startTime = Date.now() + authLock.walletAddress = walletAddress + authLock.abortController = { abort: jest.fn() } + } + + // Test releasing lock + const releaseLock = () => { + if (authLock.abortController) { + authLock.abortController.abort('Authentication completed') + } + authLock.isLocked = false + authLock.startTime = 0 + authLock.walletAddress = null + authLock.abortController = null + } + + // Initially not locked + expect(authLock.isLocked).toBe(false) + expect(authLock.walletAddress).toBeNull() + + // Acquire lock + acquireLock('0x123') + expect(authLock.isLocked).toBe(true) + expect(authLock.walletAddress).toBe('0x123') + expect(authLock.abortController).toBeDefined() + + // Release lock + releaseLock() + expect(authLock.isLocked).toBe(false) + expect(authLock.walletAddress).toBeNull() + expect(authLock.abortController).toBeNull() + }) + + it('should handle abort controller cleanup', () => { + const mockAbortController = { + abort: jest.fn(), + } + + const authLock: { + isLocked: boolean + startTime: number + walletAddress: string | null + abortController: { abort: jest.Mock } | null + } = { + isLocked: true, + startTime: Date.now(), + walletAddress: '0x123', + abortController: mockAbortController, + } + + const releaseLock = () => { + if (authLock.abortController) { + authLock.abortController.abort('Authentication completed') + } + authLock.isLocked = false + authLock.startTime = 0 + authLock.walletAddress = null + authLock.abortController = null + } + + releaseLock() + + expect(mockAbortController.abort).toHaveBeenCalledWith('Authentication completed') + expect(authLock.isLocked).toBe(false) + }) +}) + diff --git a/apps/mobile/src/hooks/useAuthenticationState.ts b/apps/mobile/src/hooks/useAuthenticationState.ts new file mode 100644 index 0000000..b1f589f --- /dev/null +++ b/apps/mobile/src/hooks/useAuthenticationState.ts @@ -0,0 +1,69 @@ +import { useRef, useState } from 'react' +import { AppError } from '../utils/errorHandling' +import { AuthenticationLock } from '../services/authenticationOrchestrator' + +export interface AuthenticationState { + authError: AppError | null + isAuthenticating: boolean + authWalletAddress: string | null +} + +export interface AuthenticationStateActions { + setAuthError: (error: AppError | null) => void + getAuthLock: () => React.MutableRefObject + releaseAuthLock: () => void +} + +/** + * Custom hook for managing authentication state + * Extracts state management concerns from the main authentication hook + */ +export const useAuthenticationState = () => { + // Authentication error state + const [authError, setAuthError] = useState(null) + + // Authentication lock to prevent concurrent attempts + const authLock = useRef({ + isLocked: false, + startTime: 0, + walletAddress: null, + abortController: null, + }) + + /** + * Releases authentication lock and cleans up abort controller + */ + const releaseAuthLock = () => { + if (authLock.current.abortController) { + authLock.current.abortController.abort('Authentication completed') + } + + authLock.current = { + isLocked: false, + startTime: 0, + walletAddress: null, + abortController: null, + } + + console.log('๐Ÿ”“ Authentication lock released') + } + + // Derived state + const authenticationState: AuthenticationState = { + authError, + isAuthenticating: authLock.current.isLocked, + authWalletAddress: authLock.current.walletAddress, + } + + // Actions + const authenticationActions: AuthenticationStateActions = { + setAuthError, + getAuthLock: () => authLock, + releaseAuthLock, + } + + return { + ...authenticationState, + ...authenticationActions, + } +} \ No newline at end of file diff --git a/apps/mobile/src/hooks/useLogoutState.ts b/apps/mobile/src/hooks/useLogoutState.ts new file mode 100644 index 0000000..06b4fcd --- /dev/null +++ b/apps/mobile/src/hooks/useLogoutState.ts @@ -0,0 +1,41 @@ +import { useCallback, useState } from 'react' + +interface LogoutState { + isLoggingOut: boolean + startLogout: () => void + finishLogout: () => void +} + +export const useLogoutState = (): LogoutState => { + const [isLoggingOut, setIsLoggingOut] = useState(false) + + const startLogout = useCallback(() => { + setIsLoggingOut(true) + }, []) + + const finishLogout = useCallback(() => { + setIsLoggingOut(false) + }, []) + + return { + isLoggingOut, + startLogout, + finishLogout, + } +} + +// Global logout state instance +let globalLogoutState: LogoutState | null = null + +export const getGlobalLogoutState = (): LogoutState => { + if (!globalLogoutState) { + throw new Error('Global logout state not initialized. Use useGlobalLogoutState in a component first.') + } + return globalLogoutState +} + +export const useGlobalLogoutState = (): LogoutState => { + const logoutState = useLogoutState() + globalLogoutState = logoutState + return logoutState +} diff --git a/apps/mobile/src/hooks/useWalletConnectionTrigger.ts b/apps/mobile/src/hooks/useWalletConnectionTrigger.ts new file mode 100644 index 0000000..4993aa9 --- /dev/null +++ b/apps/mobile/src/hooks/useWalletConnectionTrigger.ts @@ -0,0 +1,72 @@ +import { useEffect, useRef } from 'react' +import { useAccount } from 'wagmi' + +interface ConnectionTriggerCallbacks { + onNewConnection: (address: string, chainId?: number) => void + onDisconnection: () => void +} + +export const useWalletConnectionTrigger = ({ onNewConnection, onDisconnection }: ConnectionTriggerCallbacks) => { + const { isConnected, address, chain } = useAccount() + const previousConnection = useRef<{ isConnected: boolean; address?: string }>({ + isConnected: false, + address: undefined, + }) + + // Reset previous connection state on mount to ensure clean detection + useEffect(() => { + previousConnection.current = { isConnected: false, address: undefined } + console.log('๐Ÿ”„ Reset previous connection state on mount') + + return () => { + console.log('๐Ÿงน useWalletConnectionTrigger cleanup') + } + }, []) + + useEffect(() => { + const prev = previousConnection.current + + console.log('๐Ÿ”„ Connection state change detected:', { + previous: { isConnected: prev.isConnected, address: prev.address }, + current: { isConnected, address, chainId: chain?.id }, + triggerConditions: { + newConnectionCondition: !prev.isConnected && isConnected && address, + disconnectionCondition: prev.isConnected && !isConnected, + }, + wallet: chain?.name || 'unknown', + }) + + // Force log all connection state changes for debugging + if (isConnected && address) { + console.log('โœ… Wallet is connected:', { address, chainId: chain?.id, connector: chain?.name }) + } else { + console.log('โŒ Wallet not connected:', { isConnected, address }) + } + + // Detect new connection (wasn't connected before, now is connected) + if (!prev.isConnected && isConnected && address) { + console.log('๐ŸŽ‰ New wallet connection detected:', { + address, + chainId: chain?.id, + chainName: chain?.name, + }) + + // Small delay to ensure wallet connection is stable before authentication + setTimeout(() => { + onNewConnection(address, chain?.id) + }, 100) + } + + // Detect disconnection (was connected before, now isn't) + if (prev.isConnected && !isConnected) { + console.log('๐Ÿ‘‹ Wallet disconnection detected') + onDisconnection() + } + + // Update previous state + previousConnection.current = { + isConnected, + address, + } + }, [isConnected, address, chain?.id, onNewConnection, onDisconnection]) +} diff --git a/apps/mobile/src/hooks/useWalletToasts.ts b/apps/mobile/src/hooks/useWalletToasts.ts new file mode 100644 index 0000000..1efbf89 --- /dev/null +++ b/apps/mobile/src/hooks/useWalletToasts.ts @@ -0,0 +1,22 @@ +import { useEffect, useRef } from 'react' +import { useAccount } from 'wagmi' +import { appToasts } from '../utils/toast' + +export const useWalletToasts = () => { + const { isConnected, connector } = useAccount() + const previouslyConnected = useRef(false) + + // Handle wallet connection/disconnection toast notifications + useEffect(() => { + if (isConnected && !previouslyConnected.current) { + // Wallet just connected + const walletName = connector?.name + appToasts.walletConnected(walletName) + previouslyConnected.current = true + } else if (!isConnected && previouslyConnected.current) { + // Wallet just disconnected + appToasts.walletDisconnected() + previouslyConnected.current = false + } + }, [isConnected, connector?.name]) +} diff --git a/apps/mobile/src/services/authErrorRecoveryService.simple.test.ts b/apps/mobile/src/services/authErrorRecoveryService.simple.test.ts new file mode 100644 index 0000000..64fab0d --- /dev/null +++ b/apps/mobile/src/services/authErrorRecoveryService.simple.test.ts @@ -0,0 +1,218 @@ +// Simple unit tests for AuthErrorRecoveryService logic without complex dependencies +import { createAppError, ErrorType } from '../utils/errorHandling' + +// Copy the core logic we want to test without the dependencies +class AuthErrorRecoveryServiceTest { + static analyzeSessionError(error: unknown): { + errorMessage: string + sessionId?: string + isSessionError: boolean + } { + const errorMessage = error instanceof Error ? error.message : String(error) + + const isSessionError = + errorMessage.includes('No matching key') || + errorMessage.includes('session:') || + errorMessage.includes('pairing') || + errorMessage.includes('WalletConnect') || + errorMessage.includes('relayer') + + // Extract session ID from error message if present + const sessionIdMatch = errorMessage.match(/session:\s*([a-f0-9]{64})/i) + const sessionId = sessionIdMatch ? sessionIdMatch[1] : undefined + + return { + errorMessage, + sessionId, + isSessionError, + } + } + + static handleConnectorError(errorMessage: string): { + shouldDisconnect: boolean + shouldShowError: boolean + errorDelay: number + cleanupPerformed: boolean + } { + if (errorMessage.includes('ConnectorNotConnectedError') || errorMessage.includes('Connector not connected')) { + return { + shouldDisconnect: false, + shouldShowError: true, + errorDelay: 1500, + cleanupPerformed: false, + } + } + + return { + shouldDisconnect: false, + shouldShowError: false, + errorDelay: 0, + cleanupPerformed: false, + } + } + + static handleGenericError( + error: unknown, + isConnected: boolean + ): { + shouldDisconnect: boolean + shouldShowError: boolean + errorDelay: number + cleanupPerformed: boolean + } { + // Use the same categorization logic + const appError = this.categorizeError(error) + const isUserInitiated = this.isUserInitiatedError(appError) + + const shouldDisconnect = !isUserInitiated && isConnected + const errorDelay = shouldDisconnect ? 2000 : isUserInitiated ? 1500 : 0 + + return { + shouldDisconnect, + shouldShowError: true, + errorDelay, + cleanupPerformed: false, + } + } + + private static categorizeError(error: unknown) { + if (error && typeof error === 'object' && 'type' in error) { + return error as { type: string; userFriendlyMessage: string } + } + + const errorMessage = error instanceof Error ? error.message : String(error) + const lowerMessage = errorMessage.toLowerCase() + + if (lowerMessage.includes('user rejected') || lowerMessage.includes('user denied')) { + return createAppError(ErrorType.SIGNATURE_REJECTED, errorMessage, error) + } + + return createAppError(ErrorType.UNKNOWN_ERROR, errorMessage, error) + } + + private static isUserInitiatedError(error: { type: string }): boolean { + return error.type === ErrorType.SIGNATURE_REJECTED + } +} + +describe('AuthErrorRecoveryService Core Logic', () => { + describe('analyzeSessionError', () => { + it('should detect session errors', () => { + const sessionError = new Error('No matching key for session: abc123') + const result = AuthErrorRecoveryServiceTest.analyzeSessionError(sessionError) + + expect(result.isSessionError).toBe(true) + expect(result.errorMessage).toContain('No matching key') + }) + + it('should extract session ID from error message', () => { + const sessionError = new Error('session: 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef') + const result = AuthErrorRecoveryServiceTest.analyzeSessionError(sessionError) + + expect(result.sessionId).toBe('1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef') + }) + + it('should handle non-session errors', () => { + const regularError = new Error('User rejected the request') + const result = AuthErrorRecoveryServiceTest.analyzeSessionError(regularError) + + expect(result.isSessionError).toBe(false) + expect(result.sessionId).toBeUndefined() + }) + + it('should handle string errors', () => { + const result = AuthErrorRecoveryServiceTest.analyzeSessionError('WalletConnect pairing failed') + + expect(result.isSessionError).toBe(true) + expect(result.errorMessage).toBe('WalletConnect pairing failed') + }) + + it('should detect various session error patterns', () => { + const patterns = ['No matching key', 'session: abc123', 'pairing failed', 'WalletConnect error', 'relayer connection failed'] + + patterns.forEach((pattern) => { + const result = AuthErrorRecoveryServiceTest.analyzeSessionError(new Error(pattern)) + expect(result.isSessionError).toBe(true) + }) + }) + }) + + describe('handleConnectorError', () => { + it('should handle connector not connected errors', () => { + const result = AuthErrorRecoveryServiceTest.handleConnectorError('ConnectorNotConnectedError: Connector not connected') + + expect(result.shouldDisconnect).toBe(false) + expect(result.shouldShowError).toBe(true) + expect(result.errorDelay).toBe(1500) + }) + + it('should handle connector variations', () => { + const patterns = ['ConnectorNotConnectedError', 'Connector not connected'] + + patterns.forEach((pattern) => { + const result = AuthErrorRecoveryServiceTest.handleConnectorError(pattern) + expect(result.shouldDisconnect).toBe(false) + expect(result.shouldShowError).toBe(true) + }) + }) + + it('should not handle non-connector errors', () => { + const result = AuthErrorRecoveryServiceTest.handleConnectorError('Network error') + + expect(result.shouldDisconnect).toBe(false) + expect(result.shouldShowError).toBe(false) + }) + }) + + describe('handleGenericError', () => { + it('should disconnect wallet on technical failures', () => { + const technicalError = new Error('Network failed') + + const result = AuthErrorRecoveryServiceTest.handleGenericError(technicalError, true) + + expect(result.shouldDisconnect).toBe(true) + expect(result.shouldShowError).toBe(true) + expect(result.errorDelay).toBe(2000) + }) + + it('should not disconnect on user-initiated errors', () => { + const userError = new Error('User rejected the request') + + const result = AuthErrorRecoveryServiceTest.handleGenericError(userError, true) + + expect(result.shouldDisconnect).toBe(false) + expect(result.shouldShowError).toBe(true) + expect(result.errorDelay).toBe(1500) + }) + + it('should handle disconnected wallet state', () => { + const technicalError = new Error('Network failed') + + const result = AuthErrorRecoveryServiceTest.handleGenericError(technicalError, false) + + expect(result.shouldDisconnect).toBe(false) // Already disconnected + expect(result.shouldShowError).toBe(true) + }) + + it('should properly categorize different error types', () => { + const errors = [ + { error: new Error('User rejected the request'), expectUserInitiated: true }, + { error: new Error('User denied transaction'), expectUserInitiated: true }, + { error: new Error('Network timeout'), expectUserInitiated: false }, + { error: new Error('Server error'), expectUserInitiated: false }, + ] + + errors.forEach(({ error, expectUserInitiated }) => { + const result = AuthErrorRecoveryServiceTest.handleGenericError(error, true) + + if (expectUserInitiated) { + expect(result.shouldDisconnect).toBe(false) + expect(result.errorDelay).toBe(1500) + } else { + expect(result.shouldDisconnect).toBe(true) + expect(result.errorDelay).toBe(2000) + } + }) + }) + }) +}) diff --git a/apps/mobile/src/services/authErrorRecoveryService.ts b/apps/mobile/src/services/authErrorRecoveryService.ts new file mode 100644 index 0000000..6fb4abb --- /dev/null +++ b/apps/mobile/src/services/authErrorRecoveryService.ts @@ -0,0 +1,261 @@ +import { signOut } from 'firebase/auth' +import { FIREBASE_AUTH } from '../firebase.config' +import { AppError, categorizeError, isUserInitiatedError } from '../utils/errorHandling' +import { SessionManager } from '../utils/sessionManager' +import { authToasts, showErrorFromAppError } from '../utils/toast' + +export interface ErrorRecoveryResult { + shouldDisconnect: boolean + shouldShowError: boolean + errorDelay: number + cleanupPerformed: boolean +} + +export interface SessionErrorContext { + errorMessage: string + sessionId?: string + isSessionError: boolean +} + +export class AuthErrorRecoveryService { + /** + * Analyzes error and determines if it's a WalletConnect session error + */ + static analyzeSessionError(error: unknown): SessionErrorContext { + const errorMessage = error instanceof Error ? error.message : String(error) + + const isSessionError = + errorMessage.includes('No matching key') || + errorMessage.includes('session:') || + errorMessage.includes('pairing') || + errorMessage.includes('WalletConnect') || + errorMessage.includes('relayer') + + // Extract session ID from error message if present + const sessionIdMatch = errorMessage.match(/session:\s*([a-f0-9]{64})/i) + const sessionId = sessionIdMatch ? sessionIdMatch[1] : undefined + + return { + errorMessage, + sessionId, + isSessionError, + } + } + + /** + * Handles WalletConnect session errors with comprehensive cleanup + */ + static async handleSessionError(sessionContext: SessionErrorContext, disconnect: () => void): Promise { + console.log('๐Ÿšจ Detected WalletConnect session error:', sessionContext.errorMessage) + + let cleanupSuccessful = false + + try { + if (sessionContext.sessionId) { + console.log(`๐ŸŽฏ Attempting to clear specific session: ${sessionContext.sessionId}`) + await SessionManager.clearSessionByErrorId(sessionContext.sessionId) + } + + // Always perform comprehensive cleanup for session errors + console.log('๐Ÿงน Performing comprehensive session cleanup...') + await SessionManager.forceResetAllConnections() + cleanupSuccessful = true + } catch (sessionError) { + console.error('โŒ Session cleanup failed, attempting fallback cleanup:', sessionError) + + // Fallback: Try preventive cleanup as last resort + try { + console.log('๐Ÿ”„ Attempting preventive session cleanup as fallback...') + await SessionManager.preventiveSessionCleanup() + cleanupSuccessful = true + } catch (fallbackError) { + console.error('โŒ Fallback session cleanup also failed:', fallbackError) + } + } + + // Always disconnect after session error handling + console.log('๐Ÿ”Œ Disconnecting wallet after session error handling...') + disconnect() + + // Show specific error message for session issues + setTimeout(() => { + authToasts.sessionError() + }, 1500) + + if (!cleanupSuccessful) { + console.warn('โš ๏ธ Session cleanup incomplete - some orphaned sessions may remain') + } + + return { + shouldDisconnect: true, + shouldShowError: false, // We already showed session-specific error + errorDelay: 0, + cleanupPerformed: cleanupSuccessful, + } + } + + /** + * Handles timeout errors with wallet disconnection + */ + static handleTimeoutError(error: AppError, disconnect: () => void): ErrorRecoveryResult { + console.log('โฐ Signature request timed out') + + // Disconnect wallet on timeout + disconnect() + + return { + shouldDisconnect: true, + shouldShowError: true, + errorDelay: 2000, // Show after disconnect toast + cleanupPerformed: false, + } + } + + /** + * Handles connector not connected errors (treat as user cancellation) + */ + static handleConnectorError(errorMessage: string): ErrorRecoveryResult { + if (errorMessage.includes('ConnectorNotConnectedError') || errorMessage.includes('Connector not connected')) { + console.log('๐Ÿ“ฑ Wallet disconnected during signing, treating as user cancellation') + + return { + shouldDisconnect: false, + shouldShowError: true, + errorDelay: 1500, + cleanupPerformed: false, + } + } + + // Not a connector error, let other handlers deal with it + return { + shouldDisconnect: false, + shouldShowError: false, + errorDelay: 0, + cleanupPerformed: false, + } + } + + /** + * Handles generic authentication errors with appropriate disconnect logic + */ + static handleGenericError(error: unknown, isConnected: boolean): ErrorRecoveryResult { + const appError = categorizeError(error) + const isUserInitiated = isUserInitiatedError(appError) + + console.log('Authentication error details:', { + errorType: appError.type, + isUserInitiated, + message: appError.userFriendlyMessage, + originalError: appError.originalError, + }) + + // Disconnect wallet on technical failures + const shouldDisconnect = !isUserInitiated && isConnected + + // Different timing based on whether wallet was disconnected + const errorDelay = shouldDisconnect + ? 2000 // For technical failures that cause disconnect, show error after disconnect toast + : isUserInitiated + ? 1500 + : 0 // For user cancellations, brief delay; immediate for other errors + + console.log( + shouldDisconnect + ? 'Scheduling error toast after disconnect (2s delay)' + : `Scheduling error toast for non-disconnect scenario (${errorDelay}ms delay)` + ) + + return { + shouldDisconnect, + shouldShowError: true, + errorDelay, + cleanupPerformed: false, + } + } + + /** + * Comprehensive error handling for authentication failures + */ + static async handleAuthenticationError( + error: unknown, + isConnected: boolean, + disconnect: () => void + ): Promise<{ appError: AppError; recoveryResult: ErrorRecoveryResult }> { + console.error('Authentication failed:', error) + + // Step 1: Analyze if this is a session error + const sessionContext = this.analyzeSessionError(error) + + if (sessionContext.isSessionError) { + const recoveryResult = await this.handleSessionError(sessionContext, disconnect) + // For session errors, we create a generic app error since we handle display differently + const appError = categorizeError(new Error('WalletConnect session error')) + return { appError, recoveryResult } + } + + // Step 2: Check for timeout errors + const errorMessage = sessionContext.errorMessage + if (errorMessage.includes('timed out')) { + const appError = categorizeError(new Error('Signature request timed out. Please try connecting again.')) + const recoveryResult = this.handleTimeoutError(appError, disconnect) + return { appError, recoveryResult } + } + + // Step 3: Check for connector errors + const connectorResult = this.handleConnectorError(errorMessage) + if (connectorResult.shouldShowError && !connectorResult.shouldDisconnect) { + // This is a connector error treated as user cancellation + const appError = categorizeError(new Error('User rejected the request.')) + return { appError, recoveryResult: connectorResult } + } + + // Step 4: Handle as generic error + const appError = categorizeError(error) + const recoveryResult = this.handleGenericError(error, isConnected) + + // Perform disconnect if needed + if (recoveryResult.shouldDisconnect) { + console.log('Disconnecting wallet due to authentication failure') + try { + disconnect() + } catch (disconnectError) { + console.warn('Failed to disconnect wallet:', disconnectError) + } + } + + return { appError, recoveryResult } + } + + /** + * Shows error feedback with appropriate timing + */ + static showErrorFeedback(appError: AppError, recoveryResult: ErrorRecoveryResult): void { + if (!recoveryResult.shouldShowError) { + return + } + + const showError = () => { + const scenario = recoveryResult.shouldDisconnect ? 'disconnect' : 'non-disconnect' + console.log(`Showing error toast for ${scenario} scenario:`, appError.userFriendlyMessage) + showErrorFromAppError(appError) + } + + if (recoveryResult.errorDelay > 0) { + setTimeout(showError, recoveryResult.errorDelay) + } else { + showError() + } + } + + /** + * Handles Firebase authentication cleanup on state changes + */ + static async handleFirebaseCleanup(reason: string): Promise { + try { + await signOut(FIREBASE_AUTH) + console.log(`๐Ÿšช Signed out from Firebase due to ${reason}`) + } catch (signOutError) { + console.error('โŒ Failed to sign out from Firebase:', signOutError) + } + } +} diff --git a/apps/mobile/src/services/authenticationOrchestrator.ts b/apps/mobile/src/services/authenticationOrchestrator.ts new file mode 100644 index 0000000..1e53eb2 --- /dev/null +++ b/apps/mobile/src/services/authenticationOrchestrator.ts @@ -0,0 +1,444 @@ +import { router } from 'expo-router' +import { signInWithCustomToken } from 'firebase/auth' +import { httpsCallable } from 'firebase/functions' +import type { Connector } from 'wagmi' +import { FIREBASE_AUTH, FIREBASE_FUNCTIONS } from '../firebase.config' +import { getGlobalLogoutState } from '../hooks/useLogoutState' +import { AtomicConnectionState, ConnectionStateManager } from '../utils/connectionStateManager' +import { SessionManager } from '../utils/sessionManager' +import { authToasts } from '../utils/toast' +import { AuthErrorRecoveryService } from './authErrorRecoveryService' +import { SignatureFunctions, SignatureService } from './signatureService' + +const verifySignatureAndLogin = httpsCallable(FIREBASE_FUNCTIONS, 'verifySignatureAndLogin') +const generateAuthMessage = httpsCallable(FIREBASE_FUNCTIONS, 'generateAuthMessage') + +export interface AuthenticationContext { + walletAddress: string + connector?: Connector + chainId?: number + signatureFunctions: SignatureFunctions + disconnect: () => void +} + +export interface AuthenticationLock { + isLocked: boolean + startTime: number + walletAddress: string | null + abortController: AbortController | null +} + +export class AuthenticationOrchestrator { + private connectionStateManager = new ConnectionStateManager() + + constructor(private authLock: React.MutableRefObject) {} + + /** + * Acquires authentication lock to prevent concurrent attempts + */ + private acquireAuthLock(walletAddress: string): boolean { + if (this.authLock.current.isLocked) { + const timeSinceLock = Date.now() - this.authLock.current.startTime + console.log(`โš ๏ธ Authentication already in progress for ${this.authLock.current.walletAddress} (${timeSinceLock}ms ago)`) + return false + } + + this.authLock.current = { + isLocked: true, + startTime: Date.now(), + walletAddress, + abortController: new AbortController(), + } + + console.log('๐Ÿ”’ Authentication lock acquired for:', walletAddress) + return true + } + + /** + * Releases authentication lock + */ + private releaseAuthLock(): void { + if (this.authLock.current.abortController) { + this.authLock.current.abortController.abort('Authentication completed') + } + + this.authLock.current = { + isLocked: false, + startTime: 0, + walletAddress: null, + abortController: null, + } + + console.log('๐Ÿ”“ Authentication lock released') + } + + /** + * Validates that authentication should proceed + */ + private async validatePreConditions(context: AuthenticationContext, lockedState: AtomicConnectionState): Promise { + // Check if we're in the middle of a logout process + try { + const { isLoggingOut } = getGlobalLogoutState() + if (isLoggingOut) { + console.log('โธ๏ธ Skipping authentication: logout in progress') + return false + } + } catch (error) { + console.log('โ„น๏ธ Global logout state not initialized, continuing...') + } + + // Validate initial connection state + const validation = this.connectionStateManager.validateInitialState(lockedState, context.walletAddress) + + if (!validation.isValid) { + console.warn('โŒ Invalid initial connection state:', validation.error) + throw new Error(validation.error || 'Invalid connection state') + } + + return true + } + + /** + * Generates authentication message from backend + */ + private async generateAuthenticationMessage(walletAddress: string): Promise<{ + message: string + nonce: string + timestamp: number + }> { + console.log('๐Ÿ“ Step 1: Generating authentication message...') + const messageResponse = await generateAuthMessage({ walletAddress }) + const { + message, + nonce, + timestamp: rawTimestamp, + } = messageResponse.data as { + message: string + nonce: string + timestamp: number + } + + const timestamp = typeof rawTimestamp === 'number' ? rawTimestamp : parseInt(String(rawTimestamp), 10) + + console.log('โœ… Authentication message generated:', message?.substring(0, 50) + '...') + console.log('๐Ÿ“Š Timestamp debug:', { rawTimestamp, timestamp, type: typeof timestamp }) + + if (isNaN(timestamp)) { + throw new Error('Invalid timestamp received from authentication message') + } + + return { message, nonce, timestamp } + } + + /** + * Requests signature from wallet + */ + private async requestWalletSignature(context: AuthenticationContext, message: string, nonce: string, timestamp: number) { + console.log('โœ๏ธ Step 2: Requesting wallet signature...') + authToasts.signingMessage() + + const signatureRequest = { + message, + nonce, + timestamp, + walletAddress: context.walletAddress, + chainId: context.chainId, + } + + return await SignatureService.requestSignature(signatureRequest, context.signatureFunctions, context.connector) + } + + /** + * Verifies signature with backend and gets Firebase token + */ + private async verifySignatureAndGetToken(context: AuthenticationContext, signature: string, signatureType: string): Promise { + authToasts.verifying() + console.log('๐Ÿ” Step 3: Verifying signature...') + + // For Safe wallets, we need to provide device info for proper App Check validation + const deviceInfo = + signatureType === 'safe-wallet' + ? { + deviceId: 'safe-wallet-device', + platform: 'web' as const, + } + : {} + + const signatureResponse = await verifySignatureAndLogin({ + walletAddress: context.walletAddress, + signature, + chainId: context.chainId, + signatureType, + ...deviceInfo, + }) + + console.log('โœ… Backend verification successful') + const { firebaseToken } = signatureResponse.data as { firebaseToken: string } + + console.log('๐Ÿ“‹ Firebase token received:', typeof firebaseToken, firebaseToken ? 'present' : 'missing') + console.log('๐Ÿ” Token comparison:', { + length: firebaseToken?.length, + prefix: firebaseToken?.substring(0, 50), + signatureType, + }) + + return firebaseToken + } + + /** + * Signs in with Firebase using custom token + */ + private async signInWithFirebase(firebaseToken: string, signatureType: string): Promise { + console.log('๐Ÿ”‘ Step 4: Signing in with Firebase...') + + // Add a small delay for Safe wallets to allow connection to stabilize + const isSafeWallet = signatureType === 'safe-wallet' + if (isSafeWallet) { + console.log('โณ Adding delay for Safe wallet connection stabilization...') + await new Promise((resolve) => setTimeout(resolve, 2000)) + } + + try { + await signInWithCustomToken(FIREBASE_AUTH, firebaseToken) + console.log('โœ… Firebase authentication successful') + } catch (firebaseError) { + console.error('โŒ Firebase authentication failed:', firebaseError) + console.error('๐Ÿ“‹ Token details:', { + tokenType: typeof firebaseToken, + tokenLength: firebaseToken?.length, + tokenStart: firebaseToken?.substring(0, 20) + '...', + }) + + // For Safe wallets, try multiple retries with increasing delays + if (isSafeWallet) { + console.log('๐Ÿ”„ Retrying Firebase authentication for Safe wallet...') + await this.retrySafeWalletFirebaseAuth(firebaseToken) + } else { + throw firebaseError + } + } + } + + /** + * Retry logic specifically for Safe wallet Firebase authentication + */ + private async retrySafeWalletFirebaseAuth(firebaseToken: string): Promise { + let retryCount = 0 + const maxRetries = 3 + + while (retryCount < maxRetries) { + retryCount++ + const delay = retryCount * 1000 // 1s, 2s, 3s delays + + try { + console.log(`๐Ÿ”„ Retry ${retryCount}/${maxRetries} after ${delay}ms delay...`) + await new Promise((resolve) => setTimeout(resolve, delay)) + await signInWithCustomToken(FIREBASE_AUTH, firebaseToken) + console.log(`โœ… Firebase authentication successful on retry ${retryCount}`) + return // Success, exit retry loop + } catch (retryError) { + console.error(`โŒ Firebase authentication retry ${retryCount}/${maxRetries} failed:`, retryError) + + if (retryCount >= maxRetries) { + // If this was the final retry, check for App Check issues + const errorMessage = retryError instanceof Error ? retryError.message : String(retryError) + if (errorMessage.includes('internal') || errorMessage.includes('app-check')) { + console.log('๐Ÿšจ Detected potential App Check issue for Safe wallet') + throw new Error( + 'Safe wallet authentication failed due to device verification. Please try disconnecting and reconnecting your wallet.' + ) + } + throw retryError + } + } + } + } + + /** + * Validates state consistency at various checkpoints + */ + private validateStateConsistency(lockedState: AtomicConnectionState, checkpoint: string): boolean { + const currentState = this.connectionStateManager.captureState( + lockedState.isConnected, // We pass the locked values since we don't have direct access to live state + lockedState.address, + lockedState.chainId + ) + + const isValid = this.connectionStateManager.validateState(lockedState, currentState, checkpoint) + + if (!isValid) { + console.log(`โŒ Aborting authentication due to connection state change at ${checkpoint}`) + return false + } + + return true + } + + /** + * Checks if authentication was aborted by timeout or user action + */ + private checkAuthenticationAborted(): boolean { + if (this.authLock.current.abortController?.signal.aborted) { + console.log('โŒ Authentication aborted by user or timeout') + return true + } + return false + } + + /** + * Shows session debug information for troubleshooting + */ + private async logSessionDebugInfo(): Promise { + try { + const sessionInfo = await SessionManager.getSessionDebugInfo() + console.log('๐Ÿ“Š Session debug info:', { + totalKeys: sessionInfo.totalKeys, + walletConnectKeysCount: sessionInfo.walletConnectKeys.length, + walletConnectKeys: sessionInfo.walletConnectKeys.slice(0, 3), + }) + } catch (error) { + console.warn('โš ๏ธ Failed to get session debug info:', error) + } + } + + /** + * Main authentication orchestration method + */ + async authenticate(context: AuthenticationContext): Promise { + console.log('๐Ÿ” Starting authentication flow for address:', context.walletAddress) + + // Acquire authentication lock to prevent concurrent attempts + if (!this.acquireAuthLock(context.walletAddress)) { + console.log('โŒ Skipping authentication: another attempt in progress') + return + } + + try { + // Early connector logging + console.log('Wallet connector:', { + connectorId: context.connector?.id, + connectorName: context.connector?.name, + }) + + // Capture atomic connection state snapshot at the start + const lockedConnectionState = this.connectionStateManager.captureState( + true, // We assume connected since this is called from a connected context + context.walletAddress, + context.chainId + ) + console.log('๐Ÿ” Locked connection state:', lockedConnectionState) + + // Log session debug information + await this.logSessionDebugInfo() + + // Validate pre-conditions + await this.validatePreConditions(context, lockedConnectionState) + + // Show connecting toast and wallet app guidance + console.log('๐Ÿ“ข Showing connection toast...') + authToasts.connecting() + + setTimeout(() => { + console.log('๐Ÿ“ฑ Showing wallet app guidance...') + authToasts.walletAppGuidance() + }, 3000) + + // Step 1: Generate authentication message + const { message, nonce, timestamp } = await this.generateAuthenticationMessage(context.walletAddress) + + // Small delay for session stabilization + console.log('โณ Waiting 1 second for session stabilization...') + await new Promise((resolve) => setTimeout(resolve, 1000)) + + // Validate state after message generation + if (!this.validateStateConsistency(lockedConnectionState, 'after message generation delay')) { + return + } + + // Check if authentication was aborted + if (this.checkAuthenticationAborted()) { + return + } + + // Step 2: Request wallet signature + const signatureResult = await this.requestWalletSignature(context, message, nonce, timestamp) + + // Validate state after signature + if (!this.validateStateConsistency(lockedConnectionState, 'after signature completion')) { + return + } + + // Check if authentication was aborted + if (this.checkAuthenticationAborted()) { + return + } + + // Step 3: Verify signature and get Firebase token + const firebaseToken = await this.verifySignatureAndGetToken(context, signatureResult.signature, signatureResult.signatureType) + + // Validate state before Firebase auth + if (!this.validateStateConsistency(lockedConnectionState, 'before Firebase authentication')) { + return + } + + // Check if authentication was aborted + if (this.checkAuthenticationAborted()) { + return + } + + // Step 4: Sign in with Firebase + await this.signInWithFirebase(firebaseToken, signatureResult.signatureType) + + // Final validation before declaring success + if (!this.validateStateConsistency(lockedConnectionState, 'authentication completion')) { + // Sign out from Firebase since connection state is inconsistent + await AuthErrorRecoveryService.handleFirebaseCleanup('connection state change') + return + } + + // Final check if authentication was aborted + if (this.checkAuthenticationAborted()) { + await AuthErrorRecoveryService.handleFirebaseCleanup('authentication abort') + return + } + + // Success! + console.log('User successfully signed in with Firebase!') + authToasts.success() + router.replace('/dashboard') + } catch (error) { + // Handle all authentication errors through the recovery service + const { appError, recoveryResult } = await AuthErrorRecoveryService.handleAuthenticationError( + error, + true, // Assume connected since this method is called from a connected context + context.disconnect + ) + + // Show error feedback with appropriate timing + AuthErrorRecoveryService.showErrorFeedback(appError, recoveryResult) + + // Re-throw error for the calling code to handle if needed + throw appError + } finally { + // Always release authentication lock + this.releaseAuthLock() + } + } + + /** + * Gets current authentication status + */ + getAuthenticationStatus() { + return { + isAuthenticating: this.authLock.current.isLocked, + authWalletAddress: this.authLock.current.walletAddress, + } + } + + /** + * Releases authentication lock (for cleanup on disconnection) + */ + cleanup() { + this.releaseAuthLock() + } +} diff --git a/apps/mobile/src/services/signatureService.test.ts b/apps/mobile/src/services/signatureService.test.ts new file mode 100644 index 0000000..e4eed4b --- /dev/null +++ b/apps/mobile/src/services/signatureService.test.ts @@ -0,0 +1,220 @@ +import type { Connector } from 'wagmi' +import { RegularWalletSigner, SafeWalletSigner, SignatureService, WalletTypeDetector } from './signatureService' + +// Mock connector +const mockConnector = { + id: 'safe', + name: 'Safe Wallet', +} as Connector + +const mockRegularConnector = { + id: 'metamask', + name: 'MetaMask', +} as Connector + +// Mock signature functions +const mockSignatureFunctions = { + signTypedDataAsync: jest.fn(), + signMessageAsync: jest.fn(), +} + +describe('WalletTypeDetector', () => { + beforeEach(() => { + jest.clearAllMocks() + }) + + describe('detectSafeWallet', () => { + it('should detect Safe wallet by connector id', () => { + expect(WalletTypeDetector.detectSafeWallet({ id: 'safe', name: 'Test' } as Connector)).toBe(true) + }) + + it('should detect Safe wallet by connector name', () => { + expect(WalletTypeDetector.detectSafeWallet({ id: 'test', name: 'Safe Wallet' } as Connector)).toBe(true) + }) + + it('should not detect Safe wallet for regular connectors', () => { + expect(WalletTypeDetector.detectSafeWallet(mockRegularConnector)).toBe(false) + }) + + it('should return false for undefined connector', () => { + expect(WalletTypeDetector.detectSafeWallet(undefined)).toBe(false) + }) + }) + + describe('detectFromSignatureError', () => { + it('should detect Safe wallet from error patterns', () => { + expect(WalletTypeDetector.detectFromSignatureError('Method disabled')).toBe(true) + expect(WalletTypeDetector.detectFromSignatureError('safe://wc?...')).toBe(true) + expect(WalletTypeDetector.detectFromSignatureError('the method eth_signTypedData_v4 does not exist')).toBe(true) + }) + + it('should not detect Safe wallet from regular errors', () => { + expect(WalletTypeDetector.detectFromSignatureError('User rejected')).toBe(false) + expect(WalletTypeDetector.detectFromSignatureError('Network error')).toBe(false) + }) + }) +}) + +describe('SafeWalletSigner', () => { + const mockRequest = { + message: 'Test message', + nonce: '123', + timestamp: 1640995200000, + walletAddress: '0x123', + chainId: 1, + } + + beforeEach(() => { + jest.clearAllMocks() + jest.clearAllTimers() + jest.useFakeTimers() + }) + + afterEach(() => { + jest.useRealTimers() + }) + + it('should successfully sign with direct connector', async () => { + mockSignatureFunctions.signMessageAsync.mockResolvedValue('0x1234567890abcdef') + + const result = await SafeWalletSigner.sign(mockRequest, mockSignatureFunctions, mockConnector) + + expect(result).toEqual({ + signature: '0x1234567890abcdef', + signatureType: 'personal-sign', + }) + }) + + it('should fallback to ownership verification on connector failure', async () => { + mockSignatureFunctions.signMessageAsync.mockRejectedValue(new Error('Connector failed')) + + const result = await SafeWalletSigner.sign(mockRequest, mockSignatureFunctions, mockConnector) + + expect(result).toEqual({ + signature: `safe-wallet:${mockRequest.walletAddress}:${mockRequest.nonce}:${mockRequest.timestamp}`, + signatureType: 'safe-wallet', + }) + }) + + it('should handle timeout and fallback to ownership verification', async () => { + const timeoutPromise = new Promise((resolve) => { + setTimeout(() => resolve('0x1234567890abcdef'), 25000) // Longer than 20s timeout + }) + mockSignatureFunctions.signMessageAsync.mockReturnValue(timeoutPromise) + + const resultPromise = SafeWalletSigner.sign(mockRequest, mockSignatureFunctions, mockConnector) + + // Fast-forward time to trigger timeout + jest.advanceTimersByTime(20000) + + const result = await resultPromise + + expect(result.signatureType).toBe('safe-wallet') + }) +}) + +describe('RegularWalletSigner', () => { + const mockRequest = { + message: 'Test message', + nonce: '123', + timestamp: 1640995200000, + walletAddress: '0x123', + chainId: 1, + } + + beforeEach(() => { + jest.clearAllMocks() + jest.clearAllTimers() + jest.useFakeTimers() + }) + + afterEach(() => { + jest.useRealTimers() + }) + + it('should successfully sign with EIP-712 typed data', async () => { + mockSignatureFunctions.signTypedDataAsync.mockResolvedValue('0x1234567890abcdef') + + const result = await RegularWalletSigner.sign(mockRequest, mockSignatureFunctions) + + expect(result).toEqual({ + signature: '0x1234567890abcdef', + signatureType: 'typed-data', + }) + }) + + it('should fallback to personal message signing when EIP-712 fails', async () => { + mockSignatureFunctions.signTypedDataAsync.mockRejectedValue(new Error('EIP-712 not supported')) + mockSignatureFunctions.signMessageAsync.mockResolvedValue('0xabcdef1234567890') + + const result = await RegularWalletSigner.sign(mockRequest, mockSignatureFunctions) + + expect(result).toEqual({ + signature: '0xabcdef1234567890', + signatureType: 'personal-sign', + }) + }) + + it('should detect Safe wallet from personal sign error and switch to Safe authentication', async () => { + mockSignatureFunctions.signTypedDataAsync.mockRejectedValue(new Error('EIP-712 not supported')) + mockSignatureFunctions.signMessageAsync.mockResolvedValue('{"error": "Method disabled"}') + + const result = await RegularWalletSigner.sign(mockRequest, mockSignatureFunctions) + + expect(result.signatureType).toBe('safe-wallet') + expect(result.signature).toBe(`safe-wallet:${mockRequest.walletAddress}:${mockRequest.nonce}:${mockRequest.timestamp}`) + }) + + describe('validateSignatureFormat', () => { + it('should validate hex signatures', () => { + expect(RegularWalletSigner.validateSignatureFormat('0x1234567890abcdef')).toBe(true) + }) + + it('should validate Safe wallet tokens', () => { + expect(RegularWalletSigner.validateSignatureFormat('safe-wallet:0x123:nonce:timestamp')).toBe(true) + }) + + it('should reject invalid signatures', () => { + expect(RegularWalletSigner.validateSignatureFormat('invalid')).toBe(false) + expect(RegularWalletSigner.validateSignatureFormat('0x123')).toBe(false) // Too short + }) + }) +}) + +describe('SignatureService', () => { + const mockRequest = { + message: 'Test message', + nonce: '123', + timestamp: 1640995200000, + walletAddress: '0x123', + chainId: 1, + } + + beforeEach(() => { + jest.clearAllMocks() + }) + + it('should use SafeWalletSigner for Safe wallets', async () => { + mockSignatureFunctions.signMessageAsync.mockResolvedValue('0x1234567890abcdef') + + const result = await SignatureService.requestSignature(mockRequest, mockSignatureFunctions, mockConnector) + + expect(result.signatureType).toBe('personal-sign') + }) + + it('should use RegularWalletSigner for regular wallets', async () => { + mockSignatureFunctions.signTypedDataAsync.mockResolvedValue('0x1234567890abcdef') + + const result = await SignatureService.requestSignature(mockRequest, mockSignatureFunctions, mockRegularConnector) + + expect(result.signatureType).toBe('typed-data') + }) + + it('should validate signature format and throw on invalid signatures', async () => { + mockSignatureFunctions.signTypedDataAsync.mockResolvedValue('invalid-signature') + + await expect(SignatureService.requestSignature(mockRequest, mockSignatureFunctions, mockRegularConnector)).rejects.toThrow( + 'Invalid signature received' + ) + }) +}) diff --git a/apps/mobile/src/services/signatureService.ts b/apps/mobile/src/services/signatureService.ts new file mode 100644 index 0000000..cbb2d2d --- /dev/null +++ b/apps/mobile/src/services/signatureService.ts @@ -0,0 +1,233 @@ +import type { Connector } from 'wagmi' + +export type SignatureType = 'typed-data' | 'personal-sign' | 'safe-wallet' + +export interface SignatureRequest { + message: string + nonce: string + timestamp: number + walletAddress: string + chainId?: number +} + +export interface SignatureResult { + signature: string + signatureType: SignatureType +} + +interface TypedDataParameter { + name: string + type: string +} + +interface TypedDataDomain { + name?: string + version?: string + chainId?: number | bigint + verifyingContract?: `0x${string}` + salt?: `0x${string}` +} + +interface TypedData { + domain?: TypedDataDomain + types: Record + primaryType: string + message: Record + account?: `0x${string}` +} + +export interface SignatureFunctions { + signTypedDataAsync: (data: TypedData) => Promise + signMessageAsync: (params: { message: string; connector?: Connector }) => Promise +} + +export class WalletTypeDetector { + static detectSafeWallet(connector?: Connector): boolean { + if (!connector) return false + + return connector.id === 'safe' || connector.name?.toLowerCase().includes('safe') || connector.id?.toLowerCase().includes('safe') + } + + static detectFromSignatureError(error: string): boolean { + return ( + error.includes('Method disabled') || error.includes('safe://') || error.includes('the method eth_signTypedData_v4 does not exist') + ) + } +} + +export class SafeWalletSigner { + static async sign(request: SignatureRequest, functions: SignatureFunctions, connector?: Connector): Promise { + const timeoutMs = 20000 // 20s for Safe wallets + + try { + console.log('๐Ÿ” Safe wallet detected, trying direct connector signing...') + + // Try direct connector signing first + const signaturePromise = functions.signMessageAsync({ + message: request.message, + connector, + }) + + const timeoutPromise = new Promise((_, reject) => { + setTimeout(() => { + reject(new Error(`Signature request timed out after ${timeoutMs / 1000} seconds`)) + }, timeoutMs) + }) + + const signature = await Promise.race([signaturePromise, timeoutPromise]) + + // Validate signature result + if (typeof signature === 'object' || (typeof signature === 'string' && signature.includes('"error"'))) { + throw new Error(`Safe connector signing failed: ${JSON.stringify(signature)}`) + } + + console.log('โœ… Safe wallet direct signing successful:', typeof signature, signature?.substring?.(0, 20) + '...') + return { + signature, + signatureType: 'personal-sign', + } + } catch (error) { + console.log('โŒ Safe direct signing failed, using ownership verification fallback...', error) + + // Fallback to ownership verification approach + console.log('๐Ÿ” Using Safe wallet authentication (ownership verification)') + const fallbackSignature = `safe-wallet:${request.walletAddress}:${request.nonce}:${request.timestamp}` + console.log('๐Ÿ” Safe wallet authentication token generated') + + return { + signature: fallbackSignature, + signatureType: 'safe-wallet', + } + } + } +} + +export class RegularWalletSigner { + static async sign(request: SignatureRequest, functions: SignatureFunctions, isSafeWallet = false): Promise { + const timeoutMs = isSafeWallet ? 20000 : 15000 // Progressive timeout + let timeoutId: NodeJS.Timeout | undefined + + try { + // First try EIP-712 typed data (preferred for modern wallets) + try { + console.log('๐Ÿ“ฑ Trying EIP-712 typed data signing...') + + const typedData = { + domain: { + name: 'SuperPool Authentication', + version: '1', + chainId: request.chainId || 1, + }, + types: { + Authentication: [ + { name: 'wallet', type: 'address' }, + { name: 'nonce', type: 'string' }, + { name: 'timestamp', type: 'uint256' }, + ], + }, + primaryType: 'Authentication' as const, + message: { + wallet: request.walletAddress as `0x${string}`, + nonce: request.nonce, + timestamp: BigInt(request.timestamp), + }, + } + + const signaturePromise = functions.signTypedDataAsync(typedData) + const timeoutPromise = new Promise((_, reject) => { + timeoutId = setTimeout(() => { + reject(new Error(`EIP-712 signature request timed out after ${timeoutMs / 1000} seconds`)) + }, timeoutMs) + }) + + const signature = await Promise.race([signaturePromise, timeoutPromise]) + + // Validate EIP-712 signature + if (typeof signature === 'object' || (typeof signature === 'string' && signature.includes('"error"'))) { + throw new Error(`EIP-712 signing failed: ${JSON.stringify(signature)}`) + } + + console.log('โœ… EIP-712 signature successful:', typeof signature, signature?.substring?.(0, 20) + '...') + return { + signature, + signatureType: 'typed-data', + } + } catch (typedDataError: unknown) { + const errorMessage = typedDataError instanceof Error ? typedDataError.message : String(typedDataError) + console.log('โŒ EIP-712 failed, trying personal message signing...', errorMessage) + + // Clean up previous timeout + if (timeoutId) clearTimeout(timeoutId) + + // Fallback to personal message signing + const signaturePromise = functions.signMessageAsync({ message: request.message }) + const timeoutPromise = new Promise((_, reject) => { + timeoutId = setTimeout(() => { + reject(new Error(`Personal sign request timed out after ${timeoutMs / 1000} seconds`)) + }, timeoutMs) + }) + + const signature = await Promise.race([signaturePromise, timeoutPromise]) + + // Validate personal sign signature + if (typeof signature === 'object' || (typeof signature === 'string' && signature.includes('"error"'))) { + // Check if this is a Safe wallet based on error patterns + const personalSignError = JSON.stringify(signature) + if (WalletTypeDetector.detectFromSignatureError(personalSignError)) { + console.log('๐Ÿ” Safe wallet detected by personal sign error, switching to Safe authentication...') + const safeSignature = `safe-wallet:${request.walletAddress}:${request.nonce}:${request.timestamp}` + console.log('๐Ÿ” Safe wallet authentication token generated (personal sign error detection)') + return { + signature: safeSignature, + signatureType: 'safe-wallet', + } + } else { + throw new Error(`Personal message signing failed: ${JSON.stringify(signature)}`) + } + } + + console.log('โœ… Personal message signature successful:', typeof signature, signature?.substring?.(0, 20) + '...') + return { + signature, + signatureType: 'personal-sign', + } + } + } finally { + // Clean up timeout when signature resolves or errors + if (timeoutId) clearTimeout(timeoutId) + } + } + + static validateSignatureFormat(signature: string): boolean { + const isSafeToken = signature.startsWith('safe-wallet:') + const isValidHex = signature.startsWith('0x') && signature.length >= 10 + return isSafeToken || isValidHex + } +} + +export class SignatureService { + static async requestSignature(request: SignatureRequest, functions: SignatureFunctions, connector?: Connector): Promise { + const isSafeWallet = WalletTypeDetector.detectSafeWallet(connector) + + console.log('๐Ÿ” Wallet type detection:', { + connectorId: connector?.id, + connectorName: connector?.name, + isSafeWallet, + }) + + let result: SignatureResult + + if (isSafeWallet) { + result = await SafeWalletSigner.sign(request, functions, connector) + } else { + result = await RegularWalletSigner.sign(request, functions, isSafeWallet) + } + + // Final signature validation + if (!RegularWalletSigner.validateSignatureFormat(result.signature)) { + throw new Error(`Invalid signature received: ${JSON.stringify(result.signature)}`) + } + + return result + } +} diff --git a/apps/mobile/src/setupTests.ts b/apps/mobile/src/setupTests.ts new file mode 100644 index 0000000..acd0e71 --- /dev/null +++ b/apps/mobile/src/setupTests.ts @@ -0,0 +1,27 @@ +// Basic Jest setup for testing utility classes and services + +// Mock Firebase (only when needed) +jest.mock('firebase/auth', () => ({ + signInWithCustomToken: jest.fn(), + signOut: jest.fn(), +})) + +jest.mock('firebase/functions', () => ({ + httpsCallable: jest.fn(() => jest.fn()), +})) + +// Mock toast utilities (only when needed) +jest.mock('./utils/toast', () => ({ + authToasts: { + connecting: jest.fn(), + walletAppGuidance: jest.fn(), + signingMessage: jest.fn(), + verifying: jest.fn(), + success: jest.fn(), + sessionError: jest.fn(), + }, + showErrorFromAppError: jest.fn(), +})) + +// Global test timeout +jest.setTimeout(10000) \ No newline at end of file diff --git a/apps/mobile/src/utils/appCheckProvider.ts b/apps/mobile/src/utils/appCheckProvider.ts new file mode 100644 index 0000000..a4a946f --- /dev/null +++ b/apps/mobile/src/utils/appCheckProvider.ts @@ -0,0 +1,72 @@ +import * as Application from 'expo-application' +import * as SecureStore from 'expo-secure-store' +import { AppCheckToken, CustomProvider } from 'firebase/app-check' +import { Platform } from 'react-native' +import 'react-native-get-random-values' +import { v4 as uuidv4 } from 'uuid' + +const APP_CHECK_MINTER_URL = process.env.EXPO_PUBLIC_CLOUD_FUNCTIONS_BASE_URL + 'customAppCheckMinter' + +// A helper function to get a unique ID that is persistent across app updates +const getUniqueDeviceId = async (): Promise => { + if (Platform.OS === 'android') { + return Application.getAndroidId() + } + + if (Platform.OS === 'ios') { + return Application.getIosIdForVendorAsync() + } + + // Fallback for web: use a UUID stored in SecureStore + let webId = await SecureStore.getItemAsync('web_device_id') + + if (!webId) { + webId = uuidv4() + await SecureStore.setItemAsync('web_device_id', webId) + } + + return webId +} + +export const customAppCheckProviderFactory = (): CustomProvider => { + const provider = new CustomProvider({ + getToken: async (): Promise => { + try { + const uniqueDeviceId = await getUniqueDeviceId() + + if (!uniqueDeviceId) { + throw new Error('Could not get a unique device ID.') + } + + const body = JSON.stringify({ deviceId: uniqueDeviceId }) + + const response = await fetch(APP_CHECK_MINTER_URL, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body, + }) + + if (!response.ok) { + throw new Error(`Failed to fetch App Check token: ${response.statusText}`) + } + + const data = await response.json() + + return { + token: data.appCheckToken, + expireTimeMillis: data.expireTimeMillis, + } + } catch (error) { + console.error('Error fetching App Check token:', error) + // Return a dummy token to allow Firebase operations to proceed + // This will fail server-side validation but won't block client operations + return { + token: 'dummy-token-device-not-approved', + expireTimeMillis: Date.now() + 60000, // 1 minute + } + } + }, + }) + + return provider +} diff --git a/apps/mobile/src/utils/connectionStateManager.test.ts b/apps/mobile/src/utils/connectionStateManager.test.ts new file mode 100644 index 0000000..4af28e9 --- /dev/null +++ b/apps/mobile/src/utils/connectionStateManager.test.ts @@ -0,0 +1,173 @@ +import { ConnectionStateManager, connectionStateManager } from './connectionStateManager' + +describe('ConnectionStateManager', () => { + let manager: ConnectionStateManager + + beforeEach(() => { + manager = new ConnectionStateManager() + }) + + describe('captureState', () => { + it('should capture connection state with sequence number', () => { + const state1 = manager.captureState(true, '0x123', 1) + const state2 = manager.captureState(true, '0x123', 1) + + expect(state1.isConnected).toBe(true) + expect(state1.address).toBe('0x123') + expect(state1.chainId).toBe(1) + expect(state1.sequenceNumber).toBe(1) + expect(state1.timestamp).toBeDefined() + + expect(state2.sequenceNumber).toBe(2) + expect(state2.sequenceNumber).toBeGreaterThan(state1.sequenceNumber) + }) + + it('should increment sequence counter correctly', () => { + const state1 = manager.captureState(true, '0x123', 1) + const state2 = manager.captureState(false, '0x456', 2) + const state3 = manager.captureState(true, '0x789', 137) + + expect(state1.sequenceNumber).toBe(1) + expect(state2.sequenceNumber).toBe(2) + expect(state3.sequenceNumber).toBe(3) + }) + }) + + describe('validateState', () => { + it('should validate consistent states', () => { + const lockedState = manager.captureState(true, '0x123', 1) + const currentState = manager.captureState(true, '0x123', 1) + + const isValid = manager.validateState(lockedState, currentState, 'test checkpoint') + + expect(isValid).toBe(true) + }) + + it('should detect connection state changes', () => { + const lockedState = manager.captureState(true, '0x123', 1) + const currentState = manager.captureState(false, '0x123', 1) // Connection changed + + const isValid = manager.validateState(lockedState, currentState, 'test checkpoint') + + expect(isValid).toBe(false) + }) + + it('should detect address changes', () => { + const lockedState = manager.captureState(true, '0x123', 1) + const currentState = manager.captureState(true, '0x456', 1) // Address changed + + const isValid = manager.validateState(lockedState, currentState, 'test checkpoint') + + expect(isValid).toBe(false) + }) + + it('should detect chain ID changes', () => { + const lockedState = manager.captureState(true, '0x123', 1) + const currentState = manager.captureState(true, '0x123', 137) // Chain changed + + const isValid = manager.validateState(lockedState, currentState, 'test checkpoint') + + expect(isValid).toBe(false) + }) + + it('should allow sequence number progression', () => { + const lockedState = manager.captureState(true, '0x123', 1) + const currentState = manager.captureState(true, '0x123', 1) // Same state, later sequence + + const isValid = manager.validateState(lockedState, currentState, 'test checkpoint') + + expect(isValid).toBe(true) + expect(currentState.sequenceNumber).toBeGreaterThan(lockedState.sequenceNumber) + }) + + it('should reject backwards sequence numbers', () => { + const laterState = manager.captureState(true, '0x123', 1) + const earlierState = { + ...laterState, + sequenceNumber: laterState.sequenceNumber - 1, + } + + const isValid = manager.validateState(laterState, earlierState, 'test checkpoint') + + expect(isValid).toBe(false) + }) + }) + + describe('validateInitialState', () => { + it('should validate correct initial state', () => { + const state = manager.captureState(true, '0x123', 1) + + const result = manager.validateInitialState(state, '0x123') + + expect(result.isValid).toBe(true) + expect(result.error).toBeUndefined() + }) + + it('should reject disconnected state', () => { + const state = manager.captureState(false, '0x123', 1) + + const result = manager.validateInitialState(state, '0x123') + + expect(result.isValid).toBe(false) + expect(result.error).toBe('Wallet connection state invalid') + }) + + it('should reject state with no address', () => { + const state = manager.captureState(true, undefined, 1) + + const result = manager.validateInitialState(state, '0x123') + + expect(result.isValid).toBe(false) + expect(result.error).toBe('Wallet connection state invalid') + }) + + it('should reject address mismatch (case-sensitive)', () => { + const state = manager.captureState(true, '0x123', 1) + + const result = manager.validateInitialState(state, '0x456') + + expect(result.isValid).toBe(false) + expect(result.error).toBe('Wallet address mismatch') + }) + + it('should handle case-insensitive address matching', () => { + const state = manager.captureState(true, '0x123ABC', 1) + + const result = manager.validateInitialState(state, '0x123abc') + + expect(result.isValid).toBe(true) + }) + + it('should reject state with no chainId', () => { + const state = manager.captureState(true, '0x123', undefined) + + const result = manager.validateInitialState(state, '0x123') + + expect(result.isValid).toBe(false) + expect(result.error).toBe('ChainId not found') + }) + }) + + describe('resetSequence', () => { + it('should reset sequence counter', () => { + const state1 = manager.captureState(true, '0x123', 1) + expect(state1.sequenceNumber).toBe(1) + + manager.resetSequence() + + const state2 = manager.captureState(true, '0x123', 1) + expect(state2.sequenceNumber).toBe(1) // Reset back to 1 + }) + }) + + describe('singleton instance', () => { + it('should provide a singleton instance', () => { + expect(connectionStateManager).toBeInstanceOf(ConnectionStateManager) + + const state1 = connectionStateManager.captureState(true, '0x123', 1) + const state2 = connectionStateManager.captureState(true, '0x456', 2) + + expect(state2.sequenceNumber).toBe(state1.sequenceNumber + 1) + }) + }) +}) diff --git a/apps/mobile/src/utils/connectionStateManager.ts b/apps/mobile/src/utils/connectionStateManager.ts new file mode 100644 index 0000000..11f42a1 --- /dev/null +++ b/apps/mobile/src/utils/connectionStateManager.ts @@ -0,0 +1,84 @@ +export interface AtomicConnectionState { + isConnected: boolean + address: string | undefined + chainId: number | undefined + timestamp: number + sequenceNumber: number +} + +export class ConnectionStateManager { + private sequenceCounter = 0 + + /** + * Captures the current connection state as an atomic snapshot + */ + captureState(isConnected: boolean, address: string | undefined, chainId: number | undefined): AtomicConnectionState { + const sequenceNumber = ++this.sequenceCounter + return { + isConnected, + address, + chainId, + timestamp: Date.now(), + sequenceNumber, + } + } + + /** + * Validates that the connection state hasn't changed since the locked state + */ + validateState(lockedState: AtomicConnectionState, currentState: AtomicConnectionState, checkPoint: string): boolean { + const isValid = + currentState.isConnected === lockedState.isConnected && + currentState.address === lockedState.address && + currentState.chainId === lockedState.chainId && + currentState.sequenceNumber >= lockedState.sequenceNumber + + if (!isValid) { + console.log(`โŒ Connection state changed at ${checkPoint}:`, { + locked: lockedState, + current: currentState, + sequenceDrift: currentState.sequenceNumber - lockedState.sequenceNumber, + }) + } + + return isValid + } + + /** + * Validates initial connection state for authentication + */ + validateInitialState(state: AtomicConnectionState, walletAddress: string): { isValid: boolean; error?: string } { + if (!state.isConnected || !state.address) { + return { + isValid: false, + error: 'Wallet connection state invalid', + } + } + + if (state.address.toLowerCase() !== walletAddress.toLowerCase()) { + return { + isValid: false, + error: 'Wallet address mismatch', + } + } + + if (!state.chainId) { + return { + isValid: false, + error: 'ChainId not found', + } + } + + return { isValid: true } + } + + /** + * Resets the sequence counter (useful for testing) + */ + resetSequence(): void { + this.sequenceCounter = 0 + } +} + +// Singleton instance +export const connectionStateManager = new ConnectionStateManager() diff --git a/apps/mobile/src/utils/errorHandling.ts b/apps/mobile/src/utils/errorHandling.ts new file mode 100644 index 0000000..b9140ca --- /dev/null +++ b/apps/mobile/src/utils/errorHandling.ts @@ -0,0 +1,97 @@ +// Error types for better error handling and user feedback +export enum ErrorType { + WALLET_CONNECTION = 'WALLET_CONNECTION', + SIGNATURE_REJECTED = 'SIGNATURE_REJECTED', + NETWORK_ERROR = 'NETWORK_ERROR', + AUTHENTICATION_FAILED = 'AUTHENTICATION_FAILED', + BACKEND_ERROR = 'BACKEND_ERROR', + UNKNOWN_ERROR = 'UNKNOWN_ERROR', +} + +export interface AppError extends Error { + type: ErrorType + originalError?: unknown + userFriendlyMessage: string +} + +// Error message mappings for user-friendly display +export const ERROR_MESSAGES: Record = { + [ErrorType.WALLET_CONNECTION]: 'Failed to connect to wallet. Please try again.', + [ErrorType.SIGNATURE_REJECTED]: 'Authentication was cancelled. You can try connecting again when ready.', + [ErrorType.NETWORK_ERROR]: 'Network error. Please check your connection and try again.', + [ErrorType.AUTHENTICATION_FAILED]: 'Authentication failed. Please try connecting your wallet again.', + [ErrorType.BACKEND_ERROR]: 'Server error. Please try again in a moment.', + [ErrorType.UNKNOWN_ERROR]: 'Something went wrong. Please try again.', +} + +// Helper function to create structured app errors +export function createAppError(type: ErrorType, message: string, originalError?: unknown): AppError { + const error = new Error(message) as AppError + error.type = type + error.originalError = originalError + error.userFriendlyMessage = ERROR_MESSAGES[type] + return error +} + +// Function to categorize and handle different error types +export function categorizeError(error: unknown): AppError { + if (error && typeof error === 'object' && 'type' in error) { + return error as AppError + } + + const errorMessage = error instanceof Error ? error.message : String(error) + const lowerMessage = errorMessage.toLowerCase() + + // Categorize based on error message content + if (lowerMessage.includes('user rejected') || lowerMessage.includes('user denied')) { + return createAppError(ErrorType.SIGNATURE_REJECTED, errorMessage, error) + } + + if (lowerMessage.includes('no matching key') || lowerMessage.includes('session')) { + return createAppError(ErrorType.WALLET_CONNECTION, 'Wallet session expired. Please reconnect your wallet.', error) + } + + if (lowerMessage.includes('chainid not found') || (lowerMessage.includes('chain') && lowerMessage.includes('not found'))) { + return createAppError(ErrorType.WALLET_CONNECTION, 'Unsupported network. Please switch to a supported chain.', error) + } + + if (lowerMessage.includes('connectornotconnectederror') || lowerMessage.includes('connector not connected')) { + return createAppError(ErrorType.SIGNATURE_REJECTED, 'Connection was closed. Please try connecting again.', error) + } + + if (lowerMessage.includes('network') || lowerMessage.includes('fetch')) { + return createAppError(ErrorType.NETWORK_ERROR, errorMessage, error) + } + + if (lowerMessage.includes('wallet') || lowerMessage.includes('connection') || lowerMessage.includes('connector')) { + return createAppError(ErrorType.WALLET_CONNECTION, errorMessage, error) + } + + if ( + lowerMessage.includes('signature format') || + lowerMessage.includes('invalid signature') || + (lowerMessage.includes('signature') && lowerMessage.includes('invalid')) + ) { + return createAppError(ErrorType.AUTHENTICATION_FAILED, 'Signature validation failed. Please try connecting again.', error) + } + + if (lowerMessage.includes('auth') || lowerMessage.includes('token')) { + return createAppError(ErrorType.AUTHENTICATION_FAILED, errorMessage, error) + } + + if (lowerMessage.includes('functions') || lowerMessage.includes('firebase')) { + return createAppError(ErrorType.BACKEND_ERROR, errorMessage, error) + } + + return createAppError(ErrorType.UNKNOWN_ERROR, errorMessage, error) +} + +// Helper to check if error is user-initiated (like canceling a signature) +export function isUserInitiatedError(error: AppError): boolean { + return error.type === ErrorType.SIGNATURE_REJECTED +} + +// Helper to check if error should be retried automatically +export function shouldRetryError(error: AppError): boolean { + return error.type === ErrorType.NETWORK_ERROR || error.type === ErrorType.BACKEND_ERROR +} diff --git a/apps/mobile/src/utils/sessionManager.ts b/apps/mobile/src/utils/sessionManager.ts new file mode 100644 index 0000000..098d941 --- /dev/null +++ b/apps/mobile/src/utils/sessionManager.ts @@ -0,0 +1,261 @@ +import AsyncStorage from '@react-native-async-storage/async-storage' + +const WALLETCONNECT_SESSION_KEY = '@walletconnect/client0.3//session' +const REOWN_APPKIT_SESSION_KEY = '@reown/appkit' + +// Type definitions for session data +type SessionDataValue = string | number | boolean | null | object | undefined +type SessionData = Record + +interface SessionDebugInfo { + totalKeys: number + walletConnectKeys: string[] + sessionData: SessionData +} + +export class SessionManager { + static async clearAllWalletConnectSessions(): Promise { + try { + console.log('๐Ÿงน Starting comprehensive WalletConnect session cleanup...') + + // Get all AsyncStorage keys + const allKeys = await AsyncStorage.getAllKeys() + + // More comprehensive filter for WalletConnect/Reown related keys + const walletConnectKeys = allKeys.filter((key) => { + const lowerKey = key.toLowerCase() + return ( + // Standard WalletConnect patterns + lowerKey.includes('walletconnect') || + lowerKey.includes('wc@2') || + lowerKey.includes('reown') || + lowerKey.includes('appkit') || + lowerKey.includes('walletconnect') || + lowerKey.includes('wc_') || + lowerKey.startsWith('@walletconnect') || + lowerKey.startsWith('@reown') || + // Session-specific patterns + lowerKey.includes('session') || + lowerKey.includes('pairing') || + lowerKey.includes('client') || + // Protocol patterns + lowerKey.includes('wc:') || + lowerKey.includes('relay') || + // Storage patterns + lowerKey.includes('wagmi') || + lowerKey.includes('viem') || + // AppKit specific + lowerKey.includes('w3m') || + lowerKey.includes('modal') + ) + }) + + console.log(`Found ${walletConnectKeys.length} WalletConnect-related keys:`, walletConnectKeys.slice(0, 10)) + + // Clear all WalletConnect related keys in batches + if (walletConnectKeys.length > 0) { + const batchSize = 20 + for (let i = 0; i < walletConnectKeys.length; i += batchSize) { + const batch = walletConnectKeys.slice(i, i + batchSize) + await AsyncStorage.multiRemove(batch) + console.log(`Cleared batch ${Math.floor(i / batchSize) + 1}: ${batch.length} keys`) + } + console.log(`โœ… Cleared ${walletConnectKeys.length} WalletConnect session keys`) + } + + // Clear specific known problematic keys + const specificKeys = [ + WALLETCONNECT_SESSION_KEY, + REOWN_APPKIT_SESSION_KEY, + 'wagmi.store', + 'wagmi.cache', + 'wagmi.injected.shimConnected', + 'wagmi.wallet', + 'wagmi.connected', + 'reown.sessions', + 'wc.pairing', + 'wc.session', + 'wc.client', + 'w3m.wallet', + 'w3m.session', + '@w3m/wallet_id', + '@w3m/connected_wallet_image_url', + '@walletconnect/universal_provider', + '@walletconnect/ethereum_provider', + ] + + console.log('๐ŸŽฏ Clearing specific known keys...') + for (const key of specificKeys) { + try { + await AsyncStorage.removeItem(key) + } catch (error) { + // Ignore errors for non-existent keys + } + } + + // Clear any keys containing the specific session ID from the error + const sessionIdPattern = /[a-f0-9]{64}/g + const keysWithSessionIds = allKeys.filter((key) => sessionIdPattern.test(key)) + if (keysWithSessionIds.length > 0) { + console.log(`๐Ÿ” Found ${keysWithSessionIds.length} keys with session IDs, clearing...`) + await AsyncStorage.multiRemove(keysWithSessionIds) + } + + console.log('โœ… Successfully completed comprehensive WalletConnect session cleanup') + } catch (error) { + console.error('โŒ Failed to clear WalletConnect sessions:', error) + throw error + } + } + + static async getSessionDebugInfo(): Promise { + try { + const allKeys = await AsyncStorage.getAllKeys() + const walletConnectKeys = allKeys.filter( + (key) => + key.includes('walletconnect') || + key.includes('wc@2') || + key.includes('reown') || + key.includes('appkit') || + key.includes('WALLETCONNECT') || + key.includes('WC_') || + key.startsWith('@walletconnect') || + key.startsWith('@reown') + ) + + const sessionData: SessionData = {} + + // Get data for each WalletConnect key (for debugging) + for (const key of walletConnectKeys.slice(0, 5)) { + // Limit to first 5 for performance + try { + const data = await AsyncStorage.getItem(key) + sessionData[key] = data ? JSON.parse(data) : null + } catch (error) { + sessionData[key] = 'Failed to parse' + } + } + + return { + totalKeys: allKeys.length, + walletConnectKeys, + sessionData, + } + } catch (error) { + console.error('Failed to get session debug info:', error) + return { + totalKeys: 0, + walletConnectKeys: [], + sessionData: {}, + } + } + } + + static async clearSpecificSession(sessionId: string): Promise { + try { + console.log(`Clearing specific session: ${sessionId}`) + + const allKeys = await AsyncStorage.getAllKeys() + const sessionKeys = allKeys.filter((key) => key.includes(sessionId)) + + if (sessionKeys.length > 0) { + await AsyncStorage.multiRemove(sessionKeys) + console.log(`Cleared ${sessionKeys.length} keys for session ${sessionId}`) + } + } catch (error) { + console.error(`Failed to clear session ${sessionId}:`, error) + throw error + } + } + + static async hasValidSession(): Promise { + try { + const debugInfo = await this.getSessionDebugInfo() + + // Check if we have any active WalletConnect sessions + const hasActiveSession = debugInfo.walletConnectKeys.length > 0 + + console.log('Session validation result:', { + hasActiveSession, + keyCount: debugInfo.walletConnectKeys.length, + keys: debugInfo.walletConnectKeys.slice(0, 3), // Show first 3 for debugging + }) + + return hasActiveSession + } catch (error) { + console.error('Failed to validate session:', error) + return false + } + } + + static async forceResetAllConnections(): Promise { + try { + console.log('๐Ÿ”„ Force resetting all wallet connections...') + + // Clear all sessions + await this.clearAllWalletConnectSessions() + + // Clear any remaining cache data + await this.clearQueryCache() + + // Force reload app state (if needed) + console.log('โœ… All connections force reset completed') + } catch (error) { + console.error('โŒ Failed to force reset connections:', error) + throw error + } + } + + static async clearQueryCache(): Promise { + try { + // Clear TanStack Query cache keys that might hold stale connection data + const allKeys = await AsyncStorage.getAllKeys() + const queryCacheKeys = allKeys.filter((key) => key.includes('react-query') || key.includes('tanstack') || key.includes('query-cache')) + + if (queryCacheKeys.length > 0) { + await AsyncStorage.multiRemove(queryCacheKeys) + console.log(`Cleared ${queryCacheKeys.length} query cache keys`) + } + } catch (error) { + console.warn('Failed to clear query cache:', error) + } + } + + static async clearSessionByErrorId(sessionId: string): Promise { + try { + console.log(`๐ŸŽฏ Clearing sessions containing ID: ${sessionId}`) + + const allKeys = await AsyncStorage.getAllKeys() + const sessionKeys = allKeys.filter((key) => key.includes(sessionId)) + + if (sessionKeys.length > 0) { + console.log(`Found ${sessionKeys.length} keys with session ID:`, sessionKeys) + await AsyncStorage.multiRemove(sessionKeys) + console.log(`โœ… Cleared ${sessionKeys.length} keys for session ${sessionId}`) + } else { + console.log('No keys found with that session ID') + } + } catch (error) { + console.error(`Failed to clear session ${sessionId}:`, error) + throw error + } + } + + static async preventiveSessionCleanup(): Promise { + try { + console.log('๐Ÿ›ก๏ธ Running preventive session cleanup before connection...') + + // Multiple cleanup approaches + await this.clearAllWalletConnectSessions() + await this.clearQueryCache() + + // Wait a moment for cleanup to settle + await new Promise((resolve) => setTimeout(resolve, 500)) + + console.log('โœ… Preventive session cleanup completed') + } catch (error) { + console.error('โŒ Preventive session cleanup failed:', error) + throw error + } + } +} diff --git a/apps/mobile/src/utils/toast.ts b/apps/mobile/src/utils/toast.ts new file mode 100644 index 0000000..8c55f90 --- /dev/null +++ b/apps/mobile/src/utils/toast.ts @@ -0,0 +1,153 @@ +import Toast from 'react-native-toast-message' +import { AppError, ErrorType } from './errorHandling' + +export type ToastType = 'success' | 'error' | 'info' | 'warning' + +interface ToastOptions { + title?: string + message: string + duration?: number + position?: 'top' | 'bottom' +} + +// Base toast function with custom styling +function showToast(type: ToastType, { title, message, duration = 4000, position = 'top' }: ToastOptions) { + Toast.show({ + type, + text1: title, + text2: message, + position, + visibilityTime: duration, + autoHide: true, + topOffset: 60, + bottomOffset: 60, + }) +} + +// Success toast for positive feedback +export function showSuccessToast(options: ToastOptions) { + showToast('success', options) +} + +// Error toast for error feedback +export function showErrorToast(options: ToastOptions) { + showToast('error', options) +} + +// Info toast for general information +export function showInfoToast(options: ToastOptions) { + showToast('info', options) +} + +// Warning toast for warnings +export function showWarningToast(options: ToastOptions) { + showToast('warning', options) +} + +// Specialized function to show error from AppError +export function showErrorFromAppError(error: AppError) { + const title = getErrorTitle(error.type) + + showErrorToast({ + title, + message: error.userFriendlyMessage, + duration: getErrorDuration(error.type), + }) +} + +// Get appropriate title for error type +function getErrorTitle(errorType: ErrorType): string { + switch (errorType) { + case ErrorType.WALLET_CONNECTION: + return 'Connection Failed' + case ErrorType.SIGNATURE_REJECTED: + return 'Signature Rejected' + case ErrorType.NETWORK_ERROR: + return 'Network Error' + case ErrorType.AUTHENTICATION_FAILED: + return 'Authentication Failed' + case ErrorType.BACKEND_ERROR: + return 'Server Error' + case ErrorType.UNKNOWN_ERROR: + default: + return 'Error' + } +} + +// Get appropriate duration for error type +function getErrorDuration(errorType: ErrorType): number { + switch (errorType) { + case ErrorType.SIGNATURE_REJECTED: + return 3000 // Shorter for user-initiated actions + case ErrorType.NETWORK_ERROR: + case ErrorType.BACKEND_ERROR: + return 5000 // Longer for technical issues + default: + return 4000 // Standard duration + } +} + +// Authentication-specific toast helpers with extended durations for wallet app switching +export const authToasts = { + connecting: () => + showInfoToast({ + title: 'Connecting', + message: 'Please sign the message to authenticate...', + duration: 12000, // Extended for wallet app switching + }), + + success: () => + showSuccessToast({ + title: 'Welcome!', + message: 'Successfully authenticated and signed in.', + duration: 4000, + }), + + signingMessage: () => + showInfoToast({ + title: 'Sign Message', + message: + 'Check your wallet app to sign the authentication message. If you don\'t see a signature request, try switching back and forth between apps.', + duration: 15000, // Extended for wallet app switching scenarios + }), + + verifying: () => + showInfoToast({ + title: 'Verifying', + message: 'Verifying your signature...', + duration: 8000, // Extended for potential delays + }), + + // New toast for wallet app guidance + walletAppGuidance: () => + showInfoToast({ + title: 'Wallet App Required', + message: 'Authentication requires your wallet app. You may need to switch between apps to complete the process.', + duration: 10000, + }), + + // Session error toast for WalletConnect issues + sessionError: () => + showErrorToast({ + title: 'Connection Issue', + message: 'Wallet session expired. Please reconnect your wallet to continue.', + duration: 5000, + }), +} + +// General app toast helpers +export const appToasts = { + walletConnected: (walletName?: string) => + showSuccessToast({ + title: 'Wallet Connected', + message: walletName ? `Connected to ${walletName}` : 'Wallet connected successfully', + duration: 3000, + }), + + walletDisconnected: () => + showInfoToast({ + title: 'Wallet Disconnected', + message: 'Your wallet has been disconnected.', + duration: 3000, + }), +} diff --git a/apps/mobile/tsconfig.json b/apps/mobile/tsconfig.json new file mode 100644 index 0000000..a20587f --- /dev/null +++ b/apps/mobile/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "strict": true, + "paths": { + "@firebase/auth": ["../../node_modules/@firebase/auth/dist/index.rn.d.ts"] + } + }, + "extends": "expo/tsconfig.base" +} diff --git a/dev-start.js b/dev-start.js new file mode 100644 index 0000000..6530444 --- /dev/null +++ b/dev-start.js @@ -0,0 +1,319 @@ +#!/usr/bin/env node + +const { spawn, exec } = require('child_process'); +const fs = require('fs'); +const path = require('path'); +const http = require('http'); + +class DevEnvironment { + constructor() { + this.processes = []; + this.ngrokUrls = {}; + this.isShuttingDown = false; + + // Setup cleanup on exit + process.on('SIGINT', () => this.cleanup()); + process.on('SIGTERM', () => this.cleanup()); + process.on('exit', () => this.cleanup()); + } + + log(message, type = 'info') { + const timestamp = new Date().toLocaleTimeString(); + const colors = { + info: '\x1b[36m', // Cyan + success: '\x1b[32m', // Green + warning: '\x1b[33m', // Yellow + error: '\x1b[31m', // Red + reset: '\x1b[0m' // Reset + }; + + console.log(`${colors[type]}[${timestamp}] ${message}${colors.reset}`); + } + + async sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + async checkPrerequisites() { + this.log('Checking prerequisites...'); + + const checks = [ + { command: 'firebase --version', name: 'Firebase CLI' }, + { command: 'ngrok version', name: 'Ngrok' }, + { command: 'pnpm --version', name: 'PNPM' } + ]; + + for (const check of checks) { + try { + await this.execAsync(check.command); + this.log(`โœ“ ${check.name} is installed`, 'success'); + } catch (error) { + this.log(`โœ— ${check.name} is not installed or not in PATH`, 'error'); + throw new Error(`Missing prerequisite: ${check.name}`); + } + } + } + + execAsync(command) { + return new Promise((resolve, reject) => { + exec(command, (error, stdout, stderr) => { + if (error) reject(error); + else resolve(stdout); + }); + }); + } + + spawnProcess(command, args, options = {}) { + const proc = spawn(command, args, { + stdio: options.silent ? 'pipe' : 'inherit', + shell: true, + ...options + }); + + this.processes.push(proc); + return proc; + } + + async startFirebaseEmulators() { + this.log('Starting Firebase Emulators...'); + + const firebaseProc = this.spawnProcess('firebase', ['emulators:start'], { + cwd: process.cwd() + }); + + // Wait for emulators to be ready + this.log('Waiting for Firebase Emulators to start...'); + + let attempts = 0; + const maxAttempts = 30; // 30 seconds + + while (attempts < maxAttempts) { + try { + // Check if Auth emulator is ready + await this.checkPort(9099); + // Check if Functions emulator is ready + await this.checkPort(5001); + // Check if Firestore emulator is ready + await this.checkPort(8080); + + this.log('Firebase Emulators are ready!', 'success'); + break; + } catch (error) { + attempts++; + if (attempts >= maxAttempts) { + throw new Error('Firebase Emulators failed to start within 30 seconds'); + } + await this.sleep(1000); + } + } + + return firebaseProc; + } + + async checkPort(port) { + return new Promise((resolve, reject) => { + const req = http.request({ + hostname: 'localhost', + port: port, + method: 'GET', + timeout: 1000 + }, (res) => { + resolve(true); + }); + + req.on('error', reject); + req.on('timeout', reject); + req.end(); + }); + } + + async startNgrok() { + this.log('Starting Ngrok tunnels...'); + + const ngrokProc = this.spawnProcess('ngrok', ['start', '--all'], { + silent: true + }); + + // Wait for ngrok to establish tunnels + this.log('Waiting for Ngrok tunnels to establish...'); + await this.sleep(5000); + + // Get tunnel URLs from ngrok API + await this.fetchNgrokUrls(); + + this.log('Ngrok tunnels established!', 'success'); + Object.entries(this.ngrokUrls).forEach(([service, url]) => { + this.log(` ${service}: ${url}`, 'info'); + }); + + return ngrokProc; + } + + async fetchNgrokUrls() { + try { + const response = await this.httpGet('http://localhost:4040/api/tunnels'); + const data = JSON.parse(response); + + // Map tunnels by their local port to service names + const portToService = { + '9099': 'auth', + '5001': 'functions', + '8080': 'firestore' + }; + + data.tunnels.forEach(tunnel => { + const localPort = tunnel.config.addr.split(':').pop(); + const serviceName = portToService[localPort]; + + if (serviceName && tunnel.public_url.startsWith('https://')) { + // Extract just the domain part for the URLs + const urlParts = tunnel.public_url.replace('https://', '').split('/'); + this.ngrokUrls[serviceName] = urlParts[0]; + } + }); + + } catch (error) { + this.log('Failed to fetch ngrok URLs from API, will use placeholder values', 'warning'); + // Fallback to placeholder values that user can update manually + this.ngrokUrls = { + auth: 'your-auth-tunnel.ngrok-free.app', + functions: 'your-functions-tunnel.ngrok-free.app', + firestore: 'your-firestore-tunnel.ngrok-free.app' + }; + } + } + + httpGet(url) { + return new Promise((resolve, reject) => { + http.get(url, (res) => { + let data = ''; + res.on('data', (chunk) => data += chunk); + res.on('end', () => resolve(data)); + }).on('error', reject); + }); + } + + async updateEnvironmentFile() { + this.log('Updating mobile app environment variables...'); + + const envPath = path.join(process.cwd(), 'apps', 'mobile', '.env'); + + if (!fs.existsSync(envPath)) { + this.log('Environment file not found, creating from template...', 'warning'); + return; + } + + let envContent = fs.readFileSync(envPath, 'utf8'); + + // Update ngrok URLs + envContent = envContent.replace( + /EXPO_PUBLIC_NGROK_URL_AUTH="[^"]*"/, + `EXPO_PUBLIC_NGROK_URL_AUTH="https://${this.ngrokUrls.auth}"` + ); + + envContent = envContent.replace( + /EXPO_PUBLIC_NGROK_URL_FUNCTIONS="[^"]*"/, + `EXPO_PUBLIC_NGROK_URL_FUNCTIONS="${this.ngrokUrls.functions}"` + ); + + envContent = envContent.replace( + /EXPO_PUBLIC_NGROK_URL_FIRESTORE="[^"]*"/, + `EXPO_PUBLIC_NGROK_URL_FIRESTORE="${this.ngrokUrls.firestore}"` + ); + + // Update Cloud Functions URL - only replace the ngrok domain, preserve project ID and zone + envContent = envContent.replace( + /EXPO_PUBLIC_CLOUD_FUNCTIONS_BASE_URL="http:\/\/[^\/]+\/(.*?)"/, + `EXPO_PUBLIC_CLOUD_FUNCTIONS_BASE_URL="http://${this.ngrokUrls.functions}/$1"` + ); + + fs.writeFileSync(envPath, envContent); + this.log('Environment file updated successfully!', 'success'); + } + + async startExpoApp() { + this.log('Starting Expo development server...'); + + const expoProc = this.spawnProcess('pnpm', ['start'], { + cwd: path.join(process.cwd(), 'apps', 'mobile') + }); + + this.log('Expo development server started!', 'success'); + return expoProc; + } + + async cleanup() { + if (this.isShuttingDown) return; + this.isShuttingDown = true; + + this.log('Shutting down development environment...', 'warning'); + + // Kill all spawned processes + this.processes.forEach((proc, index) => { + if (!proc.killed) { + this.log(`Terminating process ${index + 1}...`); + proc.kill('SIGTERM'); + } + }); + + // Wait a bit for graceful shutdown + await this.sleep(2000); + + // Force kill if still running + this.processes.forEach((proc, index) => { + if (!proc.killed) { + this.log(`Force killing process ${index + 1}...`); + proc.kill('SIGKILL'); + } + }); + + this.log('Development environment stopped.', 'success'); + process.exit(0); + } + + async start() { + try { + this.log('๐Ÿš€ Starting SuperPool Development Environment', 'success'); + this.log(''); + + await this.checkPrerequisites(); + this.log(''); + + await this.startFirebaseEmulators(); + this.log(''); + + await this.startNgrok(); + this.log(''); + + await this.updateEnvironmentFile(); + this.log(''); + + await this.startExpoApp(); + this.log(''); + + this.log('๐ŸŽ‰ Development environment is ready!', 'success'); + this.log(''); + this.log('Available services:'); + this.log(` Firebase Auth Emulator: http://localhost:9099`); + this.log(` Firebase Functions Emulator: http://localhost:5001`); + this.log(` Firebase Firestore Emulator: http://localhost:8080`); + this.log(` Firebase Emulator UI: http://localhost:4000`); + this.log(''); + this.log('Ngrok Tunnels:'); + Object.entries(this.ngrokUrls).forEach(([service, url]) => { + this.log(` ${service.charAt(0).toUpperCase() + service.slice(1)}: https://${url}`); + }); + this.log(''); + this.log('Press Ctrl+C to stop all services'); + + } catch (error) { + this.log(`Failed to start development environment: ${error.message}`, 'error'); + await this.cleanup(); + process.exit(1); + } + } +} + +// Start the development environment +const devEnv = new DevEnvironment(); +devEnv.start(); \ No newline at end of file diff --git a/firebase.json b/firebase.json new file mode 100644 index 0000000..e94e322 --- /dev/null +++ b/firebase.json @@ -0,0 +1,40 @@ +{ + "firestore": { + "database": "(default)", + "location": "eur3", + "rules": "firestore.rules", + "indexes": "firestore.indexes.json" + }, + "functions": [ + { + "source": "packages/backend", + "codebase": "default", + "ignore": [ + "node_modules", + ".git", + "firebase-debug.log", + "firebase-debug.*.log", + "*.local" + ], + "predeploy": [ + "npm --prefix \"$RESOURCE_DIR\" run lint", + "npm --prefix \"$RESOURCE_DIR\" run build" + ] + } + ], + "emulators": { + "auth": { + "port": 9099 + }, + "functions": { + "port": 5001 + }, + "firestore": { + "port": 8080 + }, + "ui": { + "enabled": true + }, + "singleProjectMode": true + } +} \ No newline at end of file diff --git a/firestore.indexes.json b/firestore.indexes.json new file mode 100644 index 0000000..2ddb5ce --- /dev/null +++ b/firestore.indexes.json @@ -0,0 +1,4 @@ +{ + "indexes": [], + "fieldOverrides": [] +} \ No newline at end of file diff --git a/firestore.rules b/firestore.rules new file mode 100644 index 0000000..862a335 --- /dev/null +++ b/firestore.rules @@ -0,0 +1,18 @@ +rules_version='2' + +service cloud.firestore { + match /databases/{database}/documents { + match /{document=**} { + // This rule allows anyone with your database reference to view, edit, + // and delete all data in your database. It is useful for getting + // started, but it is configured to expire after 30 days because it + // leaves your app open to attackers. At that time, all client + // requests to your database will be denied. + // + // Make sure to write security rules for your app before that time, or + // else all client requests to your database will be denied until you + // update your rules. + allow read, write: if request.time < timestamp.date(2025, 8, 30); + } + } +} diff --git a/ngrok.yml.template b/ngrok.yml.template new file mode 100644 index 0000000..58a8f8a --- /dev/null +++ b/ngrok.yml.template @@ -0,0 +1,42 @@ +# Ngrok Configuration Template for SuperPool Development +# +# To use this configuration: +# 1. Copy this file to ngrok.yml: cp ngrok.yml.template ngrok.yml +# 2. Sign up for ngrok account at https://ngrok.com/ +# 3. Get your authtoken from https://dashboard.ngrok.com/get-started/your-authtoken +# 4. Replace YOUR_AUTHTOKEN_HERE with your actual authtoken in ngrok.yml +# 5. Run: pnpm dev (or ngrok start --all) +# +# This will create tunnels for all Firebase emulators used in SuperPool development + +version: "2" +authtoken: YOUR_AUTHTOKEN_HERE + +tunnels: + # Firebase Auth Emulator (port 9099) + auth: + addr: 9099 + proto: http + inspect: false + bind_tls: true + + # Firebase Functions Emulator (port 5001) + functions: + addr: 5001 + proto: http + inspect: false + bind_tls: true + + # Firebase Firestore Emulator (port 8080) + firestore: + addr: 8080 + proto: http + inspect: false + bind_tls: true + +# Optional: Configure logging +log_level: info +log_format: term + +# Optional: Configure web interface (default port 4040) +web_addr: localhost:4040 \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..90fa432 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "superpool", + "version": "1.0.0", + "description": "Monorepo for the SuperPool dApp", + "private": true, + "main": "index.js", + "scripts": { + "dev": "node dev-start.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.12.4", + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "eslint": "^8.57.1" + } +} \ No newline at end of file diff --git a/packages/backend/.eslintrc.cjs b/packages/backend/.eslintrc.cjs new file mode 100644 index 0000000..a8b8e8c --- /dev/null +++ b/packages/backend/.eslintrc.cjs @@ -0,0 +1,6 @@ +module.exports = { + root: true, + parserOptions: { + project: ['../../tsconfig.json'], + }, +}; \ No newline at end of file diff --git a/packages/backend/.gitignore b/packages/backend/.gitignore new file mode 100644 index 0000000..16cea9e --- /dev/null +++ b/packages/backend/.gitignore @@ -0,0 +1,20 @@ +# Compiled JavaScript files +lib/**/*.js +lib/**/*.js.map + +# TypeScript v1 declaration files +typings/ + +# Node.js dependency directory +node_modules/ +*.local + +# Firebase Service Account Key +service-account-key.json + +# Generated development keys +privateKey.pem +publicKey.pem + +# Test coverage reports +/coverage \ No newline at end of file diff --git a/packages/backend/jest.config.ts b/packages/backend/jest.config.ts new file mode 100644 index 0000000..79dc3b4 --- /dev/null +++ b/packages/backend/jest.config.ts @@ -0,0 +1,27 @@ +import type { Config } from 'jest' +import { createDefaultPreset } from 'ts-jest' + +const config: Config = { + // Use ts-jest as the preset + preset: 'ts-jest', + + // Specify the test environment (e.g., Node.js) + testEnvironment: 'node', + + // Tell Jest where to find your test files + testMatch: ['**/*.test.ts'], + + // Ignore files in the lib folder + testPathIgnorePatterns: ['/lib/'], + + // Enable collection of test coverage + collectCoverage: true, + + // Specify where to collect coverage from + collectCoverageFrom: ['/src/**/*.ts'], + + // Add the ts-jest default preset + ...createDefaultPreset(), +} + +export default config diff --git a/packages/backend/package.json b/packages/backend/package.json new file mode 100644 index 0000000..f8509f4 --- /dev/null +++ b/packages/backend/package.json @@ -0,0 +1,36 @@ +{ + "name": "backend", + "scripts": { + "lint": "eslint --ext .js,.ts .", + "build": "tsc", + "build:watch": "tsc --watch", + "serve": "npm run build && firebase emulators:start --only functions", + "shell": "npm run build && firebase functions:shell", + "start": "npm run shell", + "deploy": "firebase deploy --only functions", + "logs": "firebase functions:log", + "generateKey": "ts-node ./scripts/generateKey.ts", + "signMessage": "ts-node ./scripts/signMessage.ts", + "test": "jest" + }, + "engines": { + "node": "22" + }, + "main": "lib/index.js", + "dependencies": { + "dotenv": "^17.2.1", + "ethers": "^6.15.0", + "firebase-admin": "^12.7.0", + "firebase-functions": "^6.4.0", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@types/jest": "^30.0.0", + "firebase-functions-test": "^3.4.1", + "jest": "^30.0.5", + "ts-jest": "^29.4.1", + "ts-node": "^10.9.2", + "typescript": "^5.7.3" + }, + "private": true +} \ No newline at end of file diff --git a/packages/backend/scripts/generateKey.ts b/packages/backend/scripts/generateKey.ts new file mode 100644 index 0000000..c1ad7ba --- /dev/null +++ b/packages/backend/scripts/generateKey.ts @@ -0,0 +1,40 @@ +import { ethers } from 'ethers' +import fs from 'fs' +import path from 'path' + +// Generate a new random wallet +const newWallet = ethers.Wallet.createRandom() + +// Get the private key string +const privateKey = newWallet.privateKey + +// Get the public key. The 'publicKey' property is the uncompressed public key. +const publicKey = newWallet.publicKey + +// The public key in PEM format is usually derived from the private key. +// ethers.js provides the full public key, but for signature verification, +// we often just need the raw public key string. +// Let's save the public key in a format that our backend can use. + +const privateKeyPath = path.join(__dirname, 'privateKey.pem') +const publicKeyPath = path.join(__dirname, 'publicKey.pem') + +try { + // Save the private key string to a .pem file + fs.writeFileSync(privateKeyPath, privateKey, { encoding: 'utf8' }) + console.log(`โœ… Private key saved to: ${privateKeyPath}`) + + // Save the public key string to a .pem file + fs.writeFileSync(publicKeyPath, publicKey, { encoding: 'utf8' }) + console.log(`โœ… Public key saved to: ${publicKeyPath}`) + + console.log('\n-----------------------------------------') + console.log(' ย  ย  ย  ย  DUMMY KEY PAIR GENERATED ย  ย  ย  ย ') + console.log('-----------------------------------------') + console.log('Address: ย  ', newWallet.address) + console.log('Public Key:', newWallet.publicKey) + console.log('Private Key:', newWallet.privateKey) + console.log('-----------------------------------------') +} catch (error) { + console.error('โŒ An error occurred while writing key files:', error) +} diff --git a/packages/backend/scripts/signMessage.ts b/packages/backend/scripts/signMessage.ts new file mode 100644 index 0000000..2d3e630 --- /dev/null +++ b/packages/backend/scripts/signMessage.ts @@ -0,0 +1,60 @@ +import { Wallet } from 'ethers' +import fs from 'fs' +import path from 'path' + +// Get nonce and timestamp from command line arguments +const args = process.argv.slice(2) +const [nonce, timestamp] = args + +// Check if nonce and timestamp are provided +if (!nonce || !timestamp) { + console.error('โŒ Usage: pnpm signMessage ') + process.exit(1) +} + +// Define the correct path using __dirname +const privateKeyPath = path.join(__dirname, 'privateKey.pem') + +// Add a check to ensure the file exists before reading +if (!fs.existsSync(privateKeyPath)) { + console.error(`โŒ Error: Private key file not found at ${privateKeyPath}.`) + console.error('โŒ Please run "pnpm generateKey" first to create the key pair.') + process.exit(1) +} + +// Read the private key from the generated file +let privateKey: string + +try { + privateKey = fs.readFileSync(privateKeyPath, 'utf8') +} catch (error) { + console.error(`โŒ Error: Could not read private key from ${privateKeyPath}.`) + process.exit(1) +} + +// Create a wallet instance from the private key +const wallet = new Wallet(privateKey) + +// Construct the message to sign +// This message must exactly match the one generated by your backend function. +const messageToSign = + `Welcome to SuperPool!\n\n` + + `This request will not trigger a blockchain transaction.\n\n` + + `Wallet address:\n${wallet.address}\n\n` + + `Nonce:\n${nonce}\n` + + `Timestamp:\n${timestamp}` + +console.log(`Signing message for wallet: ${wallet.address}`) +console.log(`Message: \n${messageToSign}\n`) + +// Sign the message +wallet + .signMessage(messageToSign) + .then((signature) => { + console.log('โœ… Generated Signature:') + console.log(signature) + }) + .catch((error) => { + console.error('โŒ Error signing message:', error) + process.exit(1) + }) diff --git a/packages/backend/src/constants/index.ts b/packages/backend/src/constants/index.ts new file mode 100644 index 0000000..1972dde --- /dev/null +++ b/packages/backend/src/constants/index.ts @@ -0,0 +1,14 @@ +/** + * The name of the Firestore collection used to store authentication nonces. + */ +export const AUTH_NONCES_COLLECTION = 'auth_nonces' + +/** + * The name of the Firestore collection used to store users information. + */ +export const USERS_COLLECTION = 'users' + +/** + * The name of the Firestore collection used to store approved devices. + */ +export const APPROVED_DEVICES_COLLECTION = 'approved_devices' diff --git a/packages/backend/src/functions/app-check/customAppCheckMinter.test.ts b/packages/backend/src/functions/app-check/customAppCheckMinter.test.ts new file mode 100644 index 0000000..ee8addd --- /dev/null +++ b/packages/backend/src/functions/app-check/customAppCheckMinter.test.ts @@ -0,0 +1,185 @@ +import { jest } from '@jest/globals' +import * as express from 'express' +import { AppCheckToken } from 'firebase-admin/app-check' +import { Request } from 'firebase-functions/v2/https' + +// Mock the sub-path 'firebase-admin/firestore' to contain getFirestore +jest.mock('firebase-admin/firestore', () => ({ + getFirestore: jest.fn(), +})) + +// Mock the sub-path 'firebase-admin/app-check' to return getAppCheck() +type CreateTokenFunction = (appId: string, options?: { appId?: string }) => Promise +const mockCreateToken = jest.fn() + +const mockAppCheck = { createToken: mockCreateToken } + +jest.mock('firebase-admin/app-check', () => ({ + getAppCheck: () => mockAppCheck, +})) + +// Mock the root 'firebase-admin' package with all the necessary dependencies +const mockCredential = { + getAccessToken: jest.fn(() => ({ + accessToken: 'mock-access-token', + expirationTime: 123456789, + })), +} + +jest.mock('firebase-admin', () => ({ + initializeApp: jest.fn(), + credential: { cert: () => mockCredential }, +})) + +// Mock the logger to prevent console clutter during tests +const mockLoggerError = jest.fn() +const mockLoggerInfo = jest.fn() +const mockLoggerWarn = jest.fn() + +jest.mock('firebase-functions/v2', () => ({ + logger: { error: mockLoggerError, info: mockLoggerInfo, warn: mockLoggerWarn }, +})) + +// Mock the DeviceVerificationService +const mockIsDeviceApproved = jest.fn() as jest.MockedFunction<(deviceId: string) => Promise> +jest.mock('../../services/deviceVerification', () => ({ + DeviceVerificationService: { + isDeviceApproved: mockIsDeviceApproved, + }, +})) + +const { customAppCheckMinterHandler } = require('./customAppCheckMinter') + +describe('customAppCheckMinterHandler', () => { + const TTL_MILLIS = 1000 * 60 * 60 * 24 + const FIREBASE_APP_ID = 'app-id-test' + + // Use a mocked request and response object + const mockRequest = { method: 'POST' } as Request + const mockResponse = { status: jest.fn(() => mockResponse), send: jest.fn() } as Partial + + beforeEach(() => { + jest.clearAllMocks() + process.env.APP_ID_FIREBASE = FIREBASE_APP_ID + + // Default to approved device for existing tests + mockIsDeviceApproved.mockResolvedValue(true) + }) + + // Test case: Successful token minting (Happy Path) + it('should successfully mint and return an App Check token', async () => { + // Arrange + const testDeviceId = 'device-id-123' + const expectedToken: AppCheckToken = { + token: 'mock-app-check-token', + ttlMillis: 123456789, + } + + mockRequest.body = { deviceId: testDeviceId } + mockCreateToken.mockResolvedValue(expectedToken) + + // Act + await customAppCheckMinterHandler(mockRequest, mockResponse as express.Response) + + // Assert + expect(mockIsDeviceApproved).toHaveBeenCalledWith(testDeviceId) + expect(mockCreateToken).toHaveBeenCalledWith(FIREBASE_APP_ID, { ttlMillis: TTL_MILLIS }) + expect(mockLoggerInfo).toHaveBeenCalledWith('App Check token minted successfully', { deviceId: testDeviceId }) + expect(mockResponse.status).toHaveBeenCalledWith(200) + expect(mockResponse.send).toHaveBeenCalledWith({ appCheckToken: expectedToken.token, expireTimeMillis: expectedToken.ttlMillis }) + }) + + // Test case: Missing Environment Variable + it('should return a 500 error if the App ID env variable is not configured', async () => { + // Arrange + delete process.env.APP_ID_FIREBASE + + // Act + await customAppCheckMinterHandler(mockRequest, mockResponse as express.Response) + + // Assert + expect(mockResponse.status).toHaveBeenCalledWith(500) + expect(mockResponse.send).toHaveBeenCalledWith('Internal Server Error: Firebase App ID not set.') + expect(mockLoggerError).toHaveBeenCalledWith('Firebase App ID is not configured.') + }) + + // Test case: Invalid request method + it('should return a 405 error if the request method is not POST', async () => { + // Arrange + const getRequest = { + ...mockRequest, + method: 'GET', + } as Request + + // Act + await customAppCheckMinterHandler(getRequest, mockResponse as express.Response) + + // Assert + expect(mockResponse.status).toHaveBeenCalledWith(405) + expect(mockResponse.send).toHaveBeenCalledWith('Method Not Allowed') + }) + + // Test case: Invalid request (missing deviceId) + it('should return a 400 error if deviceId is missing from the request body', async () => { + // Arrange + mockRequest.body = {} + + // Act + await customAppCheckMinterHandler(mockRequest, mockResponse as express.Response) + + // Assert + expect(mockResponse.status).toHaveBeenCalledWith(400) + expect(mockResponse.send).toHaveBeenCalledWith('Bad Request: deviceId is required and must be a string.') + }) + + // Test case: Error during token minting + it('should return a 500 error if token creation fails', async () => { + // Arrange + mockRequest.body = { deviceId: 'test-device' } + mockCreateToken.mockRejectedValue(new Error('Admin SDK error')) + + // Act + await customAppCheckMinterHandler(mockRequest, mockResponse as express.Response) + + // Assert + expect(mockResponse.status).toHaveBeenCalledWith(500) + expect(mockResponse.send).toHaveBeenCalledWith('Internal Server Error: Failed to mint App Check token') + expect(mockCreateToken).toHaveBeenCalledTimes(1) + }) + + // Test case: Device not approved (Security) + it('should return a 403 error if device is not approved', async () => { + // Arrange + const testDeviceId = 'unapproved-device-123' + mockRequest.body = { deviceId: testDeviceId } + mockIsDeviceApproved.mockResolvedValue(false) + + // Act + await customAppCheckMinterHandler(mockRequest, mockResponse as express.Response) + + // Assert + expect(mockIsDeviceApproved).toHaveBeenCalledWith(testDeviceId) + expect(mockLoggerWarn).toHaveBeenCalledWith('App Check token requested for unapproved device', { deviceId: testDeviceId }) + expect(mockResponse.status).toHaveBeenCalledWith(403) + expect(mockResponse.send).toHaveBeenCalledWith('Forbidden: Device not approved. Please authenticate with your wallet first.') + expect(mockCreateToken).not.toHaveBeenCalled() + }) + + // Test case: Device verification throws error + it('should return a 403 error if device verification fails', async () => { + // Arrange + const testDeviceId = 'error-device-123' + mockRequest.body = { deviceId: testDeviceId } + mockIsDeviceApproved.mockRejectedValue(new Error('Verification service error')) + + // Act + await customAppCheckMinterHandler(mockRequest, mockResponse as express.Response) + + // Assert + expect(mockIsDeviceApproved).toHaveBeenCalledWith(testDeviceId) + expect(mockLoggerError).toHaveBeenCalledWith('Device verification failed', { error: expect.any(Error), deviceId: testDeviceId }) + expect(mockResponse.status).toHaveBeenCalledWith(403) + expect(mockResponse.send).toHaveBeenCalledWith('Forbidden: Device not approved. Please authenticate with your wallet first.') + expect(mockCreateToken).not.toHaveBeenCalled() + }) +}) diff --git a/packages/backend/src/functions/app-check/customAppCheckMinter.ts b/packages/backend/src/functions/app-check/customAppCheckMinter.ts new file mode 100644 index 0000000..a1bb17c --- /dev/null +++ b/packages/backend/src/functions/app-check/customAppCheckMinter.ts @@ -0,0 +1,99 @@ +import 'firebase-functions/v2/https' + +import * as express from 'express' +import { logger } from 'firebase-functions/v2' +import { onRequest, Request } from 'firebase-functions/v2/https' +import { appCheck } from '../../services' +import { DeviceVerificationService } from '../../services/deviceVerification' + +// Define the interface for the request body +interface CustomAppCheckMinterRequest { + deviceId: string +} + +export const customAppCheckMinterHandler = async (req: Request, res: express.Response) => { + // Check that the App ID is configured + const FIREBASE_APP_ID = process.env.APP_ID_FIREBASE + + if (!FIREBASE_APP_ID) { + logger.error('Firebase App ID is not configured.') + res.status(500).send('Internal Server Error: Firebase App ID not set.') + return + } + + // Validate the Request Method + if (req.method !== 'POST') { + res.status(405).send('Method Not Allowed') + return + } + + // Validate the Request Body + const body = req.body as CustomAppCheckMinterRequest + const { deviceId } = body + + if (!deviceId || typeof deviceId !== 'string') { + res.status(400).send('Bad Request: deviceId is required and must be a string.') + return + } + + // Verify that the device is approved before minting App Check token + try { + const isApproved = await DeviceVerificationService.isDeviceApproved(deviceId) + if (!isApproved) { + logger.warn('App Check token requested for unapproved device', { deviceId }) + res.status(403).send('Forbidden: Device not approved. Please authenticate with your wallet first.') + return + } + } catch (error) { + logger.error('Device verification failed', { error, deviceId }) + res.status(403).send('Forbidden: Device not approved. Please authenticate with your wallet first.') + return + } + + // Use the Firebase Admin SDK to mint the App Check token + try { + // The `createToken` method requires a subject, which we'll use our deviceId for. + const appCheckToken = await appCheck.createToken(FIREBASE_APP_ID, { ttlMillis: 1000 * 60 * 60 * 24 }) + + logger.info('App Check token minted successfully', { deviceId }) + + // Return the token and its expiration to the client + res.status(200).send({ + appCheckToken: appCheckToken.token, + expireTimeMillis: appCheckToken.ttlMillis, + }) + } catch (error) { + logger.error('Failed to mint App Check token', { error, deviceId }) + res.status(500).send('Internal Server Error: Failed to mint App Check token') + } +} + +/** + * Mints an App Check token for a custom provider. + * + * This HTTPS Cloud Function acts as the backend for a custom App Check provider. + * It receives a unique device ID from the client, performs a custom verification + * check on that ID, and if the verification is successful, uses the Firebase + * Admin SDK to mint a new App Check token for the specified Firebase App ID. + * + * @param {express.Request} req The HTTPS request. + * @param {express.Response} res The HTTPS response. + * + * @returns {Promise} A promise that resolves when the response has been sent. + * + * @remarks + * The function expects a POST request with a JSON body containing a 'deviceId' string. + * + * @example + * // Successful response body (HTTP 200) + * { + * "appCheckToken": "your-app-check-token-string", + * "expireTimeMillis": 1678886400000 + * } + * + * @throws {400 Bad Request} If the 'deviceId' is missing or invalid. + * @throws {403 Forbidden} If the custom verification logic fails for the device ID. + * @throws {500 Internal Server Error} For any server-side errors, such as a failure + * to mint the token. + */ +export const customAppCheckMinter = onRequest({ cors: true }, customAppCheckMinterHandler) diff --git a/packages/backend/src/functions/app-check/index.ts b/packages/backend/src/functions/app-check/index.ts new file mode 100644 index 0000000..f3f2049 --- /dev/null +++ b/packages/backend/src/functions/app-check/index.ts @@ -0,0 +1,2 @@ +/* istanbul ignore file */ +export * from './customAppCheckMinter' diff --git a/packages/backend/src/functions/auth/generateAuthMessage.test.ts b/packages/backend/src/functions/auth/generateAuthMessage.test.ts new file mode 100644 index 0000000..ac9356b --- /dev/null +++ b/packages/backend/src/functions/auth/generateAuthMessage.test.ts @@ -0,0 +1,110 @@ +import { jest } from '@jest/globals' +import { isAddress } from 'ethers' +import { AUTH_NONCES_COLLECTION } from '../../constants' +import { createAuthMessage } from '../../utils' + +// Mock the Firebase Admin SDK dependencies +const mockSet = jest.fn() +const mockDoc = jest.fn(() => ({ set: mockSet })) +const mockCollection = jest.fn(() => ({ doc: mockDoc })) +const mockFirestore = jest.fn(() => ({ collection: mockCollection })) + +jest.mock('firebase-admin/firestore', () => ({ + getFirestore: mockFirestore, +})) + +// Mock the ethers `isAddress` function +jest.mock('ethers', () => ({ + isAddress: jest.fn(), +})) + +// Mock the uuid `v4` function +const mockNonce = 'mock-uuid-nonce' +const mockV4 = jest.fn(() => mockNonce) +jest.mock('uuid', () => ({ + v4: mockV4, +})) + +// Mock the createAuthMessage utility function +jest.mock('../../utils', () => ({ + createAuthMessage: jest.fn(), +})) + +// Get the actual function handler to test +const { generateAuthMessageHandler } = require('./generateAuthMessage') + +describe('generateAuthMessage', () => { + const walletAddress = '0x1234567890123456789012345678901234567890' + const mockMessage = 'mock-message-to-sign' + const mockTimestamp = 1678886400000 + + // Mock the `new Date().getTime()` call to return a predictable value + const originalGetTime = Date.prototype.getTime + Date.prototype.getTime = () => mockTimestamp + + beforeEach(() => { + jest.clearAllMocks() + jest.mocked(isAddress).mockReturnValue(true) // Default to a valid address + jest.mocked(createAuthMessage).mockReturnValue(mockMessage) + }) + + afterAll(() => { + Date.prototype.getTime = originalGetTime // Restore the original getTime() + }) + + // Test Case: Successful message generation (Happy Path) + it('should generate and return a unique message for a valid wallet address', async () => { + // Arrange + const request = { data: { walletAddress } } + + // Act + const result = await generateAuthMessageHandler(request) + + // Assert + expect(isAddress).toHaveBeenCalledWith(walletAddress) + expect(mockV4).toHaveBeenCalled() + expect(mockCollection).toHaveBeenCalledWith(AUTH_NONCES_COLLECTION) + expect(mockDoc).toHaveBeenCalledWith(walletAddress) + expect(mockSet).toHaveBeenCalledWith({ nonce: mockNonce, timestamp: mockTimestamp, expiresAt: mockTimestamp + 10 * 60 * 1000 }) + expect(createAuthMessage).toHaveBeenCalledWith(walletAddress, mockNonce, mockTimestamp) + expect(result).toEqual({ message: mockMessage, nonce: mockNonce, timestamp: mockTimestamp }) + }) + + // Test Case: Invalid Argument - Missing walletAddress + it('should throw an HttpsError for invalid-argument if walletAddress is missing', async () => { + // Arrange + const request = { data: {} } + + // Act & Assert + await expect(generateAuthMessageHandler(request)).rejects.toThrow('The function must be called with one argument: walletAddress.') + await expect(generateAuthMessageHandler(request)).rejects.toHaveProperty('code', 'invalid-argument') + expect(isAddress).not.toHaveBeenCalled() + }) + + // Test Case: Invalid Argument - Invalid walletAddress format + it('should throw an HttpsError for invalid-argument if walletAddress is an invalid format', async () => { + // Arrange + const invalidAddress = 'invalid-eth-address' + const request = { data: { walletAddress: invalidAddress } } + jest.mocked(isAddress).mockReturnValue(false) + + // Act & Assert + await expect(generateAuthMessageHandler(request)).rejects.toThrow('Invalid Ethereum wallet address format.') + await expect(generateAuthMessageHandler(request)).rejects.toHaveProperty('code', 'invalid-argument') + expect(isAddress).toHaveBeenCalledWith(invalidAddress) + }) + + // Test Case: Error during Firestore write operation + it('should throw an HttpsError for internal error if Firestore write fails', async () => { + // Arrange + const request = { data: { walletAddress } } + const firestoreError = new Error('Firestore write failed') + + // Make the `set` method throw an error to simulate a failure + mockSet.mockRejectedValue(firestoreError) + + // Act & Assert + await expect(generateAuthMessageHandler(request)).rejects.toThrow('Failed to save authentication nonce.') + await expect(generateAuthMessageHandler(request)).rejects.toHaveProperty('code', 'internal') + }) +}) diff --git a/packages/backend/src/functions/auth/generateAuthMessage.ts b/packages/backend/src/functions/auth/generateAuthMessage.ts new file mode 100644 index 0000000..56bec4e --- /dev/null +++ b/packages/backend/src/functions/auth/generateAuthMessage.ts @@ -0,0 +1,63 @@ +import { isAddress } from 'ethers' +import { logger } from 'firebase-functions/v2' +import { CallableRequest, HttpsError, onCall } from 'firebase-functions/v2/https' +import { v4 as uuidv4 } from 'uuid' +import { AUTH_NONCES_COLLECTION } from '../../constants' +import { firestore } from '../../services' +import { createAuthMessage } from '../../utils' + +// Define the interface for your function's input +interface AuthMessageRequest { + walletAddress: string +} + +export const generateAuthMessageHandler = async (request: CallableRequest) => { + const { walletAddress } = request.data + + // Validate that the required properties exist + if (!walletAddress) { + throw new HttpsError('invalid-argument', 'The function must be called with one argument: walletAddress.') + } + + // Check if the walletAddress is a valid Ethereum address format. + if (!isAddress(walletAddress)) { + throw new HttpsError('invalid-argument', 'Invalid Ethereum wallet address format.') + } + + // Generate a unique, random nonce + const nonce = uuidv4() + const timestamp = new Date().getTime() + + // Set nonce expiration to 10 minutes from now + const expiresAt = timestamp + 10 * 60 * 1000 + + // Store the nonce in a temporary collection. This will be used for verification. + // The try/catch block ensures we handle any potential errors during the database write. + try { + await firestore.collection(AUTH_NONCES_COLLECTION).doc(walletAddress).set({ nonce, timestamp, expiresAt }) + } catch (error) { + throw new HttpsError('internal', 'Failed to save authentication nonce.') + } + + // Construct the message to be signed + const message = createAuthMessage(walletAddress, nonce, timestamp) + + logger.info('Generated auth message data', { + message: message.substring(0, 50) + '...', + nonce, + timestamp, + walletAddress + }) + + return { message, nonce, timestamp } +} + +/** + * Generates a unique message for a user to sign for wallet authentication. + * The message includes a nonce and the wallet address to prevent replay attacks. + * + * @param {CallableRequest} request The callable function's request object, containing the wallet address. + * @returns {Promise<{ message: string, nonce: string, timestamp: number }>} A promise that resolves with the unique message to be signed. + * @throws {HttpsError} If the walletAddress is invalid or not provided. + */ +export const generateAuthMessage = onCall(generateAuthMessageHandler) diff --git a/packages/backend/src/functions/auth/index.ts b/packages/backend/src/functions/auth/index.ts new file mode 100644 index 0000000..e00037b --- /dev/null +++ b/packages/backend/src/functions/auth/index.ts @@ -0,0 +1,3 @@ +/* istanbul ignore file */ +export * from './generateAuthMessage' +export * from './verifySignatureAndLogin' diff --git a/packages/backend/src/functions/auth/verifySignatureAndLogin.test.ts b/packages/backend/src/functions/auth/verifySignatureAndLogin.test.ts new file mode 100644 index 0000000..a442ea6 --- /dev/null +++ b/packages/backend/src/functions/auth/verifySignatureAndLogin.test.ts @@ -0,0 +1,591 @@ +import { jest } from '@jest/globals' +import { isAddress, verifyMessage } from 'ethers' +import { AUTH_NONCES_COLLECTION, USERS_COLLECTION } from '../../constants' + +// Mock the delete method specifically for the nonce document +const mockDelete = jest.fn() +const mockUpdate = jest.fn() +const mockSet = jest.fn() + +const mockNonceDoc = { + get: jest.fn(() => + createMockDocumentSnapshot(true, { nonce: 'test-nonce', timestamp: 1234567890, expiresAt: 1678886400000 + 10 * 60 * 1000 }) + ), + delete: mockDelete, +} + +const mockUserDoc = { + get: jest.fn(() => Promise.resolve(createMockDocumentSnapshot(true, { walletAddress: '0x1234', createdAt: 1234567890 }))), + update: mockUpdate, + set: mockSet, +} + +const mockCollection = jest.fn((collectionName) => { + if (collectionName === AUTH_NONCES_COLLECTION) { + return { doc: () => mockNonceDoc } + } + + if (collectionName === USERS_COLLECTION) { + return { doc: () => mockUserDoc } + } + + return { doc: jest.fn() } +}) + +const mockFirestore = { collection: mockCollection } + +jest.mock('firebase-admin/firestore', () => { + const actualFirestore = jest.requireActual('firebase-admin/firestore') as any + + return { + getFirestore: () => mockFirestore, + Timestamp: actualFirestore.Timestamp, + } +}) + +const mockCreateCustomToken = jest.fn() +const mockAuth = jest.fn(() => ({ createCustomToken: mockCreateCustomToken })) + +jest.mock('firebase-admin/auth', () => ({ + getAuth: mockAuth, +})) + +// Mock the ethers library +jest.mock('ethers', () => ({ + isAddress: jest.fn(), + verifyMessage: jest.fn(), + verifyTypedData: jest.fn(), +})) + +// Mock the createAuthMessage utility +const mockCreateAuthMessage = jest.fn() +jest.mock('../../utils', () => ({ + createAuthMessage: mockCreateAuthMessage, +})) + +// Mock the DeviceVerificationService +const mockApproveDevice = jest.fn() as jest.MockedFunction< + (deviceId: string, walletAddress: string, platform: 'android' | 'ios' | 'web') => Promise +> +jest.mock('../../services/deviceVerification', () => ({ + DeviceVerificationService: { + approveDevice: mockApproveDevice, + }, +})) + +const { verifySignatureAndLoginHandler } = require('./verifySignatureAndLogin') +const { createMockDocumentSnapshot } = require('../../utils/firestore-mock') + +describe('verifySignatureAndLoginHandler', () => { + const walletAddress = '0x1234567890123456789012345678901234567890' + const mockMessage = 'test-message' + const timestamp = 1234567890 + const signature = '0x' + 'a'.repeat(130) + const nonce = 'test-nonce' + const firebaseToken = 'test-firebase-token' + + // Mock the date to have a predictable 'now' + const mockNow = 1678886400000 + const originalGetTime = Date.prototype.getTime + + beforeAll(() => { + Date.prototype.getTime = () => mockNow + }) + + beforeEach(() => { + jest.clearAllMocks() + + // Mock functions for a successful run + jest.mocked(isAddress).mockReturnValue(true) + jest.mocked(verifyMessage).mockReturnValue(walletAddress) + const { verifyTypedData } = require('ethers') + jest.mocked(verifyTypedData).mockReturnValue(walletAddress) + mockCreateAuthMessage.mockReturnValue(mockMessage) + mockCreateCustomToken.mockResolvedValue(firebaseToken) + + // Explicitly mock the Firestore calls for the happy path (nonce exists, user exists) + mockNonceDoc.get.mockResolvedValue(createMockDocumentSnapshot(true, { nonce, timestamp, expiresAt: mockNow + 10 * 60 * 1000 })) + mockUserDoc.get.mockResolvedValue(createMockDocumentSnapshot(true, { walletAddress, createdAt: timestamp })) + + // Set up the mocks for the other calls + mockSet.mockResolvedValue(null as any) + mockUpdate.mockResolvedValue(null as any) + mockDelete.mockResolvedValue(null as any) + + mockCreateAuthMessage.mockReturnValue(mockMessage) + mockCreateCustomToken.mockResolvedValue(firebaseToken) + }) + + afterAll(() => { + Date.prototype.getTime = originalGetTime // Restore the original getTime() + }) + + // Test Case: Successful login and token issuance (Happy Path) + it('should successfully verify the signature and issue a Firebase token', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + + // Act + const result = await verifySignatureAndLoginHandler(request) + + // Assert + expect(isAddress).toHaveBeenCalledWith(walletAddress) + expect(mockCollection).toHaveBeenCalledWith(AUTH_NONCES_COLLECTION) + expect(mockCollection).toHaveBeenCalledWith(USERS_COLLECTION) + expect(mockNonceDoc.get).toHaveBeenCalledTimes(1) + expect(mockUserDoc.get).toHaveBeenCalledTimes(1) + expect(mockCreateAuthMessage).toHaveBeenCalledWith(walletAddress, nonce, timestamp) + expect(verifyMessage).toHaveBeenCalledWith(mockMessage, signature) + expect(mockCollection).toHaveBeenCalledWith(USERS_COLLECTION) + expect(mockUpdate).toHaveBeenCalledWith({ updatedAt: mockNow }) + expect(mockDelete).toHaveBeenCalled() + expect(mockCreateCustomToken).toHaveBeenCalledWith(walletAddress) + expect(result).toEqual({ firebaseToken }) + }) + + // Test Case: User Profile Does Not Exist + it('should create a new user profile if one does not exist', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + mockNonceDoc.get.mockResolvedValue(createMockDocumentSnapshot(true, { nonce, timestamp, expiresAt: mockNow + 10 * 60 * 1000 })) + mockUserDoc.get.mockResolvedValue(createMockDocumentSnapshot(false)) + + // Act + await verifySignatureAndLoginHandler(request) + + // Assert + expect(mockSet).toHaveBeenCalledWith({ walletAddress, createdAt: mockNow, updatedAt: mockNow }) + }) + + // Test Case: Invalid Argument - Missing walletAddress or signature + it('should throw an invalid-argument error if walletAddress or signature is missing', async () => { + // Arrange + const request = { data: { walletAddress: '', signature } } + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow( + 'The function must be called with a valid walletAddress and signature.' + ) + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'invalid-argument') + }) + + // Test Case: Invalid Argument - Invalid signature format (missing 0x prefix) + it('should throw an invalid-argument error if the signature format is incorrect', async () => { + // Arrange + const request = { data: { walletAddress, signature: 'invalid-signature' } } + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow( + 'Invalid signature format. It must be a hex string prefixed with "0x".' + ) + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'invalid-argument') + }) + + // Test Case: Invalid Argument - Invalid hex characters in signature + it('should throw an invalid-argument error if signature contains invalid hex characters', async () => { + // Arrange - signature with invalid characters (G, H not valid hex) + const invalidHexSignature = '0x' + 'G'.repeat(10) + const request = { data: { walletAddress, signature: invalidHexSignature } } + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow( + 'Invalid signature format. Signature must contain only hexadecimal characters.' + ) + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'invalid-argument') + }) + + // Test Case: Not Found - Nonce does not exist + it('should throw a not-found error if the nonce document does not exist', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + mockNonceDoc.get.mockResolvedValue(createMockDocumentSnapshot(false)) + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow( + 'No authentication message found for this wallet address. Please generate a new message.' + ) + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'not-found') + }) + + // Test Case: Deadline Exceeded - Nonce has expired + it('should throw a deadline-exceeded error if the nonce has expired and clean up the expired nonce', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + const expiredTimestamp = mockNow - 20 * 60 * 1000 // 20 minutes ago + const expiredExpiresAt = expiredTimestamp + 10 * 60 * 1000 // Expired 10 minutes ago + mockNonceDoc.get.mockResolvedValue( + createMockDocumentSnapshot(true, { + nonce, + timestamp: expiredTimestamp, + expiresAt: expiredExpiresAt, + }) + ) + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow( + 'Authentication message has expired. Please generate a new message.' + ) + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'deadline-exceeded') + + // Verify that the expired nonce was cleaned up + expect(mockDelete).toHaveBeenCalled() + }) + + // Test Case: Unauthenticated - Signature verification fails + it('should throw an unauthenticated error if the signature verification fails', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + jest.mocked(verifyMessage).mockImplementation(() => { + throw new Error('Ethers verify failed') + }) + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow('Signature verification failed: Ethers verify failed') + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'unauthenticated') + }) + + // Test Case: Unauthenticated - Recovered address does not match + it('should throw an unauthenticated error if the recovered address does not match', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + jest.mocked(verifyMessage).mockReturnValue('0xDifferentAddress') + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow('The signature does not match the provided wallet address.') + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'unauthenticated') + }) + + // Test Case: Internal - User profile creation/update fails + it('should throw an internal error if user profile creation/update fails', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + mockUserDoc.get.mockResolvedValue(createMockDocumentSnapshot(false)) + mockSet.mockRejectedValue(new Error('Firestore write error')) + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow('Failed to create or update user profile. Please try again.') + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'internal') + }) + + // Test Case: Nonce deletion fails (acceptable error) + it('should not fail if the nonce deletion operation fails', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + mockDelete.mockRejectedValue(new Error('Nonce deletion failed')) + + // Act + const result = await verifySignatureAndLoginHandler(request) + + // Assert + expect(mockDelete).toHaveBeenCalled() + expect(mockCreateCustomToken).toHaveBeenCalledWith(walletAddress) + expect(result).toEqual({ firebaseToken }) + }) + + // Test Case: Unauthenticated - Custom token creation fails + it('should throw an unauthenticated error if custom token creation fails', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + mockCreateCustomToken.mockRejectedValue(new Error('Firebase auth error')) + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow('Failed to generate a valid session token.') + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'unauthenticated') + }) + + // Test Case: Device approval on successful authentication + it('should approve device when deviceId and platform are provided', async () => { + // Arrange + const deviceId = 'test-device-123' + const platform = 'android' + const request = { + data: { + walletAddress, + signature, + deviceId, + platform, + }, + } + mockApproveDevice.mockResolvedValue(undefined) + + // Act + const result = await verifySignatureAndLoginHandler(request) + + // Assert + expect(mockApproveDevice).toHaveBeenCalledWith(deviceId, walletAddress, platform) + expect(result).toEqual({ firebaseToken }) + }) + + // Test Case: Authentication succeeds even if device approval fails + it('should continue authentication even if device approval fails', async () => { + // Arrange + const deviceId = 'test-device-456' + const platform = 'ios' + const request = { + data: { + walletAddress, + signature, + deviceId, + platform, + }, + } + mockApproveDevice.mockRejectedValue(new Error('Device approval failed')) + + // Spy on logger.error to verify it's called (logger is used instead of console in actual code) + const loggerSpy = jest.spyOn(require('firebase-functions/v2').logger, 'error').mockImplementation(() => {}) + + // Act + const result = await verifySignatureAndLoginHandler(request) + + // Assert + expect(mockApproveDevice).toHaveBeenCalledWith(deviceId, walletAddress, platform) + expect(loggerSpy).toHaveBeenCalledWith('Failed to approve device', expect.objectContaining({ + error: expect.any(Error), + deviceId, + walletAddress, + signatureType: 'personal-sign' + })) + expect(result).toEqual({ firebaseToken }) + + loggerSpy.mockRestore() + }) + + // Test Case: No device approval when deviceId not provided + it('should not attempt device approval when deviceId is not provided', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + + // Act + await verifySignatureAndLoginHandler(request) + + // Assert + expect(mockApproveDevice).not.toHaveBeenCalled() + }) + + // Test Case: No device approval when platform not provided + it('should not attempt device approval when platform is not provided', async () => { + // Arrange + const request = { + data: { + walletAddress, + signature, + deviceId: 'test-device-789', + }, + } + + // Act + await verifySignatureAndLoginHandler(request) + + // Assert + expect(mockApproveDevice).not.toHaveBeenCalled() + }) + + // Test Case: Safe wallet authentication + it('should successfully verify Safe wallet signature', async () => { + // Arrange + const safeWalletSignature = `safe-wallet:${walletAddress}:${nonce}:${timestamp}` + const request = { + data: { + walletAddress, + signature: safeWalletSignature, + signatureType: 'safe-wallet', + }, + } + + // Act + const result = await verifySignatureAndLoginHandler(request) + + // Assert + expect(isAddress).toHaveBeenCalledWith(walletAddress) + expect(verifyMessage).not.toHaveBeenCalled() // Safe wallet doesn't use verifyMessage + expect(mockCreateCustomToken).toHaveBeenCalledWith(walletAddress) + expect(result).toEqual({ firebaseToken }) + }) + + // Test Case: Safe wallet with device approval + it('should approve device with Safe wallet specific deviceId', async () => { + // Arrange + const safeWalletSignature = `safe-wallet:${walletAddress}:${nonce}:${timestamp}` + const deviceId = 'safe-wallet-device' + const platform = 'web' + const request = { + data: { + walletAddress, + signature: safeWalletSignature, + signatureType: 'safe-wallet', + deviceId, + platform, + }, + } + + // Act + const result = await verifySignatureAndLoginHandler(request) + + // Assert + const expectedDeviceId = `safe-wallet-${walletAddress.toLowerCase()}` + expect(mockApproveDevice).toHaveBeenCalledWith(expectedDeviceId, walletAddress, platform) + expect(result).toEqual({ firebaseToken }) + }) + + // Test Case: Safe wallet invalid signature format + it('should throw an error for invalid Safe wallet signature format', async () => { + // Arrange + const invalidSafeSignature = `safe-wallet:${walletAddress}:invalid:format` + const request = { + data: { + walletAddress, + signature: invalidSafeSignature, + signatureType: 'safe-wallet', + }, + } + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow('Invalid Safe wallet authentication token') + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'unauthenticated') + }) + + // Test Case: EIP-712 typed data signature verification + it('should successfully verify EIP-712 typed data signature', async () => { + // Arrange + const { verifyTypedData } = require('ethers') + const typedDataSignature = '0x' + 'b'.repeat(130) + const chainId = 137 + const request = { + data: { + walletAddress, + signature: typedDataSignature, + signatureType: 'typed-data', + chainId, + }, + } + + jest.mocked(verifyTypedData).mockReturnValue(walletAddress) + + // Act + const result = await verifySignatureAndLoginHandler(request) + + // Assert + expect(verifyTypedData).toHaveBeenCalledWith( + { + name: 'SuperPool Authentication', + version: '1', + chainId, + }, + { + Authentication: [ + { name: 'wallet', type: 'address' }, + { name: 'nonce', type: 'string' }, + { name: 'timestamp', type: 'uint256' }, + ], + }, + { + wallet: walletAddress, + nonce, + timestamp: BigInt(Math.floor(timestamp)), + }, + typedDataSignature + ) + expect(verifyMessage).not.toHaveBeenCalled() // Should not fallback to personal sign + expect(result).toEqual({ firebaseToken }) + }) + + // Test Case: EIP-712 signature verification failure + it('should throw an error when EIP-712 signature verification fails', async () => { + // Arrange + const { verifyTypedData } = require('ethers') + const typedDataSignature = '0x' + 'c'.repeat(130) + const request = { + data: { + walletAddress, + signature: typedDataSignature, + signatureType: 'typed-data', + chainId: 1, + }, + } + + jest.mocked(verifyTypedData).mockImplementation(() => { + throw new Error('EIP-712 verification failed') + }) + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow('Signature verification failed: EIP-712 verification failed') + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'unauthenticated') + }) + + // Test Case: EIP-712 with default chainId when not provided + it('should use default chainId when not provided for EIP-712', async () => { + // Arrange + const { verifyTypedData } = require('ethers') + const typedDataSignature = '0x' + 'd'.repeat(130) + const request = { + data: { + walletAddress, + signature: typedDataSignature, + signatureType: 'typed-data', + // chainId not provided + }, + } + + jest.mocked(verifyTypedData).mockReturnValue(walletAddress) + + // Act + const result = await verifySignatureAndLoginHandler(request) + + // Assert + expect(verifyTypedData).toHaveBeenCalledWith( + { + name: 'SuperPool Authentication', + version: '1', + chainId: 1, // Should default to 1 + }, + expect.any(Object), + expect.any(Object), + typedDataSignature + ) + expect(result).toEqual({ firebaseToken }) + }) + + // Test Case: Non-Error object thrown during signature verification + it('should handle non-Error objects thrown during signature verification', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + const nonErrorObject = { code: 'CUSTOM_ERROR', details: 'Some custom error' } + + jest.mocked(verifyMessage).mockImplementation(() => { + throw nonErrorObject // Throw non-Error object + }) + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow('Signature verification failed: Invalid signature') + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'unauthenticated') + }) + + // Test Case: String thrown during signature verification + it('should handle string thrown during signature verification', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + const stringError = 'Custom string error' + + jest.mocked(verifyMessage).mockImplementation(() => { + throw stringError // Throw string + }) + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow('Signature verification failed: Invalid signature') + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'unauthenticated') + }) + + // Test Case: Null thrown during signature verification + it('should handle null thrown during signature verification', async () => { + // Arrange + const request = { data: { walletAddress, signature } } + + jest.mocked(verifyMessage).mockImplementation(() => { + throw null // Throw null + }) + + // Act & Assert + await expect(verifySignatureAndLoginHandler(request)).rejects.toThrow('Signature verification failed: Invalid signature') + await expect(verifySignatureAndLoginHandler(request)).rejects.toHaveProperty('code', 'unauthenticated') + }) +}) diff --git a/packages/backend/src/functions/auth/verifySignatureAndLogin.ts b/packages/backend/src/functions/auth/verifySignatureAndLogin.ts new file mode 100644 index 0000000..1928f7a --- /dev/null +++ b/packages/backend/src/functions/auth/verifySignatureAndLogin.ts @@ -0,0 +1,218 @@ +import { isAddress, verifyMessage, verifyTypedData } from 'ethers' +import { logger } from 'firebase-functions/v2' +import { CallableRequest, HttpsError, onCall } from 'firebase-functions/v2/https' +import { AUTH_NONCES_COLLECTION, USERS_COLLECTION } from '../../constants' +import { auth, firestore } from '../../services' +import { DeviceVerificationService } from '../../services/deviceVerification' +import { AuthNonce, UserProfile } from '../../types' +import { createAuthMessage } from '../../utils' + +// Define the interface for your function's input +interface VerifySignatureAndLoginRequest { + walletAddress: string + signature: string + deviceId?: string + platform?: 'android' | 'ios' | 'web' + chainId?: number + signatureType?: 'typed-data' | 'personal-sign' | 'safe-wallet' +} + +export const verifySignatureAndLoginHandler = async (request: CallableRequest) => { + const { walletAddress, signature, deviceId, platform, chainId, signatureType = 'personal-sign' } = request.data + + // Input Validation + if (!walletAddress || !signature || !isAddress(walletAddress)) { + throw new HttpsError('invalid-argument', 'The function must be called with a valid walletAddress and signature.') + } + + // Validate signature format (support EOA, smart contract signatures, and Safe wallet tokens) + const isSafeWalletToken = signature.startsWith('safe-wallet:') + + if (!isSafeWalletToken) { + if (!signature.startsWith('0x') || signature.length < 4) { + throw new HttpsError('invalid-argument', 'Invalid signature format. It must be a hex string prefixed with "0x".') + } + + // Additional validation: ensure it's valid hex + const hexPattern = /^0x[0-9a-fA-F]*$/ + if (!hexPattern.test(signature)) { + throw new HttpsError('invalid-argument', 'Invalid signature format. Signature must contain only hexadecimal characters.') + } + } + + // Retrieve Nonce from Firestore + const nonceRef = firestore.collection(AUTH_NONCES_COLLECTION).doc(walletAddress) + const nonceDoc = await nonceRef.get() + + if (!nonceDoc.exists) { + throw new HttpsError('not-found', 'No authentication message found for this wallet address. Please generate a new message.') + } + + // Cast the data to the AuthNonce interface for type safety + const nonceData = nonceDoc.data() as AuthNonce + const { nonce, timestamp, expiresAt } = nonceData + + // Check if the nonce has expired + const currentTime = new Date().getTime() + if (currentTime > expiresAt) { + // Clean up expired nonce + await nonceRef.delete() + throw new HttpsError('deadline-exceeded', 'Authentication message has expired. Please generate a new message.') + } + + // Reconstruct the signed message + const message = createAuthMessage(walletAddress, nonce, timestamp) + + // Verify the signature - try EIP-712 first (Safe compatible), fallback to personal_sign + let recoveredAddress: string + + try { + logger.info('Attempting signature verification', { + signature: signature.substring(0, 20) + '...', + walletAddress, + signatureLength: signature.length, + chainId, + signatureType, + }) + + if (signatureType === 'typed-data') { + // EIP-712 typed data verification + const domain = { + name: 'SuperPool Authentication', + version: '1', + chainId: chainId || 1, + } + + const types = { + Authentication: [ + { name: 'wallet', type: 'address' }, + { name: 'nonce', type: 'string' }, + { name: 'timestamp', type: 'uint256' }, + ], + } + + const value = { + wallet: walletAddress, + nonce, + timestamp: BigInt(Math.floor(timestamp)), + } + + recoveredAddress = verifyTypedData(domain, types, value, signature) + logger.info('EIP-712 signature verification successful', { recoveredAddress }) + } else if (signatureType === 'safe-wallet') { + // Safe wallet verification - verify the signature format and extract address + const expectedSignature = `safe-wallet:${walletAddress}:${nonce}:${timestamp}` + if (signature !== expectedSignature) { + throw new Error('Invalid Safe wallet authentication token') + } + + // For Safe wallets, we consider the wallet address as verified since: + // 1. The user is connected to the Safe wallet (proven by the connection) + // 2. Safe wallets have strict security controls + // 3. The nonce/timestamp prevents replay attacks + recoveredAddress = walletAddress + logger.info('Safe wallet verification successful', { walletAddress }) + } else { + // Personal message verification + recoveredAddress = verifyMessage(message, signature) + logger.info('Personal sign verification successful', { recoveredAddress }) + } + } catch (error) { + logger.error('Signature verification failed', { + error, + walletAddress, + signatureLength: signature.length, + messageLength: message.length, + chainId, + signatureType, + errorMessage: error instanceof Error ? error.message : String(error), + }) + throw new HttpsError( + 'unauthenticated', + `Signature verification failed: ${error instanceof Error ? error.message : 'Invalid signature'}` + ) + } + + if (recoveredAddress.toLowerCase() !== walletAddress.toLowerCase()) { + throw new HttpsError('unauthenticated', 'The signature does not match the provided wallet address.') + } + + // Create or Update User Profile + try { + logger.info('Creating/updating user profile', { walletAddress }) + const userProfileRef = firestore.collection(USERS_COLLECTION).doc(walletAddress) + const userProfileDoc = await userProfileRef.get() + const now = new Date().getTime() + + if (!userProfileDoc.exists) { + // Profile does not exist, so create a new one + const newUserProfile: UserProfile = { walletAddress, createdAt: now, updatedAt: now } + await userProfileRef.set(newUserProfile) + logger.info('User profile created', { walletAddress }) + } else { + // Profile exists, so update the updatedAt timestamp + await userProfileRef.update({ updatedAt: now }) + logger.info('User profile updated', { walletAddress }) + } + } catch (error) { + logger.error('Failed to create or update user profile', { error, walletAddress }) + throw new HttpsError('internal', 'Failed to create or update user profile. Please try again.') + } + + // Approve device after successful authentication + if (deviceId && platform) { + try { + logger.info('Approving device', { deviceId, walletAddress, platform, signatureType }) + + // For Safe wallets, use a stable device identifier based on wallet address + const finalDeviceId = signatureType === 'safe-wallet' ? + `safe-wallet-${walletAddress.toLowerCase()}` : + deviceId + + await DeviceVerificationService.approveDevice(finalDeviceId, walletAddress, platform) + logger.info('Device approved successfully', { deviceId: finalDeviceId, walletAddress, signatureType }) + } catch (error) { + // Device approval failure shouldn't block authentication + logger.error('Failed to approve device', { error, deviceId, walletAddress, signatureType }) + } + } else { + logger.info('Skipping device approval - no deviceId or platform provided', { + deviceId, + platform, + signatureType, + walletAddress + }) + } + + // Delete the nonce to prevent replay attacks + try { + logger.info('Deleting nonce document', { walletAddress }) + await nonceRef.delete() + logger.info('Nonce document deleted successfully', { walletAddress }) + } catch (error) { + // The user has already been authenticated, so a failure here is an acceptable cleanup error. + logger.error('Failed to delete nonce document', { error, walletAddress }) + } + + // Issue a Firebase Custom Token + // Use the walletAddress as the user's unique UID in Firebase Auth. + try { + logger.info('Creating Firebase custom token', { walletAddress }) + const firebaseToken = await auth.createCustomToken(walletAddress) + logger.info('Firebase custom token created successfully', { walletAddress }) + return { firebaseToken } + } catch (error) { + logger.error('Failed to create Firebase custom token', { error, walletAddress }) + throw new HttpsError('unauthenticated', 'Failed to generate a valid session token.') + } +} + +/** + * Verifies a wallet signature against a stored nonce and issues a Firebase custom token. + * This is the final step in the wallet-based authentication flow. + * + * @param {CallableRequest} request The callable function's request object, containing the wallet address and signature. + * @returns {Promise<{ firebaseToken: string }>} A promise that resolves with a Firebase custom token upon successful verification. + * @throws {HttpsError} If the walletAddress or signature are invalid, the nonce is not found, or the signature verification fails. + */ +export const verifySignatureAndLogin = onCall({ cors: true }, verifySignatureAndLoginHandler) diff --git a/packages/backend/src/functions/index.ts b/packages/backend/src/functions/index.ts new file mode 100644 index 0000000..4a150c3 --- /dev/null +++ b/packages/backend/src/functions/index.ts @@ -0,0 +1,3 @@ +/* istanbul ignore file */ +export * from './app-check' +export * from './auth' diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts new file mode 100644 index 0000000..1dafec7 --- /dev/null +++ b/packages/backend/src/index.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +import * as dotenv from 'dotenv' +import { setGlobalOptions } from 'firebase-functions' + +dotenv.config() +setGlobalOptions({ maxInstances: 10 }) + +export { customAppCheckMinter, generateAuthMessage, verifySignatureAndLogin } from './functions' diff --git a/packages/backend/src/services/deviceVerification.test.ts b/packages/backend/src/services/deviceVerification.test.ts new file mode 100644 index 0000000..c3b433d --- /dev/null +++ b/packages/backend/src/services/deviceVerification.test.ts @@ -0,0 +1,228 @@ +import { jest } from '@jest/globals' + +// Mock Firebase services +const mockGet = jest.fn() as jest.MockedFunction<() => Promise> +const mockSet = jest.fn() as jest.MockedFunction<(data: any) => Promise> +const mockUpdate = jest.fn() as jest.MockedFunction<(data: any) => Promise> +const mockDelete = jest.fn() as jest.MockedFunction<() => Promise> +const mockCollection = jest.fn() as jest.MockedFunction<(name: string) => any> +const mockDoc = jest.fn() as jest.MockedFunction<(id: string) => any> + +mockCollection.mockReturnValue({ doc: mockDoc }) +mockDoc.mockReturnValue({ + get: mockGet, + set: mockSet, + update: mockUpdate, + delete: mockDelete, + ref: { update: mockUpdate } +}) + +jest.mock('./index', () => ({ + firestore: { collection: mockCollection } +})) + +// Mock logger +const mockLoggerInfo = jest.fn() +const mockLoggerError = jest.fn() +const mockLoggerWarn = jest.fn() + +jest.mock('firebase-functions/v2', () => ({ + logger: { + info: mockLoggerInfo, + error: mockLoggerError, + warn: mockLoggerWarn + } +})) + +import { DeviceVerificationService } from './deviceVerification' +import { APPROVED_DEVICES_COLLECTION } from '../constants' +import { ApprovedDevice } from '../types' + +describe('DeviceVerificationService', () => { + const testDeviceId = 'test-device-123' + const testWalletAddress = '0x1234567890123456789012345678901234567890' + const testPlatform: 'android' | 'ios' | 'web' = 'android' + const mockTimestamp = 1678886400000 + + beforeEach(() => { + jest.clearAllMocks() + jest.spyOn(Date.prototype, 'getTime').mockReturnValue(mockTimestamp) + }) + + afterEach(() => { + jest.restoreAllMocks() + }) + + describe('isDeviceApproved', () => { + it('should return true for approved device and update lastUsed timestamp', async () => { + // Arrange + const mockDocSnapshot = { + exists: true, + ref: { update: mockUpdate } + } + mockGet.mockResolvedValue(mockDocSnapshot) + + // Act + const result = await DeviceVerificationService.isDeviceApproved(testDeviceId) + + // Assert + expect(mockCollection).toHaveBeenCalledWith(APPROVED_DEVICES_COLLECTION) + expect(mockDoc).toHaveBeenCalledWith(testDeviceId) + expect(mockUpdate).toHaveBeenCalledWith({ lastUsed: mockTimestamp }) + expect(mockLoggerInfo).toHaveBeenCalledWith('Device verified successfully', { deviceId: testDeviceId }) + expect(result).toBe(true) + }) + + it('should return false for non-approved device', async () => { + // Arrange + const mockDocSnapshot = { exists: false } + mockGet.mockResolvedValue(mockDocSnapshot) + + // Act + const result = await DeviceVerificationService.isDeviceApproved(testDeviceId) + + // Assert + expect(mockCollection).toHaveBeenCalledWith(APPROVED_DEVICES_COLLECTION) + expect(mockDoc).toHaveBeenCalledWith(testDeviceId) + expect(mockLoggerInfo).toHaveBeenCalledWith('Device not found in approved devices', { deviceId: testDeviceId }) + expect(result).toBe(false) + }) + + it('should return false and log error when verification fails', async () => { + // Arrange + const error = new Error('Firestore error') + mockGet.mockRejectedValue(error) + + // Act + const result = await DeviceVerificationService.isDeviceApproved(testDeviceId) + + // Assert + expect(mockLoggerError).toHaveBeenCalledWith('Error verifying device', { error, deviceId: testDeviceId }) + expect(result).toBe(false) + }) + }) + + describe('approveDevice', () => { + it('should successfully approve a device', async () => { + // Arrange + mockSet.mockResolvedValue(undefined) + + const expectedDevice: ApprovedDevice = { + deviceId: testDeviceId, + walletAddress: testWalletAddress, + approvedAt: mockTimestamp, + platform: testPlatform, + lastUsed: mockTimestamp + } + + // Act + await DeviceVerificationService.approveDevice(testDeviceId, testWalletAddress, testPlatform) + + // Assert + expect(mockCollection).toHaveBeenCalledWith(APPROVED_DEVICES_COLLECTION) + expect(mockDoc).toHaveBeenCalledWith(testDeviceId) + expect(mockSet).toHaveBeenCalledWith(expectedDevice) + expect(mockLoggerInfo).toHaveBeenCalledWith('Device approved successfully', { + deviceId: testDeviceId, + walletAddress: testWalletAddress, + platform: testPlatform + }) + }) + + it('should throw error when device approval fails', async () => { + // Arrange + const error = new Error('Firestore error') + mockSet.mockRejectedValue(error) + + // Act & Assert + await expect(DeviceVerificationService.approveDevice(testDeviceId, testWalletAddress, testPlatform)) + .rejects.toThrow('Failed to approve device') + + expect(mockLoggerError).toHaveBeenCalledWith('Error approving device', { + error, + deviceId: testDeviceId, + walletAddress: testWalletAddress + }) + }) + }) + + describe('getApprovedDevice', () => { + it('should return device data for approved device', async () => { + // Arrange + const deviceData: ApprovedDevice = { + deviceId: testDeviceId, + walletAddress: testWalletAddress, + approvedAt: mockTimestamp, + platform: testPlatform, + lastUsed: mockTimestamp + } + + const mockDocSnapshot = { + exists: true, + data: () => deviceData + } + mockGet.mockResolvedValue(mockDocSnapshot) + + // Act + const result = await DeviceVerificationService.getApprovedDevice(testDeviceId) + + // Assert + expect(mockCollection).toHaveBeenCalledWith(APPROVED_DEVICES_COLLECTION) + expect(mockDoc).toHaveBeenCalledWith(testDeviceId) + expect(result).toEqual(deviceData) + }) + + it('should return null for non-approved device', async () => { + // Arrange + const mockDocSnapshot = { exists: false } + mockGet.mockResolvedValue(mockDocSnapshot) + + // Act + const result = await DeviceVerificationService.getApprovedDevice(testDeviceId) + + // Assert + expect(result).toBeNull() + }) + + it('should return null and log error when retrieval fails', async () => { + // Arrange + const error = new Error('Firestore error') + mockGet.mockRejectedValue(error) + + // Act + const result = await DeviceVerificationService.getApprovedDevice(testDeviceId) + + // Assert + expect(mockLoggerError).toHaveBeenCalledWith('Error getting approved device', { error, deviceId: testDeviceId }) + expect(result).toBeNull() + }) + }) + + describe('revokeDeviceApproval', () => { + it('should successfully revoke device approval', async () => { + // Arrange + mockDelete.mockResolvedValue(undefined) + + // Act + await DeviceVerificationService.revokeDeviceApproval(testDeviceId) + + // Assert + expect(mockCollection).toHaveBeenCalledWith(APPROVED_DEVICES_COLLECTION) + expect(mockDoc).toHaveBeenCalledWith(testDeviceId) + expect(mockDelete).toHaveBeenCalled() + expect(mockLoggerInfo).toHaveBeenCalledWith('Device approval revoked', { deviceId: testDeviceId }) + }) + + it('should throw error when revocation fails', async () => { + // Arrange + const error = new Error('Firestore error') + mockDelete.mockRejectedValue(error) + + // Act & Assert + await expect(DeviceVerificationService.revokeDeviceApproval(testDeviceId)) + .rejects.toThrow('Failed to revoke device approval') + + expect(mockLoggerError).toHaveBeenCalledWith('Error revoking device approval', { error, deviceId: testDeviceId }) + }) + }) +}) \ No newline at end of file diff --git a/packages/backend/src/services/deviceVerification.ts b/packages/backend/src/services/deviceVerification.ts new file mode 100644 index 0000000..2a257f9 --- /dev/null +++ b/packages/backend/src/services/deviceVerification.ts @@ -0,0 +1,102 @@ +import { logger } from 'firebase-functions/v2' +import { APPROVED_DEVICES_COLLECTION } from '../constants' +import { ApprovedDevice } from '../types' +import { firestore } from './index' + +/** + * Service for managing device verification and approval + */ +export class DeviceVerificationService { + /** + * Check if a device is approved for App Check token generation + */ + static async isDeviceApproved(deviceId: string): Promise { + try { + const deviceDoc = await firestore + .collection(APPROVED_DEVICES_COLLECTION) + .doc(deviceId) + .get() + + if (!deviceDoc.exists) { + logger.info('Device not found in approved devices', { deviceId }) + return false + } + + // Update last used timestamp + await deviceDoc.ref.update({ lastUsed: new Date().getTime() }) + + logger.info('Device verified successfully', { deviceId }) + return true + } catch (error) { + logger.error('Error verifying device', { error, deviceId }) + return false + } + } + + /** + * Approve a device for a specific wallet address + */ + static async approveDevice( + deviceId: string, + walletAddress: string, + platform: 'android' | 'ios' | 'web' + ): Promise { + try { + const approvedDevice: ApprovedDevice = { + deviceId, + walletAddress, + approvedAt: new Date().getTime(), + platform, + lastUsed: new Date().getTime(), + } + + await firestore + .collection(APPROVED_DEVICES_COLLECTION) + .doc(deviceId) + .set(approvedDevice) + + logger.info('Device approved successfully', { deviceId, walletAddress, platform }) + } catch (error) { + logger.error('Error approving device', { error, deviceId, walletAddress }) + throw new Error('Failed to approve device') + } + } + + /** + * Get device information if approved + */ + static async getApprovedDevice(deviceId: string): Promise { + try { + const deviceDoc = await firestore + .collection(APPROVED_DEVICES_COLLECTION) + .doc(deviceId) + .get() + + if (!deviceDoc.exists) { + return null + } + + return deviceDoc.data() as ApprovedDevice + } catch (error) { + logger.error('Error getting approved device', { error, deviceId }) + return null + } + } + + /** + * Remove device approval (for security/admin purposes) + */ + static async revokeDeviceApproval(deviceId: string): Promise { + try { + await firestore + .collection(APPROVED_DEVICES_COLLECTION) + .doc(deviceId) + .delete() + + logger.info('Device approval revoked', { deviceId }) + } catch (error) { + logger.error('Error revoking device approval', { error, deviceId }) + throw new Error('Failed to revoke device approval') + } + } +} \ No newline at end of file diff --git a/packages/backend/src/services/index.ts b/packages/backend/src/services/index.ts new file mode 100644 index 0000000..b8f7bf8 --- /dev/null +++ b/packages/backend/src/services/index.ts @@ -0,0 +1,21 @@ +import * as admin from 'firebase-admin' +import { initializeApp } from 'firebase-admin/app' +import { getAppCheck } from 'firebase-admin/app-check' +import { getAuth } from 'firebase-admin/auth' +import { getFirestore } from 'firebase-admin/firestore' + +// Use require() to safely import the JSON file. +const serviceAccountKey = require('../../service-account-key.json') + +// Initialize the Firebase Admin SDK once for the entire server. +let adminApp +try { + adminApp = admin.app() +} catch { + adminApp = initializeApp({ credential: admin.credential.cert(serviceAccountKey) }) +} + +// Initialize and export auth, firestore & appCheck services +export const auth = getAuth(adminApp) +export const firestore = getFirestore(adminApp) +export const appCheck = getAppCheck(adminApp) diff --git a/packages/backend/src/types/firebase.d.ts b/packages/backend/src/types/firebase.d.ts new file mode 100644 index 0000000..742b60a --- /dev/null +++ b/packages/backend/src/types/firebase.d.ts @@ -0,0 +1,41 @@ +/* istanbul ignore file */ + +/** + * A mock type for the Firestore `set` method. + * It simulates the function signature, expecting data to be written to a document + * and returning a Promise that resolves with a WriteResult. + */ +type SetFunctionFirestore = ( + data: FirebaseFirestore.WithFieldValue +) => Promise + +/** + * A mock type for the Firestore `get` method. + * It simulates the function signature, returning a Promise that resolves + * with a DocumentSnapshot. + */ +type GetFunctionFirestore = () => Promise + +/** + * A mock type for the Firestore `update` method. + * It simulates the function signature, expecting data to update + * and returning a Promise that resolves with a WriteResult. + */ +type UpdateFunctionFirestore = ( + data: { [x: string]: any } & FirebaseFirestore.AddPrefixToKeys, + precondition?: FirebaseFirestore.Precondition +) => Promise + +/** + * A mock type for the Firestore `delete` method. + * It simulates the function signature, returning a Promise that resolves + * with a WriteResult upon successful deletion. + */ +type DeleteFunctionFirestore = () => Promise + +/** + * A mock type for the Firebase Auth `createCustomToken` method. + * It simulates the function signature, expecting a UID and returning a + * Promise that resolves with the custom token as a string. + */ +type CreateCustomTokenFunction = (uid: string, developerClaims?: object | undefined) => Promise diff --git a/packages/backend/src/types/index.ts b/packages/backend/src/types/index.ts new file mode 100644 index 0000000..debbec9 --- /dev/null +++ b/packages/backend/src/types/index.ts @@ -0,0 +1,27 @@ +/* istanbul ignore file */ + +/** + * Interface for a user's profile document stored in Firestore. + */ +export interface UserProfile { + walletAddress: string + createdAt: number + updatedAt: number +} + +/** + * Interface for the nonce object stored in Firestore. + */ +export interface AuthNonce { + nonce: string + timestamp: number + expiresAt: number +} + +export interface ApprovedDevice { + deviceId: string + walletAddress: string + approvedAt: number + platform: 'android' | 'ios' | 'web' + lastUsed: number +} diff --git a/packages/backend/src/utils/firestore-mock.ts b/packages/backend/src/utils/firestore-mock.ts new file mode 100644 index 0000000..39c2806 --- /dev/null +++ b/packages/backend/src/utils/firestore-mock.ts @@ -0,0 +1,57 @@ +/* istanbul ignore file */ +import { jest } from '@jest/globals' +import { DocumentData, DocumentReference, DocumentSnapshot, Firestore, Timestamp } from 'firebase-admin/firestore' + +// Type for a mock Firestore instance +const mockFirestoreInstance = { + collection: jest.fn(), +} as unknown as Firestore + +/** + * Creates a type-safe mock of a Firestore DocumentReference. + * @param id The document ID. + * @returns A mocked DocumentReference. + */ +const createMockDocumentReference = (id: string): DocumentReference => { + return { + id, + firestore: mockFirestoreInstance, // Use a mocked Firestore instance + path: `mock-collection/${id}`, + parent: {} as any, // Mock the parent property + collection: jest.fn(), + withConverter: jest.fn(), + get: jest.fn(), + set: jest.fn(), + update: jest.fn(), + delete: jest.fn(), + listCollections: jest.fn(), + onSnapshot: jest.fn(), + isEqual: jest.fn(() => false), + create: jest.fn(), + } as DocumentReference +} + +/** + * Creates a type-safe mock of a Firestore DocumentSnapshot. + * This helper provides all the properties required by the DocumentSnapshot type. + * + * @param exists Whether the document exists. + * @param data The data to be returned by snapshot.data(). + * @returns A mocked DocumentSnapshot. + */ +export const createMockDocumentSnapshot = (exists: boolean, data?: DocumentData): DocumentSnapshot => { + const mockRef = createMockDocumentReference('mock-id') + const mockData = data ? () => data : () => undefined + + return { + exists, + id: 'mock-id', + ref: mockRef, + data: mockData, + get: jest.fn((field) => (data as any)?.[field as any]), + isEqual: jest.fn(() => false), + readTime: Timestamp.now(), + createTime: Timestamp.now(), + updateTime: Timestamp.now(), + } as DocumentSnapshot +} diff --git a/packages/backend/src/utils/index.test.ts b/packages/backend/src/utils/index.test.ts new file mode 100644 index 0000000..0446b92 --- /dev/null +++ b/packages/backend/src/utils/index.test.ts @@ -0,0 +1,23 @@ +import { createAuthMessage } from './index' + +describe('createAuthMessage', () => { + it('should create a correctly formatted authentication message', () => { + // Arrange + const walletAddress = '0x1234567890123456789012345678901234567890' + const nonce = 'mock-nonce-123' + const timestamp = 1678886400000 + + const expectedMessage = + `Welcome to SuperPool!\n\n` + + `This request will not trigger a blockchain transaction.\n\n` + + `Wallet address:\n${walletAddress}\n\n` + + `Nonce:\n${nonce}\n` + + `Timestamp:\n${timestamp}` + + // Act + const result = createAuthMessage(walletAddress, nonce, timestamp) + + // Assert + expect(result).toBe(expectedMessage) + }) +}) diff --git a/packages/backend/src/utils/index.ts b/packages/backend/src/utils/index.ts new file mode 100644 index 0000000..debab32 --- /dev/null +++ b/packages/backend/src/utils/index.ts @@ -0,0 +1,18 @@ +/** + * Creates the standardized authentication message to be signed by a wallet. + * This message must be identical in both the generation and verification steps. + * + * @param {string} walletAddress The user's wallet address. + * @param {string} nonce A unique nonce generated for this authentication attempt. + * @param {number} timestamp The timestamp of the message creation. + * @returns {string} The formatted authentication message. + */ +export function createAuthMessage(walletAddress: string, nonce: string, timestamp: number): string { + return ( + `Welcome to SuperPool!\n\n` + + `This request will not trigger a blockchain transaction.\n\n` + + `Wallet address:\n${walletAddress}\n\n` + + `Nonce:\n${nonce}\n` + + `Timestamp:\n${timestamp}` + ) +} diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json new file mode 100644 index 0000000..a28fc79 --- /dev/null +++ b/packages/backend/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "NodeNext", + "esModuleInterop": true, + "moduleResolution": "nodenext", + "noImplicitReturns": true, + "noUnusedLocals": true, + "outDir": "lib", + "sourceMap": true, + "strict": true, + "target": "es2022", + "isolatedModules": true + }, + "compileOnSave": true, + "include": [ + "src" + ] +} diff --git a/packages/contracts/package.json b/packages/contracts/package.json new file mode 100644 index 0000000..236f49b --- /dev/null +++ b/packages/contracts/package.json @@ -0,0 +1,13 @@ +{ + "name": "contracts", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.12.4" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..ded52bf --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,15226 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@typescript-eslint/eslint-plugin': + specifier: ^5.62.0 + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^5.62.0 + version: 5.62.0(eslint@8.57.1)(typescript@5.8.3) + eslint: + specifier: ^8.57.1 + version: 8.57.1 + + apps/mobile: + dependencies: + '@react-native-async-storage/async-storage': + specifier: 2.1.2 + version: 2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + '@react-native-community/netinfo': + specifier: 11.4.1 + version: 11.4.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + '@reown/appkit-wagmi-react-native': + specifier: ^1.3.0 + version: 1.3.0(133be0e5730d6722e74a0d74112aa8a1) + '@tanstack/react-query': + specifier: ^5.85.0 + version: 5.85.3(react@19.0.0) + '@walletconnect/react-native-compat': + specifier: ^2.21.8 + version: 2.21.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@react-native-community/netinfo@11.4.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-application@6.1.5(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)))(react-native-get-random-values@1.11.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + expo: + specifier: ~53.0.20 + version: 53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) + expo-application: + specifier: ~6.1.5 + version: 6.1.5(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)) + expo-router: + specifier: ^5.1.4 + version: 5.1.4(1c3cde4edf21b16c04251477b594b823) + expo-secure-store: + specifier: ~14.2.3 + version: 14.2.3(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)) + expo-status-bar: + specifier: ~2.2.3 + version: 2.2.3(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + firebase: + specifier: ^12.1.0 + version: 12.1.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + react: + specifier: 19.0.0 + version: 19.0.0 + react-native: + specifier: 0.79.5 + version: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-get-random-values: + specifier: ^1.11.0 + version: 1.11.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + react-native-modal: + specifier: 14.0.0-rc.1 + version: 14.0.0-rc.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react-native-svg: + specifier: 15.11.2 + version: 15.11.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react-native-toast-message: + specifier: ^2.3.3 + version: 2.3.3(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + uuid: + specifier: ^11.1.0 + version: 11.1.0 + viem: + specifier: ^2.33.3 + version: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + wagmi: + specifier: ^2.16.3 + version: 2.16.3(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.85.3)(@tanstack/react-query@5.85.3(react@19.0.0))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + devDependencies: + '@babel/core': + specifier: ^7.25.2 + version: 7.28.3 + '@babel/plugin-transform-modules-commonjs': + specifier: ^7.26.2 + version: 7.27.1(@babel/core@7.28.3) + '@babel/preset-env': + specifier: ^7.26.0 + version: 7.28.3(@babel/core@7.28.3) + '@babel/preset-react': + specifier: ^7.25.9 + version: 7.27.1(@babel/core@7.28.3) + '@babel/preset-typescript': + specifier: ^7.26.0 + version: 7.27.1(@babel/core@7.28.3) + '@testing-library/react-hooks': + specifier: ^8.0.1 + version: 8.0.1(@types/react@19.0.14)(react-test-renderer@19.0.0(react@19.0.0))(react@19.0.0) + '@testing-library/react-native': + specifier: ^12.4.3 + version: 12.9.0(jest@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react-test-renderer@19.0.0(react@19.0.0))(react@19.0.0) + '@types/jest': + specifier: ^29.5.12 + version: 29.5.14 + '@types/react': + specifier: ~19.0.10 + version: 19.0.14 + '@typescript-eslint/eslint-plugin': + specifier: ^5.62.0 + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/parser': + specifier: ^5.62.0 + version: 5.62.0(eslint@8.57.1)(typescript@5.8.3) + babel-jest: + specifier: ^29.7.0 + version: 29.7.0(@babel/core@7.28.3) + eslint: + specifier: ^8.57.1 + version: 8.57.1 + eslint-plugin-jest: + specifier: ^29.0.1 + version: 29.0.1(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(jest@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)))(typescript@5.8.3) + eslint-plugin-react-native: + specifier: ^5.0.0 + version: 5.0.0(eslint@8.57.1) + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + jest-environment-jsdom: + specifier: ^29.7.0 + version: 29.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + react-test-renderer: + specifier: 19.0.0 + version: 19.0.0(react@19.0.0) + ts-jest: + specifier: ^29.1.1 + version: 29.4.1(@babel/core@7.28.3)(@jest/transform@30.0.5)(@jest/types@30.0.5)(babel-jest@29.7.0(@babel/core@7.28.3))(jest-util@30.0.5)(jest@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)))(typescript@5.8.3) + typescript: + specifier: ~5.8.3 + version: 5.8.3 + + packages/backend: + dependencies: + dotenv: + specifier: ^17.2.1 + version: 17.2.1 + ethers: + specifier: ^6.15.0 + version: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + firebase-admin: + specifier: ^12.7.0 + version: 12.7.0 + firebase-functions: + specifier: ^6.4.0 + version: 6.4.0(firebase-admin@12.7.0) + uuid: + specifier: ^11.1.0 + version: 11.1.0 + devDependencies: + '@types/jest': + specifier: ^30.0.0 + version: 30.0.0 + firebase-functions-test: + specifier: ^3.4.1 + version: 3.4.1(firebase-admin@12.7.0)(firebase-functions@6.4.0(firebase-admin@12.7.0))(jest@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3))) + jest: + specifier: ^30.0.5 + version: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + ts-jest: + specifier: ^29.4.1 + version: 29.4.1(@babel/core@7.28.3)(@jest/transform@30.0.5)(@jest/types@30.0.5)(babel-jest@30.0.5(@babel/core@7.28.3))(jest-util@30.0.5)(jest@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)))(typescript@5.8.3) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@24.2.1)(typescript@5.8.3) + typescript: + specifier: ^5.7.3 + version: 5.8.3 + + packages/contracts: {} + +packages: + + '@0no-co/graphql.web@1.2.0': + resolution: {integrity: sha512-/1iHy9TTr63gE1YcR5idjx8UREz1s0kFhydf3bBLCXyqjhkIc6igAzTOx3zPifCwFR87tsh/4Pa9cNts6d2otw==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + graphql: + optional: true + + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.10.4': + resolution: {integrity: sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.0': + resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.3': + resolution: {integrity: sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.3': + resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.3': + resolution: {integrity: sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.27.1': + resolution: {integrity: sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.5': + resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.28.3': + resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.3': + resolution: {integrity: sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.25.9': + resolution: {integrity: sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.3': + resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1': + resolution: {integrity: sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3': + resolution: {integrity: sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-decorators@7.28.0': + resolution: {integrity: sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-export-default-from@7.27.1': + resolution: {integrity: sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.27.1': + resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-export-default-from@7.27.1': + resolution: {integrity: sha512-eBC/3KSekshx19+N40MzjWqJd7KTEdOoLesAfa4IDFI8eRz5a47i5Oszus6zG/cwIXN63YhgLOMSSNJx49sENg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-flow@7.27.1': + resolution: {integrity: sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.27.1': + resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.28.0': + resolution: {integrity: sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.27.1': + resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.28.0': + resolution: {integrity: sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.27.1': + resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.28.3': + resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.28.3': + resolution: {integrity: sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.27.1': + resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.28.0': + resolution: {integrity: sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.27.1': + resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-explicit-resource-management@7.28.0': + resolution: {integrity: sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.27.1': + resolution: {integrity: sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-flow-strip-types@7.27.1': + resolution: {integrity: sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.27.1': + resolution: {integrity: sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.27.1': + resolution: {integrity: sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.27.1': + resolution: {integrity: sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1': + resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1': + resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.27.1': + resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.28.0': + resolution: {integrity: sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.27.1': + resolution: {integrity: sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.27.1': + resolution: {integrity: sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.27.1': + resolution: {integrity: sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.27.1': + resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-display-name@7.28.0': + resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-development@7.27.1': + resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.27.1': + resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-pure-annotations@7.27.1': + resolution: {integrity: sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.28.3': + resolution: {integrity: sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regexp-modifiers@7.27.1': + resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-runtime@7.28.3': + resolution: {integrity: sha512-Y6ab1kGqZ0u42Zv/4a7l0l72n9DKP/MKoKWaUSBylrhNZO2prYuqFOLbn5aW5SIFXwSH93yfjbgllL8lxuGKLg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.27.1': + resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.0': + resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.27.1': + resolution: {integrity: sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.27.1': + resolution: {integrity: sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.28.3': + resolution: {integrity: sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-react@7.27.1': + resolution: {integrity: sha512-oJHWh2gLhU9dW9HHr42q0cI0/iHHXTLGe39qvpAZZzagHy0MzYLCnCVV0symeRvzmjHyVU7mw2K06E6u/JwbhA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.27.1': + resolution: {integrity: sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.28.3': + resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.3': + resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.2': + resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + engines: {node: '>=6.9.0'} + + '@base-org/account@1.1.1': + resolution: {integrity: sha512-IfVJPrDPhHfqXRDb89472hXkpvJuQQR7FDI9isLPHEqSYt/45whIoBxSPgZ0ssTt379VhQo4+87PWI1DoLSfAQ==} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@coinbase/wallet-sdk@3.9.3': + resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} + + '@coinbase/wallet-sdk@4.3.6': + resolution: {integrity: sha512-4q8BNG1ViL4mSAAvPAtpwlOs1gpC+67eQtgIwNvT3xyeyFFd+guwkc8bcX5rTmQhXpqnhzC4f0obACbP9CqMSA==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@ecies/ciphers@0.2.4': + resolution: {integrity: sha512-t+iX+Wf5nRKyNzk8dviW3Ikb/280+aEJAnw9YXvCp2tYGPSkMki+NRY+8aNLmVFv3eNtMdvViPNOPxS8SZNP+w==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 + + '@emnapi/core@1.4.5': + resolution: {integrity: sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q==} + + '@emnapi/runtime@1.4.5': + resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} + + '@emnapi/wasi-threads@1.0.4': + resolution: {integrity: sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g==} + + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@ethereumjs/common@3.2.0': + resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==} + + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/tx@4.2.0': + resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==} + engines: {node: '>=14'} + + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + + '@expo/cli@0.24.20': + resolution: {integrity: sha512-uF1pOVcd+xizNtVTuZqNGzy7I6IJon5YMmQidsURds1Ww96AFDxrR/NEACqeATNAmY60m8wy1VZZpSg5zLNkpw==} + hasBin: true + + '@expo/code-signing-certificates@0.0.5': + resolution: {integrity: sha512-BNhXkY1bblxKZpltzAx98G2Egj9g1Q+JRcvR7E99DOj862FTCX+ZPsAUtPTr7aHxwtrL7+fL3r0JSmM9kBm+Bw==} + + '@expo/config-plugins@10.1.2': + resolution: {integrity: sha512-IMYCxBOcnuFStuK0Ay+FzEIBKrwW8OVUMc65+v0+i7YFIIe8aL342l7T4F8lR4oCfhXn7d6M5QPgXvjtc/gAcw==} + + '@expo/config-types@53.0.5': + resolution: {integrity: sha512-kqZ0w44E+HEGBjy+Lpyn0BVL5UANg/tmNixxaRMLS6nf37YsDrLk2VMAmeKMMk5CKG0NmOdVv3ngeUjRQMsy9g==} + + '@expo/config@11.0.13': + resolution: {integrity: sha512-TnGb4u/zUZetpav9sx/3fWK71oCPaOjZHoVED9NaEncktAd0Eonhq5NUghiJmkUGt3gGSjRAEBXiBbbY9/B1LA==} + + '@expo/devcert@1.2.0': + resolution: {integrity: sha512-Uilcv3xGELD5t/b0eM4cxBFEKQRIivB3v7i+VhWLV/gL98aw810unLKKJbGAxAIhY6Ipyz8ChWibFsKFXYwstA==} + + '@expo/env@1.0.7': + resolution: {integrity: sha512-qSTEnwvuYJ3umapO9XJtrb1fAqiPlmUUg78N0IZXXGwQRt+bkp0OBls+Y5Mxw/Owj8waAM0Z3huKKskRADR5ow==} + + '@expo/fingerprint@0.13.4': + resolution: {integrity: sha512-MYfPYBTMfrrNr07DALuLhG6EaLVNVrY/PXjEzsjWdWE4ZFn0yqI0IdHNkJG7t1gePT8iztHc7qnsx+oo/rDo6w==} + hasBin: true + + '@expo/image-utils@0.7.6': + resolution: {integrity: sha512-GKnMqC79+mo/1AFrmAcUcGfbsXXTRqOMNS1umebuevl3aaw+ztsYEFEiuNhHZW7PQ3Xs3URNT513ZxKhznDscw==} + + '@expo/json-file@9.1.5': + resolution: {integrity: sha512-prWBhLUlmcQtvN6Y7BpW2k9zXGd3ySa3R6rAguMJkp1z22nunLN64KYTUWfijFlprFoxm9r2VNnGkcbndAlgKA==} + + '@expo/metro-config@0.20.17': + resolution: {integrity: sha512-lpntF2UZn5bTwrPK6guUv00Xv3X9mkN3YYla+IhEHiYXWyG7WKOtDU0U4KR8h3ubkZ6SPH3snDyRyAzMsWtZFA==} + + '@expo/metro-runtime@5.0.4': + resolution: {integrity: sha512-r694MeO+7Vi8IwOsDIDzH/Q5RPMt1kUDYbiTJwnO15nIqiDwlE8HU55UlRhffKZy6s5FmxQsZ8HA+T8DqUW8cQ==} + peerDependencies: + react-native: '*' + + '@expo/osascript@2.2.5': + resolution: {integrity: sha512-Bpp/n5rZ0UmpBOnl7Li3LtM7la0AR3H9NNesqL+ytW5UiqV/TbonYW3rDZY38u4u/lG7TnYflVIVQPD+iqZJ5w==} + engines: {node: '>=12'} + + '@expo/package-manager@1.8.6': + resolution: {integrity: sha512-gcdICLuL+nHKZagPIDC5tX8UoDDB8vNA5/+SaQEqz8D+T2C4KrEJc2Vi1gPAlDnKif834QS6YluHWyxjk0yZlQ==} + + '@expo/plist@0.3.5': + resolution: {integrity: sha512-9RYVU1iGyCJ7vWfg3e7c/NVyMFs8wbl+dMWZphtFtsqyN9zppGREU3ctlD3i8KUE0sCUTVnLjCWr+VeUIDep2g==} + + '@expo/prebuild-config@9.0.11': + resolution: {integrity: sha512-0DsxhhixRbCCvmYskBTq8czsU0YOBsntYURhWPNpkl0IPVpeP9haE5W4OwtHGzXEbmHdzaoDwNmVcWjS/mqbDw==} + + '@expo/sdk-runtime-versions@1.0.0': + resolution: {integrity: sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==} + + '@expo/server@0.6.3': + resolution: {integrity: sha512-Ea7NJn9Xk1fe4YeJ86rObHSv/bm3u/6WiQPXEqXJ2GrfYpVab2Swoh9/PnSM3KjR64JAgKjArDn1HiPjITCfHA==} + + '@expo/spawn-async@1.7.2': + resolution: {integrity: sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==} + engines: {node: '>=12'} + + '@expo/sudo-prompt@9.3.2': + resolution: {integrity: sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==} + + '@expo/vector-icons@14.1.0': + resolution: {integrity: sha512-7T09UE9h8QDTsUeMGymB4i+iqvtEeaO5VvUjryFB4tugDTG/bkzViWA74hm5pfjjDEhYMXWaX112mcvhccmIwQ==} + peerDependencies: + expo-font: '*' + react: '*' + react-native: '*' + + '@expo/ws-tunnel@1.0.6': + resolution: {integrity: sha512-nDRbLmSrJar7abvUjp3smDwH8HcbZcoOEa5jVPUv9/9CajgmWw20JNRwTuBRzWIWIkEJDkz20GoNA+tSwUqk0Q==} + + '@expo/xcpretty@4.3.2': + resolution: {integrity: sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw==} + hasBin: true + + '@fastify/busboy@3.1.1': + resolution: {integrity: sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==} + + '@firebase/ai@2.1.0': + resolution: {integrity: sha512-4HvFr4YIzNFh0MowJLahOjJDezYSTjQar0XYVu/sAycoxQ+kBsfXuTPRLVXCYfMR5oNwQgYe4Q2gAOYKKqsOyA==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-types': 0.x + + '@firebase/analytics-compat@0.2.24': + resolution: {integrity: sha512-jE+kJnPG86XSqGQGhXXYt1tpTbCTED8OQJ/PQ90SEw14CuxRxx/H+lFbWA1rlFtFSsTCptAJtgyRBwr/f00vsw==} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/analytics-types@0.8.3': + resolution: {integrity: sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==} + + '@firebase/analytics@0.10.18': + resolution: {integrity: sha512-iN7IgLvM06iFk8BeFoWqvVpRFW3Z70f+Qe2PfCJ7vPIgLPjHXDE774DhCT5Y2/ZU/ZbXPDPD60x/XPWEoZLNdg==} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/app-check-compat@0.4.0': + resolution: {integrity: sha512-UfK2Q8RJNjYM/8MFORltZRG9lJj11k0nW84rrffiKvcJxLf1jf6IEjCIkCamykHE73C6BwqhVfhIBs69GXQV0g==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/app-check-interop-types@0.3.2': + resolution: {integrity: sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==} + + '@firebase/app-check-interop-types@0.3.3': + resolution: {integrity: sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==} + + '@firebase/app-check-types@0.5.3': + resolution: {integrity: sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==} + + '@firebase/app-check@0.11.0': + resolution: {integrity: sha512-XAvALQayUMBJo58U/rxW02IhsesaxxfWVmVkauZvGEz3vOAjMEQnzFlyblqkc2iAaO82uJ2ZVyZv9XzPfxjJ6w==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/app-compat@0.5.1': + resolution: {integrity: sha512-BEy1L6Ufd85ZSP79HDIv0//T9p7d5Bepwy+2mKYkgdXBGKTbFm2e2KxyF1nq4zSQ6RRBxWi0IY0zFVmoBTZlUA==} + engines: {node: '>=20.0.0'} + + '@firebase/app-types@0.9.2': + resolution: {integrity: sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==} + + '@firebase/app-types@0.9.3': + resolution: {integrity: sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==} + + '@firebase/app@0.14.1': + resolution: {integrity: sha512-jxTrDbxnGoX7cGz7aP9E7v9iKvBbQfZ8Gz4TH3SfrrkcyIojJM3+hJnlbGnGxHrABts844AxRcg00arMZEyA6Q==} + engines: {node: '>=20.0.0'} + + '@firebase/auth-compat@0.6.0': + resolution: {integrity: sha512-J0lGSxXlG/lYVi45wbpPhcWiWUMXevY4fvLZsN1GHh+po7TZVng+figdHBVhFheaiipU8HZyc7ljw1jNojM2nw==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/auth-interop-types@0.2.3': + resolution: {integrity: sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==} + + '@firebase/auth-interop-types@0.2.4': + resolution: {integrity: sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==} + + '@firebase/auth-types@0.13.0': + resolution: {integrity: sha512-S/PuIjni0AQRLF+l9ck0YpsMOdE8GO2KU6ubmBB7P+7TJUCQDa3R1dlgYm9UzGbbePMZsp0xzB93f2b/CgxMOg==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 1.x + + '@firebase/auth@1.11.0': + resolution: {integrity: sha512-5j7+ua93X+IRcJ1oMDTClTo85l7Xe40WSkoJ+shzPrX7OISlVWLdE1mKC57PSD+/LfAbdhJmvKixINBw2ESK6w==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app': 0.x + '@react-native-async-storage/async-storage': ^1.18.1 + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@firebase/component@0.6.9': + resolution: {integrity: sha512-gm8EUEJE/fEac86AvHn8Z/QW8BvR56TBw3hMW0O838J/1mThYQXAIQBgUv75EqlCZfdawpWLrKt1uXvp9ciK3Q==} + + '@firebase/component@0.7.0': + resolution: {integrity: sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==} + engines: {node: '>=20.0.0'} + + '@firebase/data-connect@0.3.11': + resolution: {integrity: sha512-G258eLzAD6im9Bsw+Qm1Z+P4x0PGNQ45yeUuuqe5M9B1rn0RJvvsQCRHXgE52Z+n9+WX1OJd/crcuunvOGc7Vw==} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/database-compat@1.0.8': + resolution: {integrity: sha512-OpeWZoPE3sGIRPBKYnW9wLad25RaWbGyk7fFQe4xnJQKRzlynWeFBSRRAoLE2Old01WXwskUiucNqUUVlFsceg==} + + '@firebase/database-compat@2.1.0': + resolution: {integrity: sha512-8nYc43RqxScsePVd1qe1xxvWNf0OBnbwHxmXJ7MHSuuTVYFO3eLyLW3PiCKJ9fHnmIz4p4LbieXwz+qtr9PZDg==} + engines: {node: '>=20.0.0'} + + '@firebase/database-types@1.0.16': + resolution: {integrity: sha512-xkQLQfU5De7+SPhEGAXFBnDryUWhhlFXelEg2YeZOQMCdoe7dL64DDAd77SQsR+6uoXIZY5MB4y/inCs4GTfcw==} + + '@firebase/database-types@1.0.5': + resolution: {integrity: sha512-fTlqCNwFYyq/C6W7AJ5OCuq5CeZuBEsEwptnVxlNPkWCo5cTTyukzAHRSO/jaQcItz33FfYrrFk1SJofcu2AaQ==} + + '@firebase/database@1.0.8': + resolution: {integrity: sha512-dzXALZeBI1U5TXt6619cv0+tgEhJiwlUtQ55WNZY7vGAjv7Q1QioV969iYwt1AQQ0ovHnEW0YW9TiBfefLvErg==} + + '@firebase/database@1.1.0': + resolution: {integrity: sha512-gM6MJFae3pTyNLoc9VcJNuaUDej0ctdjn3cVtILo3D5lpp0dmUHHLFN/pUKe7ImyeB1KAvRlEYxvIHNF04Filg==} + engines: {node: '>=20.0.0'} + + '@firebase/firestore-compat@0.4.0': + resolution: {integrity: sha512-4O7v4VFeSEwAZtLjsaj33YrMHMRjplOIYC2CiYsF6o/MboOhrhe01VrTt8iY9Y5EwjRHuRz4pS6jMBT8LfQYJA==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/firestore-types@3.0.3': + resolution: {integrity: sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 1.x + + '@firebase/firestore@4.9.0': + resolution: {integrity: sha512-5zl0+/h1GvlCSLt06RMwqFsd7uqRtnNZt4sW99k2rKRd6k/ECObIWlEnvthm2cuOSnUmwZknFqtmd1qyYSLUuQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/functions-compat@0.4.0': + resolution: {integrity: sha512-VPgtvoGFywWbQqtvgJnVWIDFSHV1WE6Hmyi5EGI+P+56EskiGkmnw6lEqc/MEUfGpPGdvmc4I9XMU81uj766/g==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/functions-types@0.6.3': + resolution: {integrity: sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==} + + '@firebase/functions@0.13.0': + resolution: {integrity: sha512-2/LH5xIbD8aaLOWSFHAwwAybgSzHIM0dB5oVOL0zZnxFG1LctX2bc1NIAaPk1T+Zo9aVkLKUlB5fTXTkVUQprQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/installations-compat@0.2.19': + resolution: {integrity: sha512-khfzIY3EI5LePePo7vT19/VEIH1E3iYsHknI/6ek9T8QCozAZshWT9CjlwOzZrKvTHMeNcbpo/VSOSIWDSjWdQ==} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/installations-types@0.5.3': + resolution: {integrity: sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==} + peerDependencies: + '@firebase/app-types': 0.x + + '@firebase/installations@0.6.19': + resolution: {integrity: sha512-nGDmiwKLI1lerhwfwSHvMR9RZuIH5/8E3kgUWnVRqqL7kGVSktjLTWEMva7oh5yxQ3zXfIlIwJwMcaM5bK5j8Q==} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/logger@0.4.2': + resolution: {integrity: sha512-Q1VuA5M1Gjqrwom6I6NUU4lQXdo9IAQieXlujeHZWvRt1b7qQ0KwBaNAjgxG27jgF9/mUwsNmO8ptBCGVYhB0A==} + + '@firebase/logger@0.5.0': + resolution: {integrity: sha512-cGskaAvkrnh42b3BA3doDWeBmuHFO/Mx5A83rbRDYakPjO9bJtRL3dX7javzc2Rr/JHZf4HlterTW2lUkfeN4g==} + engines: {node: '>=20.0.0'} + + '@firebase/messaging-compat@0.2.23': + resolution: {integrity: sha512-SN857v/kBUvlQ9X/UjAqBoQ2FEaL1ZozpnmL1ByTe57iXkmnVVFm9KqAsTfmf+OEwWI4kJJe9NObtN/w22lUgg==} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/messaging-interop-types@0.2.3': + resolution: {integrity: sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==} + + '@firebase/messaging@0.12.23': + resolution: {integrity: sha512-cfuzv47XxqW4HH/OcR5rM+AlQd1xL/VhuaeW/wzMW1LFrsFcTn0GND/hak1vkQc2th8UisBcrkVcQAnOnKwYxg==} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/performance-compat@0.2.22': + resolution: {integrity: sha512-xLKxaSAl/FVi10wDX/CHIYEUP13jXUjinL+UaNXT9ByIvxII5Ne5150mx6IgM8G6Q3V+sPiw9C8/kygkyHUVxg==} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/performance-types@0.2.3': + resolution: {integrity: sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==} + + '@firebase/performance@0.7.9': + resolution: {integrity: sha512-UzybENl1EdM2I1sjYm74xGt/0JzRnU/0VmfMAKo2LSpHJzaj77FCLZXmYQ4oOuE+Pxtt8Wy2BVJEENiZkaZAzQ==} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/remote-config-compat@0.2.19': + resolution: {integrity: sha512-y7PZAb0l5+5oIgLJr88TNSelxuASGlXyAKj+3pUc4fDuRIdPNBoONMHaIUa9rlffBR5dErmaD2wUBJ7Z1a513Q==} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/remote-config-types@0.4.0': + resolution: {integrity: sha512-7p3mRE/ldCNYt8fmWMQ/MSGRmXYlJ15Rvs9Rk17t8p0WwZDbeK7eRmoI1tvCPaDzn9Oqh+yD6Lw+sGLsLg4kKg==} + + '@firebase/remote-config@0.6.6': + resolution: {integrity: sha512-Yelp5xd8hM4NO1G1SuWrIk4h5K42mNwC98eWZ9YLVu6Z0S6hFk1mxotAdCRmH2luH8FASlYgLLq6OQLZ4nbnCA==} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/storage-compat@0.4.0': + resolution: {integrity: sha512-vDzhgGczr1OfcOy285YAPur5pWDEvD67w4thyeCUh6Ys0izN9fNYtA1MJERmNBfqjqu0lg0FM5GLbw0Il21M+g==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app-compat': 0.x + + '@firebase/storage-types@0.8.3': + resolution: {integrity: sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 1.x + + '@firebase/storage@0.14.0': + resolution: {integrity: sha512-xWWbb15o6/pWEw8H01UQ1dC5U3rf8QTAzOChYyCpafV6Xki7KVp3Yaw2nSklUwHEziSWE9KoZJS7iYeyqWnYFA==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app': 0.x + + '@firebase/util@1.10.0': + resolution: {integrity: sha512-xKtx4A668icQqoANRxyDLBLz51TAbDP9KRfpbKGxiCAW346d0BeJe5vN6/hKxxmWwnZ0mautyv39JxviwwQMOQ==} + + '@firebase/util@1.13.0': + resolution: {integrity: sha512-0AZUyYUfpMNcztR5l09izHwXkZpghLgCUaAGjtMwXnCg3bj4ml5VgiwqOMOxJ+Nw4qN/zJAaOQBcJ7KGkWStqQ==} + engines: {node: '>=20.0.0'} + + '@firebase/webchannel-wrapper@1.0.4': + resolution: {integrity: sha512-6m8+P+dE/RPl4OPzjTxcTbQ0rGeRyeTvAi9KwIffBVCiAMKrfXfLZaqD1F+m8t4B5/Q5aHsMozOgirkH1F5oMQ==} + + '@gemini-wallet/core@0.1.1': + resolution: {integrity: sha512-97Ktv+vZszADHdu6hS/B5tRfOqebwGNyD2Pfvmo1kK8d54UsNZtC22D8LJEueXqgVbq5PeSn0jv88uav3t1fHg==} + peerDependencies: + viem: '>=2.0.0' + + '@google-cloud/firestore@7.11.3': + resolution: {integrity: sha512-qsM3/WHpawF07SRVvEJJVRwhYzM7o9qtuksyuqnrMig6fxIrwWnsezECWsG/D5TyYru51Fv5c/RTqNDQ2yU+4w==} + engines: {node: '>=14.0.0'} + + '@google-cloud/paginator@5.0.2': + resolution: {integrity: sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==} + engines: {node: '>=14.0.0'} + + '@google-cloud/projectify@4.0.0': + resolution: {integrity: sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==} + engines: {node: '>=14.0.0'} + + '@google-cloud/promisify@4.0.0': + resolution: {integrity: sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==} + engines: {node: '>=14'} + + '@google-cloud/storage@7.16.0': + resolution: {integrity: sha512-7/5LRgykyOfQENcm6hDKP8SX/u9XxE5YOiWOkgkwcoO+cG8xT/cyOvp9wwN3IxfdYgpHs8CE7Nq2PKX2lNaEXw==} + engines: {node: '>=14'} + + '@grpc/grpc-js@1.13.4': + resolution: {integrity: sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==} + engines: {node: '>=12.10.0'} + + '@grpc/grpc-js@1.9.15': + resolution: {integrity: sha512-nqE7Hc0AzI+euzUwDAy0aY5hCp10r734gMGRdU+qOPX0XSceI2ULrcXB5U2xSc5VkWwalCj4M7GzCAygZl2KoQ==} + engines: {node: ^8.13.0 || >=10.10.0} + + '@grpc/proto-loader@0.7.15': + resolution: {integrity: sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==} + engines: {node: '>=6'} + hasBin: true + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@isaacs/ttlcache@1.4.1': + resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} + engines: {node: '>=12'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/console@30.0.5': + resolution: {integrity: sha512-xY6b0XiL0Nav3ReresUarwl2oIz1gTnxGbGpho9/rbUWsLH0f1OD/VT84xs8c7VmH7MChnLb0pag6PhZhAdDiA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/core@30.0.5': + resolution: {integrity: sha512-fKD0OulvRsXF1hmaFgHhVJzczWzA1RXMMo9LTPuFXo9q/alDbME3JIyWYqovWsUBWSoBcsHaGPSLF9rz4l9Qeg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/create-cache-key-function@29.7.0': + resolution: {integrity: sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/diff-sequences@30.0.1': + resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/environment@30.0.5': + resolution: {integrity: sha512-aRX7WoaWx1oaOkDQvCWImVQ8XNtdv5sEWgk4gxR6NXb7WBUnL5sRak4WRzIQRZ1VTWPvV4VI4mgGjNL9TeKMYA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@30.0.5': + resolution: {integrity: sha512-F3lmTT7CXWYywoVUGTCmom0vXq3HTTkaZyTAzIy+bXSBizB7o5qzlC9VCtq0arOa8GqmNsbg/cE9C6HLn7Szew==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@30.0.5': + resolution: {integrity: sha512-6udac8KKrtTtC+AXZ2iUN/R7dp7Ydry+Fo6FPFnDG54wjVMnb6vW/XNlf7Xj8UDjAE3aAVAsR4KFyKk3TCXmTA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@30.0.5': + resolution: {integrity: sha512-ZO5DHfNV+kgEAeP3gK3XlpJLL4U3Sz6ebl/n68Uwt64qFFs5bv4bfEEjyRGK5uM0C90ewooNgFuKMdkbEoMEXw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/get-type@30.0.1': + resolution: {integrity: sha512-AyYdemXCptSRFirI5EPazNxyPwAL0jXt3zceFjaj8NFiKP9pOi0bfXonf6qkf82z2t3QWPeLCWWw4stPBzctLw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@30.0.5': + resolution: {integrity: sha512-7oEJT19WW4oe6HR7oLRvHxwlJk2gev0U9px3ufs8sX9PoD1Eza68KF0/tlN7X0dq/WVsBScXQGgCldA1V9Y/jA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/pattern@30.0.1': + resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/reporters@30.0.5': + resolution: {integrity: sha512-mafft7VBX4jzED1FwGC1o/9QUM2xebzavImZMeqnsklgcyxBto8mV4HzNSzUrryJ+8R9MFOM3HgYuDradWR+4g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/schemas@30.0.5': + resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/snapshot-utils@30.0.5': + resolution: {integrity: sha512-XcCQ5qWHLvi29UUrowgDFvV4t7ETxX91CbDczMnoqXPOIcZOxyNdSjm6kV5XMc8+HkxfRegU/MUmnTbJRzGrUQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@30.0.1': + resolution: {integrity: sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@30.0.5': + resolution: {integrity: sha512-wPyztnK0gbDMQAJZ43tdMro+qblDHH1Ru/ylzUo21TBKqt88ZqnKKK2m30LKmLLoKtR2lxdpCC/P3g1vfKcawQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@30.0.5': + resolution: {integrity: sha512-Aea/G1egWoIIozmDD7PBXUOxkekXl7ueGzrsGGi1SbeKgQqCYCIf+wfbflEbf2LiPxL8j2JZGLyrzZagjvW4YQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@30.0.5': + resolution: {integrity: sha512-Vk8amLQCmuZyy6GbBht1Jfo9RSdBtg7Lks+B0PecnjI8J+PCLQPGh7uI8Q/2wwpW2gLdiAfiHNsmekKlywULqg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@30.0.5': + resolution: {integrity: sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.30': + resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + + '@lit-labs/ssr-dom-shim@1.4.0': + resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} + + '@lit/reactive-element@2.1.1': + resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} + + '@metamask/eth-json-rpc-provider@1.0.1': + resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} + engines: {node: '>=14.0.0'} + + '@metamask/json-rpc-engine@7.3.3': + resolution: {integrity: sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-engine@8.0.2': + resolution: {integrity: sha512-IoQPmql8q7ABLruW7i4EYVHWUbF74yrp63bRuXV5Zf9BQwcn5H9Ww1eLtROYvI1bUXwOiHZ6qT5CWTrDc/t/AA==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-middleware-stream@7.0.2': + resolution: {integrity: sha512-yUdzsJK04Ev98Ck4D7lmRNQ8FPioXYhEUZOMS01LXW8qTvPGiRVXmVltj2p4wrLkh0vW7u6nv0mNl5xzC5Qmfg==} + engines: {node: '>=16.0.0'} + + '@metamask/object-multiplex@2.1.0': + resolution: {integrity: sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==} + engines: {node: ^16.20 || ^18.16 || >=20} + + '@metamask/onboarding@1.0.1': + resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} + + '@metamask/providers@16.1.0': + resolution: {integrity: sha512-znVCvux30+3SaUwcUGaSf+pUckzT5ukPRpcBmy+muBLC0yaWnBcvDqGfcsw6CBIenUdFrVoAFa8B6jsuCY/a+g==} + engines: {node: ^18.18 || >=20} + + '@metamask/rpc-errors@6.4.0': + resolution: {integrity: sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==} + engines: {node: '>=16.0.0'} + + '@metamask/rpc-errors@7.0.2': + resolution: {integrity: sha512-YYYHsVYd46XwY2QZzpGeU4PSdRhHdxnzkB8piWGvJW2xbikZ3R+epAYEL4q/K8bh9JPTucsUdwRFnACor1aOYw==} + engines: {node: ^18.20 || ^20.17 || >=22} + + '@metamask/safe-event-emitter@2.0.0': + resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} + + '@metamask/safe-event-emitter@3.1.2': + resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} + engines: {node: '>=12.0.0'} + + '@metamask/sdk-communication-layer@0.32.0': + resolution: {integrity: sha512-dmj/KFjMi1fsdZGIOtbhxdg3amxhKL/A5BqSU4uh/SyDKPub/OT+x5pX8bGjpTL1WPWY/Q0OIlvFyX3VWnT06Q==} + peerDependencies: + cross-fetch: ^4.0.0 + eciesjs: '*' + eventemitter2: ^6.4.9 + readable-stream: ^3.6.2 + socket.io-client: ^4.5.1 + + '@metamask/sdk-install-modal-web@0.32.0': + resolution: {integrity: sha512-TFoktj0JgfWnQaL3yFkApqNwcaqJ+dw4xcnrJueMP3aXkSNev2Ido+WVNOg4IIMxnmOrfAC9t0UJ0u/dC9MjOQ==} + + '@metamask/sdk@0.32.0': + resolution: {integrity: sha512-WmGAlP1oBuD9hk4CsdlG1WJFuPtYJY+dnTHJMeCyohTWD2GgkcLMUUuvu9lO1/NVzuOoSi1OrnjbuY1O/1NZ1g==} + + '@metamask/superstruct@3.2.1': + resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@11.4.2': + resolution: {integrity: sha512-TygCcGmUbhmpxjYMm+mx68kRiJ80jYV54/Aa8gUFBv4cTX7ulX2XZKr8CJoJAw3K3FN5ZvCRmU0IzWZFaonwhA==} + engines: {node: ^18.18 || ^20.14 || >=22} + + '@metamask/utils@5.0.2': + resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} + engines: {node: '>=14.0.0'} + + '@metamask/utils@8.5.0': + resolution: {integrity: sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@9.3.0': + resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} + engines: {node: '>=16.0.0'} + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@noble/ciphers@1.2.1': + resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.2': + resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.6': + resolution: {integrity: sha512-GIKz/j99FRthB8icyJQA51E8Uk5hXmdyThjgQXRKiv9h0zeRlzSCLIzFw6K1LotZ3XuB7yzlf76qk7uBmTdFqA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@paulmillr/qr@0.2.1': + resolution: {integrity: sha512-IHnV6A+zxU7XwmKFinmYjUcwlyK9+xkG3/s9KcQhI9BjQKycrJ1JRO+FbNYPwZiPKW3je/DR0k7w8/gLa5eaxQ==} + deprecated: 'The package is now available as "qr": npm install qr' + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.2.0': + resolution: {integrity: sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@react-native-async-storage/async-storage@2.1.2': + resolution: {integrity: sha512-dvlNq4AlGWC+ehtH12p65+17V0Dx7IecOWl6WanF2ja38O1Dcjjvn7jVzkUHJ5oWkQBlyASurTPlTHgKXyYiow==} + peerDependencies: + react-native: ^0.0.0-0 || >=0.65 <1.0 + + '@react-native-community/netinfo@11.4.1': + resolution: {integrity: sha512-B0BYAkghz3Q2V09BF88RA601XursIEA111tnc2JOaN7axJWmNefmfjZqw/KdSxKZp7CZUuPpjBmz/WCR9uaHYg==} + peerDependencies: + react-native: '>=0.59' + + '@react-native/assets-registry@0.79.5': + resolution: {integrity: sha512-N4Kt1cKxO5zgM/BLiyzuuDNquZPiIgfktEQ6TqJ/4nKA8zr4e8KJgU6Tb2eleihDO4E24HmkvGc73naybKRz/w==} + engines: {node: '>=18'} + + '@react-native/babel-plugin-codegen@0.79.5': + resolution: {integrity: sha512-Rt/imdfqXihD/sn0xnV4flxxb1aLLjPtMF1QleQjEhJsTUPpH4TFlfOpoCvsrXoDl4OIcB1k4FVM24Ez92zf5w==} + engines: {node: '>=18'} + + '@react-native/babel-preset@0.79.5': + resolution: {integrity: sha512-GDUYIWslMLbdJHEgKNfrOzXk8EDKxKzbwmBXUugoiSlr6TyepVZsj3GZDLEFarOcTwH1EXXHJsixihk8DCRQDA==} + engines: {node: '>=18'} + peerDependencies: + '@babel/core': '*' + + '@react-native/codegen@0.79.5': + resolution: {integrity: sha512-FO5U1R525A1IFpJjy+KVznEinAgcs3u7IbnbRJUG9IH/MBXi2lEU2LtN+JarJ81MCfW4V2p0pg6t/3RGHFRrlQ==} + engines: {node: '>=18'} + peerDependencies: + '@babel/core': '*' + + '@react-native/community-cli-plugin@0.79.5': + resolution: {integrity: sha512-ApLO1ARS8JnQglqS3JAHk0jrvB+zNW3dvNJyXPZPoygBpZVbf8sjvqeBiaEYpn8ETbFWddebC4HoQelDndnrrA==} + engines: {node: '>=18'} + peerDependencies: + '@react-native-community/cli': '*' + peerDependenciesMeta: + '@react-native-community/cli': + optional: true + + '@react-native/debugger-frontend@0.79.5': + resolution: {integrity: sha512-WQ49TRpCwhgUYo5/n+6GGykXmnumpOkl4Lr2l2o2buWU9qPOwoiBqJAtmWEXsAug4ciw3eLiVfthn5ufs0VB0A==} + engines: {node: '>=18'} + + '@react-native/dev-middleware@0.79.5': + resolution: {integrity: sha512-U7r9M/SEktOCP/0uS6jXMHmYjj4ESfYCkNAenBjFjjsRWekiHE+U/vRMeO+fG9gq4UCcBAUISClkQCowlftYBw==} + engines: {node: '>=18'} + + '@react-native/gradle-plugin@0.79.5': + resolution: {integrity: sha512-K3QhfFNKiWKF3HsCZCEoWwJPSMcPJQaeqOmzFP4RL8L3nkpgUwn74PfSCcKHxooVpS6bMvJFQOz7ggUZtNVT+A==} + engines: {node: '>=18'} + + '@react-native/js-polyfills@0.79.5': + resolution: {integrity: sha512-a2wsFlIhvd9ZqCD5KPRsbCQmbZi6KxhRN++jrqG0FUTEV5vY7MvjjUqDILwJd2ZBZsf7uiDuClCcKqA+EEdbvw==} + engines: {node: '>=18'} + + '@react-native/normalize-colors@0.79.5': + resolution: {integrity: sha512-nGXMNMclZgzLUxijQQ38Dm3IAEhgxuySAWQHnljFtfB0JdaMwpe0Ox9H7Tp2OgrEA+EMEv+Od9ElKlHwGKmmvQ==} + + '@react-native/virtualized-lists@0.79.5': + resolution: {integrity: sha512-EUPM2rfGNO4cbI3olAbhPkIt3q7MapwCwAJBzUfWlZ/pu0PRNOnMQ1IvaXTf3TpeozXV52K1OdprLEI/kI5eUA==} + engines: {node: '>=18'} + peerDependencies: + '@types/react': ^19.0.0 + react: '*' + react-native: '*' + peerDependenciesMeta: + '@types/react': + optional: true + + '@react-navigation/bottom-tabs@7.4.6': + resolution: {integrity: sha512-f4khxwcL70O5aKfZFbxyBo5RnzPFnBNSXmrrT7q9CRmvN4mHov9KFKGQ3H4xD5sLonsTBtyjvyvPfyEC4G7f+g==} + peerDependencies: + '@react-navigation/native': ^7.1.17 + react: '>= 18.2.0' + react-native: '*' + react-native-safe-area-context: '>= 4.0.0' + react-native-screens: '>= 4.0.0' + + '@react-navigation/core@7.12.4': + resolution: {integrity: sha512-xLFho76FA7v500XID5z/8YfGTvjQPw7/fXsq4BIrVSqetNe/o/v+KAocEw4ots6kyv3XvSTyiWKh2g3pN6xZ9Q==} + peerDependencies: + react: '>= 18.2.0' + + '@react-navigation/elements@2.6.3': + resolution: {integrity: sha512-hcPXssZg5bFD5oKX7FP0D9ZXinRgPUHkUJbTegpenSEUJcPooH1qzWJkEP22GrtO+OPDLYrCVZxEX8FcMrn4pA==} + peerDependencies: + '@react-native-masked-view/masked-view': '>= 0.2.0' + '@react-navigation/native': ^7.1.17 + react: '>= 18.2.0' + react-native: '*' + react-native-safe-area-context: '>= 4.0.0' + peerDependenciesMeta: + '@react-native-masked-view/masked-view': + optional: true + + '@react-navigation/native-stack@7.3.25': + resolution: {integrity: sha512-jGcgUpif0dDGwuqag6rKTdS78MiAVAy8vmQppyaAgjS05VbCfDX+xjhc8dUxSClO5CoWlDoby1c8Hw4kBfL2UA==} + peerDependencies: + '@react-navigation/native': ^7.1.17 + react: '>= 18.2.0' + react-native: '*' + react-native-safe-area-context: '>= 4.0.0' + react-native-screens: '>= 4.0.0' + + '@react-navigation/native@7.1.17': + resolution: {integrity: sha512-uEcYWi1NV+2Qe1oELfp9b5hTYekqWATv2cuwcOAg5EvsIsUPtzFrKIasgUXLBRGb9P7yR5ifoJ+ug4u6jdqSTQ==} + peerDependencies: + react: '>= 18.2.0' + react-native: '*' + + '@react-navigation/routers@7.5.1': + resolution: {integrity: sha512-pxipMW/iEBSUrjxz2cDD7fNwkqR4xoi0E/PcfTQGCcdJwLoaxzab5kSadBLj1MTJyT0YRrOXL9umHpXtp+Dv4w==} + + '@reown/appkit-common-react-native@1.3.0': + resolution: {integrity: sha512-x+TWx6pKf1kWarhukwU1OYs/ZRf56mfN/7TCnhZnn2MSzVrwdxBAOCyqITkqiZVMDv3EYTsC9miYVghRYczGew==} + + '@reown/appkit-common@1.7.8': + resolution: {integrity: sha512-ridIhc/x6JOp7KbDdwGKY4zwf8/iK8EYBl+HtWrruutSLwZyVi5P8WaZa+8iajL6LcDcDF7LoyLwMTym7SRuwQ==} + + '@reown/appkit-controllers@1.7.8': + resolution: {integrity: sha512-IdXlJlivrlj6m63VsGLsjtPHHsTWvKGVzWIP1fXZHVqmK+rZCBDjCi9j267Rb9/nYRGHWBtlFQhO8dK35WfeDA==} + + '@reown/appkit-core-react-native@1.3.0': + resolution: {integrity: sha512-yfDClXY6+LBcd1vCyT1R3+Stu6NzGEPLCHs/C7fvfT16JVw3rpJherG9EsioVrNDWfTWrMiJXaSonNlsmBqjLA==} + peerDependencies: + '@react-native-async-storage/async-storage': '>=1.17.0' + '@walletconnect/react-native-compat': '>=2.13.1' + react: '>=17' + react-native: '>=0.68.5' + + '@reown/appkit-pay@1.7.8': + resolution: {integrity: sha512-OSGQ+QJkXx0FEEjlpQqIhT8zGJKOoHzVnyy/0QFrl3WrQTjCzg0L6+i91Ad5Iy1zb6V5JjqtfIFpRVRWN4M3pw==} + + '@reown/appkit-polyfills@1.7.8': + resolution: {integrity: sha512-W/kq786dcHHAuJ3IV2prRLEgD/2iOey4ueMHf1sIFjhhCGMynMkhsOhQMUH0tzodPqUgAC494z4bpIDYjwWXaA==} + + '@reown/appkit-scaffold-react-native@1.3.0': + resolution: {integrity: sha512-CYe9A6Ymc2ttoXFidLaemWKEkcr+dnS0X3obQ8UB99X1eY23QeKWcRW7jB1B3Er+6XFiLIku8Bp3NV1EcGFVqg==} + peerDependencies: + react: '>=17' + react-native: '>=0.68.5' + + '@reown/appkit-scaffold-ui@1.7.8': + resolution: {integrity: sha512-RCeHhAwOrIgcvHwYlNWMcIDibdI91waaoEYBGw71inE0kDB8uZbE7tE6DAXJmDkvl0qPh+DqlC4QbJLF1FVYdQ==} + + '@reown/appkit-scaffold-utils-react-native@1.3.0': + resolution: {integrity: sha512-Rig/3/fJ1f1GVn5txHNZrOSwM8JSqHpuIJU8l6YAa9//l+qDtm6pi2e5HJckQRY+5G8UZC/hlb/Y8qgSqJuMgA==} + + '@reown/appkit-siwe-react-native@1.3.0': + resolution: {integrity: sha512-jU0/UmVgkpdsx/JCqYRIpN7k/yvaRaObsDMRalK8m0XedgV8AYJRsxejuhWr2Yaljlv564b4BzRJn4C9pxRJKw==} + peerDependencies: + '@walletconnect/utils': '>=2.16.1' + + '@reown/appkit-ui-react-native@1.3.0': + resolution: {integrity: sha512-nwmJm9IlJZMI+0/fp7iiiP6zjCt3v5Eg8+ggnlQMAEYPF0uLlWe2T1VxfY9XxNdYa3cR1/wl18L0hapGc7IfgA==} + peerDependencies: + react: '>=17' + react-native: '>=0.68.5' + react-native-svg: '>=13' + + '@reown/appkit-ui@1.7.8': + resolution: {integrity: sha512-1hjCKjf6FLMFzrulhl0Y9Vb9Fu4royE+SXCPSWh4VhZhWqlzUFc7kutnZKx8XZFVQH4pbBvY62SpRC93gqoHow==} + + '@reown/appkit-utils@1.7.8': + resolution: {integrity: sha512-8X7UvmE8GiaoitCwNoB86pttHgQtzy4ryHZM9kQpvjQ0ULpiER44t1qpVLXNM4X35O0v18W0Dk60DnYRMH2WRw==} + peerDependencies: + valtio: 1.13.2 + + '@reown/appkit-wagmi-react-native@1.3.0': + resolution: {integrity: sha512-9Kr+Zi0Rc9q9LGGJdukYjQVZL2NEqVJUZISLkltYQpEpc1pRCbxcN2GT5ihhoV13pzw662PXgkyKcWDklieECw==} + peerDependencies: + '@react-native-async-storage/async-storage': '>=1.17.0' + '@react-native-community/netinfo': '*' + '@walletconnect/react-native-compat': '>=2.13.1' + react: '>=17' + react-native: '>=0.68.5' + react-native-get-random-values: '*' + viem: '>=2.21.4' + wagmi: '>=2.12.10' + + '@reown/appkit-wallet@1.7.8': + resolution: {integrity: sha512-kspz32EwHIOT/eg/ZQbFPxgXq0B/olDOj3YMu7gvLEFz4xyOFd/wgzxxAXkp5LbG4Cp++s/elh79rVNmVFdB9A==} + + '@reown/appkit@1.7.8': + resolution: {integrity: sha512-51kTleozhA618T1UvMghkhKfaPcc9JlKwLJ5uV+riHyvSoWPKPRIa5A6M1Wano5puNyW0s3fwywhyqTHSilkaA==} + + '@safe-global/safe-apps-provider@0.18.6': + resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} + + '@safe-global/safe-apps-sdk@9.1.0': + resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==} + + '@safe-global/safe-gateway-typescript-sdk@3.23.1': + resolution: {integrity: sha512-6ORQfwtEJYpalCeVO21L4XXGSdbEMfyp2hEv6cP82afKXSwvse6d3sdelgaPWUxHIsFRkWvHDdzh8IyyKHZKxw==} + engines: {node: '>=16'} + + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + + '@scure/bip32@1.6.2': + resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sinclair/typebox@0.34.38': + resolution: {integrity: sha512-HpkxMmc2XmZKhvaKIZZThlHmx1L0I/V1hWK1NubtlFnr6ZqdiOpV72TKudZUNQjZNsyDBay72qFEhEvb+bcwcA==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@sinonjs/fake-timers@13.0.5': + resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} + + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + + '@tanstack/query-core@5.85.3': + resolution: {integrity: sha512-9Ne4USX83nHmRuEYs78LW+3lFEEO2hBDHu7mrdIgAFx5Zcrs7ker3n/i8p4kf6OgKExmaDN5oR0efRD7i2J0DQ==} + + '@tanstack/react-query@5.85.3': + resolution: {integrity: sha512-AqU8TvNh5GVIE8I+TUU0noryBRy7gOY0XhSayVXmOPll4UkZeLWKDwi0rtWOZbwLRCbyxorfJ5DIjDqE7GXpcQ==} + peerDependencies: + react: ^18 || ^19 + + '@testing-library/react-hooks@8.0.1': + resolution: {integrity: sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==} + engines: {node: '>=12'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 + react: ^16.9.0 || ^17.0.0 + react-dom: ^16.9.0 || ^17.0.0 + react-test-renderer: ^16.9.0 || ^17.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react-dom: + optional: true + react-test-renderer: + optional: true + + '@testing-library/react-native@12.9.0': + resolution: {integrity: sha512-wIn/lB1FjV2N4Q7i9PWVRck3Ehwq5pkhAef5X5/bmQ78J/NoOsGbVY2/DG5Y9Lxw+RfE+GvSEh/fe5Tz6sKSvw==} + peerDependencies: + jest: '>=28.0.0' + react: '>=16.8.0' + react-native: '>=0.59' + react-test-renderer: '>=16.8.0' + peerDependenciesMeta: + jest: + optional: true + + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@tybys/wasm-util@0.10.0': + resolution: {integrity: sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + + '@types/caseless@0.12.5': + resolution: {integrity: sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/cors@2.8.19': + resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/express-serve-static-core@4.19.6': + resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} + + '@types/express@4.17.23': + resolution: {integrity: sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + + '@types/jest@30.0.0': + resolution: {integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==} + + '@types/jsdom@20.0.1': + resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/jsonwebtoken@9.0.10': + resolution: {integrity: sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==} + + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + + '@types/long@4.0.2': + resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@22.17.1': + resolution: {integrity: sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA==} + + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + + '@types/node@24.2.1': + resolution: {integrity: sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==} + + '@types/qs@6.14.0': + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/react@19.0.14': + resolution: {integrity: sha512-ixLZ7zG7j1fM0DijL9hDArwhwcCb4vqmePgwtV0GfnkHRSCUEv4LvzarcTdhoqgyMznUx/EhoTUv31CKZzkQlw==} + + '@types/request@2.48.13': + resolution: {integrity: sha512-FGJ6udDNUCjd19pp0Q3iTiDkwhYup7J8hpMW9c4k53NrccQFFWKRho6hvtPPEhnXWKvukfwAlB6DbDz4yhH5Gg==} + + '@types/semver@7.7.0': + resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} + + '@types/send@0.17.5': + resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} + + '@types/serve-static@1.15.8': + resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + + '@typescript-eslint/eslint-plugin@5.62.0': + resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@5.62.0': + resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/project-service@8.40.0': + resolution: {integrity: sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@5.62.0': + resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/scope-manager@8.40.0': + resolution: {integrity: sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.40.0': + resolution: {integrity: sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@5.62.0': + resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@5.62.0': + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/types@8.40.0': + resolution: {integrity: sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@5.62.0': + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/typescript-estree@8.40.0': + resolution: {integrity: sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@5.62.0': + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/utils@8.40.0': + resolution: {integrity: sha512-Cgzi2MXSZyAUOY+BFwGs17s7ad/7L+gKt6Y8rAVVWS+7o6wrjeFN4nVfTpbE25MNcxyJ+iYUXflbs2xR9h4UBg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@5.62.0': + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/visitor-keys@8.40.0': + resolution: {integrity: sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + '@urql/core@5.2.0': + resolution: {integrity: sha512-/n0ieD0mvvDnVAXEQgX/7qJiVcvYvNkOHeBvkwtylfjydar123caCXcl58PXFY11oU1oquJocVXHxLAbtv4x1A==} + + '@urql/exchange-retry@1.3.2': + resolution: {integrity: sha512-TQMCz2pFJMfpNxmSfX1VSfTjwUIFx/mL+p1bnfM1xjjdla7Z+KnGMW/EhFbpckp3LyWAH4PgOsMwOMnIN+MBFg==} + peerDependencies: + '@urql/core': ^5.0.0 + + '@wagmi/connectors@5.9.3': + resolution: {integrity: sha512-HmSRFB3SFE1jAPs1E28I6/VOyA82i4KzC0OyG1JLEkOkyLlGsakPxtwXVdw/7kv9L4ppADWWktvwOjvhvpRmdQ==} + peerDependencies: + '@wagmi/core': 2.19.0 + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + typescript: + optional: true + + '@wagmi/core@2.19.0': + resolution: {integrity: sha512-lI57q6refAtNU6xnk/oyOpbEtEiwQ6g4rR+C9FEx8Gn2hZlfoyyksndrl6hIKlMBK+UkkKso3VwR5DI65j/5XQ==} + peerDependencies: + '@tanstack/query-core': '>=5.0.0' + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + '@tanstack/query-core': + optional: true + typescript: + optional: true + + '@walletconnect/core@2.21.0': + resolution: {integrity: sha512-o6R7Ua4myxR8aRUAJ1z3gT9nM+jd2B2mfamu6arzy1Cc6vi10fIwFWb6vg3bC8xJ6o9H3n/cN5TOW3aA9Y1XVw==} + engines: {node: '>=18'} + + '@walletconnect/core@2.21.1': + resolution: {integrity: sha512-Tp4MHJYcdWD846PH//2r+Mu4wz1/ZU/fr9av1UWFiaYQ2t2TPLDiZxjLw54AAEpMqlEHemwCgiRiAmjR1NDdTQ==} + engines: {node: '>=18'} + + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + + '@walletconnect/ethereum-provider@2.21.1': + resolution: {integrity: sha512-SSlIG6QEVxClgl1s0LMk4xr2wg4eT3Zn/Hb81IocyqNSGfXpjtawWxKxiC5/9Z95f1INyBD6MctJbL/R1oBwIw==} + + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + + '@walletconnect/heartbeat@1.2.2': + resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==} + + '@walletconnect/jsonrpc-http-connection@1.0.8': + resolution: {integrity: sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==} + + '@walletconnect/jsonrpc-provider@1.0.14': + resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==} + + '@walletconnect/jsonrpc-types@1.0.4': + resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + + '@walletconnect/jsonrpc-utils@1.0.8': + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + + '@walletconnect/jsonrpc-ws-connection@1.0.16': + resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@2.1.2': + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + + '@walletconnect/react-native-compat@2.21.8': + resolution: {integrity: sha512-WHYZ77rDGRQoVfQO+sVQJDgLXo/UzPlgDz0iralVFuqskXBjXMJLTQw5LQfZGw3tvao0InZaZso7lpzBTml2Ww==} + peerDependencies: + '@react-native-async-storage/async-storage': '*' + '@react-native-community/netinfo': '*' + expo-application: '*' + react-native: '*' + react-native-get-random-values: '*' + peerDependenciesMeta: + expo-application: + optional: true + + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/sign-client@2.21.0': + resolution: {integrity: sha512-z7h+PeLa5Au2R591d/8ZlziE0stJvdzP9jNFzFolf2RG/OiXulgFKum8PrIyXy+Rg2q95U9nRVUF9fWcn78yBA==} + + '@walletconnect/sign-client@2.21.1': + resolution: {integrity: sha512-QaXzmPsMnKGV6tc4UcdnQVNOz4zyXgarvdIQibJ4L3EmLat73r5ZVl4c0cCOcoaV7rgM9Wbphgu5E/7jNcd3Zg==} + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.21.0': + resolution: {integrity: sha512-ll+9upzqt95ZBWcfkOszXZkfnpbJJ2CmxMfGgE5GmhdxxxCcO5bGhXkI+x8OpiS555RJ/v/sXJYMSOLkmu4fFw==} + + '@walletconnect/types@2.21.1': + resolution: {integrity: sha512-UeefNadqP6IyfwWC1Yi7ux+ljbP2R66PLfDrDm8izmvlPmYlqRerJWJvYO4t0Vvr9wrG4Ko7E0c4M7FaPKT/sQ==} + + '@walletconnect/universal-provider@2.21.0': + resolution: {integrity: sha512-mtUQvewt+X0VBQay/xOJBvxsB3Xsm1lTwFjZ6WUwSOTR1X+FNb71hSApnV5kbsdDIpYPXeQUbGt2se1n5E5UBg==} + + '@walletconnect/universal-provider@2.21.1': + resolution: {integrity: sha512-Wjx9G8gUHVMnYfxtasC9poGm8QMiPCpXpbbLFT+iPoQskDDly8BwueWnqKs4Mx2SdIAWAwuXeZ5ojk5qQOxJJg==} + + '@walletconnect/utils@2.21.0': + resolution: {integrity: sha512-zfHLiUoBrQ8rP57HTPXW7rQMnYxYI4gT9yTACxVW6LhIFROTF6/ytm5SKNoIvi4a5nX5dfXG4D9XwQUCu8Ilig==} + + '@walletconnect/utils@2.21.1': + resolution: {integrity: sha512-VPZvTcrNQCkbGOjFRbC24mm/pzbRMUq2DSQoiHlhh0X1U7ZhuIrzVtAoKsrzu6rqjz0EEtGxCr3K1TGRqDG4NA==} + + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + + '@xmldom/xmldom@0.8.10': + resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} + engines: {node: '>=10.0.0'} + + abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead + + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-globals@7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + anser@1.4.10: + resolution: {integrity: sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + arrify@2.0.1: + resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} + engines: {node: '>=8'} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + async-limiter@1.0.1: + resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + + async-mutex@0.2.6: + resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==} + + async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-jest@30.0.5: + resolution: {integrity: sha512-mRijnKimhGDMsizTvBTWotwNpzrkHr+VvZUQBof2AufXKB8NXrL1W69TG20EvOz7aevx6FTJIaBuBkYxS8zolg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + '@babel/core': ^7.11.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-istanbul@7.0.0: + resolution: {integrity: sha512-C5OzENSx/A+gt7t4VH1I2XsflxyPUmXRFPKBxt33xncdOmq7oROVM3bZv9Ysjjkv8OJYDMa+tKuKMvqU/H3xdw==} + engines: {node: '>=12'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-plugin-jest-hoist@30.0.1: + resolution: {integrity: sha512-zTPME3pI50NsFW8ZBaVIOeAxzEY7XHlmWeXXu9srI+9kNfzCUTy8MFan46xOGZY8NZThMqq+e3qZUKsvXbasnQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + babel-plugin-polyfill-corejs2@0.4.14: + resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.13.0: + resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.5: + resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-react-native-web@0.19.13: + resolution: {integrity: sha512-4hHoto6xaN23LCyZgL9LJZc3olmAxd7b6jDzlZnKXAh4rRAbZRKNBJoOOdp46OBqgy+K0t0guTj5/mhA8inymQ==} + + babel-plugin-syntax-hermes-parser@0.25.1: + resolution: {integrity: sha512-IVNpGzboFLfXZUAwkLFcI/bnqVbwky0jP3eBno4HKtqvQJAHBLdgxiG6lQ4to0+Q/YCN3PO0od5NZwIKyY4REQ==} + + babel-plugin-transform-flow-enums@0.0.2: + resolution: {integrity: sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==} + + babel-preset-current-node-syntax@1.2.0: + resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} + peerDependencies: + '@babel/core': ^7.0.0 || ^8.0.0-0 + + babel-preset-expo@13.2.3: + resolution: {integrity: sha512-wQJn92lqj8GKR7Ojg/aW4+GkqI6ZdDNTDyOqhhl7A9bAqk6t0ukUOWLDXQb4p0qKJjMDV1F6gNWasI2KUbuVTQ==} + peerDependencies: + babel-plugin-react-compiler: ^19.0.0-beta-e993439-20250405 + peerDependenciesMeta: + babel-plugin-react-compiler: + optional: true + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@30.0.1: + resolution: {integrity: sha512-+YHejD5iTWI46cZmcc/YtX4gaKBtdqCHCVfuVinizVpbmyjO3zYmeuyFdfA8duRqQZfgCAMlsfmkVbJ+e2MAJw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + '@babel/core': ^7.11.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} + + big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + + bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + bn.js@5.2.2: + resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} + + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bowser@2.12.0: + resolution: {integrity: sha512-HcOcTudTeEWgbHh0Y1Tyb6fdeR71m4b/QACf0D4KswGTsNeIJQmg38mRENZPAYPZvGFN3fk3604XbQEPdxXdKg==} + + bplist-creator@0.1.0: + resolution: {integrity: sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==} + + bplist-parser@0.3.1: + resolution: {integrity: sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==} + engines: {node: '>= 5.10.0'} + + bplist-parser@0.3.2: + resolution: {integrity: sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==} + engines: {node: '>= 5.10.0'} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.25.2: + resolution: {integrity: sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + engines: {node: '>=6.14.2'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + caller-callsite@2.0.0: + resolution: {integrity: sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==} + engines: {node: '>=4'} + + caller-path@2.0.0: + resolution: {integrity: sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==} + engines: {node: '>=4'} + + callsites@2.0.0: + resolution: {integrity: sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==} + engines: {node: '>=4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001735: + resolution: {integrity: sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + chrome-launcher@0.15.2: + resolution: {integrity: sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==} + engines: {node: '>=12.13.0'} + hasBin: true + + chromium-edge-launcher@0.2.0: + resolution: {integrity: sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==} + + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + ci-info@4.3.0: + resolution: {integrity: sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==} + engines: {node: '>=8'} + + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + + cjs-module-lexer@2.1.0: + resolution: {integrity: sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==} + + cli-cursor@2.1.0: + resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} + engines: {node: '>=4'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + connect@3.7.0: + resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} + engines: {node: '>= 0.10.0'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + + core-js-compat@3.45.0: + resolution: {integrity: sha512-gRoVMBawZg0OnxaVv3zpqLLxaHmsubEGyTnqdpI/CEBvX4JadI1dMSHxagThprYRtSVbuQxvi6iUatdPxohHpA==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cosmiconfig@5.2.1: + resolution: {integrity: sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==} + engines: {node: '>=4'} + + countries-and-timezones@3.7.2: + resolution: {integrity: sha512-BHAMt4pKb3U3r/mRfiIlVnDhRd8m6VC20gwCWtpZGZkSsjZmnMDKFnnjWYGWhBmypQAqcQILFJwmEhIgWGVTmw==} + engines: {node: '>=8.x', npm: '>=5.x'} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + + cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + data-urls@3.0.2: + resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} + engines: {node: '>=12'} + + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + + dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + dedent@1.6.0: + resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + derive-valtio@0.1.0: + resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==} + peerDependencies: + valtio: '*' + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domexception@4.0.0: + resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} + engines: {node: '>=12'} + deprecated: Use your platform's native DOMException instead + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dotenv-expand@11.0.7: + resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} + engines: {node: '>=12'} + + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + + dotenv@17.2.1: + resolution: {integrity: sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + eciesjs@0.4.15: + resolution: {integrity: sha512-r6kEJXDKecVOCj2nLMuXK/FCPeurW33+3JRpfXVbjLja3XUYFfD9I/JBreH6sUyzcm3G/YQboBjMla6poKeSdA==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.200: + resolution: {integrity: sha512-rFCxROw7aOe4uPTfIAx+rXv9cEcGx+buAF4npnhtTqCJk5KDFRnh3+KYj7rdVh6lsFt5/aPs+Irj9rZ33WMA7w==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + engine.io-client@6.6.3: + resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} + + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} + engines: {node: '>=10.0.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + env-editor@0.4.2: + resolution: {integrity: sha512-ObFo8v4rQJAE59M69QzwloxPZtd33TpYEIjtKD1rrFDcM1Gd7IkDxEBU+HriziN6HSHQnBJi8Dmy+JWkav5HKA==} + engines: {node: '>=8'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-toolkit@1.33.0: + resolution: {integrity: sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + eslint-plugin-jest@29.0.1: + resolution: {integrity: sha512-EE44T0OSMCeXhDrrdsbKAhprobKkPtJTbQz5yEktysNpHeDZTAL1SfDTNKmcFfJkY6yrQLtTKZALrD3j/Gpmiw==} + engines: {node: ^20.12.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + + eslint-plugin-react-native-globals@0.1.2: + resolution: {integrity: sha512-9aEPf1JEpiTjcFAmmyw8eiIXmcNZOqaZyHO77wgm0/dWfT/oxC1SrIq8ET38pMxHYrcB6Uew+TzUVsBeczF88g==} + + eslint-plugin-react-native@5.0.0: + resolution: {integrity: sha512-VyWlyCC/7FC/aONibOwLkzmyKg4j9oI8fzrk9WYNs4I8/m436JuOTAFwLvEn1CVvc7La4cPfbCyspP4OYpP52Q==} + peerDependencies: + eslint: ^3.17.0 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eth-block-tracker@7.1.0: + resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==} + engines: {node: '>=14.0.0'} + + eth-json-rpc-filters@6.0.1: + resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==} + engines: {node: '>=14.0.0'} + + eth-query@2.1.2: + resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} + + eth-rpc-errors@4.0.3: + resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==} + + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + + ethers@6.15.0: + resolution: {integrity: sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==} + engines: {node: '>=14.0.0'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + exec-async@2.2.0: + resolution: {integrity: sha512-87OpwcEiMia/DeiKFzaQNBNFeN3XkkpYIh9FyOqq5mS2oKv3CBE67PXoEKcr6nodWdXNogTiQ0jE2NGuoffXPw==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + exit-x@0.2.2: + resolution: {integrity: sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==} + engines: {node: '>= 0.8.0'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + expect@30.0.5: + resolution: {integrity: sha512-P0te2pt+hHI5qLJkIR+iMvS+lYUZml8rKKsohVHAGY+uClp9XVbdyYNJOIjSRpHVp8s8YqxJCiHUkSYZGr8rtQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + expo-application@6.1.5: + resolution: {integrity: sha512-ToImFmzw8luY043pWFJhh2ZMm4IwxXoHXxNoGdlhD4Ym6+CCmkAvCglg0FK8dMLzAb+/XabmOE7Rbm8KZb6NZg==} + peerDependencies: + expo: '*' + + expo-asset@11.1.7: + resolution: {integrity: sha512-b5P8GpjUh08fRCf6m5XPVAh7ra42cQrHBIMgH2UXP+xsj4Wufl6pLy6jRF5w6U7DranUMbsXm8TOyq4EHy7ADg==} + peerDependencies: + expo: '*' + react: '*' + react-native: '*' + + expo-constants@17.1.7: + resolution: {integrity: sha512-byBjGsJ6T6FrLlhOBxw4EaiMXrZEn/MlUYIj/JAd+FS7ll5X/S4qVRbIimSJtdW47hXMq0zxPfJX6njtA56hHA==} + peerDependencies: + expo: '*' + react-native: '*' + + expo-file-system@18.1.11: + resolution: {integrity: sha512-HJw/m0nVOKeqeRjPjGdvm+zBi5/NxcdPf8M8P3G2JFvH5Z8vBWqVDic2O58jnT1OFEy0XXzoH9UqFu7cHg9DTQ==} + peerDependencies: + expo: '*' + react-native: '*' + + expo-font@13.3.2: + resolution: {integrity: sha512-wUlMdpqURmQ/CNKK/+BIHkDA5nGjMqNlYmW0pJFXY/KE/OG80Qcavdu2sHsL4efAIiNGvYdBS10WztuQYU4X0A==} + peerDependencies: + expo: '*' + react: '*' + + expo-keep-awake@14.1.4: + resolution: {integrity: sha512-wU9qOnosy4+U4z/o4h8W9PjPvcFMfZXrlUoKTMBW7F4pLqhkkP/5G4EviPZixv4XWFMjn1ExQ5rV6BX8GwJsWA==} + peerDependencies: + expo: '*' + react: '*' + + expo-linking@7.1.7: + resolution: {integrity: sha512-ZJaH1RIch2G/M3hx2QJdlrKbYFUTOjVVW4g39hfxrE5bPX9xhZUYXqxqQtzMNl1ylAevw9JkgEfWbBWddbZ3UA==} + peerDependencies: + react: '*' + react-native: '*' + + expo-modules-autolinking@2.1.14: + resolution: {integrity: sha512-nT5ERXwc+0ZT/pozDoJjYZyUQu5RnXMk9jDGm5lg+PiKvsrCTSA/2/eftJGMxLkTjVI2MXp5WjSz3JRjbA7UXA==} + hasBin: true + + expo-modules-core@2.5.0: + resolution: {integrity: sha512-aIbQxZE2vdCKsolQUl6Q9Farlf8tjh/ROR4hfN1qT7QBGPl1XrJGnaOKkcgYaGrlzCPg/7IBe0Np67GzKMZKKQ==} + + expo-router@5.1.4: + resolution: {integrity: sha512-8GulCelVN9x+VSOio74K1ZYTG6VyCdJw417gV+M/J8xJOZZTA7rFxAdzujBZZ7jd6aIAG7WEwOUU3oSvUO76Vw==} + peerDependencies: + '@react-navigation/drawer': ^7.3.9 + '@testing-library/jest-native': '*' + expo: '*' + expo-constants: '*' + expo-linking: '*' + react-native-reanimated: '*' + react-native-safe-area-context: '*' + react-native-screens: '*' + peerDependenciesMeta: + '@react-navigation/drawer': + optional: true + '@testing-library/jest-native': + optional: true + react-native-reanimated: + optional: true + + expo-secure-store@14.2.3: + resolution: {integrity: sha512-hYBbaAD70asKTFd/eZBKVu+9RTo9OSTMMLqXtzDF8ndUGjpc6tmRCoZtrMHlUo7qLtwL5jm+vpYVBWI8hxh/1Q==} + peerDependencies: + expo: '*' + + expo-status-bar@2.2.3: + resolution: {integrity: sha512-+c8R3AESBoduunxTJ8353SqKAKpxL6DvcD8VKBuh81zzJyUUbfB4CVjr1GufSJEKsMzNPXZU+HJwXx7Xh7lx8Q==} + peerDependencies: + react: '*' + react-native: '*' + + expo@53.0.20: + resolution: {integrity: sha512-Nh+HIywVy9KxT/LtH08QcXqrxtUOA9BZhsXn3KCsAYA+kNb80M8VKN8/jfQF+I6CgeKyFKJoPNsWgI0y0VBGrA==} + hasBin: true + peerDependencies: + '@expo/dom-webview': '*' + '@expo/metro-runtime': '*' + react: '*' + react-native: '*' + react-native-webview: '*' + peerDependenciesMeta: + '@expo/dom-webview': + optional: true + '@expo/metro-runtime': + optional: true + react-native-webview: + optional: true + + exponential-backoff@3.1.2: + resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==} + + express@4.21.2: + resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} + engines: {node: '>= 0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extension-port-stream@3.0.0: + resolution: {integrity: sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==} + engines: {node: '>=12.0.0'} + + farmhash-modern@1.1.0: + resolution: {integrity: sha512-6ypT4XfgqJk/F3Yuv4SX26I3doUjt0GTG4a+JgWxXQpxXzTBq8fPUeGHfcYMMDPHJHm3yPOSjaeBwBGAHWXCdA==} + engines: {node: '>=18.0.0'} + + fast-base64-decode@1.0.0: + resolution: {integrity: sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fast-text-encoding@1.0.6: + resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} + + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + + fast-xml-parser@4.5.3: + resolution: {integrity: sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==} + hasBin: true + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + + finalhandler@1.1.2: + resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} + engines: {node: '>= 0.8'} + + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + firebase-admin@12.7.0: + resolution: {integrity: sha512-raFIrOyTqREbyXsNkSHyciQLfv8AUZazehPaQS1lZBSCDYW74FYXU0nQZa3qHI4K+hawohlDbywZ4+qce9YNxA==} + engines: {node: '>=14'} + + firebase-functions-test@3.4.1: + resolution: {integrity: sha512-qAq0oszrBGdf4bnCF6t4FoSgMsepeIXh0Pi/FhikSE6e+TvKKGpfrfUP/5pFjJZxFcLsweoau88KydCql4xSeg==} + engines: {node: '>=14.0.0'} + peerDependencies: + firebase-admin: ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 + firebase-functions: '>=4.9.0' + jest: '>=28.0.0' + + firebase-functions@6.4.0: + resolution: {integrity: sha512-Q/LGhJrmJEhT0dbV60J4hCkVSeOM6/r7xJS/ccmkXzTWMjo+UPAYX9zlQmGlEjotstZ0U9GtQSJSgbB2Z+TJDg==} + engines: {node: '>=14.10.0'} + hasBin: true + peerDependencies: + firebase-admin: ^11.10.0 || ^12.0.0 || ^13.0.0 + + firebase@12.1.0: + resolution: {integrity: sha512-oZucxvfWKuAW4eHHRqGKzC43fLiPqPwHYBHPRNsnkgonqYaq0VurYgqgBosRlEulW+TWja/5Tpo2FpUU+QrfEQ==} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + flow-enums-runtime@0.0.6: + resolution: {integrity: sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==} + + fontfaceobserver@2.3.0: + resolution: {integrity: sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data@2.5.5: + resolution: {integrity: sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==} + engines: {node: '>= 0.12'} + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + freeport-async@2.0.0: + resolution: {integrity: sha512-K7od3Uw45AJg00XUmy15+Hae2hOcgKcmN3/EF6Y7i01O0gaqiRx8sUSpsb9+BRNL8RPBrhzPsVfy8q9ADlJuWQ==} + engines: {node: '>=8'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + + gaxios@6.7.1: + resolution: {integrity: sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==} + engines: {node: '>=14'} + + gcp-metadata@6.1.1: + resolution: {integrity: sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==} + engines: {node: '>=14'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + getenv@2.0.0: + resolution: {integrity: sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==} + engines: {node: '>=6'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + google-auth-library@9.15.1: + resolution: {integrity: sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==} + engines: {node: '>=14'} + + google-gax@4.6.1: + resolution: {integrity: sha512-V6eky/xz2mcKfAd1Ioxyd6nmA61gao3n01C+YeuIwu3vzM9EDR6wcVzMSIbLMDXWeoi9SHYctXuKYC5uJUT3eQ==} + engines: {node: '>=14'} + + google-logging-utils@0.0.2: + resolution: {integrity: sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==} + engines: {node: '>=14'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + gtoken@7.1.0: + resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} + engines: {node: '>=14.0.0'} + + h3@1.15.4: + resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-estree@0.29.1: + resolution: {integrity: sha512-jl+x31n4/w+wEqm0I2r4CMimukLbLQEYpisys5oCre611CI5fc9TxhqkBBCJ1edDG4Kza0f7CgNz8xVMLZQOmQ==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + + hermes-parser@0.29.1: + resolution: {integrity: sha512-xBHWmUtRC5e/UL0tI7Ivt2riA/YBq9+SiYFU7C1oBa/j2jYGlIF9043oak1F47ihuDIxQ5nbsKueYJDRY02UgA==} + + hosted-git-info@7.0.2: + resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} + engines: {node: ^16.14.0 || >=18.0.0} + + html-encoding-sniffer@3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} + + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} + + idb@7.1.1: + resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + image-size@1.2.1: + resolution: {integrity: sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==} + engines: {node: '>=16.x'} + hasBin: true + + import-fresh@2.0.0: + resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==} + engines: {node: '>=4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {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. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-directory@0.3.1: + resolution: {integrity: sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==} + engines: {node: '>=0.10.0'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + + isows@1.0.7: + resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + peerDependencies: + ws: '*' + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-changed-files@30.0.5: + resolution: {integrity: sha512-bGl2Ntdx0eAwXuGpdLdVYVr5YQHnSZlQ0y9HVDu565lCUAe9sj6JOtBbMmBBikGIegne9piDDIOeiLVoqTkz4A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@30.0.5: + resolution: {integrity: sha512-h/sjXEs4GS+NFFfqBDYT7y5Msfxh04EwWLhQi0F8kuWpe+J/7tICSlswU8qvBqumR3kFgHbfu7vU6qruWWBPug==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-cli@30.0.5: + resolution: {integrity: sha512-Sa45PGMkBZzF94HMrlX4kUyPOwUpdZasaliKN3mifvDmkhLYqLLg8HQTzn6gq7vJGahFYMQjXgyJWfYImKZzOw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-config@30.0.5: + resolution: {integrity: sha512-aIVh+JNOOpzUgzUnPn5FLtyVnqc3TQHVMupYtyeURSb//iLColiMIR8TxCIDKyx9ZgjKnXGucuW68hCxgbrwmA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + peerDependencies: + '@types/node': '*' + esbuild-register: '>=3.4.0' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + esbuild-register: + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-diff@30.0.5: + resolution: {integrity: sha512-1UIqE9PoEKaHcIKvq2vbibrCog4Y8G0zmOxgQUVEiTqwR5hJVMCoDsN1vFvI5JvwD37hjueZ1C4l2FyGnfpE0A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@30.0.1: + resolution: {integrity: sha512-/vF78qn3DYphAaIc3jy4gA7XSAz167n9Bm/wn/1XhTLW7tTBIzXtCJpb/vcmc73NIIeeohCbdL94JasyXUZsGA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@30.0.5: + resolution: {integrity: sha512-dKjRsx1uZ96TVyejD3/aAWcNKy6ajMaN531CwWIsrazIqIoXI9TnnpPlkrEYku/8rkS3dh2rbH+kMOyiEIv0xQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-environment-jsdom@29.7.0: + resolution: {integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@30.0.5: + resolution: {integrity: sha512-ppYizXdLMSvciGsRsMEnv/5EFpvOdXBaXRBzFUDPWrsfmog4kYrOGWXarLllz6AXan6ZAA/kYokgDWuos1IKDA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@30.0.5: + resolution: {integrity: sha512-dkmlWNlsTSR0nH3nRfW5BKbqHefLZv0/6LCccG0xFCTWcJu8TuEwG+5Cm75iBfjVoockmO6J35o5gxtFSn5xeg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@30.0.5: + resolution: {integrity: sha512-3Uxr5uP8jmHMcsOtYMRB/zf1gXN3yUIc+iPorhNETG54gErFIiUhLvyY/OggYpSMOEYqsmRxmuU4ZOoX5jpRFg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@30.0.5: + resolution: {integrity: sha512-uQgGWt7GOrRLP1P7IwNWwK1WAQbq+m//ZY0yXygyfWp0rJlksMSLQAA4wYQC3b6wl3zfnchyTx+k3HZ5aPtCbQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@30.0.5: + resolution: {integrity: sha512-NAiDOhsK3V7RU0Aa/HnrQo+E4JlbarbmI3q6Pi4KcxicdtjV82gcIUrejOtczChtVQR4kddu1E1EJlW6EN9IyA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@30.0.5: + resolution: {integrity: sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-regex-util@30.0.1: + resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@30.0.5: + resolution: {integrity: sha512-/xMvBR4MpwkrHW4ikZIWRttBBRZgWK4d6xt3xW1iRDSKt4tXzYkMkyPfBnSCgv96cpkrctfXs6gexeqMYqdEpw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@30.0.5: + resolution: {integrity: sha512-d+DjBQ1tIhdz91B79mywH5yYu76bZuE96sSbxj8MkjWVx5WNdt1deEFRONVL4UkKLSrAbMkdhb24XN691yDRHg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@30.0.5: + resolution: {integrity: sha512-JcCOucZmgp+YuGgLAXHNy7ualBx4wYSgJVWrYMRBnb79j9PD0Jxh0EHvR5Cx/r0Ce+ZBC4hCdz2AzFFLl9hCiw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@30.0.5: + resolution: {integrity: sha512-7oySNDkqpe4xpX5PPiJTe5vEa+Ak/NnNz2bGYZrA1ftG3RL3EFlHaUkA1Cjx+R8IhK0Vg43RML5mJedGTPNz3A==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@30.0.5: + resolution: {integrity: sha512-T00dWU/Ek3LqTp4+DcW6PraVxjk28WY5Ua/s+3zUKSERZSNyxTqhDXCWKG5p2HAJ+crVQ3WJ2P9YVHpj1tkW+g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@30.0.5: + resolution: {integrity: sha512-pvyPWssDZR0FlfMxCBoc0tvM8iUEskaRFALUtGQYzVEAqisAztmy+R8LnU14KT4XA0H/a5HMVTXat1jLne010g==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@30.0.5: + resolution: {integrity: sha512-ouTm6VFHaS2boyl+k4u+Qip4TSH7Uld5tyD8psQ8abGgt2uYYB8VwVfAHWHjHc0NWmGGbwO5h0sCPOGHHevefw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@30.0.5: + resolution: {integrity: sha512-z9slj/0vOwBDBjN3L4z4ZYaA+pG56d6p3kTUhFRYGvXbXMWhXmb/FIxREZCD06DYUwDKKnj2T80+Pb71CQ0KEg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@30.0.5: + resolution: {integrity: sha512-ojRXsWzEP16NdUuBw/4H/zkZdHOa7MMYCk4E430l+8fELeLg/mqmMlRhjL7UNZvQrDmnovWZV4DxX03fZF48fQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest@30.0.5: + resolution: {integrity: sha512-y2mfcJywuTUkvLm2Lp1/pFX8kTgMO5yyQGq/Sk/n2mN7XWYp4JsCZ/QXW34M8YScgk8bPZlREH04f6blPnoHnQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jimp-compact@0.16.1: + resolution: {integrity: sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==} + + jose@4.15.9: + resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsc-safe-url@0.2.4: + resolution: {integrity: sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==} + + jsdom@20.0.3: + resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} + engines: {node: '>=14'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-rpc-engine@6.1.0: + resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} + engines: {node: '>=10.0.0'} + + json-rpc-random-id@1.0.1: + resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonwebtoken@9.0.2: + resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} + engines: {node: '>=12', npm: '>=6'} + + jwa@1.4.2: + resolution: {integrity: sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==} + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jwks-rsa@3.2.0: + resolution: {integrity: sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==} + engines: {node: '>=14'} + + jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + + jws@4.0.0: + resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + + keccak@3.0.4: + resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} + engines: {node: '>=10.0.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + lan-network@0.1.7: + resolution: {integrity: sha512-mnIlAEMu4OyEvUNdzco9xpuB9YVcPkQec+QsgycBCtPZvEqWPCDPfbAE4OJMdBBWpZWtpCn1xw9jJYlwjWI5zQ==} + hasBin: true + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lighthouse-logger@1.4.2: + resolution: {integrity: sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==} + + lightningcss-darwin-arm64@1.27.0: + resolution: {integrity: sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.27.0: + resolution: {integrity: sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.27.0: + resolution: {integrity: sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.27.0: + resolution: {integrity: sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.27.0: + resolution: {integrity: sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.27.0: + resolution: {integrity: sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.27.0: + resolution: {integrity: sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.27.0: + resolution: {integrity: sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.27.0: + resolution: {integrity: sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.27.0: + resolution: {integrity: sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.27.0: + resolution: {integrity: sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==} + engines: {node: '>= 12.0.0'} + + limiter@1.1.5: + resolution: {integrity: sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lit-element@4.2.1: + resolution: {integrity: sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==} + + lit-html@3.3.1: + resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} + + lit@3.3.0: + resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + + lodash.throttle@4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@2.2.0: + resolution: {integrity: sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==} + engines: {node: '>=4'} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru-memoizer@2.3.0: + resolution: {integrity: sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + marky@1.3.0: + resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memoize-one@5.2.1: + resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-options@3.0.4: + resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} + engines: {node: '>=10'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + metro-babel-transformer@0.82.5: + resolution: {integrity: sha512-W/scFDnwJXSccJYnOFdGiYr9srhbHPdxX9TvvACOFsIXdLilh3XuxQl/wXW6jEJfgIb0jTvoTlwwrqvuwymr6Q==} + engines: {node: '>=18.18'} + + metro-cache-key@0.82.5: + resolution: {integrity: sha512-qpVmPbDJuRLrT4kcGlUouyqLGssJnbTllVtvIgXfR7ZuzMKf0mGS+8WzcqzNK8+kCyakombQWR0uDd8qhWGJcA==} + engines: {node: '>=18.18'} + + metro-cache@0.82.5: + resolution: {integrity: sha512-AwHV9607xZpedu1NQcjUkua8v7HfOTKfftl6Vc9OGr/jbpiJX6Gpy8E/V9jo/U9UuVYX2PqSUcVNZmu+LTm71Q==} + engines: {node: '>=18.18'} + + metro-config@0.82.5: + resolution: {integrity: sha512-/r83VqE55l0WsBf8IhNmc/3z71y2zIPe5kRSuqA5tY/SL/ULzlHUJEMd1szztd0G45JozLwjvrhAzhDPJ/Qo/g==} + engines: {node: '>=18.18'} + + metro-core@0.82.5: + resolution: {integrity: sha512-OJL18VbSw2RgtBm1f2P3J5kb892LCVJqMvslXxuxjAPex8OH7Eb8RBfgEo7VZSjgb/LOf4jhC4UFk5l5tAOHHA==} + engines: {node: '>=18.18'} + + metro-file-map@0.82.5: + resolution: {integrity: sha512-vpMDxkGIB+MTN8Af5hvSAanc6zXQipsAUO+XUx3PCQieKUfLwdoa8qaZ1WAQYRpaU+CJ8vhBcxtzzo3d9IsCIQ==} + engines: {node: '>=18.18'} + + metro-minify-terser@0.82.5: + resolution: {integrity: sha512-v6Nx7A4We6PqPu/ta1oGTqJ4Usz0P7c+3XNeBxW9kp8zayS3lHUKR0sY0wsCHInxZlNAEICx791x+uXytFUuwg==} + engines: {node: '>=18.18'} + + metro-resolver@0.82.5: + resolution: {integrity: sha512-kFowLnWACt3bEsuVsaRNgwplT8U7kETnaFHaZePlARz4Fg8tZtmRDUmjaD68CGAwc0rwdwNCkWizLYpnyVcs2g==} + engines: {node: '>=18.18'} + + metro-runtime@0.82.5: + resolution: {integrity: sha512-rQZDoCUf7k4Broyw3Ixxlq5ieIPiR1ULONdpcYpbJQ6yQ5GGEyYjtkztGD+OhHlw81LCR2SUAoPvtTus2WDK5g==} + engines: {node: '>=18.18'} + + metro-source-map@0.82.5: + resolution: {integrity: sha512-wH+awTOQJVkbhn2SKyaw+0cd+RVSCZ3sHVgyqJFQXIee/yLs3dZqKjjeKKhhVeudgjXo7aE/vSu/zVfcQEcUfw==} + engines: {node: '>=18.18'} + + metro-symbolicate@0.82.5: + resolution: {integrity: sha512-1u+07gzrvYDJ/oNXuOG1EXSvXZka/0JSW1q2EYBWerVKMOhvv9JzDGyzmuV7hHbF2Hg3T3S2uiM36sLz1qKsiw==} + engines: {node: '>=18.18'} + hasBin: true + + metro-transform-plugins@0.82.5: + resolution: {integrity: sha512-57Bqf3rgq9nPqLrT2d9kf/2WVieTFqsQ6qWHpEng5naIUtc/Iiw9+0bfLLWSAw0GH40iJ4yMjFcFJDtNSYynMA==} + engines: {node: '>=18.18'} + + metro-transform-worker@0.82.5: + resolution: {integrity: sha512-mx0grhAX7xe+XUQH6qoHHlWedI8fhSpDGsfga7CpkO9Lk9W+aPitNtJWNGrW8PfjKEWbT9Uz9O50dkI8bJqigw==} + engines: {node: '>=18.18'} + + metro@0.82.5: + resolution: {integrity: sha512-8oAXxL7do8QckID/WZEKaIFuQJFUTLzfVcC48ghkHhNK2RGuQq8Xvf4AVd+TUA0SZtX0q8TGNXZ/eba1ckeGCg==} + engines: {node: '>=18.18'} + hasBin: true + + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + mimic-fn@1.2.0: + resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} + engines: {node: '>=4'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + + mipd@0.0.7: + resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-postinstall@0.3.3: + resolution: {integrity: sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + nested-error-stacks@2.0.1: + resolution: {integrity: sha512-SrQrok4CATudVzBS7coSz26QRSmlK9TzzoFbeKfcPBUFPjcQM9Rqvr/DlJkOrwI/0KcgvMub1n1g5Jt9EgRn4A==} + + node-addon-api@2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-mock-http@1.0.2: + resolution: {integrity: sha512-zWaamgDUdo9SSLw47we78+zYw/bDr5gH8pH7oRRs8V3KmBtu8GLgGIbV2p/gRPd3LWpEOpjQj7X1FOU3VFMJ8g==} + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-package-arg@11.0.3: + resolution: {integrity: sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==} + engines: {node: ^16.14.0 || >=18.0.0} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nullthrows@1.1.1: + resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + + nwsapi@2.2.21: + resolution: {integrity: sha512-o6nIY3qwiSXl7/LuOU0Dmuctd34Yay0yeuZRLFmDPrrdHpXKFndPj3hM+YEPVHYC5fx2otBx4Ilc/gyYSAUaIA==} + + ob1@0.82.5: + resolution: {integrity: sha512-QyQQ6e66f+Ut/qUVjEce0E/wux5nAGLXYZDn1jr15JWstHsCH3l6VVrg8NKDptW9NEiBXKOJeGF/ydxeSDF3IQ==} + engines: {node: '>=18.18'} + + obj-multiplex@1.0.0: + resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + ofetch@1.4.1: + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + + on-finished@2.3.0: + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} + engines: {node: '>= 0.8'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@2.0.1: + resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} + engines: {node: '>=4'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@7.4.2: + resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} + engines: {node: '>=8'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@3.4.0: + resolution: {integrity: sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==} + engines: {node: '>=6'} + + ox@0.6.7: + resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.6.9: + resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.8.6: + resolution: {integrity: sha512-eiKcgiVVEGDtEpEdFi1EGoVVI48j6icXHce9nFwCNM7CKG3uoCXKdr4TPhS00Iy1TR2aWSF1ltPD0x/YgqIL9w==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-png@2.1.0: + resolution: {integrity: sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==} + engines: {node: '>=10'} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@3.0.1: + resolution: {integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==} + engines: {node: '>=10'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@5.0.0: + resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} + engines: {node: '>=10'} + + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + plist@3.1.0: + resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} + engines: {node: '>=10.4.0'} + + pngjs@3.4.0: + resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} + engines: {node: '>=4.0.0'} + + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + polished@4.3.1: + resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} + engines: {node: '>=10'} + + pony-cause@2.1.11: + resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} + engines: {node: '>=12.0.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + preact@10.24.2: + resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} + + preact@10.27.0: + resolution: {integrity: sha512-/DTYoB6mwwgPytiqQTh/7SFRL98ZdiD8Sk8zIUVOxtwq4oWcwrcd1uno9fE/zZmUaUrFNYzbH14CPebOz9tZQw==} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + pretty-bytes@5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + pretty-format@30.0.5: + resolution: {integrity: sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + proc-log@4.2.0: + resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise@8.3.0: + resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + proto3-json-serializer@2.0.2: + resolution: {integrity: sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==} + engines: {node: '>=14.0.0'} + + protobufjs@7.5.3: + resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==} + engines: {node: '>=12.0.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-compare@2.6.0: + resolution: {integrity: sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw==} + + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + pure-rand@7.0.1: + resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==} + + qrcode-terminal@0.11.0: + resolution: {integrity: sha512-Uu7ii+FQy4Qf82G4xu7ShHhjhGahEpCWc3x8UavY3CTcWV+ufmmCtwkr7ZKsX42jdL0kr1B5FKUeqJvAn51jzQ==} + hasBin: true + + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + queue@6.0.2: + resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-devtools-core@6.1.5: + resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==} + + react-error-boundary@3.1.4: + resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} + engines: {node: '>=10', npm: '>=6'} + peerDependencies: + react: '>=16.13.1' + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-freeze@1.0.4: + resolution: {integrity: sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==} + engines: {node: '>=10'} + peerDependencies: + react: '>=17.0.0' + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-is@19.1.1: + resolution: {integrity: sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==} + + react-native-animatable@1.4.0: + resolution: {integrity: sha512-DZwaDVWm2NBvBxf7I0wXKXLKb/TxDnkV53sWhCvei1pRyTX3MVFpkvdYBknNBqPrxYuAIlPxEp7gJOidIauUkw==} + + react-native-edge-to-edge@1.6.0: + resolution: {integrity: sha512-2WCNdE3Qd6Fwg9+4BpbATUxCLcouF6YRY7K+J36KJ4l3y+tWN6XCqAC4DuoGblAAbb2sLkhEDp4FOlbOIot2Og==} + peerDependencies: + react: '*' + react-native: '*' + + react-native-get-random-values@1.11.0: + resolution: {integrity: sha512-4BTbDbRmS7iPdhYLRcz3PGFIpFJBwNZg9g42iwa2P6FOv9vZj/xJc678RZXnLNZzd0qd7Q3CCF6Yd+CU2eoXKQ==} + peerDependencies: + react-native: '>=0.56' + + react-native-is-edge-to-edge@1.2.1: + resolution: {integrity: sha512-FLbPWl/MyYQWz+KwqOZsSyj2JmLKglHatd3xLZWskXOpRaio4LfEDEz8E/A6uD8QoTHW6Aobw1jbEwK7KMgR7Q==} + peerDependencies: + react: '*' + react-native: '*' + + react-native-modal@14.0.0-rc.1: + resolution: {integrity: sha512-v5pvGyx1FlmBzdHyPqBsYQyS2mIJhVmuXyNo5EarIzxicKhuoul6XasXMviGcXboEUT0dTYWs88/VendojPiVw==} + peerDependencies: + react: '*' + react-native: '>=0.70.0' + + react-native-safe-area-context@5.6.0: + resolution: {integrity: sha512-tJas3YOdsuCg3kepCTGF3LWZp9onMbb9Agju2xfs2kRX8d/5TMUPmupBpjerk/B7Tv/zeJnk+qp5neA96Y0otQ==} + peerDependencies: + react: '*' + react-native: '*' + + react-native-screens@4.14.1: + resolution: {integrity: sha512-/7zxVdk2H4BH/dvqpQQh45VCA05UeC+LCE8TPtGfjn5A+9/UJfKPB8LHhAcWxciLYfMCyW8J2u5dGLGQJH/Ecg==} + peerDependencies: + react: '*' + react-native: '*' + + react-native-svg@15.11.2: + resolution: {integrity: sha512-+YfF72IbWQUKzCIydlijV1fLuBsQNGMT6Da2kFlo1sh+LE3BIm/2Q7AR1zAAR6L0BFLi1WaQPLfFUC9bNZpOmw==} + peerDependencies: + react: '*' + react-native: '*' + + react-native-toast-message@2.3.3: + resolution: {integrity: sha512-4IIUHwUPvKHu4gjD0Vj2aGQzqPATiblL1ey8tOqsxOWRPGGu52iIbL8M/mCz4uyqecvPdIcMY38AfwRuUADfQQ==} + peerDependencies: + react: '*' + react-native: '*' + + react-native-url-polyfill@2.0.0: + resolution: {integrity: sha512-My330Do7/DvKnEvwQc0WdcBnFPploYKp9CYlefDXzIdEaA+PAhDYllkvGeEroEzvc4Kzzj2O4yVdz8v6fjRvhA==} + peerDependencies: + react-native: '*' + + react-native@0.79.5: + resolution: {integrity: sha512-jVihwsE4mWEHZ9HkO1J2eUZSwHyDByZOqthwnGrVZCh6kTQBCm4v8dicsyDa6p0fpWNE5KicTcpX/XXl0ASJFg==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@types/react': ^19.0.0 + react: ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + + react-test-renderer@19.0.0: + resolution: {integrity: sha512-oX5u9rOQlHzqrE/64CNr0HB0uWxkCQmZNSfozlYvwE71TLVgeZxVf0IjouGEr1v7r1kcDifdAJBeOhdhxsG/DA==} + peerDependencies: + react: ^19.0.0 + + react@19.0.0: + resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} + engines: {node: '>=0.10.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + regenerate-unicode-properties@10.2.0: + resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + + regexpu-core@6.2.0: + resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==} + engines: {node: '>=4'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.12.0: + resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} + hasBin: true + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + requireg@0.2.2: + resolution: {integrity: sha512-nYzyjnFcPNGR3lx9lwPPPnuQxv6JWEZd2Ci0u9opN7N5zUEPIhY/GbL3vMGOr2UXwEg9WwSyV9X9Y/kLFgPsOg==} + engines: {node: '>= 4.0.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@3.0.0: + resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} + engines: {node: '>=4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-workspace-root@2.0.0: + resolution: {integrity: sha512-IsaBUZETJD5WsI11Wt8PKHwaIe45or6pwNc8yflvLJ4DWtImK9kuLoH5kUva/2Mmx/RdIyr4aONNSa2v9LTJsw==} + + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@1.7.1: + resolution: {integrity: sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==} + + restore-cursor@2.0.0: + resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} + engines: {node: '>=4'} + + retry-request@7.0.2: + resolution: {integrity: sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==} + engines: {node: '>=14'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.25.0: + resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} + + schema-utils@4.3.2: + resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} + engines: {node: '>= 10.13.0'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + + send@0.19.1: + resolution: {integrity: sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg==} + engines: {node: '>= 0.8.0'} + + serialize-error@2.1.0: + resolution: {integrity: sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==} + engines: {node: '>=0.10.0'} + + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + + server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-plist@1.3.1: + resolution: {integrity: sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slugify@1.6.6: + resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} + engines: {node: '>=8.0.0'} + + socket.io-client@4.8.1: + resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} + engines: {node: '>=10.0.0'} + + socket.io-parser@4.2.4: + resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} + engines: {node: '>=10.0.0'} + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + + stacktrace-parser@0.1.11: + resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} + engines: {node: '>=6'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + stream-buffers@2.2.0: + resolution: {integrity: sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==} + engines: {node: '>= 0.10.0'} + + stream-events@1.0.5: + resolution: {integrity: sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strnum@1.1.2: + resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==} + + structured-headers@0.4.1: + resolution: {integrity: sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==} + + stubs@3.0.0: + resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + superstruct@1.0.4: + resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} + engines: {node: '>=14.0.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-hyperlinks@2.3.0: + resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + synckit@0.11.11: + resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + engines: {node: ^14.18.0 || >=16.0.0} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + teeny-request@9.0.0: + resolution: {integrity: sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==} + engines: {node: '>=14'} + + temp-dir@2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + + terminal-link@2.1.1: + resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} + engines: {node: '>=8'} + + terser@5.43.1: + resolution: {integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + + throat@5.0.0: + resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-buffer@1.2.1: + resolution: {integrity: sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==} + engines: {node: '>= 0.4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-deepmerge@2.0.7: + resolution: {integrity: sha512-3phiGcxPSSR47RBubQxPoZ+pqXsEsozLo4G4AlSrsMKTFg9TA3l+3he5BqpUi9wiuDbaHWXH/amlzQ49uEdXtg==} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + ts-jest@29.4.1: + resolution: {integrity: sha512-SaeUtjfpg9Uqu8IbeDKtdaS0g8lS6FT6OzM3ezrDfErPJPHNDo/Ey+VFGP1bQIDfagYDLyRpd7O15XpG1Es2Uw==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 || ^30.0.0 + '@jest/types': ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 + esbuild: '*' + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + jest-util: + optional: true + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.7.1: + resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} + engines: {node: '>=8'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + uint8arrays@3.1.0: + resolution: {integrity: sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@7.10.0: + resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + + undici@6.21.3: + resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} + engines: {node: '>=18.17'} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.0: + resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + + unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + unstorage@1.16.1: + resolution: {integrity: sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6.0.3 || ^7.0.0 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + use-latest-callback@0.2.4: + resolution: {integrity: sha512-LS2s2n1usUUnDq4oVh1ca6JFX9uSqUncTfAm44WMg0v6TxL7POUTk1B044NH8TeLkFbNajIsgDHcgNpNzZucdg==} + peerDependencies: + react: '>=16.8' + + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + use-sync-external-store@1.4.0: + resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + use-sync-external-store@1.5.0: + resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + uuid@7.0.3: + resolution: {integrity: sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==} + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + valtio@1.13.2: + resolution: {integrity: sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + viem@2.23.2: + resolution: {integrity: sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.33.3: + resolution: {integrity: sha512-aWDr6i6r3OfNCs0h9IieHFhn7xQJJ8YsuA49+9T5JRyGGAkWhLgcbLq2YMecgwM7HdUZpx1vPugZjsShqNi7Gw==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + vlq@1.0.1: + resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==} + + w3c-xmlserializer@4.0.0: + resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} + engines: {node: '>=14'} + + wagmi@2.16.3: + resolution: {integrity: sha512-CJkt6e+PKM7sNQOVcExY2SWHoDNNMdS1L5q5gLujiu8Ngi6T2V4YlHj0Sm40nVC+NsW4MZOfscsx12FbVJ0iug==} + peerDependencies: + '@tanstack/react-query': '>=5.0.0' + react: '>=18' + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + typescript: + optional: true + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + warn-once@0.1.1: + resolution: {integrity: sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + web-vitals@4.2.4: + resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} + + webextension-polyfill@0.10.0: + resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@5.0.0: + resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} + engines: {node: '>=8'} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + + whatwg-fetch@3.6.20: + resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url-without-unicode@8.0.0-3: + resolution: {integrity: sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==} + engines: {node: '>=10'} + + whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wonka@6.3.5: + resolution: {integrity: sha512-SSil+ecw6B4/Dm7Pf2sAshKQ5hWFvfyGlfPbEd6A14dOH6VDjrmbY86u6nZvy9omGwwIPFR8V41+of1EezgoUw==} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ws@6.2.3: + resolution: {integrity: sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.2: + resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xcode@3.0.1: + resolution: {integrity: sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==} + engines: {node: '>=10.0.0'} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xml2js@0.6.0: + resolution: {integrity: sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xmlbuilder@15.1.1: + resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} + engines: {node: '>=8.0'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + xmlhttprequest-ssl@2.1.2: + resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} + engines: {node: '>=0.4.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + + zustand@5.0.0: + resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + + zustand@5.0.3: + resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + +snapshots: + + '@0no-co/graphql.web@1.2.0': {} + + '@adraffy/ens-normalize@1.10.1': {} + + '@adraffy/ens-normalize@1.11.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.30 + + '@babel/code-frame@7.10.4': + dependencies: + '@babel/highlight': 7.25.9 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.0': {} + + '@babel/core@7.28.3': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/helpers': 7.28.3 + '@babel/parser': 7.28.3 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.3': + dependencies: + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.30 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.2 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.25.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.2.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + debug: 4.4.1 + lodash.debounce: 4.0.8 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.27.1': + dependencies: + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.28.2 + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.3 + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.3': + dependencies: + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.28.3': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + + '@babel/highlight@7.25.9': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/parser@7.28.3': + dependencies: + '@babel/types': 7.28.2 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-export-default-from@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-export-default-from@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-flow@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.3) + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoping@7.28.0(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/template': 7.27.2 + + '@babel/plugin-transform-destructuring@7.28.0(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-exponentiation-operator@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-flow': 7.27.1(@babel/core@7.28.3) + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-logical-assignment-operators@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-object-rest-spread@7.28.0(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) + '@babel/traverse': 7.28.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-optional-chaining@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-regenerator@7.28.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-runtime@7.28.3(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.3) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.3) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.3) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.3(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-create-regexp-features-plugin': 7.27.1(@babel/core@7.28.3) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/preset-env@7.28.3(@babel/core@7.28.3)': + dependencies: + '@babel/compat-data': 7.28.0 + '@babel/core': 7.28.3 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.3) + '@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.3) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-block-scoping': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-transform-classes': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-exponentiation-operator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-systemjs': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-object-rest-spread': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-regenerator': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.3) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.3) + babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.3) + babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.3) + babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.3) + core-js-compat: 3.45.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/types': 7.28.2 + esutils: 2.0.3 + + '@babel/preset-react@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.27.1(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.28.3': {} + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 + + '@babel/traverse@7.28.3': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.3 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.3 + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.2': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@base-org/account@1.1.1(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.8.3)(zod@3.22.4) + preact: 10.24.2 + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + zustand: 5.0.3(@types/react@19.0.14)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@bcoe/v8-coverage@0.2.3': {} + + '@coinbase/wallet-sdk@3.9.3': + dependencies: + bn.js: 5.2.2 + buffer: 6.0.3 + clsx: 1.2.1 + eth-block-tracker: 7.1.0 + eth-json-rpc-filters: 6.0.1 + eventemitter3: 5.0.1 + keccak: 3.0.4 + preact: 10.27.0 + sha.js: 2.4.12 + transitivePeerDependencies: + - supports-color + + '@coinbase/wallet-sdk@4.3.6(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.8.3)(zod@3.22.4) + preact: 10.24.2 + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + zustand: 5.0.3(@types/react@19.0.14)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@ecies/ciphers@0.2.4(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + + '@emnapi/core@1.4.5': + dependencies: + '@emnapi/wasi-threads': 1.0.4 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.4.5': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.0.4': + dependencies: + tslib: 2.8.1 + optional: true + + '@eslint-community/eslint-utils@4.7.0(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.4.1 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@ethereumjs/common@3.2.0': + dependencies: + '@ethereumjs/util': 8.1.0 + crc-32: 1.2.2 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/tx@4.2.0': + dependencies: + '@ethereumjs/common': 3.2.0 + '@ethereumjs/rlp': 4.0.1 + '@ethereumjs/util': 8.1.0 + ethereum-cryptography: 2.2.1 + + '@ethereumjs/util@8.1.0': + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.2.1 + micro-ftch: 0.3.1 + + '@expo/cli@0.24.20(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@0no-co/graphql.web': 1.2.0 + '@babel/runtime': 7.28.3 + '@expo/code-signing-certificates': 0.0.5 + '@expo/config': 11.0.13 + '@expo/config-plugins': 10.1.2 + '@expo/devcert': 1.2.0 + '@expo/env': 1.0.7 + '@expo/image-utils': 0.7.6 + '@expo/json-file': 9.1.5 + '@expo/metro-config': 0.20.17 + '@expo/osascript': 2.2.5 + '@expo/package-manager': 1.8.6 + '@expo/plist': 0.3.5 + '@expo/prebuild-config': 9.0.11 + '@expo/spawn-async': 1.7.2 + '@expo/ws-tunnel': 1.0.6 + '@expo/xcpretty': 4.3.2 + '@react-native/dev-middleware': 0.79.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@urql/core': 5.2.0 + '@urql/exchange-retry': 1.3.2(@urql/core@5.2.0) + accepts: 1.3.8 + arg: 5.0.2 + better-opn: 3.0.2 + bplist-creator: 0.1.0 + bplist-parser: 0.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + compression: 1.8.1 + connect: 3.7.0 + debug: 4.4.1 + env-editor: 0.4.2 + freeport-async: 2.0.0 + getenv: 2.0.0 + glob: 10.4.5 + lan-network: 0.1.7 + minimatch: 9.0.5 + node-forge: 1.3.1 + npm-package-arg: 11.0.3 + ora: 3.4.0 + picomatch: 3.0.1 + pretty-bytes: 5.6.0 + pretty-format: 29.7.0 + progress: 2.0.3 + prompts: 2.4.2 + qrcode-terminal: 0.11.0 + require-from-string: 2.0.2 + requireg: 0.2.2 + resolve: 1.22.10 + resolve-from: 5.0.0 + resolve.exports: 2.0.3 + semver: 7.7.2 + send: 0.19.1 + slugify: 1.6.6 + source-map-support: 0.5.21 + stacktrace-parser: 0.1.11 + structured-headers: 0.4.1 + tar: 7.4.3 + terminal-link: 2.1.1 + undici: 6.21.3 + wrap-ansi: 7.0.0 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - graphql + - supports-color + - utf-8-validate + + '@expo/code-signing-certificates@0.0.5': + dependencies: + node-forge: 1.3.1 + nullthrows: 1.1.1 + + '@expo/config-plugins@10.1.2': + dependencies: + '@expo/config-types': 53.0.5 + '@expo/json-file': 9.1.5 + '@expo/plist': 0.3.5 + '@expo/sdk-runtime-versions': 1.0.0 + chalk: 4.1.2 + debug: 4.4.1 + getenv: 2.0.0 + glob: 10.4.5 + resolve-from: 5.0.0 + semver: 7.7.2 + slash: 3.0.0 + slugify: 1.6.6 + xcode: 3.0.1 + xml2js: 0.6.0 + transitivePeerDependencies: + - supports-color + + '@expo/config-types@53.0.5': {} + + '@expo/config@11.0.13': + dependencies: + '@babel/code-frame': 7.10.4 + '@expo/config-plugins': 10.1.2 + '@expo/config-types': 53.0.5 + '@expo/json-file': 9.1.5 + deepmerge: 4.3.1 + getenv: 2.0.0 + glob: 10.4.5 + require-from-string: 2.0.2 + resolve-from: 5.0.0 + resolve-workspace-root: 2.0.0 + semver: 7.7.2 + slugify: 1.6.6 + sucrase: 3.35.0 + transitivePeerDependencies: + - supports-color + + '@expo/devcert@1.2.0': + dependencies: + '@expo/sudo-prompt': 9.3.2 + debug: 3.2.7 + glob: 10.4.5 + transitivePeerDependencies: + - supports-color + + '@expo/env@1.0.7': + dependencies: + chalk: 4.1.2 + debug: 4.4.1 + dotenv: 16.4.7 + dotenv-expand: 11.0.7 + getenv: 2.0.0 + transitivePeerDependencies: + - supports-color + + '@expo/fingerprint@0.13.4': + dependencies: + '@expo/spawn-async': 1.7.2 + arg: 5.0.2 + chalk: 4.1.2 + debug: 4.4.1 + find-up: 5.0.0 + getenv: 2.0.0 + glob: 10.4.5 + ignore: 5.3.2 + minimatch: 9.0.5 + p-limit: 3.1.0 + resolve-from: 5.0.0 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + + '@expo/image-utils@0.7.6': + dependencies: + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + getenv: 2.0.0 + jimp-compact: 0.16.1 + parse-png: 2.1.0 + resolve-from: 5.0.0 + semver: 7.7.2 + temp-dir: 2.0.0 + unique-string: 2.0.0 + + '@expo/json-file@9.1.5': + dependencies: + '@babel/code-frame': 7.10.4 + json5: 2.2.3 + + '@expo/metro-config@0.20.17': + dependencies: + '@babel/core': 7.28.3 + '@babel/generator': 7.28.3 + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 + '@expo/config': 11.0.13 + '@expo/env': 1.0.7 + '@expo/json-file': 9.1.5 + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + debug: 4.4.1 + dotenv: 16.4.7 + dotenv-expand: 11.0.7 + getenv: 2.0.0 + glob: 10.4.5 + jsc-safe-url: 0.2.4 + lightningcss: 1.27.0 + minimatch: 9.0.5 + postcss: 8.4.49 + resolve-from: 5.0.0 + transitivePeerDependencies: + - supports-color + + '@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))': + dependencies: + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + '@expo/osascript@2.2.5': + dependencies: + '@expo/spawn-async': 1.7.2 + exec-async: 2.2.0 + + '@expo/package-manager@1.8.6': + dependencies: + '@expo/json-file': 9.1.5 + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + npm-package-arg: 11.0.3 + ora: 3.4.0 + resolve-workspace-root: 2.0.0 + + '@expo/plist@0.3.5': + dependencies: + '@xmldom/xmldom': 0.8.10 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + + '@expo/prebuild-config@9.0.11': + dependencies: + '@expo/config': 11.0.13 + '@expo/config-plugins': 10.1.2 + '@expo/config-types': 53.0.5 + '@expo/image-utils': 0.7.6 + '@expo/json-file': 9.1.5 + '@react-native/normalize-colors': 0.79.5 + debug: 4.4.1 + resolve-from: 5.0.0 + semver: 7.7.2 + xml2js: 0.6.0 + transitivePeerDependencies: + - supports-color + + '@expo/sdk-runtime-versions@1.0.0': {} + + '@expo/server@0.6.3': + dependencies: + abort-controller: 3.0.0 + debug: 4.4.1 + source-map-support: 0.5.21 + undici: 6.21.3 + transitivePeerDependencies: + - supports-color + + '@expo/spawn-async@1.7.2': + dependencies: + cross-spawn: 7.0.6 + + '@expo/sudo-prompt@9.3.2': {} + + '@expo/vector-icons@14.1.0(expo-font@13.3.2(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + dependencies: + expo-font: 13.3.2(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + '@expo/ws-tunnel@1.0.6': {} + + '@expo/xcpretty@4.3.2': + dependencies: + '@babel/code-frame': 7.10.4 + chalk: 4.1.2 + find-up: 5.0.0 + js-yaml: 4.1.0 + + '@fastify/busboy@3.1.1': {} + + '@firebase/ai@2.1.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/app-check-interop-types': 0.3.3 + '@firebase/app-types': 0.9.3 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/analytics-compat@0.2.24(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1)': + dependencies: + '@firebase/analytics': 0.10.18(@firebase/app@0.14.1) + '@firebase/analytics-types': 0.8.3 + '@firebase/app-compat': 0.5.1 + '@firebase/component': 0.7.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + + '@firebase/analytics-types@0.8.3': {} + + '@firebase/analytics@0.10.18(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/installations': 0.6.19(@firebase/app@0.14.1) + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/app-check-compat@0.4.0(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1)': + dependencies: + '@firebase/app-check': 0.11.0(@firebase/app@0.14.1) + '@firebase/app-check-types': 0.5.3 + '@firebase/app-compat': 0.5.1 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + + '@firebase/app-check-interop-types@0.3.2': {} + + '@firebase/app-check-interop-types@0.3.3': {} + + '@firebase/app-check-types@0.5.3': {} + + '@firebase/app-check@0.11.0(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/app-compat@0.5.1': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/app-types@0.9.2': {} + + '@firebase/app-types@0.9.3': {} + + '@firebase/app@0.14.1': + dependencies: + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + idb: 7.1.1 + tslib: 2.8.1 + + '@firebase/auth-compat@0.6.0(@firebase/app-compat@0.5.1)(@firebase/app-types@0.9.3)(@firebase/app@0.14.1)(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))': + dependencies: + '@firebase/app-compat': 0.5.1 + '@firebase/auth': 1.11.0(@firebase/app@0.14.1)(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@firebase/auth-types': 0.13.0(@firebase/app-types@0.9.3)(@firebase/util@1.13.0) + '@firebase/component': 0.7.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + - '@firebase/app-types' + - '@react-native-async-storage/async-storage' + + '@firebase/auth-interop-types@0.2.3': {} + + '@firebase/auth-interop-types@0.2.4': {} + + '@firebase/auth-types@0.13.0(@firebase/app-types@0.9.3)(@firebase/util@1.13.0)': + dependencies: + '@firebase/app-types': 0.9.3 + '@firebase/util': 1.13.0 + + '@firebase/auth@1.11.0(@firebase/app@0.14.1)(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + optionalDependencies: + '@react-native-async-storage/async-storage': 2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + + '@firebase/component@0.6.9': + dependencies: + '@firebase/util': 1.10.0 + tslib: 2.8.1 + + '@firebase/component@0.7.0': + dependencies: + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/data-connect@0.3.11(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/auth-interop-types': 0.2.4 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/database-compat@1.0.8': + dependencies: + '@firebase/component': 0.6.9 + '@firebase/database': 1.0.8 + '@firebase/database-types': 1.0.5 + '@firebase/logger': 0.4.2 + '@firebase/util': 1.10.0 + tslib: 2.8.1 + + '@firebase/database-compat@2.1.0': + dependencies: + '@firebase/component': 0.7.0 + '@firebase/database': 1.1.0 + '@firebase/database-types': 1.0.16 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/database-types@1.0.16': + dependencies: + '@firebase/app-types': 0.9.3 + '@firebase/util': 1.13.0 + + '@firebase/database-types@1.0.5': + dependencies: + '@firebase/app-types': 0.9.2 + '@firebase/util': 1.10.0 + + '@firebase/database@1.0.8': + dependencies: + '@firebase/app-check-interop-types': 0.3.2 + '@firebase/auth-interop-types': 0.2.3 + '@firebase/component': 0.6.9 + '@firebase/logger': 0.4.2 + '@firebase/util': 1.10.0 + faye-websocket: 0.11.4 + tslib: 2.8.1 + + '@firebase/database@1.1.0': + dependencies: + '@firebase/app-check-interop-types': 0.3.3 + '@firebase/auth-interop-types': 0.2.4 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + faye-websocket: 0.11.4 + tslib: 2.8.1 + + '@firebase/firestore-compat@0.4.0(@firebase/app-compat@0.5.1)(@firebase/app-types@0.9.3)(@firebase/app@0.14.1)': + dependencies: + '@firebase/app-compat': 0.5.1 + '@firebase/component': 0.7.0 + '@firebase/firestore': 4.9.0(@firebase/app@0.14.1) + '@firebase/firestore-types': 3.0.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0) + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + - '@firebase/app-types' + + '@firebase/firestore-types@3.0.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0)': + dependencies: + '@firebase/app-types': 0.9.3 + '@firebase/util': 1.13.0 + + '@firebase/firestore@4.9.0(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + '@firebase/webchannel-wrapper': 1.0.4 + '@grpc/grpc-js': 1.9.15 + '@grpc/proto-loader': 0.7.15 + tslib: 2.8.1 + + '@firebase/functions-compat@0.4.0(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1)': + dependencies: + '@firebase/app-compat': 0.5.1 + '@firebase/component': 0.7.0 + '@firebase/functions': 0.13.0(@firebase/app@0.14.1) + '@firebase/functions-types': 0.6.3 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + + '@firebase/functions-types@0.6.3': {} + + '@firebase/functions@0.13.0(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/app-check-interop-types': 0.3.3 + '@firebase/auth-interop-types': 0.2.4 + '@firebase/component': 0.7.0 + '@firebase/messaging-interop-types': 0.2.3 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/installations-compat@0.2.19(@firebase/app-compat@0.5.1)(@firebase/app-types@0.9.3)(@firebase/app@0.14.1)': + dependencies: + '@firebase/app-compat': 0.5.1 + '@firebase/component': 0.7.0 + '@firebase/installations': 0.6.19(@firebase/app@0.14.1) + '@firebase/installations-types': 0.5.3(@firebase/app-types@0.9.3) + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + - '@firebase/app-types' + + '@firebase/installations-types@0.5.3(@firebase/app-types@0.9.3)': + dependencies: + '@firebase/app-types': 0.9.3 + + '@firebase/installations@0.6.19(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/util': 1.13.0 + idb: 7.1.1 + tslib: 2.8.1 + + '@firebase/logger@0.4.2': + dependencies: + tslib: 2.8.1 + + '@firebase/logger@0.5.0': + dependencies: + tslib: 2.8.1 + + '@firebase/messaging-compat@0.2.23(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1)': + dependencies: + '@firebase/app-compat': 0.5.1 + '@firebase/component': 0.7.0 + '@firebase/messaging': 0.12.23(@firebase/app@0.14.1) + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + + '@firebase/messaging-interop-types@0.2.3': {} + + '@firebase/messaging@0.12.23(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/installations': 0.6.19(@firebase/app@0.14.1) + '@firebase/messaging-interop-types': 0.2.3 + '@firebase/util': 1.13.0 + idb: 7.1.1 + tslib: 2.8.1 + + '@firebase/performance-compat@0.2.22(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1)': + dependencies: + '@firebase/app-compat': 0.5.1 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/performance': 0.7.9(@firebase/app@0.14.1) + '@firebase/performance-types': 0.2.3 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + + '@firebase/performance-types@0.2.3': {} + + '@firebase/performance@0.7.9(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/installations': 0.6.19(@firebase/app@0.14.1) + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + web-vitals: 4.2.4 + + '@firebase/remote-config-compat@0.2.19(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1)': + dependencies: + '@firebase/app-compat': 0.5.1 + '@firebase/component': 0.7.0 + '@firebase/logger': 0.5.0 + '@firebase/remote-config': 0.6.6(@firebase/app@0.14.1) + '@firebase/remote-config-types': 0.4.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + + '@firebase/remote-config-types@0.4.0': {} + + '@firebase/remote-config@0.6.6(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/installations': 0.6.19(@firebase/app@0.14.1) + '@firebase/logger': 0.5.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/storage-compat@0.4.0(@firebase/app-compat@0.5.1)(@firebase/app-types@0.9.3)(@firebase/app@0.14.1)': + dependencies: + '@firebase/app-compat': 0.5.1 + '@firebase/component': 0.7.0 + '@firebase/storage': 0.14.0(@firebase/app@0.14.1) + '@firebase/storage-types': 0.8.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0) + '@firebase/util': 1.13.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@firebase/app' + - '@firebase/app-types' + + '@firebase/storage-types@0.8.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0)': + dependencies: + '@firebase/app-types': 0.9.3 + '@firebase/util': 1.13.0 + + '@firebase/storage@0.14.0(@firebase/app@0.14.1)': + dependencies: + '@firebase/app': 0.14.1 + '@firebase/component': 0.7.0 + '@firebase/util': 1.13.0 + tslib: 2.8.1 + + '@firebase/util@1.10.0': + dependencies: + tslib: 2.8.1 + + '@firebase/util@1.13.0': + dependencies: + tslib: 2.8.1 + + '@firebase/webchannel-wrapper@1.0.4': {} + + '@gemini-wallet/core@0.1.1(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))': + dependencies: + '@metamask/rpc-errors': 7.0.2 + eventemitter3: 5.0.1 + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - supports-color + + '@google-cloud/firestore@7.11.3': + dependencies: + '@opentelemetry/api': 1.9.0 + fast-deep-equal: 3.1.3 + functional-red-black-tree: 1.0.1 + google-gax: 4.6.1 + protobufjs: 7.5.3 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + '@google-cloud/paginator@5.0.2': + dependencies: + arrify: 2.0.1 + extend: 3.0.2 + optional: true + + '@google-cloud/projectify@4.0.0': + optional: true + + '@google-cloud/promisify@4.0.0': + optional: true + + '@google-cloud/storage@7.16.0': + dependencies: + '@google-cloud/paginator': 5.0.2 + '@google-cloud/projectify': 4.0.0 + '@google-cloud/promisify': 4.0.0 + abort-controller: 3.0.0 + async-retry: 1.3.3 + duplexify: 4.1.3 + fast-xml-parser: 4.5.3 + gaxios: 6.7.1 + google-auth-library: 9.15.1 + html-entities: 2.6.0 + mime: 3.0.0 + p-limit: 3.1.0 + retry-request: 7.0.2 + teeny-request: 9.0.0 + uuid: 8.3.2 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + '@grpc/grpc-js@1.13.4': + dependencies: + '@grpc/proto-loader': 0.7.15 + '@js-sdsl/ordered-map': 4.4.2 + optional: true + + '@grpc/grpc-js@1.9.15': + dependencies: + '@grpc/proto-loader': 0.7.15 + '@types/node': 24.2.1 + + '@grpc/proto-loader@0.7.15': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.3.2 + protobufjs: 7.5.3 + yargs: 17.7.2 + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@isaacs/ttlcache@1.4.1': {} + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/console@30.0.5': + dependencies: + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + chalk: 4.1.2 + jest-message-util: 30.0.5 + jest-util: 30.0.5 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/core@30.0.5(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3))': + dependencies: + '@jest/console': 30.0.5 + '@jest/pattern': 30.0.1 + '@jest/reporters': 30.0.5 + '@jest/test-result': 30.0.5 + '@jest/transform': 30.0.5 + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 4.3.0 + exit-x: 0.2.2 + graceful-fs: 4.2.11 + jest-changed-files: 30.0.5 + jest-config: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + jest-haste-map: 30.0.5 + jest-message-util: 30.0.5 + jest-regex-util: 30.0.1 + jest-resolve: 30.0.5 + jest-resolve-dependencies: 30.0.5 + jest-runner: 30.0.5 + jest-runtime: 30.0.5 + jest-snapshot: 30.0.5 + jest-util: 30.0.5 + jest-validate: 30.0.5 + jest-watcher: 30.0.5 + micromatch: 4.0.8 + pretty-format: 30.0.5 + slash: 3.0.0 + transitivePeerDependencies: + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + + '@jest/create-cache-key-function@29.7.0': + dependencies: + '@jest/types': 29.6.3 + + '@jest/diff-sequences@30.0.1': {} + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + jest-mock: 29.7.0 + + '@jest/environment@30.0.5': + dependencies: + '@jest/fake-timers': 30.0.5 + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + jest-mock: 30.0.5 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect-utils@30.0.5': + dependencies: + '@jest/get-type': 30.0.1 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/expect@30.0.5': + dependencies: + expect: 30.0.5 + jest-snapshot: 30.0.5 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 24.2.1 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/fake-timers@30.0.5': + dependencies: + '@jest/types': 30.0.5 + '@sinonjs/fake-timers': 13.0.5 + '@types/node': 24.2.1 + jest-message-util: 30.0.5 + jest-mock: 30.0.5 + jest-util: 30.0.5 + + '@jest/get-type@30.0.1': {} + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/globals@30.0.5': + dependencies: + '@jest/environment': 30.0.5 + '@jest/expect': 30.0.5 + '@jest/types': 30.0.5 + jest-mock: 30.0.5 + transitivePeerDependencies: + - supports-color + + '@jest/pattern@30.0.1': + dependencies: + '@types/node': 24.2.1 + jest-regex-util: 30.0.1 + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.30 + '@types/node': 24.2.1 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@30.0.5': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 30.0.5 + '@jest/test-result': 30.0.5 + '@jest/transform': 30.0.5 + '@jest/types': 30.0.5 + '@jridgewell/trace-mapping': 0.3.30 + '@types/node': 24.2.1 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit-x: 0.2.2 + glob: 10.4.5 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + jest-message-util: 30.0.5 + jest-util: 30.0.5 + jest-worker: 30.0.5 + slash: 3.0.0 + string-length: 4.0.2 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/schemas@30.0.5': + dependencies: + '@sinclair/typebox': 0.34.38 + + '@jest/snapshot-utils@30.0.5': + dependencies: + '@jest/types': 30.0.5 + chalk: 4.1.2 + graceful-fs: 4.2.11 + natural-compare: 1.4.0 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.30 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/source-map@30.0.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.30 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-result@30.0.5': + dependencies: + '@jest/console': 30.0.5 + '@jest/types': 30.0.5 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/test-sequencer@30.0.5': + dependencies: + '@jest/test-result': 30.0.5 + graceful-fs: 4.2.11 + jest-haste-map: 30.0.5 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.28.3 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.30 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/transform@30.0.5': + dependencies: + '@babel/core': 7.28.3 + '@jest/types': 30.0.5 + '@jridgewell/trace-mapping': 0.3.30 + babel-plugin-istanbul: 7.0.0 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 30.0.5 + jest-regex-util: 30.0.1 + jest-util: 30.0.5 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 5.0.1 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.2.1 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@jest/types@30.0.5': + dependencies: + '@jest/pattern': 30.0.1 + '@jest/schemas': 30.0.5 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.2.1 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.30 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.30 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.30': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@js-sdsl/ordered-map@4.4.2': + optional: true + + '@lit-labs/ssr-dom-shim@1.4.0': {} + + '@lit/reactive-element@2.1.1': + dependencies: + '@lit-labs/ssr-dom-shim': 1.4.0 + + '@metamask/eth-json-rpc-provider@1.0.1': + dependencies: + '@metamask/json-rpc-engine': 7.3.3 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 5.0.2 + transitivePeerDependencies: + - supports-color + + '@metamask/json-rpc-engine@7.3.3': + dependencies: + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color + + '@metamask/json-rpc-engine@8.0.2': + dependencies: + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color + + '@metamask/json-rpc-middleware-stream@7.0.2': + dependencies: + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + readable-stream: 3.6.2 + transitivePeerDependencies: + - supports-color + + '@metamask/object-multiplex@2.1.0': + dependencies: + once: 1.4.0 + readable-stream: 3.6.2 + + '@metamask/onboarding@1.0.1': + dependencies: + bowser: 2.12.0 + + '@metamask/providers@16.1.0': + dependencies: + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/json-rpc-middleware-stream': 7.0.2 + '@metamask/object-multiplex': 2.1.0 + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + detect-browser: 5.3.0 + extension-port-stream: 3.0.0 + fast-deep-equal: 3.1.3 + is-stream: 2.0.1 + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + transitivePeerDependencies: + - supports-color + + '@metamask/rpc-errors@6.4.0': + dependencies: + '@metamask/utils': 9.3.0 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + + '@metamask/rpc-errors@7.0.2': + dependencies: + '@metamask/utils': 11.4.2 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + + '@metamask/safe-event-emitter@2.0.0': {} + + '@metamask/safe-event-emitter@3.1.2': {} + + '@metamask/sdk-communication-layer@0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + bufferutil: 4.0.9 + cross-fetch: 4.1.0 + date-fns: 2.30.0 + debug: 4.4.1 + eciesjs: 0.4.15 + eventemitter2: 6.4.9 + readable-stream: 3.6.2 + socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + utf-8-validate: 5.0.10 + uuid: 8.3.2 + transitivePeerDependencies: + - supports-color + + '@metamask/sdk-install-modal-web@0.32.0': + dependencies: + '@paulmillr/qr': 0.2.1 + + '@metamask/sdk@0.32.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.28.3 + '@metamask/onboarding': 1.0.1 + '@metamask/providers': 16.1.0 + '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0)(eciesjs@0.4.15)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metamask/sdk-install-modal-web': 0.32.0 + '@paulmillr/qr': 0.2.1 + bowser: 2.12.0 + cross-fetch: 4.1.0 + debug: 4.4.1 + eciesjs: 0.4.15 + eth-rpc-errors: 4.0.3 + eventemitter2: 6.4.9 + obj-multiplex: 1.0.0 + pump: 3.0.3 + readable-stream: 3.6.2 + socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + tslib: 2.8.1 + util: 0.12.5 + uuid: 8.3.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metamask/superstruct@3.2.1': {} + + '@metamask/utils@11.4.2': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.1 + lodash.memoize: 4.1.2 + pony-cause: 2.1.11 + semver: 7.7.2 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@5.0.2': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@types/debug': 4.1.12 + debug: 4.4.1 + semver: 7.7.2 + superstruct: 1.0.4 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@8.5.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.1 + pony-cause: 2.1.11 + semver: 7.7.2 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@9.3.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.1 + pony-cause: 2.1.11 + semver: 7.7.2 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.4.5 + '@emnapi/runtime': 1.4.5 + '@tybys/wasm-util': 0.10.0 + optional: true + + '@noble/ciphers@1.2.1': {} + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/curves@1.9.2': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.6': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.3.2': {} + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.7.0': {} + + '@noble/hashes@1.7.1': {} + + '@noble/hashes@1.8.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@opentelemetry/api@1.9.0': + optional: true + + '@paulmillr/qr@0.2.1': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.2.9': {} + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.0.14)(react@19.0.0)': + dependencies: + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.14 + + '@radix-ui/react-slot@1.2.0(@types/react@19.0.14)(react@19.0.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.0.14)(react@19.0.0) + react: 19.0.0 + optionalDependencies: + '@types/react': 19.0.14 + + '@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))': + dependencies: + merge-options: 3.0.4 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + '@react-native-community/netinfo@11.4.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))': + dependencies: + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + '@react-native/assets-registry@0.79.5': {} + + '@react-native/babel-plugin-codegen@0.79.5(@babel/core@7.28.3)': + dependencies: + '@babel/traverse': 7.28.3 + '@react-native/codegen': 0.79.5(@babel/core@7.28.3) + transitivePeerDependencies: + - '@babel/core' + - supports-color + + '@react-native/babel-preset@0.79.5(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.28.3) + '@babel/plugin-syntax-export-default-from': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.3) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.3) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-block-scoping': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-classes': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-destructuring': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-logical-assignment-operators': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-object-rest-spread': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-optional-chaining': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-regenerator': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-transform-runtime': 7.28.3(@babel/core@7.28.3) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.3) + '@babel/template': 7.27.2 + '@react-native/babel-plugin-codegen': 0.79.5(@babel/core@7.28.3) + babel-plugin-syntax-hermes-parser: 0.25.1 + babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.28.3) + react-refresh: 0.14.2 + transitivePeerDependencies: + - supports-color + + '@react-native/codegen@0.79.5(@babel/core@7.28.3)': + dependencies: + '@babel/core': 7.28.3 + glob: 7.2.3 + hermes-parser: 0.25.1 + invariant: 2.2.4 + nullthrows: 1.1.1 + yargs: 17.7.2 + + '@react-native/community-cli-plugin@0.79.5(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@react-native/dev-middleware': 0.79.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + chalk: 4.1.2 + debug: 2.6.9 + invariant: 2.2.4 + metro: 0.82.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + metro-config: 0.82.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + metro-core: 0.82.5 + semver: 7.7.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@react-native/debugger-frontend@0.79.5': {} + + '@react-native/dev-middleware@0.79.5(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@isaacs/ttlcache': 1.4.1 + '@react-native/debugger-frontend': 0.79.5 + chrome-launcher: 0.15.2 + chromium-edge-launcher: 0.2.0 + connect: 3.7.0 + debug: 2.6.9 + invariant: 2.2.4 + nullthrows: 1.1.1 + open: 7.4.2 + serve-static: 1.16.2 + ws: 6.2.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@react-native/gradle-plugin@0.79.5': {} + + '@react-native/js-polyfills@0.79.5': {} + + '@react-native/normalize-colors@0.79.5': {} + + '@react-native/virtualized-lists@0.79.5(@types/react@19.0.14)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + dependencies: + invariant: 2.2.4 + nullthrows: 1.1.1 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + optionalDependencies: + '@types/react': 19.0.14 + + '@react-navigation/bottom-tabs@7.4.6(@react-navigation/native@7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-safe-area-context@5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-screens@4.14.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + dependencies: + '@react-navigation/elements': 2.6.3(@react-navigation/native@7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-safe-area-context@5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@react-navigation/native': 7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + color: 4.2.3 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-safe-area-context: 5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react-native-screens: 4.14.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + transitivePeerDependencies: + - '@react-native-masked-view/masked-view' + + '@react-navigation/core@7.12.4(react@19.0.0)': + dependencies: + '@react-navigation/routers': 7.5.1 + escape-string-regexp: 4.0.0 + nanoid: 3.3.11 + query-string: 7.1.3 + react: 19.0.0 + react-is: 19.1.1 + use-latest-callback: 0.2.4(react@19.0.0) + use-sync-external-store: 1.5.0(react@19.0.0) + + '@react-navigation/elements@2.6.3(@react-navigation/native@7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-safe-area-context@5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + dependencies: + '@react-navigation/native': 7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + color: 4.2.3 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-safe-area-context: 5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + use-latest-callback: 0.2.4(react@19.0.0) + use-sync-external-store: 1.5.0(react@19.0.0) + + '@react-navigation/native-stack@7.3.25(@react-navigation/native@7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-safe-area-context@5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-screens@4.14.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + dependencies: + '@react-navigation/elements': 2.6.3(@react-navigation/native@7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-safe-area-context@5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@react-navigation/native': 7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-safe-area-context: 5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react-native-screens: 4.14.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + warn-once: 0.1.1 + transitivePeerDependencies: + - '@react-native-masked-view/masked-view' + + '@react-navigation/native@7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + dependencies: + '@react-navigation/core': 7.12.4(react@19.0.0) + escape-string-regexp: 4.0.0 + fast-deep-equal: 3.1.3 + nanoid: 3.3.11 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + use-latest-callback: 0.2.4(react@19.0.0) + + '@react-navigation/routers@7.5.1': + dependencies: + nanoid: 3.3.11 + + '@reown/appkit-common-react-native@1.3.0': + dependencies: + bignumber.js: 9.1.2 + dayjs: 1.11.10 + + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + valtio: 1.13.2(@types/react@19.0.14)(react@19.0.0) + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-core-react-native@1.3.0(4ec877573a446b3f23231d35e8aefcd5)': + dependencies: + '@react-native-async-storage/async-storage': 2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + '@reown/appkit-common-react-native': 1.3.0 + '@walletconnect/react-native-compat': 2.21.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@react-native-community/netinfo@11.4.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-application@6.1.5(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)))(react-native-get-random-values@1.11.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + countries-and-timezones: 3.7.2 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + valtio: 1.13.2(@types/react@19.0.14)(react@19.0.0) + transitivePeerDependencies: + - '@types/react' + + '@reown/appkit-pay@1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-controllers': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-ui': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-utils': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.0.14)(react@19.0.0))(zod@3.22.4) + lit: 3.3.0 + valtio: 1.13.2(@types/react@19.0.14)(react@19.0.0) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-polyfills@1.7.8': + dependencies: + buffer: 6.0.3 + + '@reown/appkit-scaffold-react-native@1.3.0(2cd6adc1223ff687c47c77ab966a2176)': + dependencies: + '@reown/appkit-common-react-native': 1.3.0 + '@reown/appkit-core-react-native': 1.3.0(4ec877573a446b3f23231d35e8aefcd5) + '@reown/appkit-siwe-react-native': 1.3.0(2cd6adc1223ff687c47c77ab966a2176) + '@reown/appkit-ui-react-native': 1.3.0(react-native-svg@15.11.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@walletconnect/react-native-compat' + - '@walletconnect/utils' + - react-native-svg + + '@reown/appkit-scaffold-ui@1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.0.14)(react@19.0.0))(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-controllers': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-ui': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-utils': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.0.14)(react@19.0.0))(zod@3.22.4) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + lit: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - valtio + - zod + + '@reown/appkit-scaffold-utils-react-native@1.3.0(2cd6adc1223ff687c47c77ab966a2176)': + dependencies: + '@reown/appkit-common-react-native': 1.3.0 + '@reown/appkit-scaffold-react-native': 1.3.0(2cd6adc1223ff687c47c77ab966a2176) + transitivePeerDependencies: + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@walletconnect/react-native-compat' + - '@walletconnect/utils' + - react + - react-native + - react-native-svg + + '@reown/appkit-siwe-react-native@1.3.0(2cd6adc1223ff687c47c77ab966a2176)': + dependencies: + '@reown/appkit-common-react-native': 1.3.0 + '@reown/appkit-core-react-native': 1.3.0(4ec877573a446b3f23231d35e8aefcd5) + '@reown/appkit-ui-react-native': 1.3.0(react-native-svg@15.11.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@walletconnect/utils': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + valtio: 1.13.2(@types/react@19.0.14)(react@19.0.0) + transitivePeerDependencies: + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@walletconnect/react-native-compat' + - react + - react-native + - react-native-svg + + '@reown/appkit-ui-react-native@1.3.0(react-native-svg@15.11.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + dependencies: + polished: 4.3.1 + qrcode: 1.5.3 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-svg: 15.11.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + + '@reown/appkit-ui@1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-controllers': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + lit: 3.3.0 + qrcode: 1.5.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-utils@1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.0.14)(react@19.0.0))(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-controllers': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/logger': 2.1.2 + '@walletconnect/universal-provider': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + valtio: 1.13.2(@types/react@19.0.14)(react@19.0.0) + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-wagmi-react-native@1.3.0(133be0e5730d6722e74a0d74112aa8a1)': + dependencies: + '@react-native-async-storage/async-storage': 2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + '@react-native-community/netinfo': 11.4.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + '@reown/appkit-common-react-native': 1.3.0 + '@reown/appkit-scaffold-react-native': 1.3.0(2cd6adc1223ff687c47c77ab966a2176) + '@reown/appkit-scaffold-utils-react-native': 1.3.0(2cd6adc1223ff687c47c77ab966a2176) + '@reown/appkit-siwe-react-native': 1.3.0(2cd6adc1223ff687c47c77ab966a2176) + '@walletconnect/react-native-compat': 2.21.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@react-native-community/netinfo@11.4.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-application@6.1.5(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)))(react-native-get-random-values@1.11.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-get-random-values: 1.11.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + wagmi: 2.16.3(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.85.3)(@tanstack/react-query@5.85.3(react@19.0.0))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + transitivePeerDependencies: + - '@types/react' + - '@walletconnect/utils' + - react-native-svg + + '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-polyfills': 1.7.8 + '@walletconnect/logger': 2.1.2 + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@reown/appkit@1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-controllers': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-pay': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-scaffold-ui': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.0.14)(react@19.0.0))(zod@3.22.4) + '@reown/appkit-ui': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-utils': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.0.14)(react@19.0.0))(zod@3.22.4) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/universal-provider': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@19.0.14)(react@19.0.0) + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + events: 3.3.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@safe-global/safe-gateway-typescript-sdk': 3.23.1 + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-gateway-typescript-sdk@3.23.1': {} + + '@scure/base@1.1.9': {} + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip32@1.6.2': + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.6 + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.2 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.5.4': + dependencies: + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@sinclair/typebox@0.27.8': {} + + '@sinclair/typebox@0.34.38': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@sinonjs/fake-timers@13.0.5': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@socket.io/component-emitter@3.1.2': {} + + '@tanstack/query-core@5.85.3': {} + + '@tanstack/react-query@5.85.3(react@19.0.0)': + dependencies: + '@tanstack/query-core': 5.85.3 + react: 19.0.0 + + '@testing-library/react-hooks@8.0.1(@types/react@19.0.14)(react-test-renderer@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@babel/runtime': 7.28.3 + react: 19.0.0 + react-error-boundary: 3.1.4(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.14 + react-test-renderer: 19.0.0(react@19.0.0) + + '@testing-library/react-native@12.9.0(jest@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react-test-renderer@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + jest-matcher-utils: 29.7.0 + pretty-format: 29.7.0 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-test-renderer: 19.0.0(react@19.0.0) + redent: 3.0.0 + optionalDependencies: + jest: 29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + + '@tootallnate/once@2.0.0': {} + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@tybys/wasm-util@0.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.2 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.2 + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 24.2.1 + + '@types/caseless@0.12.5': + optional: true + + '@types/connect@3.4.38': + dependencies: + '@types/node': 24.2.1 + + '@types/cors@2.8.19': + dependencies: + '@types/node': 24.2.1 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/express-serve-static-core@4.19.6': + dependencies: + '@types/node': 24.2.1 + '@types/qs': 6.14.0 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.5 + + '@types/express@4.17.23': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.6 + '@types/qs': 6.14.0 + '@types/serve-static': 1.15.8 + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 24.2.1 + + '@types/http-errors@2.0.5': {} + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@29.5.14': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + '@types/jest@30.0.0': + dependencies: + expect: 30.0.5 + pretty-format: 30.0.5 + + '@types/jsdom@20.0.1': + dependencies: + '@types/node': 24.2.1 + '@types/tough-cookie': 4.0.5 + parse5: 7.3.0 + + '@types/json-schema@7.0.15': {} + + '@types/jsonwebtoken@9.0.10': + dependencies: + '@types/ms': 2.1.0 + '@types/node': 24.2.1 + + '@types/lodash@4.17.20': {} + + '@types/long@4.0.2': + optional: true + + '@types/mime@1.3.5': {} + + '@types/ms@2.1.0': {} + + '@types/node@22.17.1': + dependencies: + undici-types: 6.21.0 + + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 + + '@types/node@24.2.1': + dependencies: + undici-types: 7.10.0 + + '@types/qs@6.14.0': {} + + '@types/range-parser@1.2.7': {} + + '@types/react@19.0.14': + dependencies: + csstype: 3.1.3 + + '@types/request@2.48.13': + dependencies: + '@types/caseless': 0.12.5 + '@types/node': 24.2.1 + '@types/tough-cookie': 4.0.5 + form-data: 2.5.5 + optional: true + + '@types/semver@7.7.0': {} + + '@types/send@0.17.5': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 24.2.1 + + '@types/serve-static@1.15.8': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 24.2.1 + '@types/send': 0.17.5 + + '@types/stack-utils@2.0.3': {} + + '@types/tough-cookie@4.0.5': {} + + '@types/trusted-types@2.0.7': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.33': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3) + debug: 4.4.1 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.7.2 + tsutils: 3.21.0(typescript@5.8.3) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) + debug: 4.4.1 + eslint: 8.57.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.40.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.8.3) + '@typescript-eslint/types': 8.40.0 + debug: 4.4.1 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + + '@typescript-eslint/scope-manager@8.40.0': + dependencies: + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/visitor-keys': 8.40.0 + + '@typescript-eslint/tsconfig-utils@8.40.0(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 + + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@5.8.3)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.8.3) + debug: 4.4.1 + eslint: 8.57.1 + tsutils: 3.21.0(typescript@5.8.3) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@5.62.0': {} + + '@typescript-eslint/types@8.40.0': {} + + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.4.1 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.7.2 + tsutils: 3.21.0(typescript@5.8.3) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.40.0(typescript@5.8.3)': + dependencies: + '@typescript-eslint/project-service': 8.40.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.8.3) + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/visitor-keys': 8.40.0 + debug: 4.4.1 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.0 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.8.3) + eslint: 8.57.1 + eslint-scope: 5.1.1 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@8.40.0(eslint@8.57.1)(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) + '@typescript-eslint/scope-manager': 8.40.0 + '@typescript-eslint/types': 8.40.0 + '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.8.3) + eslint: 8.57.1 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + + '@typescript-eslint/visitor-keys@8.40.0': + dependencies: + '@typescript-eslint/types': 8.40.0 + eslint-visitor-keys: 4.2.1 + + '@ungap/structured-clone@1.3.0': {} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + '@urql/core@5.2.0': + dependencies: + '@0no-co/graphql.web': 1.2.0 + wonka: 6.3.5 + transitivePeerDependencies: + - graphql + + '@urql/exchange-retry@1.3.2(@urql/core@5.2.0)': + dependencies: + '@urql/core': 5.2.0 + wonka: 6.3.5 + + '@wagmi/connectors@5.9.3(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.3)(@types/react@19.0.14)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)))(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(utf-8-validate@5.0.10)(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)': + dependencies: + '@base-org/account': 1.1.1(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(utf-8-validate@5.0.10)(zod@3.22.4) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(utf-8-validate@5.0.10)(zod@3.22.4) + '@gemini-wallet/core': 0.1.1(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)) + '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.3)(@types/react@19.0.14)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)) + '@walletconnect/ethereum-provider': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - immer + - ioredis + - react + - supports-color + - uploadthing + - use-sync-external-store + - utf-8-validate + - zod + + '@wagmi/core@2.19.0(@tanstack/query-core@5.85.3)(@types/react@19.0.14)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))': + dependencies: + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.8.3) + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + zustand: 5.0.0(@types/react@19.0.14)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)) + optionalDependencies: + '@tanstack/query-core': 5.85.3 + typescript: 5.8.3 + transitivePeerDependencies: + - '@types/react' + - immer + - react + - use-sync-external-store + + '@walletconnect/core@2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/utils': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/core@2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/utils': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/ethereum-provider@2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@reown/appkit': 1.7.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/sign-client': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/types': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/universal-provider': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/utils': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-http-connection@1.0.8': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + cross-fetch: 3.2.0 + events: 3.3.0 + transitivePeerDependencies: + - encoding + + '@walletconnect/jsonrpc-provider@1.0.14': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-types@1.0.4': + dependencies: + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 + + '@walletconnect/jsonrpc-utils@1.0.8': + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@walletconnect/keyvaluestorage@1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.2 + unstorage: 1.16.1(idb-keyval@6.2.2) + optionalDependencies: + '@react-native-async-storage/async-storage': 2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/logger@2.1.2': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + + '@walletconnect/react-native-compat@2.21.8(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@react-native-community/netinfo@11.4.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(expo-application@6.1.5(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)))(react-native-get-random-values@1.11.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))': + dependencies: + '@react-native-async-storage/async-storage': 2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + '@react-native-community/netinfo': 11.4.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + events: 3.3.0 + fast-text-encoding: 1.0.6 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-get-random-values: 1.11.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + react-native-url-polyfill: 2.0.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + optionalDependencies: + expo-application: 6.1.5(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)) + + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.4 + + '@walletconnect/relay-auth@1.1.0': + dependencies: + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + uint8arrays: 3.1.0 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/sign-client@2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@walletconnect/core': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/utils': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/sign-client@2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@walletconnect/core': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/utils': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/types@2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/types@2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/universal-provider@2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/types': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/utils': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/universal-provider@2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@walletconnect/types': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/utils': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/utils@2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/utils@2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/window-getters@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/window-metadata@1.0.1': + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + + '@xmldom/xmldom@0.8.10': {} + + abab@2.0.6: {} + + abitype@1.0.8(typescript@5.8.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.8.3 + zod: 3.22.4 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-globals@7.0.1: + dependencies: + acorn: 8.15.0 + acorn-walk: 8.3.4 + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + aes-js@4.0.0-beta.5: {} + + agent-base@6.0.2: + dependencies: + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + agent-base@7.1.4: {} + + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + anser@1.4.10: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@4.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-flatten@1.1.1: {} + + array-union@2.1.0: {} + + arrify@2.0.1: + optional: true + + asap@2.0.6: {} + + async-limiter@1.0.1: {} + + async-mutex@0.2.6: + dependencies: + tslib: 2.8.1 + + async-retry@1.3.3: + dependencies: + retry: 0.13.1 + optional: true + + asynckit@0.4.0: {} + + atomic-sleep@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + babel-jest@29.7.0(@babel/core@7.28.3): + dependencies: + '@babel/core': 7.28.3 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.28.3) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-jest@30.0.5(@babel/core@7.28.3): + dependencies: + '@babel/core': 7.28.3 + '@jest/transform': 30.0.5 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 7.0.0 + babel-preset-jest: 30.0.1(@babel/core@7.28.3) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@7.0.0: + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 6.0.3 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + + babel-plugin-jest-hoist@30.0.1: + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + '@types/babel__core': 7.20.5 + + babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.3): + dependencies: + '@babel/compat-data': 7.28.0 + '@babel/core': 7.28.3 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.3): + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) + core-js-compat: 3.45.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.3): + dependencies: + '@babel/core': 7.28.3 + '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.3) + transitivePeerDependencies: + - supports-color + + babel-plugin-react-native-web@0.19.13: {} + + babel-plugin-syntax-hermes-parser@0.25.1: + dependencies: + hermes-parser: 0.25.1 + + babel-plugin-transform-flow-enums@0.0.2(@babel/core@7.28.3): + dependencies: + '@babel/plugin-syntax-flow': 7.27.1(@babel/core@7.28.3) + transitivePeerDependencies: + - '@babel/core' + + babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.3): + dependencies: + '@babel/core': 7.28.3 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.3) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.3) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.3) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.3) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.3) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.3) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.3) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.3) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.3) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.3) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.3) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.3) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.3) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.3) + + babel-preset-expo@13.2.3(@babel/core@7.28.3): + dependencies: + '@babel/helper-module-imports': 7.27.1 + '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-export-default-from': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-object-rest-spread': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.3) + '@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-transform-runtime': 7.28.3(@babel/core@7.28.3) + '@babel/preset-react': 7.27.1(@babel/core@7.28.3) + '@babel/preset-typescript': 7.27.1(@babel/core@7.28.3) + '@react-native/babel-preset': 0.79.5(@babel/core@7.28.3) + babel-plugin-react-native-web: 0.19.13 + babel-plugin-syntax-hermes-parser: 0.25.1 + babel-plugin-transform-flow-enums: 0.0.2(@babel/core@7.28.3) + debug: 4.4.1 + react-refresh: 0.14.2 + resolve-from: 5.0.0 + transitivePeerDependencies: + - '@babel/core' + - supports-color + + babel-preset-jest@29.6.3(@babel/core@7.28.3): + dependencies: + '@babel/core': 7.28.3 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.3) + + babel-preset-jest@30.0.1(@babel/core@7.28.3): + dependencies: + '@babel/core': 7.28.3 + babel-plugin-jest-hoist: 30.0.1 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.3) + + balanced-match@1.0.2: {} + + base-x@5.0.1: {} + + base64-js@1.5.1: {} + + better-opn@3.0.2: + dependencies: + open: 8.4.2 + + big-integer@1.6.52: {} + + big.js@6.2.2: {} + + bignumber.js@9.1.2: {} + + bignumber.js@9.3.1: + optional: true + + bn.js@5.2.2: {} + + body-parser@1.20.3: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + bowser@2.12.0: {} + + bplist-creator@0.1.0: + dependencies: + stream-buffers: 2.2.0 + + bplist-parser@0.3.1: + dependencies: + big-integer: 1.6.52 + + bplist-parser@0.3.2: + dependencies: + big-integer: 1.6.52 + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.25.2: + dependencies: + caniuse-lite: 1.0.30001735 + electron-to-chromium: 1.5.200 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.25.2) + + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + + bs58@6.0.0: + dependencies: + base-x: 5.0.1 + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-equal-constant-time@1.0.1: {} + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.0.9: + dependencies: + node-gyp-build: 4.8.4 + + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + caller-callsite@2.0.0: + dependencies: + callsites: 2.0.0 + + caller-path@2.0.0: + dependencies: + caller-callsite: 2.0.0 + + callsites@2.0.0: {} + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001735: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + char-regex@1.0.2: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chownr@3.0.0: {} + + chrome-launcher@0.15.2: + dependencies: + '@types/node': 24.2.1 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 1.4.2 + transitivePeerDependencies: + - supports-color + + chromium-edge-launcher@0.2.0: + dependencies: + '@types/node': 24.2.1 + escape-string-regexp: 4.0.0 + is-wsl: 2.2.0 + lighthouse-logger: 1.4.2 + mkdirp: 1.0.4 + rimraf: 3.0.2 + transitivePeerDependencies: + - supports-color + + ci-info@2.0.0: {} + + ci-info@3.9.0: {} + + ci-info@4.3.0: {} + + cjs-module-lexer@1.4.3: {} + + cjs-module-lexer@2.1.0: {} + + cli-cursor@2.1.0: + dependencies: + restore-cursor: 2.0.0 + + cli-spinners@2.9.2: {} + + client-only@0.0.1: {} + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@1.0.4: {} + + clsx@1.2.1: {} + + co@4.6.0: {} + + collect-v8-coverage@1.0.2: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@12.1.0: {} + + commander@2.20.3: {} + + commander@4.1.1: {} + + commander@7.2.0: {} + + compressible@2.0.18: + dependencies: + mime-db: 1.54.0 + + compression@1.8.1: + dependencies: + bytes: 3.1.2 + compressible: 2.0.18 + debug: 2.6.9 + negotiator: 0.6.4 + on-headers: 1.1.0 + safe-buffer: 5.2.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + concat-map@0.0.1: {} + + connect@3.7.0: + dependencies: + debug: 2.6.9 + finalhandler: 1.1.2 + parseurl: 1.3.3 + utils-merge: 1.0.1 + transitivePeerDependencies: + - supports-color + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-es@1.2.2: {} + + cookie-signature@1.0.6: {} + + cookie@0.7.1: {} + + core-js-compat@3.45.0: + dependencies: + browserslist: 4.25.2 + + core-util-is@1.0.3: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cosmiconfig@5.2.1: + dependencies: + import-fresh: 2.0.0 + is-directory: 0.3.1 + js-yaml: 3.14.1 + parse-json: 4.0.0 + + countries-and-timezones@3.7.2: {} + + crc-32@1.2.2: {} + + create-jest@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: {} + + cross-fetch@3.2.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-fetch@4.1.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + crypto-random-string@2.0.0: {} + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-what@6.2.2: {} + + cssom@0.3.8: {} + + cssom@0.5.0: {} + + cssstyle@2.3.0: + dependencies: + cssom: 0.3.8 + + csstype@3.1.3: {} + + data-urls@3.0.2: + dependencies: + abab: 2.0.6 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + + date-fns@2.30.0: + dependencies: + '@babel/runtime': 7.28.3 + + dayjs@1.11.10: {} + + dayjs@1.11.13: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + debug@4.4.1: + dependencies: + ms: 2.1.3 + + decamelize@1.2.0: {} + + decimal.js@10.6.0: {} + + decode-uri-component@0.2.2: {} + + dedent@1.6.0: {} + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + defu@6.1.4: {} + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.0.14)(react@19.0.0)): + dependencies: + valtio: 1.13.2(@types/react@19.0.14)(react@19.0.0) + + destr@2.0.5: {} + + destroy@1.2.0: {} + + detect-browser@5.3.0: {} + + detect-libc@1.0.3: {} + + detect-newline@3.1.0: {} + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + dijkstrajs@1.0.3: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domexception@4.0.0: + dependencies: + webidl-conversions: 7.0.0 + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dotenv-expand@11.0.7: + dependencies: + dotenv: 16.4.7 + + dotenv@16.4.7: {} + + dotenv@17.2.1: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + + eastasianwidth@0.2.0: {} + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + eciesjs@0.4.15: + dependencies: + '@ecies/ciphers': 0.2.4(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.200: {} + + emittery@0.13.1: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encode-utf8@1.0.3: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + engine.io-parser: 5.2.3 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + xmlhttprequest-ssl: 2.1.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + engine.io-parser@5.2.3: {} + + entities@4.5.0: {} + + entities@6.0.1: {} + + env-editor@0.4.2: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-toolkit@1.33.0: {} + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + escape-string-regexp@4.0.0: {} + + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + + eslint-plugin-jest@29.0.1(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(jest@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)))(typescript@5.8.3): + dependencies: + '@typescript-eslint/utils': 8.40.0(eslint@8.57.1)(typescript@5.8.3) + eslint: 8.57.1 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) + jest: 29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-react-native-globals@0.1.2: {} + + eslint-plugin-react-native@5.0.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-plugin-react-native-globals: 0.1.2 + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.1 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eth-block-tracker@7.1.0: + dependencies: + '@metamask/eth-json-rpc-provider': 1.0.1 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 5.0.2 + json-rpc-random-id: 1.0.1 + pify: 3.0.0 + transitivePeerDependencies: + - supports-color + + eth-json-rpc-filters@6.0.1: + dependencies: + '@metamask/safe-event-emitter': 3.1.2 + async-mutex: 0.2.6 + eth-query: 2.1.2 + json-rpc-engine: 6.1.0 + pify: 5.0.0 + + eth-query@2.1.2: + dependencies: + json-rpc-random-id: 1.0.1 + xtend: 4.0.2 + + eth-rpc-errors@4.0.3: + dependencies: + fast-safe-stringify: 2.1.1 + + ethereum-cryptography@2.2.1: + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + + ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + event-target-shim@5.0.1: {} + + eventemitter2@6.4.9: {} + + eventemitter3@5.0.1: {} + + events@3.3.0: {} + + exec-async@2.2.0: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + exit-x@0.2.2: {} + + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + expect@30.0.5: + dependencies: + '@jest/expect-utils': 30.0.5 + '@jest/get-type': 30.0.1 + jest-matcher-utils: 30.0.5 + jest-message-util: 30.0.5 + jest-mock: 30.0.5 + jest-util: 30.0.5 + + expo-application@6.1.5(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)): + dependencies: + expo: 53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) + + expo-asset@11.1.7(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + '@expo/image-utils': 0.7.6 + expo: 53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) + expo-constants: 17.1.7(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - supports-color + + expo-constants@17.1.7(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)): + dependencies: + '@expo/config': 11.0.13 + '@expo/env': 1.0.7 + expo: 53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - supports-color + + expo-file-system@18.1.11(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)): + dependencies: + expo: 53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + expo-font@13.3.2(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + expo: 53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) + fontfaceobserver: 2.3.0 + react: 19.0.0 + + expo-keep-awake@14.1.4(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + expo: 53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) + react: 19.0.0 + + expo-linking@7.1.7(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + expo-constants: 17.1.7(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + invariant: 2.2.4 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - expo + - supports-color + + expo-modules-autolinking@2.1.14: + dependencies: + '@expo/spawn-async': 1.7.2 + chalk: 4.1.2 + commander: 7.2.0 + find-up: 5.0.0 + glob: 10.4.5 + require-from-string: 2.0.2 + resolve-from: 5.0.0 + + expo-modules-core@2.5.0: + dependencies: + invariant: 2.2.4 + + expo-router@5.1.4(1c3cde4edf21b16c04251477b594b823): + dependencies: + '@expo/metro-runtime': 5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + '@expo/server': 0.6.3 + '@radix-ui/react-slot': 1.2.0(@types/react@19.0.14)(react@19.0.0) + '@react-navigation/bottom-tabs': 7.4.6(@react-navigation/native@7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-safe-area-context@5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-screens@4.14.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@react-navigation/native': 7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@react-navigation/native-stack': 7.3.25(@react-navigation/native@7.1.17(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-safe-area-context@5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native-screens@4.14.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + client-only: 0.0.1 + expo: 53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) + expo-constants: 17.1.7(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + expo-linking: 7.1.7(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + invariant: 2.2.4 + react-fast-compare: 3.2.2 + react-native-is-edge-to-edge: 1.2.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react-native-safe-area-context: 5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react-native-screens: 4.14.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + schema-utils: 4.3.2 + semver: 7.6.3 + server-only: 0.0.1 + shallowequal: 1.1.0 + transitivePeerDependencies: + - '@react-native-masked-view/masked-view' + - '@types/react' + - react + - react-native + - supports-color + + expo-secure-store@14.2.3(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10)): + dependencies: + expo: 53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10) + + expo-status-bar@2.2.3(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-edge-to-edge: 1.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + react-native-is-edge-to-edge: 1.2.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + + expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10): + dependencies: + '@babel/runtime': 7.28.3 + '@expo/cli': 0.24.20(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@expo/config': 11.0.13 + '@expo/config-plugins': 10.1.2 + '@expo/fingerprint': 0.13.4 + '@expo/metro-config': 0.20.17 + '@expo/vector-icons': 14.1.0(expo-font@13.3.2(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + babel-preset-expo: 13.2.3(@babel/core@7.28.3) + expo-asset: 11.1.7(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + expo-constants: 17.1.7(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + expo-file-system: 18.1.11(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + expo-font: 13.3.2(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + expo-keep-awake: 14.1.4(expo@53.0.20(@babel/core@7.28.3)(@expo/metro-runtime@5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + expo-modules-autolinking: 2.1.14 + expo-modules-core: 2.5.0 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-edge-to-edge: 1.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + whatwg-url-without-unicode: 8.0.0-3 + optionalDependencies: + '@expo/metro-runtime': 5.0.4(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)) + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-react-compiler + - bufferutil + - graphql + - supports-color + - utf-8-validate + + exponential-backoff@3.1.2: {} + + express@4.21.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.12 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend@3.0.2: + optional: true + + extension-port-stream@3.0.0: + dependencies: + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + + farmhash-modern@1.1.0: {} + + fast-base64-decode@1.0.0: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-redact@3.5.0: {} + + fast-safe-stringify@2.1.1: {} + + fast-text-encoding@1.0.6: {} + + fast-uri@3.0.6: {} + + fast-xml-parser@4.5.3: + dependencies: + strnum: 1.1.2 + optional: true + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + faye-websocket@0.11.4: + dependencies: + websocket-driver: 0.7.4 + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + filter-obj@1.1.0: {} + + finalhandler@1.1.2: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.3.0 + parseurl: 1.3.3 + statuses: 1.5.0 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + finalhandler@1.3.1: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + firebase-admin@12.7.0: + dependencies: + '@fastify/busboy': 3.1.1 + '@firebase/database-compat': 1.0.8 + '@firebase/database-types': 1.0.5 + '@types/node': 22.17.1 + farmhash-modern: 1.1.0 + jsonwebtoken: 9.0.2 + jwks-rsa: 3.2.0 + node-forge: 1.3.1 + uuid: 10.0.0 + optionalDependencies: + '@google-cloud/firestore': 7.11.3 + '@google-cloud/storage': 7.16.0 + transitivePeerDependencies: + - encoding + - supports-color + + firebase-functions-test@3.4.1(firebase-admin@12.7.0)(firebase-functions@6.4.0(firebase-admin@12.7.0))(jest@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3))): + dependencies: + '@types/lodash': 4.17.20 + firebase-admin: 12.7.0 + firebase-functions: 6.4.0(firebase-admin@12.7.0) + jest: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + lodash: 4.17.21 + ts-deepmerge: 2.0.7 + + firebase-functions@6.4.0(firebase-admin@12.7.0): + dependencies: + '@types/cors': 2.8.19 + '@types/express': 4.17.23 + cors: 2.8.5 + express: 4.21.2 + firebase-admin: 12.7.0 + protobufjs: 7.5.3 + transitivePeerDependencies: + - supports-color + + firebase@12.1.0(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))): + dependencies: + '@firebase/ai': 2.1.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.1) + '@firebase/analytics': 0.10.18(@firebase/app@0.14.1) + '@firebase/analytics-compat': 0.2.24(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1) + '@firebase/app': 0.14.1 + '@firebase/app-check': 0.11.0(@firebase/app@0.14.1) + '@firebase/app-check-compat': 0.4.0(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1) + '@firebase/app-compat': 0.5.1 + '@firebase/app-types': 0.9.3 + '@firebase/auth': 1.11.0(@firebase/app@0.14.1)(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@firebase/auth-compat': 0.6.0(@firebase/app-compat@0.5.1)(@firebase/app-types@0.9.3)(@firebase/app@0.14.1)(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))) + '@firebase/data-connect': 0.3.11(@firebase/app@0.14.1) + '@firebase/database': 1.1.0 + '@firebase/database-compat': 2.1.0 + '@firebase/firestore': 4.9.0(@firebase/app@0.14.1) + '@firebase/firestore-compat': 0.4.0(@firebase/app-compat@0.5.1)(@firebase/app-types@0.9.3)(@firebase/app@0.14.1) + '@firebase/functions': 0.13.0(@firebase/app@0.14.1) + '@firebase/functions-compat': 0.4.0(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1) + '@firebase/installations': 0.6.19(@firebase/app@0.14.1) + '@firebase/installations-compat': 0.2.19(@firebase/app-compat@0.5.1)(@firebase/app-types@0.9.3)(@firebase/app@0.14.1) + '@firebase/messaging': 0.12.23(@firebase/app@0.14.1) + '@firebase/messaging-compat': 0.2.23(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1) + '@firebase/performance': 0.7.9(@firebase/app@0.14.1) + '@firebase/performance-compat': 0.2.22(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1) + '@firebase/remote-config': 0.6.6(@firebase/app@0.14.1) + '@firebase/remote-config-compat': 0.2.19(@firebase/app-compat@0.5.1)(@firebase/app@0.14.1) + '@firebase/storage': 0.14.0(@firebase/app@0.14.1) + '@firebase/storage-compat': 0.4.0(@firebase/app-compat@0.5.1)(@firebase/app-types@0.9.3)(@firebase/app@0.14.1) + '@firebase/util': 1.13.0 + transitivePeerDependencies: + - '@react-native-async-storage/async-storage' + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.3.3: {} + + flow-enums-runtime@0.0.6: {} + + fontfaceobserver@2.3.0: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@2.5.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + safe-buffer: 5.2.1 + optional: true + + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + freeport-async@2.0.0: {} + + fresh@0.5.2: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + functional-red-black-tree@1.0.1: + optional: true + + gaxios@6.7.1: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + is-stream: 2.0.1 + node-fetch: 2.7.0 + uuid: 9.0.1 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + gcp-metadata@6.1.1: + dependencies: + gaxios: 6.7.1 + google-logging-utils: 0.0.2 + json-bigint: 1.0.0 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + 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 + + get-package-type@0.1.0: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@6.0.1: {} + + getenv@2.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + google-auth-library@9.15.1: + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 6.7.1 + gcp-metadata: 6.1.1 + gtoken: 7.1.0 + jws: 4.0.0 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + google-gax@4.6.1: + dependencies: + '@grpc/grpc-js': 1.13.4 + '@grpc/proto-loader': 0.7.15 + '@types/long': 4.0.2 + abort-controller: 3.0.0 + duplexify: 4.1.3 + google-auth-library: 9.15.1 + node-fetch: 2.7.0 + object-hash: 3.0.0 + proto3-json-serializer: 2.0.2 + protobufjs: 7.5.3 + retry-request: 7.0.2 + uuid: 9.0.1 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + google-logging-utils@0.0.2: + optional: true + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + gtoken@7.1.0: + dependencies: + gaxios: 6.7.1 + jws: 4.0.0 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + h3@1.15.4: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.5 + defu: 6.1.4 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.2 + radix3: 1.1.2 + ufo: 1.6.1 + uncrypto: 0.1.3 + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hermes-estree@0.25.1: {} + + hermes-estree@0.29.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + + hermes-parser@0.29.1: + dependencies: + hermes-estree: 0.29.1 + + hosted-git-info@7.0.2: + dependencies: + lru-cache: 10.4.3 + + html-encoding-sniffer@3.0.0: + dependencies: + whatwg-encoding: 2.0.0 + + html-entities@2.6.0: + optional: true + + html-escaper@2.0.2: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-parser-js@0.5.10: {} + + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + human-signals@2.1.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + idb-keyval@6.2.1: {} + + idb-keyval@6.2.2: {} + + idb@7.1.1: {} + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + image-size@1.2.1: + dependencies: + queue: 6.0.2 + + import-fresh@2.0.0: + dependencies: + caller-path: 2.0.0 + resolve-from: 3.0.0 + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + ipaddr.js@1.9.1: {} + + iron-webcrypto@1.2.1: {} + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-arrayish@0.2.1: {} + + is-arrayish@0.3.2: {} + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-directory@0.3.1: {} + + is-docker@2.2.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-generator-fn@2.1.0: {} + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@2.1.0: {} + + is-potential-custom-element-name@1.0.1: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-stream@2.0.1: {} + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + isows@1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.28.3 + '@babel/parser': 7.28.3 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.28.3 + '@babel/parser': 7.28.3 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.30 + debug: 4.4.1 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-changed-files@30.0.5: + dependencies: + execa: 5.1.1 + jest-util: 30.0.5 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.6.0 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-circus@30.0.5: + dependencies: + '@jest/environment': 30.0.5 + '@jest/expect': 30.0.5 + '@jest/test-result': 30.0.5 + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.6.0 + is-generator-fn: 2.1.0 + jest-each: 30.0.5 + jest-matcher-utils: 30.0.5 + jest-message-util: 30.0.5 + jest-runtime: 30.0.5 + jest-snapshot: 30.0.5 + jest-util: 30.0.5 + p-limit: 3.1.0 + pretty-format: 30.0.5 + pure-rand: 7.0.1 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-cli@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)): + dependencies: + '@jest/core': 30.0.5(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + '@jest/test-result': 30.0.5 + '@jest/types': 30.0.5 + chalk: 4.1.2 + exit-x: 0.2.2 + import-local: 3.2.0 + jest-config: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + jest-util: 30.0.5 + jest-validate: 30.0.5 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)): + dependencies: + '@babel/core': 7.28.3 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.28.3) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 24.2.1 + ts-node: 10.9.2(@types/node@24.2.1)(typescript@5.8.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-config@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)): + dependencies: + '@babel/core': 7.28.3 + '@jest/get-type': 30.0.1 + '@jest/pattern': 30.0.1 + '@jest/test-sequencer': 30.0.5 + '@jest/types': 30.0.5 + babel-jest: 30.0.5(@babel/core@7.28.3) + chalk: 4.1.2 + ci-info: 4.3.0 + deepmerge: 4.3.1 + glob: 10.4.5 + graceful-fs: 4.2.11 + jest-circus: 30.0.5 + jest-docblock: 30.0.1 + jest-environment-node: 30.0.5 + jest-regex-util: 30.0.1 + jest-resolve: 30.0.5 + jest-runner: 30.0.5 + jest-util: 30.0.5 + jest-validate: 30.0.5 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 30.0.5 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 24.2.1 + ts-node: 10.9.2(@types/node@24.2.1)(typescript@5.8.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-diff@30.0.5: + dependencies: + '@jest/diff-sequences': 30.0.1 + '@jest/get-type': 30.0.1 + chalk: 4.1.2 + pretty-format: 30.0.5 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-docblock@30.0.1: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-each@30.0.5: + dependencies: + '@jest/get-type': 30.0.1 + '@jest/types': 30.0.5 + chalk: 4.1.2 + jest-util: 30.0.5 + pretty-format: 30.0.5 + + jest-environment-jsdom@29.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/jsdom': 20.0.1 + '@types/node': 24.2.1 + jest-mock: 29.7.0 + jest-util: 29.7.0 + jsdom: 20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-environment-node@30.0.5: + dependencies: + '@jest/environment': 30.0.5 + '@jest/fake-timers': 30.0.5 + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + jest-mock: 30.0.5 + jest-util: 30.0.5 + jest-validate: 30.0.5 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 24.2.1 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-haste-map@30.0.5: + dependencies: + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 30.0.1 + jest-util: 30.0.5 + jest-worker: 30.0.5 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-leak-detector@30.0.5: + dependencies: + '@jest/get-type': 30.0.1 + pretty-format: 30.0.5 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@30.0.5: + dependencies: + '@jest/get-type': 30.0.1 + chalk: 4.1.2 + jest-diff: 30.0.5 + pretty-format: 30.0.5 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-message-util@30.0.5: + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 30.0.5 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 30.0.5 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + jest-util: 29.7.0 + + jest-mock@30.0.5: + dependencies: + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + jest-util: 30.0.5 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@30.0.5): + optionalDependencies: + jest-resolve: 30.0.5 + + jest-regex-util@29.6.3: {} + + jest-regex-util@30.0.1: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve-dependencies@30.0.5: + dependencies: + jest-regex-util: 30.0.1 + jest-snapshot: 30.0.5 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.10 + resolve.exports: 2.0.3 + slash: 3.0.0 + + jest-resolve@30.0.5: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 30.0.5 + jest-pnp-resolver: 1.2.3(jest-resolve@30.0.5) + jest-util: 30.0.5 + jest-validate: 30.0.5 + slash: 3.0.0 + unrs-resolver: 1.11.1 + + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runner@30.0.5: + dependencies: + '@jest/console': 30.0.5 + '@jest/environment': 30.0.5 + '@jest/test-result': 30.0.5 + '@jest/transform': 30.0.5 + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + chalk: 4.1.2 + emittery: 0.13.1 + exit-x: 0.2.2 + graceful-fs: 4.2.11 + jest-docblock: 30.0.1 + jest-environment-node: 30.0.5 + jest-haste-map: 30.0.5 + jest-leak-detector: 30.0.5 + jest-message-util: 30.0.5 + jest-resolve: 30.0.5 + jest-runtime: 30.0.5 + jest-util: 30.0.5 + jest-watcher: 30.0.5 + jest-worker: 30.0.5 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-runtime@30.0.5: + dependencies: + '@jest/environment': 30.0.5 + '@jest/fake-timers': 30.0.5 + '@jest/globals': 30.0.5 + '@jest/source-map': 30.0.1 + '@jest/test-result': 30.0.5 + '@jest/transform': 30.0.5 + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + chalk: 4.1.2 + cjs-module-lexer: 2.1.0 + collect-v8-coverage: 1.0.2 + glob: 10.4.5 + graceful-fs: 4.2.11 + jest-haste-map: 30.0.5 + jest-message-util: 30.0.5 + jest-mock: 30.0.5 + jest-regex-util: 30.0.1 + jest-resolve: 30.0.5 + jest-snapshot: 30.0.5 + jest-util: 30.0.5 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.28.3 + '@babel/generator': 7.28.3 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.3) + '@babel/types': 7.28.2 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.3) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + + jest-snapshot@30.0.5: + dependencies: + '@babel/core': 7.28.3 + '@babel/generator': 7.28.3 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.3) + '@babel/types': 7.28.2 + '@jest/expect-utils': 30.0.5 + '@jest/get-type': 30.0.1 + '@jest/snapshot-utils': 30.0.5 + '@jest/transform': 30.0.5 + '@jest/types': 30.0.5 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.3) + chalk: 4.1.2 + expect: 30.0.5 + graceful-fs: 4.2.11 + jest-diff: 30.0.5 + jest-matcher-utils: 30.0.5 + jest-message-util: 30.0.5 + jest-util: 30.0.5 + pretty-format: 30.0.5 + semver: 7.7.2 + synckit: 0.11.11 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-util@30.0.5: + dependencies: + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + chalk: 4.1.2 + ci-info: 4.3.0 + graceful-fs: 4.2.11 + picomatch: 4.0.3 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-validate@30.0.5: + dependencies: + '@jest/get-type': 30.0.1 + '@jest/types': 30.0.5 + camelcase: 6.3.0 + chalk: 4.1.2 + leven: 3.1.0 + pretty-format: 30.0.5 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.2.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-watcher@30.0.5: + dependencies: + '@jest/test-result': 30.0.5 + '@jest/types': 30.0.5 + '@types/node': 24.2.1 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 30.0.5 + string-length: 4.0.2 + + jest-worker@29.7.0: + dependencies: + '@types/node': 24.2.1 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest-worker@30.0.5: + dependencies: + '@types/node': 24.2.1 + '@ungap/structured-clone': 1.3.0 + jest-util: 30.0.5 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)): + dependencies: + '@jest/core': 30.0.5(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + '@jest/types': 30.0.5 + import-local: 3.2.0 + jest-cli: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - esbuild-register + - supports-color + - ts-node + + jimp-compact@0.16.1: {} + + jose@4.15.9: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsc-safe-url@0.2.4: {} + + jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + abab: 2.0.6 + acorn: 8.15.0 + acorn-globals: 7.0.1 + cssom: 0.5.0 + cssstyle: 2.3.0 + data-urls: 3.0.2 + decimal.js: 10.6.0 + domexception: 4.0.0 + escodegen: 2.1.0 + form-data: 4.0.4 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.21 + parse5: 7.3.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 4.1.4 + w3c-xmlserializer: 4.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsesc@3.0.2: {} + + jsesc@3.1.0: {} + + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.3.1 + optional: true + + json-buffer@3.0.1: {} + + json-parse-better-errors@1.0.2: {} + + json-parse-even-better-errors@2.3.1: {} + + json-rpc-engine@6.1.0: + dependencies: + '@metamask/safe-event-emitter': 2.0.0 + eth-rpc-errors: 4.0.3 + + json-rpc-random-id@1.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jsonwebtoken@9.0.2: + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 7.7.2 + + jwa@1.4.2: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + optional: true + + jwks-rsa@3.2.0: + dependencies: + '@types/express': 4.17.23 + '@types/jsonwebtoken': 9.0.10 + debug: 4.4.1 + jose: 4.15.9 + limiter: 1.1.5 + lru-memoizer: 2.3.0 + transitivePeerDependencies: + - supports-color + + jws@3.2.2: + dependencies: + jwa: 1.4.2 + safe-buffer: 5.2.1 + + jws@4.0.0: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + optional: true + + keccak@3.0.4: + dependencies: + node-addon-api: 2.0.2 + node-gyp-build: 4.8.4 + readable-stream: 3.6.2 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + keyvaluestorage-interface@1.0.0: {} + + kleur@3.0.3: {} + + lan-network@0.1.7: {} + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lighthouse-logger@1.4.2: + dependencies: + debug: 2.6.9 + marky: 1.3.0 + transitivePeerDependencies: + - supports-color + + lightningcss-darwin-arm64@1.27.0: + optional: true + + lightningcss-darwin-x64@1.27.0: + optional: true + + lightningcss-freebsd-x64@1.27.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.27.0: + optional: true + + lightningcss-linux-arm64-gnu@1.27.0: + optional: true + + lightningcss-linux-arm64-musl@1.27.0: + optional: true + + lightningcss-linux-x64-gnu@1.27.0: + optional: true + + lightningcss-linux-x64-musl@1.27.0: + optional: true + + lightningcss-win32-arm64-msvc@1.27.0: + optional: true + + lightningcss-win32-x64-msvc@1.27.0: + optional: true + + lightningcss@1.27.0: + dependencies: + detect-libc: 1.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.27.0 + lightningcss-darwin-x64: 1.27.0 + lightningcss-freebsd-x64: 1.27.0 + lightningcss-linux-arm-gnueabihf: 1.27.0 + lightningcss-linux-arm64-gnu: 1.27.0 + lightningcss-linux-arm64-musl: 1.27.0 + lightningcss-linux-x64-gnu: 1.27.0 + lightningcss-linux-x64-musl: 1.27.0 + lightningcss-win32-arm64-msvc: 1.27.0 + lightningcss-win32-x64-msvc: 1.27.0 + + limiter@1.1.5: {} + + lines-and-columns@1.2.4: {} + + lit-element@4.2.1: + dependencies: + '@lit-labs/ssr-dom-shim': 1.4.0 + '@lit/reactive-element': 2.1.1 + lit-html: 3.3.1 + + lit-html@3.3.1: + dependencies: + '@types/trusted-types': 2.0.7 + + lit@3.3.0: + dependencies: + '@lit/reactive-element': 2.1.1 + lit-element: 4.2.1 + lit-html: 3.3.1 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.camelcase@4.3.0: {} + + lodash.clonedeep@4.5.0: {} + + lodash.debounce@4.0.8: {} + + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + + lodash.memoize@4.1.2: {} + + lodash.merge@4.6.2: {} + + lodash.once@4.1.1: {} + + lodash.throttle@4.1.1: {} + + lodash@4.17.21: {} + + log-symbols@2.2.0: + dependencies: + chalk: 2.4.2 + + long@5.3.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru-memoizer@2.3.0: + dependencies: + lodash.clonedeep: 4.5.0 + lru-cache: 6.0.0 + + make-dir@4.0.0: + dependencies: + semver: 7.7.2 + + make-error@1.3.6: {} + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + marky@1.3.0: {} + + math-intrinsics@1.1.0: {} + + mdn-data@2.0.14: {} + + media-typer@0.3.0: {} + + memoize-one@5.2.1: {} + + merge-descriptors@1.0.3: {} + + merge-options@3.0.4: + dependencies: + is-plain-obj: 2.1.0 + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + metro-babel-transformer@0.82.5: + dependencies: + '@babel/core': 7.28.3 + flow-enums-runtime: 0.0.6 + hermes-parser: 0.29.1 + nullthrows: 1.1.1 + transitivePeerDependencies: + - supports-color + + metro-cache-key@0.82.5: + dependencies: + flow-enums-runtime: 0.0.6 + + metro-cache@0.82.5: + dependencies: + exponential-backoff: 3.1.2 + flow-enums-runtime: 0.0.6 + https-proxy-agent: 7.0.6 + metro-core: 0.82.5 + transitivePeerDependencies: + - supports-color + + metro-config@0.82.5(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + connect: 3.7.0 + cosmiconfig: 5.2.1 + flow-enums-runtime: 0.0.6 + jest-validate: 29.7.0 + metro: 0.82.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + metro-cache: 0.82.5 + metro-core: 0.82.5 + metro-runtime: 0.82.5 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + metro-core@0.82.5: + dependencies: + flow-enums-runtime: 0.0.6 + lodash.throttle: 4.1.1 + metro-resolver: 0.82.5 + + metro-file-map@0.82.5: + dependencies: + debug: 4.4.1 + fb-watchman: 2.0.2 + flow-enums-runtime: 0.0.6 + graceful-fs: 4.2.11 + invariant: 2.2.4 + jest-worker: 29.7.0 + micromatch: 4.0.8 + nullthrows: 1.1.1 + walker: 1.0.8 + transitivePeerDependencies: + - supports-color + + metro-minify-terser@0.82.5: + dependencies: + flow-enums-runtime: 0.0.6 + terser: 5.43.1 + + metro-resolver@0.82.5: + dependencies: + flow-enums-runtime: 0.0.6 + + metro-runtime@0.82.5: + dependencies: + '@babel/runtime': 7.28.3 + flow-enums-runtime: 0.0.6 + + metro-source-map@0.82.5: + dependencies: + '@babel/traverse': 7.28.3 + '@babel/traverse--for-generate-function-map': '@babel/traverse@7.28.3' + '@babel/types': 7.28.2 + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + metro-symbolicate: 0.82.5 + nullthrows: 1.1.1 + ob1: 0.82.5 + source-map: 0.5.7 + vlq: 1.0.1 + transitivePeerDependencies: + - supports-color + + metro-symbolicate@0.82.5: + dependencies: + flow-enums-runtime: 0.0.6 + invariant: 2.2.4 + metro-source-map: 0.82.5 + nullthrows: 1.1.1 + source-map: 0.5.7 + vlq: 1.0.1 + transitivePeerDependencies: + - supports-color + + metro-transform-plugins@0.82.5: + dependencies: + '@babel/core': 7.28.3 + '@babel/generator': 7.28.3 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.3 + flow-enums-runtime: 0.0.6 + nullthrows: 1.1.1 + transitivePeerDependencies: + - supports-color + + metro-transform-worker@0.82.5(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@babel/core': 7.28.3 + '@babel/generator': 7.28.3 + '@babel/parser': 7.28.3 + '@babel/types': 7.28.2 + flow-enums-runtime: 0.0.6 + metro: 0.82.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + metro-babel-transformer: 0.82.5 + metro-cache: 0.82.5 + metro-cache-key: 0.82.5 + metro-minify-terser: 0.82.5 + metro-source-map: 0.82.5 + metro-transform-plugins: 0.82.5 + nullthrows: 1.1.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + metro@0.82.5(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.28.3 + '@babel/generator': 7.28.3 + '@babel/parser': 7.28.3 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.3 + '@babel/types': 7.28.2 + accepts: 1.3.8 + chalk: 4.1.2 + ci-info: 2.0.0 + connect: 3.7.0 + debug: 4.4.1 + error-stack-parser: 2.1.4 + flow-enums-runtime: 0.0.6 + graceful-fs: 4.2.11 + hermes-parser: 0.29.1 + image-size: 1.2.1 + invariant: 2.2.4 + jest-worker: 29.7.0 + jsc-safe-url: 0.2.4 + lodash.throttle: 4.1.1 + metro-babel-transformer: 0.82.5 + metro-cache: 0.82.5 + metro-cache-key: 0.82.5 + metro-config: 0.82.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + metro-core: 0.82.5 + metro-file-map: 0.82.5 + metro-resolver: 0.82.5 + metro-runtime: 0.82.5 + metro-source-map: 0.82.5 + metro-symbolicate: 0.82.5 + metro-transform-plugins: 0.82.5 + metro-transform-worker: 0.82.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + mime-types: 2.1.35 + nullthrows: 1.1.1 + serialize-error: 2.1.0 + source-map: 0.5.7 + throat: 5.0.0 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + yargs: 17.7.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + micro-ftch@0.3.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mime@3.0.0: + optional: true + + mimic-fn@1.2.0: {} + + mimic-fn@2.1.0: {} + + min-indent@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + + mipd@0.0.7(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 + + mkdirp@1.0.4: {} + + mkdirp@3.0.1: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + multiformats@9.9.0: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + napi-postinstall@0.3.3: {} + + natural-compare-lite@1.4.0: {} + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + nested-error-stacks@2.0.1: {} + + node-addon-api@2.0.2: {} + + node-fetch-native@1.6.7: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-forge@1.3.1: {} + + node-gyp-build@4.8.4: {} + + node-int64@0.4.0: {} + + node-mock-http@1.0.2: {} + + node-releases@2.0.19: {} + + normalize-path@3.0.0: {} + + npm-package-arg@11.0.3: + dependencies: + hosted-git-info: 7.0.2 + proc-log: 4.2.0 + semver: 7.7.2 + validate-npm-package-name: 5.0.1 + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nullthrows@1.1.1: {} + + nwsapi@2.2.21: {} + + ob1@0.82.5: + dependencies: + flow-enums-runtime: 0.0.6 + + obj-multiplex@1.0.0: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + readable-stream: 2.3.8 + + object-assign@4.1.1: {} + + object-hash@3.0.0: + optional: true + + object-inspect@1.13.4: {} + + ofetch@1.4.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.1 + + on-exit-leak-free@0.2.0: {} + + on-finished@2.3.0: + dependencies: + ee-first: 1.1.1 + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@2.0.1: + dependencies: + mimic-fn: 1.2.0 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@7.4.2: + dependencies: + is-docker: 2.2.1 + is-wsl: 2.2.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@3.4.0: + dependencies: + chalk: 2.4.2 + cli-cursor: 2.1.0 + cli-spinners: 2.9.2 + log-symbols: 2.2.0 + strip-ansi: 5.2.0 + wcwidth: 1.0.1 + + ox@0.6.7(typescript@5.8.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@5.8.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + ox@0.8.6(typescript@5.8.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.2 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.2 + json-parse-better-errors: 1.0.2 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-png@2.1.0: + dependencies: + pngjs: 3.4.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + parseurl@1.3.3: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@0.1.12: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@3.0.1: {} + + picomatch@4.0.3: {} + + pify@3.0.0: {} + + pify@5.0.0: {} + + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.3 + split2: 4.2.0 + + pino-std-serializers@4.0.0: {} + + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + + pirates@4.0.7: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + plist@3.1.0: + dependencies: + '@xmldom/xmldom': 0.8.10 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + + pngjs@3.4.0: {} + + pngjs@5.0.0: {} + + polished@4.3.1: + dependencies: + '@babel/runtime': 7.28.3 + + pony-cause@2.1.11: {} + + possible-typed-array-names@1.1.0: {} + + postcss@8.4.49: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + preact@10.24.2: {} + + preact@10.27.0: {} + + prelude-ls@1.2.1: {} + + pretty-bytes@5.6.0: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + pretty-format@30.0.5: + dependencies: + '@jest/schemas': 30.0.5 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + proc-log@4.2.0: {} + + process-nextick-args@2.0.1: {} + + process-warning@1.0.0: {} + + progress@2.0.3: {} + + promise@8.3.0: + dependencies: + asap: 2.0.6 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + proto3-json-serializer@2.0.2: + dependencies: + protobufjs: 7.5.3 + optional: true + + protobufjs@7.5.3: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 24.2.1 + long: 5.3.2 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-compare@2.6.0: {} + + psl@1.15.0: + dependencies: + punycode: 2.3.1 + + pump@3.0.3: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + punycode@2.3.1: {} + + pure-rand@6.1.0: {} + + pure-rand@7.0.1: {} + + qrcode-terminal@0.11.0: {} + + qrcode@1.5.3: + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + qs@6.13.0: + dependencies: + side-channel: 1.1.0 + + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + queue@6.0.2: + dependencies: + inherits: 2.0.4 + + quick-format-unescaped@4.0.4: {} + + radix3@1.1.2: {} + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + react-devtools-core@6.1.5(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + shell-quote: 1.8.3 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + react-error-boundary@3.1.4(react@19.0.0): + dependencies: + '@babel/runtime': 7.28.3 + react: 19.0.0 + + react-fast-compare@3.2.2: {} + + react-freeze@1.0.4(react@19.0.0): + dependencies: + react: 19.0.0 + + react-is@16.13.1: {} + + react-is@18.3.1: {} + + react-is@19.1.1: {} + + react-native-animatable@1.4.0: + dependencies: + prop-types: 15.8.1 + + react-native-edge-to-edge@1.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + react-native-get-random-values@1.11.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)): + dependencies: + fast-base64-decode: 1.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + react-native-is-edge-to-edge@1.2.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + react-native-modal@14.0.0-rc.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-animatable: 1.4.0 + + react-native-safe-area-context@5.6.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + react-native-screens@4.14.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + react: 19.0.0 + react-freeze: 1.0.4(react@19.0.0) + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + react-native-is-edge-to-edge: 1.2.1(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + warn-once: 0.1.1 + + react-native-svg@15.11.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + css-select: 5.2.2 + css-tree: 1.1.3 + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + warn-once: 0.1.1 + + react-native-toast-message@2.3.3(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0): + dependencies: + react: 19.0.0 + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + + react-native-url-polyfill@2.0.0(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)): + dependencies: + react-native: 0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10) + whatwg-url-without-unicode: 8.0.0-3 + + react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10): + dependencies: + '@jest/create-cache-key-function': 29.7.0 + '@react-native/assets-registry': 0.79.5 + '@react-native/codegen': 0.79.5(@babel/core@7.28.3) + '@react-native/community-cli-plugin': 0.79.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@react-native/gradle-plugin': 0.79.5 + '@react-native/js-polyfills': 0.79.5 + '@react-native/normalize-colors': 0.79.5 + '@react-native/virtualized-lists': 0.79.5(@types/react@19.0.14)(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + abort-controller: 3.0.0 + anser: 1.4.10 + ansi-regex: 5.0.1 + babel-jest: 29.7.0(@babel/core@7.28.3) + babel-plugin-syntax-hermes-parser: 0.25.1 + base64-js: 1.5.1 + chalk: 4.1.2 + commander: 12.1.0 + event-target-shim: 5.0.1 + flow-enums-runtime: 0.0.6 + glob: 7.2.3 + invariant: 2.2.4 + jest-environment-node: 29.7.0 + memoize-one: 5.2.1 + metro-runtime: 0.82.5 + metro-source-map: 0.82.5 + nullthrows: 1.1.1 + pretty-format: 29.7.0 + promise: 8.3.0 + react: 19.0.0 + react-devtools-core: 6.1.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) + react-refresh: 0.14.2 + regenerator-runtime: 0.13.11 + scheduler: 0.25.0 + semver: 7.7.2 + stacktrace-parser: 0.1.11 + whatwg-fetch: 3.6.20 + ws: 6.2.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + yargs: 17.7.2 + optionalDependencies: + '@types/react': 19.0.14 + transitivePeerDependencies: + - '@babel/core' + - '@react-native-community/cli' + - bufferutil + - supports-color + - utf-8-validate + + react-refresh@0.14.2: {} + + react-test-renderer@19.0.0(react@19.0.0): + dependencies: + react: 19.0.0 + react-is: 19.1.1 + scheduler: 0.25.0 + + react@19.0.0: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@4.1.2: {} + + real-require@0.1.0: {} + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + regenerate-unicode-properties@10.2.0: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regenerator-runtime@0.13.11: {} + + regexpu-core@6.2.0: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.0 + regjsgen: 0.8.0 + regjsparser: 0.12.0 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.0 + + regjsgen@0.8.0: {} + + regjsparser@0.12.0: + dependencies: + jsesc: 3.0.2 + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + require-main-filename@2.0.0: {} + + requireg@0.2.2: + dependencies: + nested-error-stacks: 2.0.1 + rc: 1.2.8 + resolve: 1.7.1 + + requires-port@1.0.0: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@3.0.0: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-workspace-root@2.0.0: {} + + resolve.exports@2.0.3: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@1.7.1: + dependencies: + path-parse: 1.0.7 + + restore-cursor@2.0.0: + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.7 + + retry-request@7.0.2: + dependencies: + '@types/request': 2.48.13 + extend: 3.0.2 + teeny-request: 9.0.0 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + retry@0.13.1: + optional: true + + reusify@1.1.0: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + sax@1.4.1: {} + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.25.0: {} + + schema-utils@4.3.2: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + + semver@6.3.1: {} + + semver@7.6.3: {} + + semver@7.7.2: {} + + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + send@0.19.1: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serialize-error@2.1.0: {} + + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + + server-only@0.0.1: {} + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.1 + + shallowequal@1.1.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.3: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-plist@1.3.1: + dependencies: + bplist-creator: 0.1.0 + bplist-parser: 0.3.1 + plist: 3.1.0 + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + slugify@1.6.6: {} + + socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + engine.io-client: 6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + socket.io-parser@4.2.4: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + + source-map-js@1.2.1: {} + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + split-on-first@1.1.0: {} + + split2@4.2.0: {} + + sprintf-js@1.0.3: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + stackframe@1.3.4: {} + + stacktrace-parser@0.1.11: + dependencies: + type-fest: 0.7.1 + + statuses@1.5.0: {} + + statuses@2.0.1: {} + + stream-buffers@2.2.0: {} + + stream-events@1.0.5: + dependencies: + stubs: 3.0.0 + optional: true + + stream-shift@1.0.3: {} + + strict-uri-encode@2.0.0: {} + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@5.2.0: + dependencies: + ansi-regex: 4.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@4.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + + strnum@1.1.2: + optional: true + + structured-headers@0.4.1: {} + + stubs@3.0.0: + optional: true + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + ts-interface-checker: 0.1.13 + + superstruct@1.0.4: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-hyperlinks@2.3.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + symbol-tree@3.2.4: {} + + synckit@0.11.11: + dependencies: + '@pkgr/core': 0.2.9 + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + + teeny-request@9.0.0: + dependencies: + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + node-fetch: 2.7.0 + stream-events: 1.0.5 + uuid: 9.0.1 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + temp-dir@2.0.0: {} + + terminal-link@2.1.1: + dependencies: + ansi-escapes: 4.3.2 + supports-hyperlinks: 2.3.0 + + terser@5.43.1: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + text-table@0.2.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + thread-stream@0.15.2: + dependencies: + real-require: 0.1.0 + + throat@5.0.0: {} + + tmpl@1.0.5: {} + + to-buffer@1.2.1: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + tough-cookie@4.1.4: + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + + tr46@0.0.3: {} + + tr46@3.0.0: + dependencies: + punycode: 2.3.1 + + ts-api-utils@2.1.0(typescript@5.8.3): + dependencies: + typescript: 5.8.3 + + ts-deepmerge@2.0.7: {} + + ts-interface-checker@0.1.13: {} + + ts-jest@29.4.1(@babel/core@7.28.3)(@jest/transform@30.0.5)(@jest/types@30.0.5)(babel-jest@29.7.0(@babel/core@7.28.3))(jest-util@30.0.5)(jest@29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)))(typescript@5.8.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.8 + jest: 29.7.0(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.2 + type-fest: 4.41.0 + typescript: 5.8.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.28.3 + '@jest/transform': 30.0.5 + '@jest/types': 30.0.5 + babel-jest: 29.7.0(@babel/core@7.28.3) + jest-util: 30.0.5 + + ts-jest@29.4.1(@babel/core@7.28.3)(@jest/transform@30.0.5)(@jest/types@30.0.5)(babel-jest@30.0.5(@babel/core@7.28.3))(jest-util@30.0.5)(jest@30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)))(typescript@5.8.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.8 + jest: 30.0.5(@types/node@24.2.1)(ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3)) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.2 + type-fest: 4.41.0 + typescript: 5.8.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.28.3 + '@jest/transform': 30.0.5 + '@jest/types': 30.0.5 + babel-jest: 30.0.5(@babel/core@7.28.3) + jest-util: 30.0.5 + + ts-node@10.9.2(@types/node@24.2.1)(typescript@5.8.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 24.2.1 + acorn: 8.15.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.8.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tslib@1.14.1: {} + + tslib@2.7.0: {} + + tslib@2.8.1: {} + + tsutils@3.21.0(typescript@5.8.3): + dependencies: + tslib: 1.14.1 + typescript: 5.8.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@0.7.1: {} + + type-fest@4.41.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typescript@5.8.3: {} + + ufo@1.6.1: {} + + uglify-js@3.19.3: + optional: true + + uint8arrays@3.1.0: + dependencies: + multiformats: 9.9.0 + + uncrypto@0.1.3: {} + + undici-types@6.19.8: {} + + undici-types@6.21.0: {} + + undici-types@7.10.0: {} + + undici@6.21.3: {} + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.1.0 + + unicode-match-property-value-ecmascript@2.2.0: {} + + unicode-property-aliases-ecmascript@2.1.0: {} + + unique-string@2.0.0: + dependencies: + crypto-random-string: 2.0.0 + + universalify@0.2.0: {} + + unpipe@1.0.0: {} + + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.3 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + unstorage@1.16.1(idb-keyval@6.2.2): + dependencies: + anymatch: 3.1.3 + chokidar: 4.0.3 + destr: 2.0.5 + h3: 1.15.4 + lru-cache: 10.4.3 + node-fetch-native: 1.6.7 + ofetch: 1.4.1 + ufo: 1.6.1 + optionalDependencies: + idb-keyval: 6.2.2 + + update-browserslist-db@1.1.3(browserslist@4.25.2): + dependencies: + browserslist: 4.25.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + use-latest-callback@0.2.4(react@19.0.0): + dependencies: + react: 19.0.0 + + use-sync-external-store@1.2.0(react@19.0.0): + dependencies: + react: 19.0.0 + + use-sync-external-store@1.4.0(react@19.0.0): + dependencies: + react: 19.0.0 + + use-sync-external-store@1.5.0(react@19.0.0): + dependencies: + react: 19.0.0 + + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.4 + + util-deprecate@1.0.2: {} + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.0 + is-typed-array: 1.1.15 + which-typed-array: 1.1.19 + + utils-merge@1.0.1: {} + + uuid@10.0.0: {} + + uuid@11.1.0: {} + + uuid@7.0.3: {} + + uuid@8.3.2: {} + + uuid@9.0.1: {} + + v8-compile-cache-lib@3.0.1: {} + + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.30 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + validate-npm-package-name@5.0.1: {} + + valtio@1.13.2(@types/react@19.0.14)(react@19.0.0): + dependencies: + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.0.14)(react@19.0.0)) + proxy-compare: 2.6.0 + use-sync-external-store: 1.2.0(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.14 + react: 19.0.0 + + vary@1.1.2: {} + + viem@2.23.2(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4): + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.7(typescript@5.8.3)(zod@3.22.4) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4): + dependencies: + '@noble/curves': 1.9.2 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8(typescript@5.8.3)(zod@3.22.4) + isows: 1.0.7(ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.8.6(typescript@5.8.3)(zod@3.22.4) + ws: 8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vlq@1.0.1: {} + + w3c-xmlserializer@4.0.0: + dependencies: + xml-name-validator: 4.0.0 + + wagmi@2.16.3(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.85.3)(@tanstack/react-query@5.85.3(react@19.0.0))(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(utf-8-validate@5.0.10)(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4): + dependencies: + '@tanstack/react-query': 5.85.3(react@19.0.0) + '@wagmi/connectors': 5.9.3(@react-native-async-storage/async-storage@2.1.2(react-native@0.79.5(@babel/core@7.28.3)(@types/react@19.0.14)(bufferutil@4.0.9)(react@19.0.0)(utf-8-validate@5.0.10)))(@types/react@19.0.14)(@wagmi/core@2.19.0(@tanstack/query-core@5.85.3)(@types/react@19.0.14)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)))(bufferutil@4.0.9)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(utf-8-validate@5.0.10)(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4) + '@wagmi/core': 2.19.0(@tanstack/query-core@5.85.3)(@types/react@19.0.14)(react@19.0.0)(typescript@5.8.3)(use-sync-external-store@1.4.0(react@19.0.0))(viem@2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4)) + react: 19.0.0 + use-sync-external-store: 1.4.0(react@19.0.0) + viem: 2.33.3(bufferutil@4.0.9)(typescript@5.8.3)(utf-8-validate@5.0.10)(zod@3.22.4) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@tanstack/query-core' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - immer + - ioredis + - supports-color + - uploadthing + - utf-8-validate + - zod + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + warn-once@0.1.1: {} + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + web-vitals@4.2.4: {} + + webextension-polyfill@0.10.0: {} + + webidl-conversions@3.0.1: {} + + webidl-conversions@5.0.0: {} + + webidl-conversions@7.0.0: {} + + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + + whatwg-encoding@2.0.0: + dependencies: + iconv-lite: 0.6.3 + + whatwg-fetch@3.6.20: {} + + whatwg-mimetype@3.0.0: {} + + whatwg-url-without-unicode@8.0.0-3: + dependencies: + buffer: 5.7.1 + punycode: 2.3.1 + webidl-conversions: 5.0.0 + + whatwg-url@11.0.0: + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-module@2.0.1: {} + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wonka@6.3.5: {} + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + write-file-atomic@5.0.1: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + ws@6.2.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + async-limiter: 1.0.1 + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.2(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + xcode@3.0.1: + dependencies: + simple-plist: 1.3.1 + uuid: 7.0.3 + + xml-name-validator@4.0.0: {} + + xml2js@0.6.0: + dependencies: + sax: 1.4.1 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + xmlbuilder@15.1.1: {} + + xmlchars@2.2.0: {} + + xmlhttprequest-ssl@2.1.2: {} + + xtend@4.0.2: {} + + y18n@4.0.3: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yallist@5.0.0: {} + + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs-parser@21.1.1: {} + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} + + zod@3.22.4: {} + + zustand@5.0.0(@types/react@19.0.14)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)): + optionalDependencies: + '@types/react': 19.0.14 + react: 19.0.0 + use-sync-external-store: 1.4.0(react@19.0.0) + + zustand@5.0.3(@types/react@19.0.14)(react@19.0.0)(use-sync-external-store@1.4.0(react@19.0.0)): + optionalDependencies: + '@types/react': 19.0.14 + react: 19.0.0 + use-sync-external-store: 1.4.0(react@19.0.0) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..1bb170b --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +packages: + - apps/* + - packages/* + +nodeLinker: hoisted diff --git a/tsconfig.dev.json b/tsconfig.dev.json new file mode 100644 index 0000000..2e17fb3 --- /dev/null +++ b/tsconfig.dev.json @@ -0,0 +1,5 @@ +{ + "include": [ + ".eslintrc.cjs" + ] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..0a02279 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./packages/backend" }, + { "path": "./apps/mobile" } + ] +} \ No newline at end of file