diff --git a/.claude/settings.json b/.claude/settings.json
deleted file mode 100644
index 176e6a5..0000000
--- a/.claude/settings.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "enabledPlugins": {
- "expo@claude-plugins-official": true
- }
-}
diff --git a/.eas/workflows/build-android.yml b/.eas/workflows/build-android.yml
deleted file mode 100644
index a958a84..0000000
--- a/.eas/workflows/build-android.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-name: Build Android APK
-
-on:
- workflow_dispatch:
- inputs:
- profile:
- type: choice
- description: EAS build profile to use.
- default: production
- options:
- - preview
- - production
-
-jobs:
- build_android:
- name: Build Android APK
- type: build
- environment: ${{ inputs.profile }}
- params:
- platform: android
- profile: ${{ inputs.profile }}
- message: Android ${{ inputs.profile }} APK from ${{ github.ref_name }}
diff --git a/.eas/workflows/publish-updates.yml b/.eas/workflows/publish-updates.yml
deleted file mode 100644
index 5f807f4..0000000
--- a/.eas/workflows/publish-updates.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-name: Publish OTA updates
-
-on:
- push:
- branches: ['main']
- paths:
- - 'app/**'
- - 'components/**'
- - 'hooks/**'
- - 'lib/**'
- - 'types/**'
- - 'assets/**'
- - 'App.tsx'
- - 'index.ts'
- - 'global.css'
- - 'tailwind.config.js'
- - 'babel.config.js'
- - 'metro.config.js'
- workflow_dispatch:
- inputs:
- channel:
- type: choice
- description: Update channel to publish.
- default: production
- options:
- - preview
- - production
- environment:
- type: choice
- description: EAS environment to use for the update job.
- default: production
- options:
- - preview
- - production
- message:
- description: Optional update message override.
- required: false
-
-jobs:
- publish_main:
- if: ${{ github.event_name == 'push' }}
- name: Publish production update
- type: update
- environment: production
- params:
- channel: production
- platform: all
-
- publish_manual:
- if: ${{ github.event_name == 'workflow_dispatch' }}
- name: Publish selected update
- type: update
- environment: ${{ inputs.environment }}
- params:
- channel: ${{ inputs.channel }}
- message: ${{ inputs.message }}
- platform: all
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..12287c6
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,11 @@
+* text=auto
+*.gradle text eol=lf
+*.kt text eol=lf
+*.kts text eol=lf
+*.properties text eol=lf
+*.xml text eol=lf
+*.yml text eol=lf
+*.md text eol=lf
+gradlew text eol=lf
+*.bat text eol=crlf
+*.jar binary
diff --git a/.gitea/workflows/build-android.yml b/.gitea/workflows/build-android.yml
index 1dcbccf..316dcb6 100644
--- a/.gitea/workflows/build-android.yml
+++ b/.gitea/workflows/build-android.yml
@@ -1,29 +1,21 @@
-name: CodexBar Mobile Build
+name: android-release
on:
push:
branches:
- main
- paths:
- - "**/*.ts"
- - "**/*.tsx"
- - "**/*.js"
- - "**/*.json"
- - ".gitea/workflows/**"
+ tags:
+ - 'v*'
+ workflow_dispatch:
jobs:
- build-android:
+ build:
runs-on: ubuntu-latest
steps:
- - name: 🏗 Setup repo
- uses: actions/checkout@v2
+ - name: Checkout
+ uses: actions/checkout@v4
- - name: 🏗 Setup Node
- uses: actions/setup-node@v2
- with:
- node-version: 22
-
- - name: 🏗 Setup Java
+ - name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
@@ -46,62 +38,48 @@ jobs:
- name: Set up Gradle cache
uses: gradle/actions/setup-gradle@v3
- - name: 🏗 Setup Expo and EAS
- uses: expo/expo-github-action@v8
- with:
- token: ${{ secrets.EXPO_TOKEN }}
- eas-version: latest
- packager: npm
-
- - name: 📦 Install dependencies
- run: npm ci --legacy-peer-deps
-
- - name: 👷 Build app
+ - name: Write release keystore
+ env:
+ CODEXMOBILE_KEYSTORE_BASE64: ${{ secrets.CODEXMOBILE_KEYSTORE_BASE64 }}
+ CODEXMOBILE_KEYSTORE_PASSWORD: ${{ secrets.CODEXMOBILE_KEYSTORE_PASSWORD }}
+ CODEXMOBILE_KEY_ALIAS: ${{ secrets.CODEXMOBILE_KEY_ALIAS }}
+ CODEXMOBILE_KEY_PASSWORD: ${{ secrets.CODEXMOBILE_KEY_PASSWORD }}
run: |
- eas build --local \
- --non-interactive \
- --output=./app-build \
- --platform=android \
- --profile=preview
+ if [ -z "$CODEXMOBILE_KEYSTORE_BASE64" ] || [ -z "$CODEXMOBILE_KEYSTORE_PASSWORD" ] || [ -z "$CODEXMOBILE_KEY_ALIAS" ] || [ -z "$CODEXMOBILE_KEY_PASSWORD" ]; then
+ echo "Missing release signing secrets" >&2
+ exit 1
+ fi
+ echo "$CODEXMOBILE_KEYSTORE_BASE64" | base64 -d > "$HOME/codexmobile-release.jks"
+ {
+ echo "CODEXMOBILE_STORE_FILE=$HOME/codexmobile-release.jks"
+ echo "CODEXMOBILE_STORE_PASSWORD=$CODEXMOBILE_KEYSTORE_PASSWORD"
+ echo "CODEXMOBILE_KEY_ALIAS=$CODEXMOBILE_KEY_ALIAS"
+ echo "CODEXMOBILE_KEY_PASSWORD=$CODEXMOBILE_KEY_PASSWORD"
+ } >> "$GITHUB_ENV"
- - name: 📝 Rename build to APK
- run: mv app-build codexbar-release.apk
-
- - name: 🗜 Zip APK
- run: zip codexbar-release.zip codexbar-release.apk
-
- - name: 📤 Upload build artifact
- uses: actions/upload-artifact@v3
- with:
- name: codexbar-android-preview-build
- path: codexbar-release.zip
- if-no-files-found: error
-
- release:
- runs-on: ubuntu-latest
- needs: [build-android]
- steps:
- - name: 🏗 Setup repo
- uses: actions/checkout@v2
-
- - name: 📥 Download Android artifact
- uses: actions/download-artifact@v3
- with:
- name: codexbar-android-preview-build
-
- - name: 🏷 Create tag
+ - name: Build release APK
run: |
- TAG="codexbar-build-$(git rev-parse --short HEAD)"
- git tag "$TAG"
- git push origin "$TAG"
- echo "RELEASE_TAG=$TAG" >> $GITHUB_ENV
+ chmod +x gradlew
+ ./gradlew assembleRelease
- - name: 🚀 Create release
- uses: softprops/action-gh-release@v1
+ - name: Compute release tag
+ run: |
+ if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
+ echo "RELEASE_TAG=${GITHUB_REF_NAME}" >> "$GITHUB_ENV"
+ else
+ echo "RELEASE_TAG=main-${GITHUB_RUN_NUMBER}-${GITHUB_SHA::7}" >> "$GITHUB_ENV"
+ fi
+
+ - name: Publish Gitea release
+ uses: akkuman/gitea-release-action@v1
+ env:
+ NODE_OPTIONS: --experimental-fetch
with:
tag_name: ${{ env.RELEASE_TAG }}
- name: ${{ env.RELEASE_TAG }}
- files: codexbar-release.zip
- generate_release_notes: true
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ target_commitish: ${{ github.sha }}
+ files: |
+ app/build/outputs/apk/release/*.apk
+ body: |
+ CodexMobile release built from ${{ github.ref_name }} at ${{ github.sha }}.
+ prerelease: false
+ draft: false
diff --git a/.gitignore b/.gitignore
index d914c32..e697753 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,41 +1,16 @@
-# 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
+.gradle/
+build/
+app/build/
+local.properties
+keystore.properties
.kotlin/
-*.orig.*
*.jks
+*.keystore
*.p8
*.p12
*.key
-*.mobileprovision
-
-# Metro
-.metro-health-check*
-
-# debug
-npm-debug.*
-yarn-debug.*
-yarn-error.*
-
-# macOS
-.DS_Store
*.pem
-
-# local env files
+*.orig.*
+.env.ci
.env*.local
-
-# typescript
-*.tsbuildinfo
-
-# generated native folders
-/ios
-/android
+.DS_Store
diff --git a/AGENTS.md b/AGENTS.md
deleted file mode 100644
index a26b4bb..0000000
--- a/AGENTS.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Expo HAS CHANGED
-
-Read the exact versioned docs at https://docs.expo.dev/versions/v56.0.0/ before writing any code.
diff --git a/App.tsx b/App.tsx
deleted file mode 100644
index 0329d0c..0000000
--- a/App.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { StatusBar } from 'expo-status-bar';
-import { StyleSheet, Text, View } from 'react-native';
-
-export default function App() {
- return (
-
- Open up App.tsx to start working on your app!
-
-
- );
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: '#fff',
- alignItems: 'center',
- justifyContent: 'center',
- },
-});
diff --git a/CLAUDE.md b/CLAUDE.md
deleted file mode 100644
index 078aeeb..0000000
--- a/CLAUDE.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# CLAUDE.md
-
-This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
-
-@AGENTS.md
-
-## Commands
-
-```bash
-npx expo start # Start Expo dev server (scan QR with Expo Go)
-npx expo start --android
-npx expo start --ios
-npx expo start --web
-
-eas build --profile preview --platform android # Build APK via EAS
-eas build --profile production --platform android
-```
-
-There is no test suite or lint script configured in package.json.
-
-## Architecture
-
-This is an Expo SDK 56 app that monitors AI service usage limits for **Codex CLI** and **Claude.ai**. It fetches usage data from their private REST APIs using credentials the user provides.
-
-### Navigation (Expo Router v3)
-
-```
-app/index.tsx → checks onboarding state, redirects
-app/onboarding/ → stack: welcome → codex → claude → done
-app/(tabs)/
- _layout.tsx → bottom tab navigator (4 tabs)
- index.tsx → Dashboard: both services side-by-side
- codex.tsx → Codex CLI detailed view
- claude.tsx → Claude.ai detailed view (not yet in git)
- settings.tsx → Settings (not yet in git)
-```
-
-### Data Flow
-
-Each service follows the same pattern:
-
-1. **Hook** (`hooks/useCodexUsage.ts`, `hooks/useClaudeUsage.ts`) — manages auth + usage state, persists credentials to SecureStore, exposes `refresh()` / `clear()`.
-2. **API module** (`lib/api/codexApi.ts`, `lib/api/claudeApi.ts`) — thin fetch wrappers with no side effects.
-3. **Screen** — calls the hook, renders `ServiceStatusCard` or the detailed usage UI.
-
-### Credential Storage
-
-All credentials live in `expo-secure-store` (never AsyncStorage). Keys:
-
-- `codex_auth` — serialized `CodexAuth` object (Bearer token + optional account ID), imported from the user's `auth.json` file via `expo-document-picker`.
-- `claude_session_key` — cookie value used as `Cookie: sessionKey=…` on claude.ai API calls.
-
-`TOKEN_EXPIRED` errors automatically clear the stored credential and prompt re-entry.
-
-### Styling
-
-NativeWind v4 (Tailwind CSS for React Native). Brand colors:
-- Codex: `#10a37f` (teal)
-- Claude: `#d97706` (amber)
-
-Use Tailwind utility classes on all components. Dark mode is supported via `dark:` variants.
-
-### Key Types
-
-- `lib/types/codex.ts` — `CodexAuth`, `CodexUsageResponse`, `UsageWindow`
-- `lib/types/claude.ts` — `ClaudeOrg`, `ClaudeUsageResponse`, `ClaudeWindowUsage`
-
-### Path Alias
-
-`@/` maps to the repo root (configured in `tsconfig.json`). Use `@/components/...`, `@/lib/...`, `@/hooks/...` everywhere.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c473d3f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+# CodexMobile
+
+Native Android app for monitoring Codex CLI and Claude.ai usage windows, reset credits, and local quota reminders.
+
+## Build
+
+```bash
+./gradlew assembleDebug
+```
+
+Release builds require signing values from environment variables or `keystore.properties`:
+
+```properties
+CODEXMOBILE_STORE_FILE=/path/to/codexmobile-release.jks
+CODEXMOBILE_STORE_PASSWORD=...
+CODEXMOBILE_KEY_ALIAS=codexmobile-release
+CODEXMOBILE_KEY_PASSWORD=...
+```
+
+CI secrets are generated into `.env.ci` for copying into Gitea.
diff --git a/app.json b/app.json
deleted file mode 100644
index 205c738..0000000
--- a/app.json
+++ /dev/null
@@ -1,87 +0,0 @@
-{
- "expo": {
- "name": "Codexbar",
- "slug": "codexbar-mobile",
- "description": "Monitor Codex CLI and Claude.ai usage limits, resets, and credits at a glance.",
- "scheme": "codexbar",
- "version": "1.0.0",
- "runtimeVersion": {
- "policy": "appVersion"
- },
- "updates": {
- "url": "https://u.expo.dev/9196c5ee-4c6e-4229-9a99-54b50afe38e8"
- },
- "orientation": "portrait",
- "icon": "./assets/icon.png",
- "backgroundColor": "#090D11",
- "primaryColor": "#10A37F",
- "userInterfaceStyle": "automatic",
- "ios": {
- "bundleIdentifier": "dev.reversed.codexbar",
- "buildNumber": "1",
- "supportsTablet": true,
- "config": {
- "usesNonExemptEncryption": false
- }
- },
- "android": {
- "package": "dev.reversed.codexbar",
- "versionCode": 1,
- "adaptiveIcon": {
- "backgroundColor": "#090D11",
- "foregroundImage": "./assets/android-icon-foreground.png",
- "backgroundImage": "./assets/android-icon-background.png",
- "monochromeImage": "./assets/android-icon-monochrome.png"
- },
- "predictiveBackGestureEnabled": true
- },
- "web": {
- "bundler": "metro",
- "output": "static",
- "favicon": "./assets/favicon.png"
- },
- "plugins": [
- "expo-router",
- [
- "expo-splash-screen",
- {
- "image": "./assets/splash-icon.png",
- "imageWidth": 220,
- "resizeMode": "contain",
- "backgroundColor": "#090D11",
- "dark": {
- "image": "./assets/splash-icon.png",
- "backgroundColor": "#090D11"
- }
- }
- ],
- [
- "expo-secure-store",
- {
- "configureAndroidBackup": true,
- "faceIDPermission": "Allow Codexbar to access your securely stored credentials."
- }
- ],
- "expo-document-picker",
- [
- "expo-notifications",
- {
- "icon": "./assets/notification-icon.png",
- "color": "#10A37F",
- "defaultChannel": "usage-alerts"
- }
- ],
- "expo-font"
- ],
- "experiments": {
- "typedRoutes": true
- },
- "extra": {
- "router": {},
- "eas": {
- "projectId": "9196c5ee-4c6e-4229-9a99-54b50afe38e8"
- }
- },
- "owner": "spacebanane"
- }
-}
diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
deleted file mode 100644
index 8da326f..0000000
--- a/app/(tabs)/_layout.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import { Tabs } from "expo-router";
-import { useColorScheme } from "react-native";
-import { useSafeAreaInsets } from "react-native-safe-area-context";
-import { MaterialIcons } from "@expo/vector-icons";
-import { COLORS } from "@/lib/constants";
-
-export default function TabLayout() {
- const colorScheme = useColorScheme();
- const isDark = colorScheme === "dark";
- const insets = useSafeAreaInsets();
-
- return (
-
- (
-
- ),
- }}
- />
-
-
- (
-
- ),
- }}
- />
-
- );
-}
diff --git a/app/(tabs)/claude.tsx b/app/(tabs)/claude.tsx
deleted file mode 100644
index 5ffb790..0000000
--- a/app/(tabs)/claude.tsx
+++ /dev/null
@@ -1,230 +0,0 @@
-import {
- ScrollView,
- View,
- Text,
- TouchableOpacity,
- TextInput,
- ActivityIndicator,
- RefreshControl,
- KeyboardAvoidingView,
- Platform,
-} from "react-native";
-import { SafeAreaView } from "react-native-safe-area-context";
-import { MaterialIcons } from "@expo/vector-icons";
-import { useClaudeUsage } from "@/hooks/useClaudeUsage";
-import { UsageStat } from "@/components/UsageStat";
-import { ErrorMessage } from "@/components/ErrorMessage";
-import { LastUpdated } from "@/components/LastUpdated";
-import { ScreenErrorBoundary } from "@/components/ScreenErrorBoundary";
-import { COLORS } from "@/lib/constants";
-
-function ClaudeTabContent() {
- const {
- auth,
- pendingKey,
- setPendingKey,
- pendingOrg,
- setPendingOrg,
- usage,
- lastFetchedAt,
- status,
- error,
- keyValidationError,
- canSaveKey,
- saveKey,
- refresh,
- clearKey,
- } = useClaudeUsage();
-
- return (
-
-
-
- }
- >
- {/* Header */}
-
-
-
-
-
-
- Claude.ai
-
-
- Usage windows
-
-
-
-
- {/* Configuration card */}
-
-
- Configuration
-
-
- {auth ? (
-
-
-
-
- Connected
-
-
- {auth.sessionKey.slice(0, 10)}…
-
-
-
-
- Clear
-
-
-
- ) : (
-
-
- {keyValidationError && (
-
- {keyValidationError}
-
- )}
-
-
-
- Save Session Key
-
-
-
-
- Where to find it
-
-
- Chrome DevTools → Application → Cookies → claude.ai → copy{" "}
- sessionKey
- {" "}and optionally{" "}
- lastActiveOrg
-
-
-
- )}
-
-
- {/* Usage card */}
-
-
- Usage
-
-
- {status === "idle" && !auth && (
-
-
-
- Enter your session key to see usage windows
-
-
- )}
- {status === "loading" && !usage && (
-
- )}
- {status === "error" && error && }
- {usage && (
-
-
-
-
- {(usage.seven_day_sonnet || usage.seven_day_opus) && (
-
-
- By Model (7-day)
-
- {usage.seven_day_sonnet && (
-
- )}
- {usage.seven_day_opus && (
-
- )}
-
- )}
-
-
-
-
- )}
-
-
-
-
- );
-}
-
-export default function ClaudeTab() {
- return (
-
-
-
- );
-}
diff --git a/app/(tabs)/codex.tsx b/app/(tabs)/codex.tsx
deleted file mode 100644
index 4f505a6..0000000
--- a/app/(tabs)/codex.tsx
+++ /dev/null
@@ -1,276 +0,0 @@
-import {
- ScrollView,
- View,
- Text,
- TouchableOpacity,
- ActivityIndicator,
- RefreshControl,
-} from "react-native";
-import { SafeAreaView } from "react-native-safe-area-context";
-import { MaterialIcons } from "@expo/vector-icons";
-import { useCodexUsage } from "@/hooks/useCodexUsage";
-import { UsageStat } from "@/components/UsageStat";
-import { ErrorMessage } from "@/components/ErrorMessage";
-import { LastUpdated } from "@/components/LastUpdated";
-import { ScreenErrorBoundary } from "@/components/ScreenErrorBoundary";
-import { COLORS } from "@/lib/constants";
-import { windowLabel } from "@/lib/timeUtils";
-import type { CodexResetCredit } from "@/types/codex";
-
-function formatResetStatus(status?: string) {
- if (!status) return "Unknown";
- return status.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
-}
-
-function ResetCreditRow({ credit }: { credit: CodexResetCredit }) {
- return (
-
-
-
- Credit {credit.index}
-
-
-
- {formatResetStatus(credit.status)}
-
-
-
- {credit.timeUntilExpiry && (
-
- Expires in {credit.timeUntilExpiry}
-
- )}
- {credit.expiresAtLocal && (
-
- Expires {credit.expiresAtLocal}
-
- )}
- {credit.grantedAtLocal && (
-
- Granted {credit.grantedAtLocal}
-
- )}
-
- );
-}
-
-function CodexTabContent() {
- const {
- auth,
- usage,
- lastFetchedAt,
- status,
- error,
- importAuthFile,
- refresh,
- clearAuth,
- } =
- useCodexUsage();
- const resetCoupons = usage?.resetCoupons;
- const availableResetCredits =
- resetCoupons?.credits?.filter((credit) => credit.status === "available") ?? [];
-
- return (
-
-
- }
- >
- {/* Header */}
-
-
-
-
-
-
- Codex CLI
-
-
- Rate limits & credits
-
-
-
-
- {/* Configuration card */}
-
-
- Configuration
-
-
- {auth ? (
-
-
-
-
- Connected
-
- {auth.accountId && (
-
- {auth.accountId.slice(0, 10)}…
-
- )}
-
-
-
- Clear
-
-
-
- ) : (
-
-
-
-
- Import auth.json
-
-
-
- Located at ~/.codex/auth.json
-
-
- )}
-
-
- {/* Usage card */}
-
-
- Usage
-
-
- {status === "idle" && !auth && (
-
-
-
- Import auth.json to see your rate limits
-
-
- )}
- {status === "loading" && !usage && (
-
- )}
- {status === "error" && error && }
- {usage && (
-
- {/* Plan badge */}
-
-
-
- {usage.planType ?? "codex"}
-
-
-
-
- {usage.primary && (
-
- )}
- {usage.secondary && (
-
- )}
-
- {/* Credits */}
-
-
- Credits
-
- {usage.credits.unlimited ? (
-
-
-
- Unlimited
-
-
- ) : usage.credits.hasCredits ? (
-
- ${Number(usage.credits.balance).toFixed(2)} remaining
-
- ) : (
- No credits
- )}
-
-
- {resetCoupons && (
-
-
- Reset Credits
-
-
- {resetCoupons.availableCount ?? 0} available
-
- {typeof resetCoupons.totalEarnedCount === "number" && (
-
- {resetCoupons.totalEarnedCount} earned total
-
- )}
- {resetCoupons.nextExpiringCredit?.expiresAtLocal && (
-
- Next expires {resetCoupons.nextExpiringCredit.expiresAtLocal}
-
- )}
- {resetCoupons.nextExpiringCredit?.timeUntilExpiry && (
-
- In {resetCoupons.nextExpiringCredit.timeUntilExpiry}
-
- )}
- {availableResetCredits.length > 0 && (
-
-
- Available Now
-
- {availableResetCredits.map((credit) => (
-
- ))}
-
- )}
- {resetCoupons.source !== "live_api" && (
-
- Source: {resetCoupons.sourceDescription}
-
- )}
-
- )}
-
-
-
-
- )}
-
-
-
- );
-}
-
-export default function CodexTab() {
- return (
-
-
-
- );
-}
diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx
deleted file mode 100644
index a29d099..0000000
--- a/app/(tabs)/index.tsx
+++ /dev/null
@@ -1,338 +0,0 @@
-import {
- ScrollView,
- View,
- Text,
- TouchableOpacity,
- RefreshControl,
- ActivityIndicator,
-} from "react-native";
-import { SafeAreaView } from "react-native-safe-area-context";
-import { router, useFocusEffect } from "expo-router";
-import { useCallback, useEffect } from "react";
-import { MaterialIcons } from "@expo/vector-icons";
-import { useCodexUsage } from "@/hooks/useCodexUsage";
-import { useClaudeUsage } from "@/hooks/useClaudeUsage";
-import { onUsageDataLoaded } from "@/lib/notifications";
-import { ProgressBar } from "@/components/ProgressBar";
-import { ResetCountdown } from "@/components/ResetCountdown";
-import { LastUpdated } from "@/components/LastUpdated";
-import { ErrorMessage } from "@/components/ErrorMessage";
-import { ScreenErrorBoundary } from "@/components/ScreenErrorBoundary";
-import { COLORS, getUsageColor } from "@/lib/constants";
-import { windowLabel } from "@/lib/timeUtils";
-
-function UsageRow({
- label,
- percent,
- resetAtSeconds,
- resetAtISO,
-}: {
- label: string;
- percent: number;
- resetAtSeconds?: number;
- resetAtISO?: string;
-}) {
- const color = getUsageColor(percent);
- return (
-
-
-
- {label}
-
-
- {Math.round(percent)}% used
-
-
-
-
-
- );
-}
-
-function SetupPrompt({ label }: { label: string }) {
- return (
-
-
- {label}
-
- router.navigate("/(tabs)/settings")}
- className="flex-row items-center self-start gap-x-1.5 px-3 py-2 rounded-xl border border-neutral-200 dark:border-neutral-700"
- >
-
- Set up in Settings
-
-
-
-
- );
-}
-
-function DashboardTabContent() {
- const codex = useCodexUsage();
- const claude = useClaudeUsage();
-
- // Fire daily digest reschedule + threshold check whenever fresh data arrives
- useEffect(() => {
- if (codex.usage || claude.usage) {
- void onUsageDataLoaded(
- claude.usage,
- codex.usage
- );
- }
- }, [codex.lastFetchedAt, claude.lastFetchedAt]);
-
- useFocusEffect(
- useCallback(() => {
- void codex.reloadCredentials();
- void claude.reloadCredentials();
- }, [codex.reloadCredentials, claude.reloadCredentials])
- );
-
- const isRefreshing =
- codex.status === "loading" || claude.status === "loading";
-
- const handleRefresh = () => {
- void codex.refresh();
- void claude.refresh();
- };
-
- const connectedCount = [codex.auth, claude.auth].filter(Boolean).length;
-
- return (
-
-
- }
- >
- {/* Header */}
-
-
-
-
-
-
-
- Codexbar
-
-
- {connectedCount === 0
- ? "No services connected"
- : connectedCount === 2
- ? "2 services connected"
- : "1 of 2 services connected"}
-
-
-
-
-
-
-
-
- {/* Codex card */}
-
-
-
-
-
-
-
-
-
- Codex CLI
-
-
-
- {codex.usage?.planType && (
-
-
- {codex.usage.planType}
-
-
- )}
- {codex.auth && codex.status === "error" && (
-
- )}
- {codex.status === "success" && !codex.usage?.planType && (
-
- )}
-
-
-
- {!codex.auth && (
-
- )}
- {codex.auth && codex.status === "loading" && !codex.usage && (
-
- )}
- {codex.auth && codex.status === "error" && (
-
- )}
- {codex.usage && (
-
- {codex.usage.primary && (
-
- )}
- {codex.usage.secondary && (
-
- )}
- {!codex.usage.credits.unlimited &&
- codex.usage.credits.hasCredits && (
-
-
-
- ${Number(codex.usage.credits.balance).toFixed(2)}{" "}
- credits remaining
-
-
- )}
- {codex.usage.credits.unlimited && (
-
-
-
- Unlimited credits
-
-
- )}
-
- {!!codex.usage.resetCoupons && (
-
-
-
-
- {codex.usage.resetCoupons.availableCount ?? 0} reset credits
- available
-
-
- {!!codex.usage.resetCoupons.nextExpiringCredit?.timeUntilExpiry && (
-
- Next expires in {codex.usage.resetCoupons.nextExpiringCredit.timeUntilExpiry}
-
- )}
-
- )}
-
-
-
- )}
-
-
-
- {/* Claude card */}
-
-
-
-
-
-
-
-
-
- Claude.ai
-
-
- {claude.auth && claude.status === "error" && (
-
- )}
- {claude.status === "success" && (
-
- )}
-
-
- {!claude.auth && (
-
- )}
- {claude.auth && claude.status === "loading" && !claude.usage && (
-
- )}
- {claude.auth && claude.status === "error" && (
-
- )}
- {claude.usage && (
-
-
-
- {(claude.usage.seven_day_sonnet ||
- claude.usage.seven_day_opus) && (
-
-
- By Model (7-day)
-
- {claude.usage.seven_day_sonnet && (
-
- )}
- {claude.usage.seven_day_opus && (
-
- )}
-
- )}
-
-
-
-
- )}
-
-
-
-
- );
-}
-
-export default function DashboardTab() {
- return (
-
-
-
- );
-}
diff --git a/app/(tabs)/settings.tsx b/app/(tabs)/settings.tsx
deleted file mode 100644
index f3fc121..0000000
--- a/app/(tabs)/settings.tsx
+++ /dev/null
@@ -1,580 +0,0 @@
-import { useEffect, useState, useCallback } from "react";
-import {
- View,
- Text,
- TouchableOpacity,
- Alert,
- ScrollView,
- TextInput,
- Switch,
- KeyboardAvoidingView,
-} from "react-native";
-import { SafeAreaView } from "react-native-safe-area-context";
-import { router, useFocusEffect } from "expo-router";
-import { MaterialIcons } from "@expo/vector-icons";
-import {
- loadCodexAuth,
- clearCodexAuth,
- saveCodexAuth,
- loadClaudeSessionKey,
- clearClaudeSessionKey,
- saveClaudeSessionKey,
- saveClaudeLastActiveOrg,
- clearClaudeLastActiveOrg,
-} from "@/lib/storage";
-import { pickAndReadCodexAuth } from "@/lib/fileReader";
-import { resetOnboarding } from "@/lib/setupState";
-import { useNotificationSettings } from "@/hooks/useNotificationSettings";
-import {
- isClaudeSessionKeyValid,
- validateClaudeSessionKey,
-} from "@/lib/claudeCredentials";
-import { COLORS } from "@/lib/constants";
-import { formatTime, parseTimeInput } from "@/lib/timeUtils";
-import { ScreenErrorBoundary } from "@/components/ScreenErrorBoundary";
-import type { CodexAuth } from "@/types/codex";
-import Constants from "expo-constants";
-
-function humanizeImportError(code: string): string {
- if (code === "DOCUMENT_NOT_READABLE") {
- return "The selected file could not be read. Try copying auth.json into Files or Downloads and import it again.";
- }
- return code;
-}
-function SettingRow({
- icon,
- label,
- value,
- onPress,
- destructive,
- disabled,
-}: {
- icon: React.ComponentProps["name"];
- label: string;
- value?: string;
- onPress?: () => void;
- destructive?: boolean;
- disabled?: boolean;
-}) {
- return (
-
-
-
-
-
-
- {label}
-
- {value && (
-
- {value}
-
- )}
-
- {onPress && !disabled && (
-
- )}
-
- );
-}
-
-function SectionHeader({ title }: { title: string }) {
- return (
-
- {title}
-
- );
-}
-
-function SectionCard({ children }: { children: React.ReactNode }) {
- return (
-
- {children}
-
- );
-}
-
-function Divider() {
- return ;
-}
-
-function SettingsTabContent() {
- const [codexAuth, setCodexAuth] = useState(null);
- const [claudeKey, setClaudeKey] = useState(null);
- const [pendingKey, setPendingKey] = useState("");
- const [pendingOrg, setPendingOrg] = useState("");
- const [claudeError, setClaudeError] = useState(null);
-
- const notif = useNotificationSettings();
- const [timeInput, setTimeInput] = useState("");
- const [timeError, setTimeError] = useState(null);
- const [thresholdInput, setThresholdInput] = useState("");
-
- // Sync local text inputs when settings load
- useEffect(() => {
- if (notif.loaded) {
- setTimeInput(formatTime(notif.settings.dailyHour, notif.settings.dailyMinute));
- setThresholdInput(String(notif.settings.thresholdPct));
- }
- }, [notif.loaded]);
-
- const reload = useCallback(() => {
- Promise.all([loadCodexAuth(), loadClaudeSessionKey()]).then(
- ([codex, claude]) => {
- setCodexAuth(codex);
- setClaudeKey(claude);
- }
- );
- }, []);
-
- useEffect(() => {
- reload();
- }, [reload]);
-
- useFocusEffect(
- useCallback(() => {
- reload();
- }, [reload])
- );
-
- const handleImportCodex = async () => {
- try {
- const auth = await pickAndReadCodexAuth();
- await saveCodexAuth(auth);
- setCodexAuth(auth);
- } catch (e: unknown) {
- const msg = e instanceof Error ? e.message : "UNKNOWN_ERROR";
- if (msg !== "PICKER_CANCELLED") {
- Alert.alert("Import failed", humanizeImportError(msg));
- }
- }
- };
-
- const handleSaveClaude = async () => {
- const trimmed = pendingKey.trim();
- const validationError = validateClaudeSessionKey(trimmed);
- if (validationError) {
- setClaudeError(validationError);
- return;
- }
- const orgTrimmed = pendingOrg.trim() || undefined;
- await saveClaudeSessionKey(trimmed);
- if (orgTrimmed) await saveClaudeLastActiveOrg(orgTrimmed);
- else await clearClaudeLastActiveOrg();
- setClaudeKey(trimmed);
- setPendingKey("");
- setPendingOrg("");
- setClaudeError(null);
- };
-
- const handleClearCodex = () => {
- Alert.alert(
- "Clear Codex credentials",
- "This will remove your stored auth.json data. You can re-import it anytime.",
- [
- { text: "Cancel", style: "cancel" },
- {
- text: "Clear",
- style: "destructive",
- onPress: async () => {
- await clearCodexAuth();
- setCodexAuth(null);
- },
- },
- ]
- );
- };
-
- const handleClearClaude = () => {
- Alert.alert(
- "Clear Claude session key",
- "Your session key will be removed. You can re-enter it anytime.",
- [
- { text: "Cancel", style: "cancel" },
- {
- text: "Clear",
- style: "destructive",
- onPress: async () => {
- await clearClaudeSessionKey();
- setClaudeKey(null);
- },
- },
- ]
- );
- };
-
- const handleResetSetup = () => {
- Alert.alert(
- "Re-run Setup Wizard",
- "This will clear all credentials and restart the setup flow.",
- [
- { text: "Cancel", style: "cancel" },
- {
- text: "Reset & Re-run",
- style: "destructive",
- onPress: async () => {
- await Promise.all([
- clearCodexAuth(),
- clearClaudeSessionKey(),
- resetOnboarding(),
- ]);
- router.replace("/onboarding");
- },
- },
- ]
- );
- };
-
- const handleTimeBlur = useCallback(() => {
- const parsed = parseTimeInput(timeInput);
- if (parsed) {
- void notif.update({ dailyHour: parsed.hour, dailyMinute: parsed.minute });
- setTimeInput(formatTime(parsed.hour, parsed.minute));
- setTimeError(null);
- } else {
- setTimeError("Use HH:MM format, from 00:00 to 23:59.");
- }
- }, [timeInput, notif]);
-
- const handleThresholdBlur = useCallback(() => {
- const n = parseInt(thresholdInput, 10);
- if (!isNaN(n) && n >= 1 && n <= 99) {
- void notif.update({ thresholdPct: n });
- } else {
- setThresholdInput(String(notif.settings.thresholdPct));
- }
- }, [thresholdInput, notif]);
-
- const canSaveClaude = isClaudeSessionKeyValid(pendingKey);
- const inlineClaudeError =
- claudeError ?? (pendingKey ? validateClaudeSessionKey(pendingKey) : null);
- const appVersion = Constants.expoConfig?.version ?? "1.0.0";
-
- return (
-
-
-
- {/* Header */}
-
-
- Settings
-
-
-
- {/* Codex CLI section */}
-
-
- {codexAuth ? (
- <>
-
-
-
- >
- ) : (
-
- )}
-
-
- {/* Claude.ai section */}
-
-
- {claudeKey ? (
- <>
-
-
-
- >
- ) : (
-
- {inlineClaudeError && (
-
- {inlineClaudeError}
-
- )}
- {
- setPendingKey(t);
- setClaudeError(null);
- }}
- placeholder="sk-ant-… (required)"
- placeholderTextColor="#a3a3a3"
- autoCapitalize="none"
- autoCorrect={false}
- secureTextEntry
- className="border border-neutral-200 dark:border-neutral-700 rounded-xl px-3 py-3 text-sm text-neutral-900 dark:text-white bg-neutral-50 dark:bg-neutral-800 mb-2"
- />
-
-
-
- Save Session Key
-
-
-
- Chrome DevTools → Application → Cookies → claude.ai →{" "}
- sessionKey
-
-
- )}
-
-
- {/* Notifications section */}
-
-
- {notif.permissionStatus !== "granted" ? (
- {
- const granted = await notif.askPermissions();
- if (!granted && notif.permissionStatus === "denied") {
- Alert.alert(
- "Notifications blocked",
- "Go to Settings → CodexBar → Notifications to enable them."
- );
- }
- }}
- className="flex-row items-center gap-x-3 py-3.5 px-4"
- >
-
-
-
-
-
- Enable notifications
-
-
- {notif.permissionStatus === "denied"
- ? "Blocked — open system Settings to allow"
- : "Required to receive alerts"}
-
-
- {notif.permissionStatus !== "denied" && (
-
-
- Allow
-
-
- )}
-
- ) : (
- <>
- {/* Daily digest */}
-
-
-
-
-
-
- Daily digest
-
-
- Daily reminder with last-known usage
-
-
- void notif.update({ dailyEnabled: v })}
- trackColor={{ false: COLORS.disabled, true: COLORS.codex }}
- thumbColor="white"
- />
-
-
- {notif.settings.dailyEnabled && (
- <>
-
-
-
-
-
-
-
- Time
-
- {
- setTimeInput(value);
- setTimeError(null);
- }}
- onBlur={handleTimeBlur}
- placeholder="09:00"
- placeholderTextColor={COLORS.muted}
- keyboardType="numbers-and-punctuation"
- returnKeyType="done"
- maxLength={5}
- className="text-sm font-mono text-neutral-600 dark:text-neutral-300 text-right"
- style={{ minWidth: 52 }}
- />
-
- {timeError && (
-
- {timeError}
-
- )}
-
- >
- )}
-
-
-
- {/* Threshold alert */}
-
-
-
-
-
-
- Low quota alert
-
-
- Alert when weekly quota runs low
-
-
- void notif.update({ thresholdEnabled: v })}
- trackColor={{ false: COLORS.disabled, true: COLORS.claude }}
- thumbColor="white"
- />
-
-
- {notif.settings.thresholdEnabled && (
- <>
-
-
-
-
-
-
- Alert below
-
-
-
-
- % remaining
-
-
-
- >
- )}
- >
- )}
-
-
- {/* App section */}
-
-
-
-
-
-
-
-
-
- );
-}
-
-export default function SettingsTab() {
- return (
-
-
-
- );
-}
diff --git a/app/_layout.tsx b/app/_layout.tsx
deleted file mode 100644
index 109c5e4..0000000
--- a/app/_layout.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import "../global.css";
-import { Stack } from "expo-router";
-import { SafeAreaProvider } from "react-native-safe-area-context";
-import { StatusBar } from "expo-status-bar";
-import "@/lib/notifications"; // registers setNotificationHandler on app start
-
-export default function RootLayout() {
- return (
-
-
-
-
- );
-}
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..4c2288d
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,140 @@
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+def getVersionCode = {
+ def stdout = new ByteArrayOutputStream()
+ try {
+ exec {
+ commandLine 'git', 'rev-list', '--count', 'HEAD'
+ standardOutput = stdout
+ errorOutput = new ByteArrayOutputStream()
+ ignoreExitValue = true
+ }
+ def count = stdout.toString().trim()
+ return count.isInteger() ? count.toInteger() : 1
+ } catch (ignored) {
+ return 1
+ }
+}
+
+def signingPropertiesFile = rootProject.file('keystore.properties')
+def signingProperties = new Properties()
+if (signingPropertiesFile.exists()) {
+ signingPropertiesFile.withInputStream(signingProperties.&load)
+}
+
+def readSigningValue = { String... keys ->
+ keys.collect { key -> System.getenv(key) ?: signingProperties.getProperty(key) }
+ .find { value -> value != null && !value.trim().isEmpty() }
+}
+
+def releaseKeystorePath = readSigningValue('CODEXMOBILE_STORE_FILE', 'CODEXMOBILE_KEYSTORE_FILE')
+def releaseKeystorePassword = readSigningValue('CODEXMOBILE_STORE_PASSWORD', 'CODEXMOBILE_KEYSTORE_PASSWORD')
+def releaseKeyAlias = readSigningValue('CODEXMOBILE_KEY_ALIAS')
+def releaseKeyPassword = readSigningValue('CODEXMOBILE_KEY_PASSWORD')
+def hasReleaseSigning = [releaseKeystorePath, releaseKeystorePassword, releaseKeyAlias, releaseKeyPassword].every { it }
+def releaseSigningHelp = '''Release signing is not configured.
+
+Provide these values either as environment variables or in keystore.properties:
+- CODEXMOBILE_STORE_FILE or CODEXMOBILE_KEYSTORE_FILE
+- CODEXMOBILE_STORE_PASSWORD or CODEXMOBILE_KEYSTORE_PASSWORD
+- CODEXMOBILE_KEY_ALIAS
+- CODEXMOBILE_KEY_PASSWORD
+'''
+
+android {
+ namespace 'dev.reversed.codexbarmobile'
+ compileSdk 34
+
+ signingConfigs {
+ if (hasReleaseSigning) {
+ release {
+ storeFile rootProject.file(releaseKeystorePath)
+ storePassword releaseKeystorePassword
+ keyAlias releaseKeyAlias
+ keyPassword releaseKeyPassword
+ }
+ }
+ }
+
+ defaultConfig {
+ applicationId 'dev.reversed.codexbarmobile'
+ minSdk 26
+ targetSdk 34
+ versionCode getVersionCode()
+ versionName '1.0.0'
+ vectorDrawables.useSupportLibrary = true
+ }
+
+ buildTypes {
+ debug {
+ applicationIdSuffix '.debug'
+ versionNameSuffix '-debug'
+ }
+ release {
+ if (hasReleaseSigning) {
+ signingConfig signingConfigs.release
+ }
+ minifyEnabled true
+ shrinkResources true
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+
+ kotlinOptions {
+ jvmTarget = '17'
+ }
+
+ buildFeatures {
+ compose true
+ }
+
+ composeOptions {
+ kotlinCompilerExtensionVersion '1.5.14'
+ }
+
+ packaging {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+gradle.taskGraph.whenReady { graph ->
+ def needsSignedRelease = graph.allTasks.any { task ->
+ task.project == project &&
+ task.name.toLowerCase().contains('release') &&
+ !task.name.toLowerCase().contains('lint') &&
+ !task.name.toLowerCase().contains('unittest') &&
+ !task.name.toLowerCase().contains('signingreport')
+ }
+
+ if (needsSignedRelease && !hasReleaseSigning) {
+ throw new GradleException(releaseSigningHelp)
+ }
+}
+
+dependencies {
+ implementation 'androidx.core:core-ktx:1.13.1'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.4'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.4'
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.8.4'
+ implementation 'androidx.activity:activity-compose:1.9.2'
+ implementation platform('androidx.compose:compose-bom:2024.06.00')
+ implementation 'androidx.compose.ui:ui'
+ implementation 'androidx.compose.ui:ui-tooling-preview'
+ implementation 'androidx.compose.material3:material3'
+ implementation 'androidx.compose.material:material-icons-extended'
+ implementation 'androidx.security:security-crypto:1.1.0-alpha06'
+ implementation 'com.google.errorprone:error_prone_annotations:2.28.0'
+ implementation 'com.squareup.okhttp3:okhttp:4.12.0'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1'
+ debugImplementation 'androidx.compose.ui:ui-tooling'
+}
diff --git a/app/index.tsx b/app/index.tsx
deleted file mode 100644
index 9d8b5e9..0000000
--- a/app/index.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { useEffect } from "react";
-import { View, ActivityIndicator } from "react-native";
-import { router } from "expo-router";
-import { hasCompletedOnboarding } from "@/lib/setupState";
-import { COLORS } from "@/lib/constants";
-
-export default function Index() {
- useEffect(() => {
- hasCompletedOnboarding().then((done) => {
- router.replace(done ? "/(tabs)" : "/onboarding");
- });
- }, []);
-
- return (
-
-
-
- );
-}
diff --git a/app/onboarding/_layout.tsx b/app/onboarding/_layout.tsx
deleted file mode 100644
index e30c6af..0000000
--- a/app/onboarding/_layout.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { Stack } from "expo-router";
-
-export default function OnboardingLayout() {
- return (
-
- );
-}
diff --git a/app/onboarding/claude.tsx b/app/onboarding/claude.tsx
deleted file mode 100644
index 4eaabb3..0000000
--- a/app/onboarding/claude.tsx
+++ /dev/null
@@ -1,236 +0,0 @@
-import { useState, useCallback, useEffect } from "react";
-import {
- View,
- Text,
- TouchableOpacity,
- TextInput,
- KeyboardAvoidingView,
- ScrollView,
-} from "react-native";
-import { SafeAreaView } from "react-native-safe-area-context";
-import { router } from "expo-router";
-import { MaterialIcons } from "@expo/vector-icons";
-import {
- saveClaudeSessionKey,
- saveClaudeLastActiveOrg,
- clearClaudeLastActiveOrg,
- loadClaudeSessionKey,
- loadClaudeLastActiveOrg,
-} from "@/lib/storage";
-import {
- isClaudeSessionKeyValid,
- validateClaudeSessionKey,
-} from "@/lib/claudeCredentials";
-import { COLORS } from "@/lib/constants";
-
-export default function OnboardingClaudeScreen() {
- const [savedKey, setSavedKey] = useState(null);
- const [savedOrg, setSavedOrg] = useState(null);
- const [pendingKey, setPendingKey] = useState("");
- const [pendingOrg, setPendingOrg] = useState("");
- const [error, setError] = useState(null);
-
- useEffect(() => {
- Promise.all([loadClaudeSessionKey(), loadClaudeLastActiveOrg()]).then(
- ([k, o]) => {
- if (k) setSavedKey(k);
- if (o) setSavedOrg(o);
- }
- );
- }, []);
-
- const canSave = isClaudeSessionKeyValid(pendingKey);
- const inlineError =
- error ?? (pendingKey ? validateClaudeSessionKey(pendingKey) : null);
-
- const handleSave = useCallback(async () => {
- const trimmed = pendingKey.trim();
- const validationError = validateClaudeSessionKey(trimmed);
- if (validationError) {
- setError(validationError);
- return;
- }
- const orgTrimmed = pendingOrg.trim() || undefined;
- await saveClaudeSessionKey(trimmed);
- if (orgTrimmed) await saveClaudeLastActiveOrg(orgTrimmed);
- else await clearClaudeLastActiveOrg();
- setSavedKey(trimmed);
- setSavedOrg(orgTrimmed ?? null);
- setPendingKey("");
- setPendingOrg("");
- setError(null);
- }, [pendingKey, pendingOrg]);
-
- return (
-
-
-
-
- {/* Top: back + step indicator */}
-
- router.back()}
- className="w-9 h-9 rounded-xl bg-neutral-900 items-center justify-center"
- >
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
- {/* Content */}
-
-
-
-
-
- Connect Claude.ai
-
-
- Enter your session key to monitor your Claude.ai usage windows.
-
-
- {savedKey ? (
-
-
-
-
-
-
- Connected
-
- {savedKey.slice(0, 16)}…
-
-
- {
- setSavedKey(null);
- setSavedOrg(null);
- setPendingKey("");
- setPendingOrg("");
- }}
- >
- Change
-
-
- {savedOrg && (
-
-
- org: {savedOrg.slice(0, 8)}…
-
-
- )}
-
- ) : (
-
- {inlineError && (
-
- {inlineError}
-
- )}
- {
- setPendingKey(t);
- setError(null);
- }}
- placeholder="sk-ant-… (required)"
- placeholderTextColor="#525252"
- autoCapitalize="none"
- autoCorrect={false}
- secureTextEntry
- className="border border-neutral-800 rounded-xl px-4 py-3.5 text-sm text-white bg-neutral-900 mb-3"
- />
-
-
-
- Save Session Key
-
-
-
-
- How to find your credentials
-
-
- Open Claude.ai in Chrome → DevTools (F12) → Application → Cookies → claude.ai{"\n"}
- Copy sessionKey and optionally lastActiveOrg
-
-
-
- )}
-
-
- {/* Bottom actions */}
-
- router.push("/onboarding/done")}
- className="rounded-2xl py-4 items-center"
- style={{
- backgroundColor: savedKey ? COLORS.claude : "#1a1a1a",
- }}
- >
-
- Continue
-
-
- router.push("/onboarding/done")}
- className="py-3 items-center"
- >
- Skip for now
-
-
-
-
-
-
- );
-}
diff --git a/app/onboarding/codex.tsx b/app/onboarding/codex.tsx
deleted file mode 100644
index 6c3f50a..0000000
--- a/app/onboarding/codex.tsx
+++ /dev/null
@@ -1,162 +0,0 @@
-import { useState, useCallback, useEffect } from "react";
-import { View, Text, TouchableOpacity, ActivityIndicator } from "react-native";
-import { SafeAreaView } from "react-native-safe-area-context";
-import { router } from "expo-router";
-import { MaterialIcons } from "@expo/vector-icons";
-import { pickAndReadCodexAuth } from "@/lib/fileReader";
-import { saveCodexAuth, loadCodexAuth } from "@/lib/storage";
-import type { CodexAuth } from "@/types/codex";
-import { COLORS } from "@/lib/constants";
-
-function humanizeImportError(code: string): string {
- if (code === "DOCUMENT_NOT_READABLE") {
- return "The selected file could not be read. Try copying auth.json into Files or Downloads and import it again.";
- }
- return code;
-}
-
-export default function OnboardingCodexScreen() {
- const [auth, setAuth] = useState(null);
- const [loading, setLoading] = useState(false);
- const [error, setError] = useState(null);
-
- useEffect(() => {
- loadCodexAuth().then((stored) => {
- if (stored) setAuth(stored);
- });
- }, []);
-
- const importFile = useCallback(async () => {
- setLoading(true);
- setError(null);
- try {
- const parsed = await pickAndReadCodexAuth();
- await saveCodexAuth(parsed);
- setAuth(parsed);
- } catch (e: unknown) {
- const msg = e instanceof Error ? e.message : "UNKNOWN_ERROR";
- if (msg !== "PICKER_CANCELLED") setError(humanizeImportError(msg));
- } finally {
- setLoading(false);
- }
- }, []);
-
- return (
-
-
- {/* Top: back + step indicator */}
-
- router.back()}
- className="w-9 h-9 rounded-xl bg-neutral-900 items-center justify-center"
- >
-
-
-
-
- 1
-
-
-
- 2
-
-
-
-
-
- {/* Content */}
-
-
-
-
-
- Connect Codex CLI
-
-
- Import your{" "}
-
- ~/.codex/auth.json
- {" "}
- file to track your rate limits and credits.
-
-
- {/* Status / action */}
- {auth ? (
-
-
-
-
-
- Imported
- {auth.accountId && (
-
- {auth.accountId.slice(0, 12)}…
-
- )}
-
-
- Re-import
-
-
- ) : (
-
- {error && (
-
- {error}
-
- )}
-
- {loading ? (
-
- ) : (
-
-
-
- Import auth.json
-
-
- )}
-
-
- Located at ~/.codex/auth.json on your Mac
-
-
- )}
-
-
- {/* Bottom actions */}
-
- router.push("/onboarding/claude")}
- className="rounded-2xl py-4 items-center"
- style={{ backgroundColor: auth ? COLORS.codex : "#1a1a1a" }}
- >
-
- Continue
-
-
- router.push("/onboarding/claude")}
- className="py-3 items-center"
- >
- Skip for now
-
-
-
-
- );
-}
diff --git a/app/onboarding/done.tsx b/app/onboarding/done.tsx
deleted file mode 100644
index f3dee71..0000000
--- a/app/onboarding/done.tsx
+++ /dev/null
@@ -1,125 +0,0 @@
-import { useEffect, useState } from "react";
-import { View, Text, TouchableOpacity } from "react-native";
-import { SafeAreaView } from "react-native-safe-area-context";
-import { router } from "expo-router";
-import { MaterialIcons } from "@expo/vector-icons";
-import { markOnboardingComplete } from "@/lib/setupState";
-import { loadCodexAuth, loadClaudeSessionKey } from "@/lib/storage";
-import { COLORS } from "@/lib/constants";
-
-export default function OnboardingDoneScreen() {
- const [codexConfigured, setCodexConfigured] = useState(false);
- const [claudeConfigured, setClaudeConfigured] = useState(false);
-
- useEffect(() => {
- Promise.all([loadCodexAuth(), loadClaudeSessionKey()]).then(
- ([codex, claude]) => {
- setCodexConfigured(!!codex);
- setClaudeConfigured(!!claude);
- }
- );
- }, []);
-
- const handleEnterApp = async () => {
- await markOnboardingComplete();
- router.replace("/(tabs)");
- };
-
- const noneConfigured = !codexConfigured && !claudeConfigured;
-
- return (
-
-
- {/* Icon */}
-
-
-
-
- {/* Title */}
-
- {noneConfigured ? "Almost there" : "You're all set!"}
-
-
- {noneConfigured
- ? "No services configured yet. You can set them up anytime in Settings."
- : "Your services are connected and ready to monitor."}
-
-
- {/* Summary cards */}
-
-
-
-
-
-
-
- Codex CLI
-
-
- {codexConfigured ? "Auth imported" : "Not configured"}
-
-
-
-
-
-
-
-
-
-
- Claude.ai
-
-
- {claudeConfigured ? "Session saved" : "Not configured"}
-
-
-
-
-
- {/* CTA */}
-
- Open App
-
-
-
- );
-}
diff --git a/app/onboarding/index.tsx b/app/onboarding/index.tsx
deleted file mode 100644
index 462dd4d..0000000
--- a/app/onboarding/index.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import { View, Text, TouchableOpacity } from "react-native";
-import { SafeAreaView } from "react-native-safe-area-context";
-import { router } from "expo-router";
-import { MaterialIcons } from "@expo/vector-icons";
-import { COLORS } from "@/lib/constants";
-
-export default function WelcomeScreen() {
- return (
-
-
- {/* Logo + title */}
-
-
-
-
-
-
-
-
-
-
- Codexbar
-
-
- Monitor your Codex CLI and Claude.ai{"\n"}usage limits at a glance.
-
-
-
- {/* Feature pills */}
-
-
-
-
-
-
- Codex CLI
-
- Rate limits · Credits · Windows
-
-
-
-
-
-
-
-
- Claude.ai
-
- 5-hour · 7-day · Model usage
-
-
-
-
-
- {/* CTA */}
-
- router.push("/onboarding/codex")}
- className="rounded-2xl py-4 items-center"
- style={{ backgroundColor: COLORS.codex }}
- >
- Get Started
-
-
- You can configure services at any time in Settings
-
-
-
-
- );
-}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..2908a65
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,2 @@
+-dontwarn okhttp3.**
+-dontwarn okio.**
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..1707225
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/java/dev/reversed/codexbarmobile/AppStorage.kt b/app/src/main/java/dev/reversed/codexbarmobile/AppStorage.kt
new file mode 100644
index 0000000..ec4d40b
--- /dev/null
+++ b/app/src/main/java/dev/reversed/codexbarmobile/AppStorage.kt
@@ -0,0 +1,282 @@
+package dev.reversed.codexbarmobile
+
+import android.content.Context
+import android.content.SharedPreferences
+import androidx.security.crypto.EncryptedSharedPreferences
+import androidx.security.crypto.MasterKey
+import org.json.JSONArray
+import org.json.JSONObject
+
+class AppStorage(context: Context) {
+ private val prefs: SharedPreferences
+
+ init {
+ val masterKey = MasterKey.Builder(context)
+ .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
+ .build()
+ prefs = EncryptedSharedPreferences.create(
+ context,
+ "codexmobile_secure",
+ masterKey,
+ EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
+ EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM,
+ )
+ }
+
+ fun hasCompletedOnboarding(): Boolean = prefs.getBoolean(KEY_ONBOARDING_DONE, false)
+
+ fun markOnboardingComplete() {
+ prefs.edit().putBoolean(KEY_ONBOARDING_DONE, true).apply()
+ }
+
+ fun resetOnboarding() {
+ prefs.edit().remove(KEY_ONBOARDING_DONE).apply()
+ }
+
+ fun saveCodexAuth(auth: CodexAuth) {
+ prefs.edit().putString(KEY_CODEX_AUTH, JSONObject().apply {
+ put("accessToken", auth.accessToken)
+ putNullable("accountId", auth.accountId)
+ }.toString()).apply()
+ }
+
+ fun loadCodexAuth(): CodexAuth? = prefs.getString(KEY_CODEX_AUTH, null)?.let { raw ->
+ runCatching {
+ val json = JSONObject(raw)
+ CodexAuth(
+ accessToken = json.getString("accessToken"),
+ accountId = json.optStringOrNull("accountId"),
+ )
+ }.getOrNull()
+ }
+
+ fun clearCodexAuth() {
+ prefs.edit().remove(KEY_CODEX_AUTH).remove(KEY_CODEX_USAGE_CACHE).apply()
+ }
+
+ fun saveClaudeAuth(auth: ClaudeAuth) {
+ prefs.edit().putString(KEY_CLAUDE_AUTH, JSONObject().apply {
+ put("sessionKey", auth.sessionKey)
+ putNullable("lastActiveOrg", auth.lastActiveOrg)
+ }.toString()).apply()
+ }
+
+ fun loadClaudeAuth(): ClaudeAuth? = prefs.getString(KEY_CLAUDE_AUTH, null)?.let { raw ->
+ runCatching {
+ val json = JSONObject(raw)
+ ClaudeAuth(
+ sessionKey = json.getString("sessionKey"),
+ lastActiveOrg = json.optStringOrNull("lastActiveOrg"),
+ )
+ }.getOrNull()
+ }
+
+ fun clearClaudeAuth() {
+ prefs.edit().remove(KEY_CLAUDE_AUTH).remove(KEY_CLAUDE_USAGE_CACHE).apply()
+ }
+
+ fun saveCodexUsageCache(cache: UsageCache) {
+ prefs.edit().putString(KEY_CODEX_USAGE_CACHE, JSONObject().apply {
+ put("lastFetchedAt", cache.lastFetchedAt)
+ put("data", cache.data.toJson())
+ }.toString()).apply()
+ }
+
+ fun loadCodexUsageCache(): UsageCache? = prefs.getString(KEY_CODEX_USAGE_CACHE, null)?.let { raw ->
+ runCatching {
+ val json = JSONObject(raw)
+ UsageCache(
+ data = json.getJSONObject("data").toCodexUsage(),
+ lastFetchedAt = json.getLong("lastFetchedAt"),
+ )
+ }.getOrNull()
+ }
+
+ fun saveClaudeUsageCache(cache: UsageCache) {
+ prefs.edit().putString(KEY_CLAUDE_USAGE_CACHE, JSONObject().apply {
+ put("lastFetchedAt", cache.lastFetchedAt)
+ put("data", cache.data.toJson())
+ }.toString()).apply()
+ }
+
+ fun loadClaudeUsageCache(): UsageCache? = prefs.getString(KEY_CLAUDE_USAGE_CACHE, null)?.let { raw ->
+ runCatching {
+ val json = JSONObject(raw)
+ UsageCache(
+ data = json.getJSONObject("data").toClaudeUsage(),
+ lastFetchedAt = json.getLong("lastFetchedAt"),
+ )
+ }.getOrNull()
+ }
+
+ fun loadNotificationSettings(): NotificationSettings = NotificationSettings(
+ dailyEnabled = prefs.getBoolean(KEY_DAILY_ENABLED, false),
+ dailyHour = prefs.getInt(KEY_DAILY_HOUR, 9),
+ dailyMinute = prefs.getInt(KEY_DAILY_MINUTE, 0),
+ thresholdEnabled = prefs.getBoolean(KEY_THRESHOLD_ENABLED, false),
+ thresholdPct = prefs.getInt(KEY_THRESHOLD_PCT, 20),
+ )
+
+ fun saveNotificationSettings(settings: NotificationSettings) {
+ prefs.edit()
+ .putBoolean(KEY_DAILY_ENABLED, settings.dailyEnabled)
+ .putInt(KEY_DAILY_HOUR, settings.dailyHour)
+ .putInt(KEY_DAILY_MINUTE, settings.dailyMinute)
+ .putBoolean(KEY_THRESHOLD_ENABLED, settings.thresholdEnabled)
+ .putInt(KEY_THRESHOLD_PCT, settings.thresholdPct)
+ .apply()
+ }
+
+ fun loadThresholdLastFired(): String? = prefs.getString(KEY_THRESHOLD_LAST_FIRED, null)
+
+ fun saveThresholdLastFired(date: String) {
+ prefs.edit().putString(KEY_THRESHOLD_LAST_FIRED, date).apply()
+ }
+
+ companion object {
+ private const val KEY_ONBOARDING_DONE = "codexmobile_onboarding_v1"
+ private const val KEY_CODEX_AUTH = "codexmobile_codex_auth"
+ private const val KEY_CLAUDE_AUTH = "codexmobile_claude_auth"
+ private const val KEY_CODEX_USAGE_CACHE = "codexmobile_codex_usage_cache"
+ private const val KEY_CLAUDE_USAGE_CACHE = "codexmobile_claude_usage_cache"
+ private const val KEY_DAILY_ENABLED = "codexmobile_daily_enabled"
+ private const val KEY_DAILY_HOUR = "codexmobile_daily_hour"
+ private const val KEY_DAILY_MINUTE = "codexmobile_daily_minute"
+ private const val KEY_THRESHOLD_ENABLED = "codexmobile_threshold_enabled"
+ private const val KEY_THRESHOLD_PCT = "codexmobile_threshold_pct"
+ private const val KEY_THRESHOLD_LAST_FIRED = "codexmobile_threshold_last_fired"
+
+ fun parseCodexAuthJson(text: String): CodexAuth {
+ val json = JSONObject(text)
+ val tokens = json.optJSONObject("tokens")
+ val accessToken = tokens?.optStringOrNull("access_token")
+ ?: json.optStringOrNull("accessToken")
+ ?: throw IllegalArgumentException("MISSING_ACCESS_TOKEN")
+ val accountId = tokens?.optStringOrNull("account_id")
+ ?: json.optStringOrNull("accountId")
+ ?: json.optStringOrNull("account_id")
+ return CodexAuth(accessToken = accessToken, accountId = accountId)
+ }
+ }
+}
+
+fun JSONObject.optStringOrNull(name: String): String? = if (has(name) && !isNull(name)) {
+ optString(name).takeIf { it.isNotBlank() }
+} else null
+
+fun JSONObject.optDoubleOrNull(name: String): Double? = if (has(name) && !isNull(name)) optDouble(name) else null
+
+fun JSONObject.optLongOrNull(name: String): Long? = if (has(name) && !isNull(name)) optLong(name) else null
+
+fun JSONObject.optIntOrNull(name: String): Int? = if (has(name) && !isNull(name)) optInt(name) else null
+
+fun JSONObject.putNullable(name: String, value: Any?) {
+ if (value == null) put(name, JSONObject.NULL) else put(name, value)
+}
+
+fun UsageWindow.toJson(): JSONObject = JSONObject().apply {
+ put("usedPercent", usedPercent)
+ putNullable("resetsAt", resetsAt)
+ putNullable("resetsAtIso", resetsAtIso)
+ putNullable("windowSeconds", windowSeconds)
+}
+
+fun JSONObject.toUsageWindow(): UsageWindow = UsageWindow(
+ usedPercent = getDouble("usedPercent"),
+ resetsAt = optLongOrNull("resetsAt"),
+ resetsAtIso = optStringOrNull("resetsAtIso"),
+ windowSeconds = optLongOrNull("windowSeconds"),
+)
+
+fun CodexUsage.toJson(): JSONObject = JSONObject().apply {
+ putNullable("planType", planType)
+ putNullable("rateLimitReachedType", rateLimitReachedType)
+ putNullable("primary", primary?.toJson())
+ putNullable("secondary", secondary?.toJson())
+ put("credits", JSONObject().apply {
+ put("hasCredits", credits.hasCredits)
+ put("unlimited", credits.unlimited)
+ put("balance", credits.balance)
+ })
+ putNullable("resetCoupons", resetCoupons?.toJson())
+}
+
+fun JSONObject.toCodexUsage(): CodexUsage {
+ val creditsJson = getJSONObject("credits")
+ return CodexUsage(
+ planType = optStringOrNull("planType"),
+ rateLimitReachedType = optStringOrNull("rateLimitReachedType"),
+ primary = optJSONObject("primary")?.toUsageWindow(),
+ secondary = optJSONObject("secondary")?.toUsageWindow(),
+ credits = CodexCredits(
+ hasCredits = creditsJson.optBoolean("hasCredits"),
+ unlimited = creditsJson.optBoolean("unlimited"),
+ balance = creditsJson.optDouble("balance", 0.0),
+ ),
+ resetCoupons = optJSONObject("resetCoupons")?.toResetCoupons(),
+ )
+}
+
+fun ResetCoupons.toJson(): JSONObject = JSONObject().apply {
+ put("source", source)
+ put("sourceDescription", sourceDescription)
+ putNullable("availableCount", availableCount)
+ putNullable("totalEarnedCount", totalEarnedCount)
+ put("credits", JSONArray().also { arr -> credits.forEach { arr.put(it.toJson()) } })
+ putNullable("nextExpiringCredit", nextExpiringCredit?.toJson())
+ putNullable("error", error)
+}
+
+fun ResetCredit.toJson(): JSONObject = JSONObject().apply {
+ put("index", index)
+ putNullable("status", status)
+ putNullable("grantedAt", grantedAt)
+ putNullable("expiresAt", expiresAt)
+ putNullable("timeUntilExpiry", timeUntilExpiry)
+}
+
+fun JSONObject.toResetCoupons(): ResetCoupons {
+ val arr = optJSONArray("credits") ?: JSONArray()
+ val credits = (0 until arr.length()).mapNotNull { arr.optJSONObject(it)?.toResetCredit() }
+ return ResetCoupons(
+ source = optString("source", "unavailable"),
+ sourceDescription = optString("sourceDescription", "Reset-credit endpoint unavailable"),
+ availableCount = optIntOrNull("availableCount"),
+ totalEarnedCount = optIntOrNull("totalEarnedCount"),
+ credits = credits,
+ nextExpiringCredit = optJSONObject("nextExpiringCredit")?.toResetCredit(),
+ error = optStringOrNull("error"),
+ )
+}
+
+fun JSONObject.toResetCredit(): ResetCredit = ResetCredit(
+ index = optInt("index"),
+ status = optStringOrNull("status"),
+ grantedAt = optStringOrNull("grantedAt"),
+ expiresAt = optStringOrNull("expiresAt"),
+ timeUntilExpiry = optStringOrNull("timeUntilExpiry"),
+)
+
+fun ClaudeUsage.toJson(): JSONObject = JSONObject().apply {
+ put("fiveHour", fiveHour.toJson())
+ put("sevenDay", sevenDay.toJson())
+ putNullable("sevenDaySonnet", sevenDaySonnet?.toJson())
+ putNullable("sevenDayOpus", sevenDayOpus?.toJson())
+}
+
+fun ClaudeWindowUsage.toJson(): JSONObject = JSONObject().apply {
+ put("utilization", utilization)
+ putNullable("resetsAt", resetsAt)
+}
+
+fun JSONObject.toClaudeUsage(): ClaudeUsage = ClaudeUsage(
+ fiveHour = getJSONObject("fiveHour").toClaudeWindowUsage(),
+ sevenDay = getJSONObject("sevenDay").toClaudeWindowUsage(),
+ sevenDaySonnet = optJSONObject("sevenDaySonnet")?.toClaudeWindowUsage(),
+ sevenDayOpus = optJSONObject("sevenDayOpus")?.toClaudeWindowUsage(),
+)
+
+fun JSONObject.toClaudeWindowUsage(): ClaudeWindowUsage = ClaudeWindowUsage(
+ utilization = getDouble("utilization"),
+ resetsAt = optStringOrNull("resetsAt"),
+)
diff --git a/app/src/main/java/dev/reversed/codexbarmobile/AppViewModel.kt b/app/src/main/java/dev/reversed/codexbarmobile/AppViewModel.kt
new file mode 100644
index 0000000..ae4d636
--- /dev/null
+++ b/app/src/main/java/dev/reversed/codexbarmobile/AppViewModel.kt
@@ -0,0 +1,256 @@
+package dev.reversed.codexbarmobile
+
+import android.app.Application
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.setValue
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+class AppViewModel(application: Application) : AndroidViewModel(application) {
+ private val storage = AppStorage(application)
+ private val api = UsageApi()
+
+ var screen by androidx.compose.runtime.mutableStateOf(AppScreen.Splash)
+ private set
+ var tab by androidx.compose.runtime.mutableStateOf(MainTab.Dashboard)
+ private set
+
+ var codexAuth by androidx.compose.runtime.mutableStateOf(null)
+ private set
+ var codexUsage by androidx.compose.runtime.mutableStateOf(null)
+ private set
+ var codexLastFetchedAt by androidx.compose.runtime.mutableStateOf(null)
+ private set
+ var codexStatus by androidx.compose.runtime.mutableStateOf(LoadStatus.Idle)
+ private set
+ var codexError by androidx.compose.runtime.mutableStateOf(null)
+ private set
+
+ var claudeAuth by androidx.compose.runtime.mutableStateOf(null)
+ private set
+ var claudeUsage by androidx.compose.runtime.mutableStateOf(null)
+ private set
+ var claudeLastFetchedAt by androidx.compose.runtime.mutableStateOf(null)
+ private set
+ var claudeStatus by androidx.compose.runtime.mutableStateOf(LoadStatus.Idle)
+ private set
+ var claudeError by androidx.compose.runtime.mutableStateOf(null)
+ private set
+
+ var notificationSettings by androidx.compose.runtime.mutableStateOf(NotificationSettings())
+ private set
+
+ init {
+ loadInitialState()
+ }
+
+ fun selectTab(next: MainTab) {
+ tab = next
+ }
+
+ fun goTo(next: AppScreen) {
+ screen = next
+ }
+
+ fun openMain() {
+ storage.markOnboardingComplete()
+ screen = AppScreen.Main
+ }
+
+ fun resetSetup() {
+ storage.clearCodexAuth()
+ storage.clearClaudeAuth()
+ storage.resetOnboarding()
+ codexAuth = null
+ codexUsage = null
+ codexLastFetchedAt = null
+ codexStatus = LoadStatus.Idle
+ codexError = null
+ claudeAuth = null
+ claudeUsage = null
+ claudeLastFetchedAt = null
+ claudeStatus = LoadStatus.Idle
+ claudeError = null
+ screen = AppScreen.Welcome
+ tab = MainTab.Dashboard
+ }
+
+ fun importCodexAuthText(text: String) {
+ viewModelScope.launch {
+ runCatching { AppStorage.parseCodexAuthJson(text) }
+ .onSuccess { auth ->
+ storage.saveCodexAuth(auth)
+ codexAuth = auth
+ codexError = null
+ refreshCodex()
+ }
+ .onFailure { codexError = humanizeImportError(it.message ?: "INVALID_JSON") }
+ }
+ }
+
+ fun saveClaude(sessionKey: String, lastActiveOrg: String?) {
+ val trimmed = sessionKey.trim()
+ val validationError = validateClaudeSessionKey(trimmed)
+ if (validationError != null) {
+ claudeError = validationError
+ return
+ }
+ val auth = ClaudeAuth(trimmed, lastActiveOrg?.trim()?.takeIf { it.isNotBlank() })
+ storage.saveClaudeAuth(auth)
+ claudeAuth = auth
+ claudeError = null
+ refreshClaude()
+ }
+
+ fun clearCodex() {
+ storage.clearCodexAuth()
+ codexAuth = null
+ codexUsage = null
+ codexLastFetchedAt = null
+ codexStatus = LoadStatus.Idle
+ codexError = null
+ }
+
+ fun clearClaude() {
+ storage.clearClaudeAuth()
+ claudeAuth = null
+ claudeUsage = null
+ claudeLastFetchedAt = null
+ claudeStatus = LoadStatus.Idle
+ claudeError = null
+ }
+
+ fun refreshAll() {
+ refreshCodex()
+ refreshClaude()
+ }
+
+ fun refreshCodex() {
+ val auth = codexAuth ?: return
+ viewModelScope.launch {
+ codexStatus = LoadStatus.Loading
+ codexError = null
+ runCatchingWithRetry { api.fetchCodexUsage(auth) }
+ .onSuccess { usage ->
+ val fetchedAt = System.currentTimeMillis()
+ codexUsage = usage
+ codexLastFetchedAt = fetchedAt
+ codexStatus = LoadStatus.Success
+ storage.saveCodexUsageCache(UsageCache(usage, fetchedAt))
+ syncNotifications()
+ }
+ .onFailure { error ->
+ if (error.message == "TOKEN_EXPIRED") clearCodex()
+ codexStatus = LoadStatus.Error
+ codexError = humanizeError(error)
+ }
+ }
+ }
+
+ fun refreshClaude() {
+ val auth = claudeAuth ?: return
+ viewModelScope.launch {
+ claudeStatus = LoadStatus.Loading
+ claudeError = null
+ runCatchingWithRetry { api.fetchClaudeUsage(auth) }
+ .onSuccess { usage ->
+ val fetchedAt = System.currentTimeMillis()
+ claudeUsage = usage
+ claudeLastFetchedAt = fetchedAt
+ claudeStatus = LoadStatus.Success
+ storage.saveClaudeUsageCache(UsageCache(usage, fetchedAt))
+ syncNotifications()
+ }
+ .onFailure { error ->
+ if (error.message == "TOKEN_EXPIRED") clearClaude()
+ claudeStatus = LoadStatus.Error
+ claudeError = humanizeError(error)
+ }
+ }
+ }
+
+ fun updateNotificationSettings(settings: NotificationSettings) {
+ notificationSettings = settings
+ storage.saveNotificationSettings(settings)
+ syncNotifications()
+ }
+
+ private fun loadInitialState() {
+ codexAuth = storage.loadCodexAuth()
+ claudeAuth = storage.loadClaudeAuth()
+ notificationSettings = storage.loadNotificationSettings()
+ storage.loadCodexUsageCache()?.let {
+ codexUsage = it.data
+ codexLastFetchedAt = it.lastFetchedAt
+ codexStatus = LoadStatus.Success
+ }
+ storage.loadClaudeUsageCache()?.let {
+ claudeUsage = it.data
+ claudeLastFetchedAt = it.lastFetchedAt
+ claudeStatus = LoadStatus.Success
+ }
+ screen = if (storage.hasCompletedOnboarding()) AppScreen.Main else AppScreen.Welcome
+ refreshAll()
+ }
+
+ private fun syncNotifications() {
+ val context = getApplication()
+ if (notificationSettings.dailyEnabled) {
+ NotificationScheduler.scheduleDailyDigest(
+ context = context,
+ hour = notificationSettings.dailyHour,
+ minute = notificationSettings.dailyMinute,
+ body = buildDailyDigestBody(claudeUsage, codexUsage),
+ )
+ } else {
+ NotificationScheduler.cancelDailyDigest(context)
+ }
+ maybeFireThresholdAlert(context, storage, notificationSettings, claudeUsage, codexUsage)
+ }
+
+ private suspend fun runCatchingWithRetry(block: suspend () -> T): Result {
+ return runCatching { block() }.recoverCatching { first ->
+ if (!shouldRetry(first)) throw first
+ delay(RETRY_DELAY_MS)
+ block()
+ }
+ }
+
+ private fun shouldRetry(error: Throwable): Boolean = when (error.message) {
+ "TOKEN_EXPIRED", "NO_ORGS_FOUND", "INVALID_CODEX_RESPONSE", "INVALID_CLAUDE_RESPONSE" -> false
+ else -> true
+ }
+
+ private fun humanizeImportError(code: String): String = when (code) {
+ "MISSING_ACCESS_TOKEN" -> "That auth.json does not contain a Codex access token."
+ "INVALID_JSON" -> "That file is not valid JSON."
+ else -> "The selected file could not be read. Try another copy of auth.json."
+ }
+
+ private fun humanizeError(error: Throwable): String = when (val message = error.message) {
+ "TOKEN_EXPIRED" -> "Credentials expired. Reconnect this service."
+ "NO_ORGS_FOUND" -> "No Claude organizations were found for this session."
+ null -> "Something went wrong. Pull to retry."
+ else -> if (message.startsWith("HTTP_ERROR_")) "Service request failed (${message.removePrefix("HTTP_ERROR_")}). Pull to retry." else message
+ }
+
+ companion object {
+ private const val RETRY_DELAY_MS = 5_000L
+ }
+}
+
+private val claudeSessionPattern = Regex("^sk-ant-[A-Za-z0-9_-]+$")
+
+fun validateClaudeSessionKey(value: String): String? {
+ val key = value.trim()
+ return when {
+ !key.startsWith("sk-ant-") -> "Session key must start with sk-ant-."
+ key.length <= 40 -> "Session key looks too short. Paste the complete cookie value."
+ !claudeSessionPattern.matches(key) -> "Session key contains unexpected characters."
+ else -> null
+ }
+}
+
+fun isClaudeSessionKeyValid(value: String): Boolean = validateClaudeSessionKey(value) == null
diff --git a/app/src/main/java/dev/reversed/codexbarmobile/MainActivity.kt b/app/src/main/java/dev/reversed/codexbarmobile/MainActivity.kt
new file mode 100644
index 0000000..1225d99
--- /dev/null
+++ b/app/src/main/java/dev/reversed/codexbarmobile/MainActivity.kt
@@ -0,0 +1,855 @@
+package dev.reversed.codexbarmobile
+
+import android.Manifest
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.rememberLauncherForActivityResult
+import androidx.activity.compose.setContent
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.rounded.Alarm
+import androidx.compose.material.icons.rounded.AutoAwesome
+import androidx.compose.material.icons.rounded.BarChart
+import androidx.compose.material.icons.rounded.CheckCircle
+import androidx.compose.material.icons.rounded.DeleteOutline
+import androidx.compose.material.icons.rounded.Home
+import androidx.compose.material.icons.rounded.Info
+import androidx.compose.material.icons.rounded.Notifications
+import androidx.compose.material.icons.rounded.Psychology
+import androidx.compose.material.icons.rounded.Refresh
+import androidx.compose.material.icons.rounded.RestartAlt
+import androidx.compose.material.icons.rounded.Settings
+import androidx.compose.material.icons.rounded.UploadFile
+import androidx.compose.material.icons.rounded.Warning
+import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.AssistChip
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.Card
+import androidx.compose.material3.CardDefaults
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.LinearProgressIndicator
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.NavigationBar
+import androidx.compose.material3.NavigationBarItem
+import androidx.compose.material3.OutlinedButton
+import androidx.compose.material3.OutlinedTextField
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Surface
+import androidx.compose.material3.Switch
+import androidx.compose.material3.Text
+import androidx.compose.material3.TextButton
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import androidx.lifecycle.viewmodel.compose.viewModel
+import java.time.Instant
+import java.time.ZoneId
+import java.time.format.DateTimeFormatter
+import kotlin.math.roundToInt
+
+class MainActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ CodexMobileTheme {
+ val vm: AppViewModel = viewModel()
+ CodexMobileApp(vm)
+ }
+ }
+ }
+}
+
+@Composable
+private fun CodexMobileApp(vm: AppViewModel) {
+ val context = LocalContext.current
+ val pickCodexAuth = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { uri: Uri? ->
+ if (uri != null) {
+ val text = context.contentResolver.openInputStream(uri)?.bufferedReader()?.use { it.readText() }
+ if (text != null) vm.importCodexAuthText(text)
+ }
+ }
+ val requestNotifications = rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {}
+
+ val pickAuth = { pickCodexAuth.launch(arrayOf("application/json", "text/*", "*/*")) }
+ val askNotifications = {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ requestNotifications.launch(Manifest.permission.POST_NOTIFICATIONS)
+ }
+ }
+
+ when (vm.screen) {
+ AppScreen.Splash -> SplashScreen()
+ AppScreen.Welcome -> WelcomeScreen(vm)
+ AppScreen.OnboardingCodex -> OnboardingCodexScreen(vm, pickAuth)
+ AppScreen.OnboardingClaude -> OnboardingClaudeScreen(vm)
+ AppScreen.OnboardingDone -> OnboardingDoneScreen(vm)
+ AppScreen.Main -> MainScreen(vm, pickAuth, askNotifications)
+ }
+}
+
+@Composable
+private fun SplashScreen() {
+ Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+ CircularProgressIndicator(color = CodexGreen)
+ }
+}
+
+@Composable
+private fun WelcomeScreen(vm: AppViewModel) {
+ OnboardingShell {
+ Spacer(Modifier.height(32.dp))
+ AppMark(size = 72)
+ Spacer(Modifier.height(28.dp))
+ Text("CodexMobile", style = MaterialTheme.typography.displaySmall, fontWeight = FontWeight.Black)
+ Text(
+ "Monitor Codex CLI and Claude.ai usage limits without a web stack.",
+ style = MaterialTheme.typography.bodyLarge,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.padding(top = 12.dp),
+ )
+ Spacer(Modifier.weight(1f))
+ FeaturePill(Icons.Rounded.AutoAwesome, "Codex CLI", "Rate limits, credits, reset coupons", CodexGreen)
+ Spacer(Modifier.height(12.dp))
+ FeaturePill(Icons.Rounded.Psychology, "Claude.ai", "5-hour, 7-day, and model windows", ClaudeAmber)
+ Spacer(Modifier.weight(1f))
+ PrimaryButton("Get started", CodexGreen) { vm.goTo(AppScreen.OnboardingCodex) }
+ Text(
+ "You can configure services later in Settings.",
+ style = MaterialTheme.typography.bodySmall,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.padding(top = 12.dp),
+ )
+ }
+}
+
+@Composable
+private fun OnboardingCodexScreen(vm: AppViewModel, pickAuth: () -> Unit) {
+ OnboardingShell {
+ StepHeader(1, 2)
+ Spacer(Modifier.height(36.dp))
+ ServiceIcon(Icons.Rounded.AutoAwesome, CodexGreen)
+ Text("Connect Codex CLI", style = MaterialTheme.typography.headlineLarge, fontWeight = FontWeight.Bold)
+ Text(
+ "Import your ~/.codex/auth.json file to track rate limits, credits, and reset coupons.",
+ style = MaterialTheme.typography.bodyLarge,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.padding(top = 12.dp),
+ )
+ Spacer(Modifier.height(24.dp))
+ vm.codexError?.let { ErrorCard(it) }
+ if (vm.codexAuth != null) {
+ ConnectedCard("Imported", vm.codexAuth?.accountId?.take(16), CodexGreen)
+ TextButton(onClick = pickAuth) { Text("Re-import auth.json") }
+ } else {
+ PrimaryButton("Import auth.json", CodexGreen, icon = Icons.Rounded.UploadFile, onClick = pickAuth)
+ Text("File picker accepts the Codex auth JSON export.", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ }
+ Spacer(Modifier.weight(1f))
+ PrimaryButton("Continue", if (vm.codexAuth != null) CodexGreen else MutedButton) { vm.goTo(AppScreen.OnboardingClaude) }
+ TextButton(onClick = { vm.goTo(AppScreen.OnboardingClaude) }) { Text("Skip for now") }
+ }
+}
+
+@Composable
+private fun OnboardingClaudeScreen(vm: AppViewModel) {
+ var key by remember { mutableStateOf("") }
+ var org by remember { mutableStateOf("") }
+ val inlineError = if (key.isBlank()) null else validateClaudeSessionKey(key)
+ OnboardingShell {
+ StepHeader(2, 2)
+ Spacer(Modifier.height(36.dp))
+ ServiceIcon(Icons.Rounded.Psychology, ClaudeAmber)
+ Text("Connect Claude.ai", style = MaterialTheme.typography.headlineLarge, fontWeight = FontWeight.Bold)
+ Text(
+ "Paste your sessionKey cookie and optionally lastActiveOrg to monitor Claude usage windows.",
+ style = MaterialTheme.typography.bodyLarge,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.padding(top = 12.dp),
+ )
+ Spacer(Modifier.height(24.dp))
+ if (vm.claudeAuth != null) {
+ ConnectedCard("Connected", vm.claudeAuth?.sessionKey?.take(16), ClaudeAmber)
+ TextButton(onClick = { vm.clearClaude() }) { Text("Change session key") }
+ } else {
+ (vm.claudeError ?: inlineError)?.let { ErrorCard(it) }
+ OutlinedTextField(
+ value = key,
+ onValueChange = { key = it },
+ label = { Text("sessionKey") },
+ visualTransformation = PasswordVisualTransformation(),
+ singleLine = true,
+ modifier = Modifier.fillMaxWidth(),
+ )
+ Spacer(Modifier.height(10.dp))
+ OutlinedTextField(
+ value = org,
+ onValueChange = { org = it },
+ label = { Text("lastActiveOrg (optional)") },
+ singleLine = true,
+ modifier = Modifier.fillMaxWidth(),
+ )
+ Spacer(Modifier.height(12.dp))
+ PrimaryButton("Save session key", if (isClaudeSessionKeyValid(key)) ClaudeAmber else MutedButton) {
+ vm.saveClaude(key, org)
+ }
+ HelpCard("Find it in Chrome DevTools > Application > Cookies > claude.ai > sessionKey.")
+ }
+ Spacer(Modifier.weight(1f))
+ PrimaryButton("Continue", if (vm.claudeAuth != null) ClaudeAmber else MutedButton) { vm.goTo(AppScreen.OnboardingDone) }
+ TextButton(onClick = { vm.goTo(AppScreen.OnboardingDone) }) { Text("Skip for now") }
+ }
+}
+
+@Composable
+private fun OnboardingDoneScreen(vm: AppViewModel) {
+ OnboardingShell(horizontalAlignment = Alignment.CenterHorizontally) {
+ Spacer(Modifier.weight(1f))
+ ServiceIcon(if (vm.codexAuth != null || vm.claudeAuth != null) Icons.Rounded.CheckCircle else Icons.Rounded.Info, CodexGreen, 84)
+ Text(
+ if (vm.codexAuth == null && vm.claudeAuth == null) "Almost there" else "You're all set",
+ style = MaterialTheme.typography.headlineLarge,
+ fontWeight = FontWeight.Black,
+ )
+ Text(
+ if (vm.codexAuth == null && vm.claudeAuth == null) "No services are configured yet. Settings can finish setup anytime." else "Your connected services are ready to monitor.",
+ style = MaterialTheme.typography.bodyLarge,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ modifier = Modifier.padding(top = 12.dp),
+ )
+ Spacer(Modifier.height(28.dp))
+ SummaryRow("Codex CLI", if (vm.codexAuth != null) "Auth imported" else "Not configured", vm.codexAuth != null, CodexGreen)
+ SummaryRow("Claude.ai", if (vm.claudeAuth != null) "Session saved" else "Not configured", vm.claudeAuth != null, ClaudeAmber)
+ Spacer(Modifier.weight(1f))
+ PrimaryButton("Open app", CodexGreen) { vm.openMain() }
+ }
+}
+
+@Composable
+private fun MainScreen(vm: AppViewModel, pickAuth: () -> Unit, askNotifications: () -> Unit) {
+ Scaffold(
+ bottomBar = {
+ NavigationBar {
+ MainTab.entries.forEach { item ->
+ NavigationBarItem(
+ selected = vm.tab == item,
+ onClick = { vm.selectTab(item) },
+ icon = { Icon(item.icon, null) },
+ label = { Text(item.label) },
+ )
+ }
+ }
+ },
+ ) { padding ->
+ Box(Modifier.padding(padding)) {
+ when (vm.tab) {
+ MainTab.Dashboard -> DashboardScreen(vm)
+ MainTab.Codex -> CodexScreen(vm, pickAuth)
+ MainTab.Claude -> ClaudeScreen(vm)
+ MainTab.Settings -> SettingsScreen(vm, pickAuth, askNotifications)
+ }
+ }
+ }
+}
+
+@Composable
+private fun DashboardScreen(vm: AppViewModel) {
+ ScreenColumn {
+ Header("CodexMobile", connectedSummary(vm), Icons.Rounded.BarChart, CodexGreen) { vm.refreshAll() }
+ ServiceCard("Codex CLI", Icons.Rounded.AutoAwesome, CodexGreen, vm.codexStatus, vm.codexError, vm.codexAuth != null) {
+ vm.codexUsage?.let { CodexUsageContent(it, vm.codexLastFetchedAt, compact = true) }
+ ?: EmptyState("Import auth.json in Settings to see Codex rate limits.") { vm.selectTab(MainTab.Settings) }
+ }
+ ServiceCard("Claude.ai", Icons.Rounded.Psychology, ClaudeAmber, vm.claudeStatus, vm.claudeError, vm.claudeAuth != null) {
+ vm.claudeUsage?.let { ClaudeUsageContent(it, vm.claudeLastFetchedAt) }
+ ?: EmptyState("Add a session key in Settings to see Claude usage.") { vm.selectTab(MainTab.Settings) }
+ }
+ }
+}
+
+@Composable
+private fun CodexScreen(vm: AppViewModel, pickAuth: () -> Unit) {
+ ScreenColumn {
+ Header("Codex CLI", "Rate limits and reset credits", Icons.Rounded.AutoAwesome, CodexGreen) { vm.refreshCodex() }
+ ConfigCard(
+ connected = vm.codexAuth != null,
+ label = vm.codexAuth?.accountId?.take(16),
+ color = CodexGreen,
+ connectLabel = "Import auth.json",
+ onConnect = pickAuth,
+ onClear = vm::clearCodex,
+ )
+ vm.codexError?.let { ErrorCard(it) }
+ UsageSurface(vm.codexStatus) {
+ vm.codexUsage?.let { CodexUsageContent(it, vm.codexLastFetchedAt, compact = false) }
+ ?: EmptyState("Import Codex auth.json to load usage windows.") { pickAuth() }
+ }
+ }
+}
+
+@Composable
+private fun ClaudeScreen(vm: AppViewModel) {
+ var key by remember { mutableStateOf("") }
+ var org by remember { mutableStateOf("") }
+ ScreenColumn {
+ Header("Claude.ai", "Usage windows", Icons.Rounded.Psychology, ClaudeAmber) { vm.refreshClaude() }
+ if (vm.claudeAuth != null) {
+ ConfigCard(
+ connected = true,
+ label = vm.claudeAuth?.sessionKey?.take(16),
+ color = ClaudeAmber,
+ connectLabel = "Save session key",
+ onConnect = {},
+ onClear = vm::clearClaude,
+ )
+ } else {
+ ClaudeCredentialCard(key, org, vm.claudeError, onKey = { key = it }, onOrg = { org = it }) { vm.saveClaude(key, org) }
+ }
+ UsageSurface(vm.claudeStatus) {
+ vm.claudeUsage?.let { ClaudeUsageContent(it, vm.claudeLastFetchedAt) }
+ ?: EmptyState("Enter a Claude session key to load usage windows.")
+ }
+ }
+}
+
+@Composable
+private fun SettingsScreen(vm: AppViewModel, pickAuth: () -> Unit, askNotifications: () -> Unit) {
+ var key by remember { mutableStateOf("") }
+ var org by remember { mutableStateOf("") }
+ var showResetDialog by remember { mutableStateOf(false) }
+ val context = LocalContext.current
+ ScreenColumn {
+ Text("Settings", style = MaterialTheme.typography.headlineLarge, fontWeight = FontWeight.Black)
+ SectionTitle("Codex CLI")
+ ConfigCard(vm.codexAuth != null, vm.codexAuth?.accountId?.take(16), CodexGreen, "Import auth.json", pickAuth, vm::clearCodex)
+ SectionTitle("Claude.ai")
+ if (vm.claudeAuth != null) {
+ ConfigCard(true, vm.claudeAuth?.sessionKey?.take(16), ClaudeAmber, "Save session key", {}, vm::clearClaude)
+ } else {
+ ClaudeCredentialCard(key, org, vm.claudeError, onKey = { key = it }, onOrg = { org = it }) { vm.saveClaude(key, org) }
+ }
+ SectionTitle("Notifications")
+ SettingsCard {
+ val hasPermission = NotificationScheduler.hasNotificationPermission(context)
+ if (!hasPermission) {
+ RowItem(Icons.Rounded.Notifications, "Enable notifications", "Required for digests and quota alerts") {
+ OutlinedButton(onClick = askNotifications) { Text("Allow") }
+ }
+ HorizontalDivider()
+ }
+ SwitchRow("Daily digest", "Last-known usage at a chosen time", vm.notificationSettings.dailyEnabled) {
+ vm.updateNotificationSettings(vm.notificationSettings.copy(dailyEnabled = it))
+ }
+ if (vm.notificationSettings.dailyEnabled) {
+ TimeSetting(vm.notificationSettings) { hour, minute ->
+ vm.updateNotificationSettings(vm.notificationSettings.copy(dailyHour = hour, dailyMinute = minute))
+ }
+ }
+ HorizontalDivider()
+ SwitchRow("Low quota alert", "Warn when weekly quota runs low", vm.notificationSettings.thresholdEnabled) {
+ vm.updateNotificationSettings(vm.notificationSettings.copy(thresholdEnabled = it))
+ }
+ if (vm.notificationSettings.thresholdEnabled) {
+ ThresholdSetting(vm.notificationSettings) {
+ vm.updateNotificationSettings(vm.notificationSettings.copy(thresholdPct = it))
+ }
+ }
+ }
+ SectionTitle("App")
+ SettingsCard {
+ RowItem(Icons.Rounded.Info, "Version", "1.0.0") {}
+ HorizontalDivider()
+ RowItem(Icons.Rounded.RestartAlt, "Re-run setup wizard", "Clears credentials and onboarding", danger = true) {
+ TextButton(onClick = { showResetDialog = true }) { Text("Reset") }
+ }
+ }
+ }
+ if (showResetDialog) {
+ AlertDialog(
+ onDismissRequest = { showResetDialog = false },
+ title = { Text("Reset setup?") },
+ text = { Text("This clears stored credentials and restarts onboarding.") },
+ confirmButton = { TextButton(onClick = { showResetDialog = false; vm.resetSetup() }) { Text("Reset") } },
+ dismissButton = { TextButton(onClick = { showResetDialog = false }) { Text("Cancel") } },
+ )
+ }
+}
+
+@Composable
+private fun CodexUsageContent(usage: CodexUsage, lastFetchedAt: Long?, compact: Boolean) {
+ usage.planType?.let { AssistChip(onClick = {}, label = { Text(it.replaceFirstChar(Char::uppercase)) }) }
+ usage.primary?.let { UsageRow("${windowLabel(it.windowSeconds)} window", it, CodexGreen) }
+ usage.secondary?.let { UsageRow("${windowLabel(it.windowSeconds)} window", it, CodexGreen) }
+ CreditCard(usage)
+ if (!compact) ResetCreditsCard(usage.resetCoupons)
+ LastUpdated(lastFetchedAt)
+}
+
+@Composable
+private fun ClaudeUsageContent(usage: ClaudeUsage, lastFetchedAt: Long?) {
+ UsageRow("5-hour window", UsageWindow(usage.fiveHour.utilization, resetsAtIso = usage.fiveHour.resetsAt), ClaudeAmber)
+ UsageRow("7-day window", UsageWindow(usage.sevenDay.utilization, resetsAtIso = usage.sevenDay.resetsAt), ClaudeAmber)
+ if (usage.sevenDaySonnet != null || usage.sevenDayOpus != null) {
+ CardBlock {
+ Text("By model (7-day)", style = MaterialTheme.typography.labelLarge, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ usage.sevenDaySonnet?.let { UsageRow("Sonnet", UsageWindow(it.utilization), ClaudeAmber) }
+ usage.sevenDayOpus?.let { UsageRow("Opus", UsageWindow(it.utilization), ClaudeAmber) }
+ }
+ }
+ LastUpdated(lastFetchedAt)
+}
+
+@Composable
+private fun UsageRow(label: String, window: UsageWindow, accent: Color) {
+ val percent = window.usedPercent.roundToInt().coerceIn(0, 100)
+ Column(Modifier.padding(vertical = 10.dp)) {
+ Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.Bottom) {
+ Text(label, style = MaterialTheme.typography.labelLarge, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ Text("$percent% used", style = MaterialTheme.typography.titleSmall, color = usageColor(percent, accent), fontWeight = FontWeight.Bold)
+ }
+ Spacer(Modifier.height(8.dp))
+ LinearProgressIndicator(
+ progress = { percent / 100f },
+ modifier = Modifier.fillMaxWidth().height(8.dp),
+ color = usageColor(percent, accent),
+ trackColor = MaterialTheme.colorScheme.surfaceVariant,
+ )
+ resetText(window)?.let { Text(it, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(top = 6.dp)) }
+ }
+}
+
+@Composable
+private fun CreditCard(usage: CodexUsage) {
+ CardBlock {
+ Text("Credits", style = MaterialTheme.typography.labelLarge, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ val text = when {
+ usage.credits.unlimited -> "Unlimited credits"
+ usage.credits.hasCredits -> "\$${"%.2f".format(usage.credits.balance)} remaining"
+ else -> "No credits"
+ }
+ Text(text, style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
+ usage.resetCoupons?.let {
+ Text("${it.availableCount ?: 0} reset credits available", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ it.nextExpiringCredit?.timeUntilExpiry?.let { expiry -> Text("Next expires in $expiry", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant) }
+ }
+ }
+}
+
+@Composable
+private fun ResetCreditsCard(resetCoupons: ResetCoupons?) {
+ if (resetCoupons == null) return
+ CardBlock {
+ Text("Reset credits", style = MaterialTheme.typography.labelLarge, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ Text("${resetCoupons.availableCount ?: 0} available", style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold)
+ resetCoupons.totalEarnedCount?.let { Text("$it earned total", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant) }
+ resetCoupons.credits.filter { it.status == "available" }.forEach { credit ->
+ Text("Credit ${credit.index}: expires ${credit.timeUntilExpiry ?: credit.expiresAt ?: "unknown"}", style = MaterialTheme.typography.bodySmall)
+ }
+ if (resetCoupons.source != "live_api") Text("Source: ${resetCoupons.sourceDescription}", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ }
+}
+
+@Composable
+private fun ServiceCard(title: String, icon: ImageVector, color: Color, status: LoadStatus, error: String?, connected: Boolean, content: @Composable () -> Unit) {
+ Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), shape = RoundedCornerShape(28.dp), modifier = Modifier.fillMaxWidth()) {
+ Column(Modifier.padding(18.dp)) {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ ServiceIcon(icon, color, 40)
+ Spacer(Modifier.width(12.dp))
+ Text(title, style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold, modifier = Modifier.weight(1f))
+ StatusDot(status, connected)
+ }
+ Spacer(Modifier.height(12.dp))
+ if (status == LoadStatus.Loading && !connected) CircularProgressIndicator(color = color)
+ if (status == LoadStatus.Error && error != null) ErrorCard(error)
+ content()
+ }
+ }
+}
+
+@Composable
+private fun UsageSurface(status: LoadStatus, content: @Composable () -> Unit) {
+ Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), shape = RoundedCornerShape(28.dp), modifier = Modifier.fillMaxWidth()) {
+ Column(Modifier.padding(18.dp)) {
+ if (status == LoadStatus.Loading) {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ CircularProgressIndicator(Modifier.size(20.dp))
+ Spacer(Modifier.width(10.dp))
+ Text("Refreshing usage…", style = MaterialTheme.typography.bodyMedium)
+ }
+ Spacer(Modifier.height(12.dp))
+ }
+ content()
+ }
+ }
+}
+
+@Composable
+private fun ConfigCard(connected: Boolean, label: String?, color: Color, connectLabel: String, onConnect: () -> Unit, onClear: () -> Unit) {
+ SettingsCard {
+ if (connected) {
+ RowItem(Icons.Rounded.CheckCircle, "Connected", label ?: "Credentials saved") {
+ TextButton(onClick = onClear) { Text("Clear", color = MaterialTheme.colorScheme.error) }
+ }
+ } else {
+ RowItem(Icons.Rounded.UploadFile, connectLabel, "Credentials stay encrypted on this device") {
+ Button(onClick = onConnect, colors = ButtonDefaults.buttonColors(containerColor = color)) { Text("Connect") }
+ }
+ }
+ }
+}
+
+@Composable
+private fun ClaudeCredentialCard(key: String, org: String, error: String?, onKey: (String) -> Unit, onOrg: (String) -> Unit, onSave: () -> Unit) {
+ SettingsCard {
+ Column(Modifier.padding(16.dp)) {
+ (error ?: if (key.isBlank()) null else validateClaudeSessionKey(key))?.let { ErrorCard(it) }
+ OutlinedTextField(key, onKey, Modifier.fillMaxWidth(), label = { Text("sessionKey") }, singleLine = true, visualTransformation = PasswordVisualTransformation())
+ Spacer(Modifier.height(10.dp))
+ OutlinedTextField(org, onOrg, Modifier.fillMaxWidth(), label = { Text("lastActiveOrg (optional)") }, singleLine = true)
+ Spacer(Modifier.height(12.dp))
+ PrimaryButton("Save session key", if (isClaudeSessionKeyValid(key)) ClaudeAmber else MutedButton, onClick = onSave)
+ HelpCard("Chrome DevTools > Application > Cookies > claude.ai > sessionKey")
+ }
+ }
+}
+
+@Composable
+private fun ScreenColumn(content: @Composable ColumnScope.() -> Unit) {
+ Column(
+ modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(18.dp),
+ verticalArrangement = Arrangement.spacedBy(16.dp),
+ content = content,
+ )
+}
+
+@Composable
+private fun OnboardingShell(horizontalAlignment: Alignment.Horizontal = Alignment.Start, content: @Composable ColumnScope.() -> Unit) {
+ Column(
+ modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(28.dp),
+ horizontalAlignment = horizontalAlignment,
+ content = content,
+ )
+}
+
+@Composable
+private fun Header(title: String, subtitle: String, icon: ImageVector, color: Color, onRefresh: () -> Unit) {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ ServiceIcon(icon, color, 48)
+ Spacer(Modifier.width(14.dp))
+ Column(Modifier.weight(1f)) {
+ Text(title, style = MaterialTheme.typography.headlineSmall, fontWeight = FontWeight.Black)
+ Text(subtitle, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ }
+ IconButton(onClick = onRefresh) { Icon(Icons.Rounded.Refresh, "Refresh") }
+ }
+}
+
+@Composable
+private fun PrimaryButton(text: String, color: Color, icon: ImageVector? = null, onClick: () -> Unit) {
+ Button(onClick = onClick, colors = ButtonDefaults.buttonColors(containerColor = color), shape = RoundedCornerShape(18.dp), modifier = Modifier.fillMaxWidth().height(54.dp)) {
+ if (icon != null) { Icon(icon, null); Spacer(Modifier.width(8.dp)) }
+ Text(text, fontWeight = FontWeight.Bold)
+ }
+}
+
+@Composable
+private fun ServiceIcon(icon: ImageVector, color: Color, size: Int = 56) {
+ Surface(shape = RoundedCornerShape((size / 3).dp), color = color.copy(alpha = 0.16f), modifier = Modifier.size(size.dp)) {
+ Box(contentAlignment = Alignment.Center) { Icon(icon, null, tint = color, modifier = Modifier.size((size / 2).dp)) }
+ }
+}
+
+@Composable
+private fun AppMark(size: Int) {
+ Row(horizontalArrangement = Arrangement.Center) {
+ ServiceIcon(Icons.Rounded.AutoAwesome, CodexGreen, size)
+ Spacer(Modifier.width(8.dp))
+ ServiceIcon(Icons.Rounded.Psychology, ClaudeAmber, size)
+ }
+}
+
+@Composable
+private fun StepHeader(current: Int, total: Int) {
+ Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically) {
+ (1..total).forEach { step ->
+ Surface(
+ shape = CircleShape,
+ color = if (step <= current) CodexGreen else MaterialTheme.colorScheme.surfaceVariant,
+ modifier = Modifier.size(28.dp),
+ ) {
+ Box(contentAlignment = Alignment.Center) {
+ Text(
+ step.toString(),
+ style = MaterialTheme.typography.labelMedium,
+ color = if (step <= current) Color.White else MaterialTheme.colorScheme.onSurfaceVariant,
+ fontWeight = FontWeight.Bold,
+ )
+ }
+ }
+ if (step < total) {
+ Spacer(Modifier.width(8.dp))
+ HorizontalDivider(Modifier.width(42.dp), color = if (step < current) CodexGreen else MaterialTheme.colorScheme.surfaceVariant)
+ Spacer(Modifier.width(8.dp))
+ }
+ }
+ }
+}
+
+@Composable
+private fun FeaturePill(icon: ImageVector, title: String, subtitle: String, color: Color) {
+ SettingsCard {
+ Row(Modifier.padding(16.dp), verticalAlignment = Alignment.CenterVertically) {
+ ServiceIcon(icon, color, 42)
+ Spacer(Modifier.width(12.dp))
+ Column {
+ Text(title, fontWeight = FontWeight.Bold)
+ Text(subtitle, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ }
+ }
+ }
+}
+
+@Composable
+private fun ConnectedCard(title: String, label: String?, color: Color) {
+ SettingsCard {
+ Row(Modifier.padding(16.dp), verticalAlignment = Alignment.CenterVertically) {
+ Icon(Icons.Rounded.CheckCircle, null, tint = color)
+ Spacer(Modifier.width(12.dp))
+ Column {
+ Text(title, fontWeight = FontWeight.Bold)
+ label?.let { Text("$it…", fontFamily = FontFamily.Monospace, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant) }
+ }
+ }
+ }
+}
+
+@Composable
+private fun SummaryRow(title: String, subtitle: String, ok: Boolean, color: Color) {
+ SettingsCard {
+ Row(Modifier.padding(16.dp), verticalAlignment = Alignment.CenterVertically) {
+ Surface(shape = CircleShape, color = if (ok) color else MaterialTheme.colorScheme.surfaceVariant, modifier = Modifier.size(10.dp)) {}
+ Spacer(Modifier.width(12.dp))
+ Column { Text(title, fontWeight = FontWeight.Bold); Text(subtitle, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant) }
+ }
+ }
+ Spacer(Modifier.height(10.dp))
+}
+
+@Composable
+private fun ErrorCard(text: String) {
+ Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.errorContainer), shape = RoundedCornerShape(18.dp), modifier = Modifier.fillMaxWidth()) {
+ Text(text, color = MaterialTheme.colorScheme.onErrorContainer, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.padding(14.dp))
+ }
+}
+
+@Composable
+private fun HelpCard(text: String) {
+ Text(text, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(top = 10.dp))
+}
+
+@Composable
+private fun CardBlock(content: @Composable ColumnScope.() -> Unit) {
+ Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.45f)), shape = RoundedCornerShape(20.dp), modifier = Modifier.fillMaxWidth().padding(top = 8.dp)) {
+ Column(Modifier.padding(14.dp), content = content)
+ }
+}
+
+@Composable
+private fun EmptyState(text: String, onAction: (() -> Unit)? = null) {
+ Column(Modifier.fillMaxWidth().padding(vertical = 18.dp), horizontalAlignment = Alignment.CenterHorizontally) {
+ Text(text, style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant)
+ if (onAction != null) TextButton(onClick = onAction) { Text("Open Settings") }
+ }
+}
+
+@Composable
+private fun LastUpdated(timestamp: Long?) {
+ Text("Updated ${timestamp?.let(::formatTimestamp) ?: "never"}", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(top = 8.dp))
+}
+
+@Composable
+private fun SettingsCard(content: @Composable ColumnScope.() -> Unit) {
+ Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface), shape = RoundedCornerShape(24.dp), modifier = Modifier.fillMaxWidth()) {
+ Column(content = content)
+ }
+}
+
+@Composable
+private fun SectionTitle(title: String) {
+ Text(title.uppercase(), style = MaterialTheme.typography.labelLarge, color = MaterialTheme.colorScheme.onSurfaceVariant, modifier = Modifier.padding(top = 8.dp))
+}
+
+@Composable
+private fun RowItem(icon: ImageVector, title: String, subtitle: String, danger: Boolean = false, action: @Composable () -> Unit) {
+ Row(Modifier.fillMaxWidth().padding(16.dp), verticalAlignment = Alignment.CenterVertically) {
+ Icon(icon, null, tint = if (danger) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurfaceVariant)
+ Spacer(Modifier.width(14.dp))
+ Column(Modifier.weight(1f)) {
+ Text(title, fontWeight = FontWeight.SemiBold, color = if (danger) MaterialTheme.colorScheme.error else MaterialTheme.colorScheme.onSurface)
+ Text(subtitle, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1, overflow = TextOverflow.Ellipsis)
+ }
+ action()
+ }
+}
+
+@Composable
+private fun SwitchRow(title: String, subtitle: String, checked: Boolean, onChecked: (Boolean) -> Unit) {
+ RowItem(Icons.Rounded.Alarm, title, subtitle) { Switch(checked = checked, onCheckedChange = onChecked) }
+}
+
+@Composable
+private fun TimeSetting(settings: NotificationSettings, onChange: (Int, Int) -> Unit) {
+ var value by remember(settings.dailyHour, settings.dailyMinute) { mutableStateOf("%02d:%02d".format(settings.dailyHour, settings.dailyMinute)) }
+ OutlinedTextField(
+ value = value,
+ onValueChange = {
+ value = it.take(5)
+ parseTime(value)?.let { parsed -> onChange(parsed.first, parsed.second) }
+ },
+ label = { Text("Digest time") },
+ keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
+ singleLine = true,
+ modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
+ supportingText = { Text("Use 24-hour HH:MM format.") },
+ )
+}
+
+@Composable
+private fun ThresholdSetting(settings: NotificationSettings, onChange: (Int) -> Unit) {
+ var value by remember(settings.thresholdPct) { mutableStateOf(settings.thresholdPct.toString()) }
+ OutlinedTextField(
+ value = value,
+ onValueChange = { next -> value = next.filter(Char::isDigit).take(2); value.toIntOrNull()?.takeIf { it in 1..99 }?.let(onChange) },
+ label = { Text("Alert below % remaining") },
+ keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
+ singleLine = true,
+ modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp, vertical = 8.dp),
+ )
+}
+
+@Composable
+private fun StatusDot(status: LoadStatus, connected: Boolean) {
+ val color = when {
+ status == LoadStatus.Error -> MaterialTheme.colorScheme.error
+ connected -> CodexGreen
+ else -> MaterialTheme.colorScheme.outline
+ }
+ Surface(shape = CircleShape, color = color, modifier = Modifier.size(10.dp)) {}
+}
+
+private fun connectedSummary(vm: AppViewModel): String = when (listOf(vm.codexAuth, vm.claudeAuth).count { it != null }) {
+ 0 -> "No services connected"
+ 1 -> "1 of 2 services connected"
+ else -> "2 services connected"
+}
+
+private val MainTab.icon: ImageVector get() = when (this) {
+ MainTab.Dashboard -> Icons.Rounded.Home
+ MainTab.Codex -> Icons.Rounded.AutoAwesome
+ MainTab.Claude -> Icons.Rounded.Psychology
+ MainTab.Settings -> Icons.Rounded.Settings
+}
+
+private fun usageColor(percent: Int, fallback: Color): Color = when {
+ percent >= 85 -> DangerRed
+ percent >= 60 -> WarningAmber
+ else -> fallback
+}
+
+private fun resetText(window: UsageWindow): String? = when {
+ window.resetsAt != null -> "Resets ${formatTimestamp(window.resetsAt * 1000L)}"
+ window.resetsAtIso != null -> runCatching { "Resets ${formatTimestamp(Instant.parse(window.resetsAtIso).toEpochMilli())}" }.getOrNull()
+ else -> null
+}
+
+private fun windowLabel(seconds: Long?): String = when {
+ seconds == null || seconds <= 0L -> "Usage"
+ seconds < 3_600L -> "${seconds / 60L}m"
+ seconds < 86_400L -> "${seconds / 3_600L}h"
+ else -> "${seconds / 86_400L}d"
+}
+
+private fun formatTimestamp(value: Long): String = DateTimeFormatter.ofPattern("MMM d, HH:mm")
+ .withZone(ZoneId.systemDefault())
+ .format(Instant.ofEpochMilli(value))
+
+private fun parseTime(value: String): Pair? {
+ val parts = value.split(":")
+ if (parts.size != 2) return null
+ val hour = parts[0].toIntOrNull() ?: return null
+ val minute = parts[1].toIntOrNull() ?: return null
+ return if (hour in 0..23 && minute in 0..59) hour to minute else null
+}
+
+private val CodexGreen = Color(0xFF10A37F)
+private val ClaudeAmber = Color(0xFFD97706)
+private val WarningAmber = Color(0xFFF59E0B)
+private val DangerRed = Color(0xFFEF4444)
+private val MutedButton = Color(0xFF52525B)
+
+@Composable
+private fun CodexMobileTheme(content: @Composable () -> Unit) {
+ val dark = darkColorScheme(
+ primary = CodexGreen,
+ secondary = ClaudeAmber,
+ background = Color(0xFF090D11),
+ surface = Color(0xFF10161B),
+ surfaceVariant = Color(0xFF1A2229),
+ onPrimary = Color.White,
+ onSecondary = Color.White,
+ onBackground = Color(0xFFE7ECEF),
+ onSurface = Color(0xFFE7ECEF),
+ onSurfaceVariant = Color(0xFF9CA3AF),
+ )
+ val light = lightColorScheme(
+ primary = CodexGreen,
+ secondary = ClaudeAmber,
+ background = Color(0xFFF6F8F7),
+ surface = Color.White,
+ surfaceVariant = Color(0xFFECEFED),
+ onPrimary = Color.White,
+ onSecondary = Color.White,
+ )
+ MaterialTheme(colorScheme = if (isSystemInDarkTheme()) dark else light, content = {
+ Surface(Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background, content = content)
+ })
+}
diff --git a/app/src/main/java/dev/reversed/codexbarmobile/Models.kt b/app/src/main/java/dev/reversed/codexbarmobile/Models.kt
new file mode 100644
index 0000000..fa5425d
--- /dev/null
+++ b/app/src/main/java/dev/reversed/codexbarmobile/Models.kt
@@ -0,0 +1,104 @@
+package dev.reversed.codexbarmobile
+
+data class CodexAuth(
+ val accessToken: String,
+ val accountId: String? = null,
+)
+
+data class UsageWindow(
+ val usedPercent: Double,
+ val resetsAt: Long? = null,
+ val resetsAtIso: String? = null,
+ val windowSeconds: Long? = null,
+)
+
+data class CodexCredits(
+ val hasCredits: Boolean,
+ val unlimited: Boolean,
+ val balance: Double,
+)
+
+data class ResetCredit(
+ val index: Int,
+ val status: String?,
+ val grantedAt: String?,
+ val expiresAt: String?,
+ val timeUntilExpiry: String?,
+)
+
+data class ResetCoupons(
+ val source: String,
+ val sourceDescription: String,
+ val availableCount: Int?,
+ val totalEarnedCount: Int?,
+ val credits: List,
+ val nextExpiringCredit: ResetCredit?,
+ val error: String? = null,
+)
+
+data class CodexUsage(
+ val planType: String?,
+ val rateLimitReachedType: String?,
+ val primary: UsageWindow?,
+ val secondary: UsageWindow?,
+ val credits: CodexCredits,
+ val resetCoupons: ResetCoupons?,
+)
+
+data class ClaudeAuth(
+ val sessionKey: String,
+ val lastActiveOrg: String? = null,
+)
+
+data class ClaudeOrg(
+ val uuid: String,
+ val name: String,
+)
+
+data class ClaudeWindowUsage(
+ val utilization: Double,
+ val resetsAt: String? = null,
+)
+
+data class ClaudeUsage(
+ val fiveHour: ClaudeWindowUsage,
+ val sevenDay: ClaudeWindowUsage,
+ val sevenDaySonnet: ClaudeWindowUsage? = null,
+ val sevenDayOpus: ClaudeWindowUsage? = null,
+)
+
+data class UsageCache(
+ val data: T,
+ val lastFetchedAt: Long,
+)
+
+data class NotificationSettings(
+ val dailyEnabled: Boolean = false,
+ val dailyHour: Int = 9,
+ val dailyMinute: Int = 0,
+ val thresholdEnabled: Boolean = false,
+ val thresholdPct: Int = 20,
+)
+
+enum class LoadStatus {
+ Idle,
+ Loading,
+ Success,
+ Error,
+}
+
+enum class AppScreen {
+ Splash,
+ Welcome,
+ OnboardingCodex,
+ OnboardingClaude,
+ OnboardingDone,
+ Main,
+}
+
+enum class MainTab(val label: String) {
+ Dashboard("Home"),
+ Codex("Codex"),
+ Claude("Claude"),
+ Settings("Settings"),
+}
diff --git a/app/src/main/java/dev/reversed/codexbarmobile/Notifications.kt b/app/src/main/java/dev/reversed/codexbarmobile/Notifications.kt
new file mode 100644
index 0000000..d566693
--- /dev/null
+++ b/app/src/main/java/dev/reversed/codexbarmobile/Notifications.kt
@@ -0,0 +1,168 @@
+package dev.reversed.codexbarmobile
+
+import android.Manifest
+import android.app.AlarmManager
+import android.app.Application
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build
+import androidx.core.app.NotificationCompat
+import androidx.core.app.NotificationManagerCompat
+import androidx.core.content.ContextCompat
+import java.time.LocalDate
+import java.util.Calendar
+import kotlin.math.roundToInt
+
+class CodexMobileApp : Application() {
+ override fun onCreate() {
+ super.onCreate()
+ NotificationScheduler.ensureChannel(this)
+ }
+}
+
+object NotificationScheduler {
+ private const val CHANNEL_ID = "usage-alerts"
+ private const val CHANNEL_NAME = "Usage alerts"
+ private const val DAILY_REQUEST_CODE = 1001
+ private const val EXTRA_BODY = "body"
+
+ fun ensureChannel(context: Context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val manager = context.getSystemService(NotificationManager::class.java)
+ val channel = NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT).apply {
+ description = "CodexMobile usage digests and quota warnings"
+ }
+ manager.createNotificationChannel(channel)
+ }
+ }
+
+ fun hasNotificationPermission(context: Context): Boolean =
+ Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU ||
+ ContextCompat.checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED
+
+ fun scheduleDailyDigest(context: Context, hour: Int, minute: Int, body: String) {
+ if (!hasNotificationPermission(context)) return
+ ensureChannel(context)
+ val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
+ val intent = Intent(context, DailyDigestReceiver::class.java).putExtra(EXTRA_BODY, body)
+ val pending = PendingIntent.getBroadcast(
+ context,
+ DAILY_REQUEST_CODE,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
+ )
+ val firstRun = Calendar.getInstance().apply {
+ set(Calendar.HOUR_OF_DAY, hour)
+ set(Calendar.MINUTE, minute)
+ set(Calendar.SECOND, 0)
+ set(Calendar.MILLISECOND, 0)
+ if (timeInMillis <= System.currentTimeMillis()) add(Calendar.DAY_OF_YEAR, 1)
+ }
+ alarmManager.setInexactRepeating(
+ AlarmManager.RTC_WAKEUP,
+ firstRun.timeInMillis,
+ AlarmManager.INTERVAL_DAY,
+ pending,
+ )
+ }
+
+ fun cancelDailyDigest(context: Context) {
+ val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
+ val pending = PendingIntent.getBroadcast(
+ context,
+ DAILY_REQUEST_CODE,
+ Intent(context, DailyDigestReceiver::class.java),
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
+ )
+ alarmManager.cancel(pending)
+ pending.cancel()
+ }
+
+ fun showQuotaAlert(context: Context, body: String) {
+ if (!hasNotificationPermission(context)) return
+ showNotification(
+ context = context,
+ id = 2001,
+ title = "Low quota warning",
+ body = body,
+ )
+ }
+
+ fun showDailyDigest(context: Context, body: String) {
+ showNotification(
+ context = context,
+ id = 1002,
+ title = "Usage digest",
+ body = body.ifBlank { "Open CodexMobile to check your usage limits." },
+ )
+ }
+
+ private fun showNotification(context: Context, id: Int, title: String, body: String) {
+ if (!hasNotificationPermission(context)) return
+ ensureChannel(context)
+ val openIntent = PendingIntent.getActivity(
+ context,
+ id,
+ Intent(context, MainActivity::class.java),
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
+ )
+ val notification = NotificationCompat.Builder(context, CHANNEL_ID)
+ .setSmallIcon(R.drawable.ic_notification)
+ .setContentTitle(title)
+ .setContentText(body)
+ .setStyle(NotificationCompat.BigTextStyle().bigText(body))
+ .setContentIntent(openIntent)
+ .setAutoCancel(true)
+ .setColor(0xFF10A37F.toInt())
+ .build()
+ NotificationManagerCompat.from(context).notify(id, notification)
+ }
+}
+
+class DailyDigestReceiver : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ NotificationScheduler.showDailyDigest(context, intent.getStringExtra("body").orEmpty())
+ }
+}
+
+fun maybeFireThresholdAlert(
+ context: Context,
+ storage: AppStorage,
+ settings: NotificationSettings,
+ claudeUsage: ClaudeUsage?,
+ codexUsage: CodexUsage?,
+) {
+ if (!settings.thresholdEnabled) return
+ val today = LocalDate.now().toString()
+ if (storage.loadThresholdLastFired() == today) return
+
+ val alerts = buildList {
+ claudeUsage?.let {
+ val remaining = 100.0 - it.sevenDay.utilization
+ if (remaining <= settings.thresholdPct) add("Claude 7-day: ${remaining.roundPercent()}% remaining")
+ }
+ codexUsage?.let {
+ val remaining = 100.0 - (it.secondary?.usedPercent ?: 0.0)
+ if (remaining <= settings.thresholdPct) add("Codex weekly: ${remaining.roundPercent()}% remaining")
+ }
+ }
+ if (alerts.isNotEmpty()) {
+ NotificationScheduler.showQuotaAlert(context, alerts.joinToString("\n"))
+ storage.saveThresholdLastFired(today)
+ }
+}
+
+fun buildDailyDigestBody(claudeUsage: ClaudeUsage?, codexUsage: CodexUsage?): String {
+ val parts = buildList {
+ claudeUsage?.let { add("Claude 7d: ${it.sevenDay.utilization.roundPercent()}% used") }
+ codexUsage?.secondary?.let { add("Codex weekly: ${it.usedPercent.roundPercent()}% used") }
+ }
+ return if (parts.isEmpty()) "Open CodexMobile to check your usage limits." else parts.joinToString(" · ")
+}
+
+fun Double.roundPercent(): Int = roundToInt().coerceIn(0, 100)
diff --git a/app/src/main/java/dev/reversed/codexbarmobile/UsageApi.kt b/app/src/main/java/dev/reversed/codexbarmobile/UsageApi.kt
new file mode 100644
index 0000000..3251e94
--- /dev/null
+++ b/app/src/main/java/dev/reversed/codexbarmobile/UsageApi.kt
@@ -0,0 +1,196 @@
+package dev.reversed.codexbarmobile
+
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import org.json.JSONArray
+import org.json.JSONObject
+import java.time.Instant
+import java.util.concurrent.TimeUnit
+
+class UsageApi {
+ private val client = OkHttpClient.Builder()
+ .connectTimeout(25, TimeUnit.SECONDS)
+ .readTimeout(25, TimeUnit.SECONDS)
+ .build()
+
+ suspend fun fetchCodexUsage(auth: CodexAuth): CodexUsage = withContext(Dispatchers.IO) {
+ val request = Request.Builder()
+ .url(CODEX_USAGE_URL)
+ .applyCodexHeaders(auth)
+ .get()
+ .build()
+
+ val payload = client.newCall(request).execute().use { response ->
+ if (response.code == 401 || response.code == 403) throw IllegalStateException("TOKEN_EXPIRED")
+ if (!response.isSuccessful) throw IllegalStateException("HTTP_ERROR_${response.code}")
+ JSONObject(response.body?.string().orEmpty())
+ }
+
+ val resetCoupons = fetchResetCoupons(auth, payload)
+ CodexUsage(
+ planType = payload.optStringOrNull("plan_type"),
+ rateLimitReachedType = payload.optStringOrNull("rate_limit_reached_type"),
+ primary = payload.optJSONObject("rate_limit")?.optJSONObject("primary_window")?.toCodexWindow(),
+ secondary = payload.optJSONObject("rate_limit")?.optJSONObject("secondary_window")?.toCodexWindow(),
+ credits = payload.optJSONObject("credits").let { credits ->
+ CodexCredits(
+ hasCredits = credits?.optBoolean("has_credits") ?: false,
+ unlimited = credits?.optBoolean("unlimited") ?: false,
+ balance = credits?.optDouble("balance", 0.0) ?: 0.0,
+ )
+ },
+ resetCoupons = resetCoupons,
+ )
+ }
+
+ private fun fetchResetCoupons(auth: CodexAuth, usagePayload: JSONObject): ResetCoupons {
+ val request = Request.Builder()
+ .url(CODEX_RESET_CREDITS_URL)
+ .applyCodexHeaders(auth)
+ .header("OpenAI-Beta", "codex-1")
+ .header("originator", "Codex Desktop")
+ .get()
+ .build()
+
+ return runCatching {
+ client.newCall(request).execute().use { response ->
+ if (!response.isSuccessful) throw IllegalStateException("HTTP_ERROR_${response.code}")
+ val payload = JSONObject(response.body?.string().orEmpty())
+ val rawCredits = payload.optJSONArray("credits") ?: JSONArray()
+ val credits = (0 until rawCredits.length())
+ .mapNotNull { index -> rawCredits.optJSONObject(index)?.toResetCredit(index + 1) }
+ .sortedBy { credit -> credit.expiresAt?.let { runCatching { Instant.parse(it) }.getOrNull() } ?: Instant.MAX }
+ val available = credits.filter { it.status == "available" }
+ ResetCoupons(
+ source = "live_api",
+ sourceDescription = "Live Codex reset-credit endpoint",
+ availableCount = payload.optIntOrNull("available_count")
+ ?: usagePayload.optJSONObject("rate_limit_reset_credits")?.optIntOrNull("available_count"),
+ totalEarnedCount = payload.optIntOrNull("total_earned_count"),
+ credits = credits,
+ nextExpiringCredit = available.firstOrNull() ?: credits.firstOrNull(),
+ )
+ }
+ }.getOrElse { error ->
+ ResetCoupons(
+ source = "unavailable",
+ sourceDescription = "Reset-credit endpoint unavailable",
+ availableCount = usagePayload.optJSONObject("rate_limit_reset_credits")?.optIntOrNull("available_count"),
+ totalEarnedCount = null,
+ credits = emptyList(),
+ nextExpiringCredit = null,
+ error = error.message ?: "UNKNOWN_ERROR",
+ )
+ }
+ }
+
+ suspend fun fetchClaudeUsage(auth: ClaudeAuth): ClaudeUsage = withContext(Dispatchers.IO) {
+ val orgId = auth.lastActiveOrg?.takeIf { it.isNotBlank() } ?: fetchClaudeOrgs(auth).firstOrNull()?.uuid
+ ?: throw IllegalStateException("NO_ORGS_FOUND")
+
+ val request = Request.Builder()
+ .url("$CLAUDE_BASE_URL/organizations/$orgId/usage")
+ .applyClaudeHeaders(auth)
+ .get()
+ .build()
+
+ client.newCall(request).execute().use { response ->
+ if (response.code == 401 || response.code == 403) throw IllegalStateException("TOKEN_EXPIRED")
+ if (!response.isSuccessful) throw IllegalStateException("HTTP_ERROR_${response.code}")
+ JSONObject(response.body?.string().orEmpty()).toClaudeUsageFromApi()
+ }
+ }
+
+ private fun fetchClaudeOrgs(auth: ClaudeAuth): List {
+ val request = Request.Builder()
+ .url("$CLAUDE_BASE_URL/organizations")
+ .applyClaudeHeaders(auth)
+ .get()
+ .build()
+
+ return client.newCall(request).execute().use { response ->
+ if (response.code == 401 || response.code == 403) throw IllegalStateException("TOKEN_EXPIRED")
+ if (!response.isSuccessful) throw IllegalStateException("HTTP_ERROR_${response.code}")
+ val arr = JSONArray(response.body?.string().orEmpty())
+ (0 until arr.length()).mapNotNull { index ->
+ arr.optJSONObject(index)?.let { ClaudeOrg(it.getString("uuid"), it.optString("name")) }
+ }
+ }
+ }
+
+ private fun Request.Builder.applyCodexHeaders(auth: CodexAuth): Request.Builder = apply {
+ header("Authorization", "Bearer ${auth.accessToken}")
+ header("Content-Type", "application/json")
+ auth.accountId?.takeIf { it.isNotBlank() }?.let { header("ChatGPT-Account-Id", it) }
+ }
+
+ private fun Request.Builder.applyClaudeHeaders(auth: ClaudeAuth): Request.Builder = apply {
+ val cookies = buildList {
+ add("sessionKey=${auth.sessionKey}")
+ auth.lastActiveOrg?.takeIf { it.isNotBlank() }?.let { add("lastActiveOrg=$it") }
+ }
+ header("Cookie", cookies.joinToString("; "))
+ header("Accept", "application/json, text/plain, */*")
+ header("Accept-Language", "en-US,en;q=0.9")
+ header("User-Agent", BROWSER_USER_AGENT)
+ header("Referer", "https://claude.ai/")
+ header("Origin", "https://claude.ai")
+ header("anthropic-client-platform", "web_claude_to_cc_migration")
+ }
+
+ companion object {
+ private const val CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage"
+ private const val CODEX_RESET_CREDITS_URL = "https://chatgpt.com/backend-api/wham/rate-limit-reset-credits"
+ private const val CLAUDE_BASE_URL = "https://claude.ai/api"
+ private const val BROWSER_USER_AGENT = "Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36"
+ }
+}
+
+private fun JSONObject.toCodexWindow(): UsageWindow {
+ val seconds = optLong("limit_window_seconds", 0L)
+ return UsageWindow(
+ usedPercent = optDouble("used_percent", 0.0),
+ resetsAt = optLong("reset_at", 0L).takeIf { it > 0L },
+ windowSeconds = seconds.takeIf { it > 0L },
+ )
+}
+
+private fun JSONObject.toResetCredit(index: Int): ResetCredit = ResetCredit(
+ index = index,
+ status = optStringOrNull("status"),
+ grantedAt = optStringOrNull("granted_at"),
+ expiresAt = optStringOrNull("expires_at"),
+ timeUntilExpiry = formatDurationUntil(optStringOrNull("expires_at")),
+)
+
+private fun JSONObject.toClaudeUsageFromApi(): ClaudeUsage = ClaudeUsage(
+ fiveHour = getJSONObject("five_hour").toClaudeWindowFromApi(),
+ sevenDay = getJSONObject("seven_day").toClaudeWindowFromApi(),
+ sevenDaySonnet = optJSONObject("seven_day_sonnet")?.toClaudeWindowFromApi(),
+ sevenDayOpus = optJSONObject("seven_day_opus")?.toClaudeWindowFromApi(),
+)
+
+private fun JSONObject.toClaudeWindowFromApi(): ClaudeWindowUsage = ClaudeWindowUsage(
+ utilization = optDouble("utilization", 0.0),
+ resetsAt = optStringOrNull("resets_at"),
+)
+
+fun formatDurationUntil(isoString: String?): String? {
+ if (isoString.isNullOrBlank()) return null
+ val target = runCatching { Instant.parse(isoString).toEpochMilli() }.getOrNull() ?: return null
+ var remaining = ((target - System.currentTimeMillis()).coerceAtLeast(0L) / 1000L)
+ val days = remaining / 86_400L
+ remaining -= days * 86_400L
+ val hours = remaining / 3_600L
+ remaining -= hours * 3_600L
+ val minutes = remaining / 60L
+ remaining -= minutes * 60L
+ return buildList {
+ if (days > 0) add("${days}d")
+ if (hours > 0) add("${hours}h")
+ if (minutes > 0) add("${minutes}m")
+ if (remaining > 0 || isEmpty()) add("${remaining}s")
+ }.joinToString(" ")
+}
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 0000000..8e61c97
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_notification.xml b/app/src/main/res/drawable/ic_notification.xml
new file mode 100644
index 0000000..2f64864
--- /dev/null
+++ b/app/src/main/res/drawable/ic_notification.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..a8a8fa5
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..a8a8fa5
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..e7d5998
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #10A37F
+ #071311
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..9444666
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+
+ CodexMobile
+
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..1517501
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,10 @@
+
+
+
+
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..aebb820
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/assets/android-icon-background.png b/assets/android-icon-background.png
deleted file mode 100644
index 8f0d024..0000000
Binary files a/assets/android-icon-background.png and /dev/null differ
diff --git a/assets/android-icon-foreground.png b/assets/android-icon-foreground.png
deleted file mode 100644
index 4aa3c05..0000000
Binary files a/assets/android-icon-foreground.png and /dev/null differ
diff --git a/assets/android-icon-monochrome.png b/assets/android-icon-monochrome.png
deleted file mode 100644
index ef4a0dd..0000000
Binary files a/assets/android-icon-monochrome.png and /dev/null differ
diff --git a/assets/favicon.png b/assets/favicon.png
deleted file mode 100644
index 7bb5cd6..0000000
Binary files a/assets/favicon.png and /dev/null differ
diff --git a/assets/icon.png b/assets/icon.png
deleted file mode 100644
index 0fac318..0000000
Binary files a/assets/icon.png and /dev/null differ
diff --git a/assets/notification-icon.png b/assets/notification-icon.png
deleted file mode 100644
index a4a6585..0000000
Binary files a/assets/notification-icon.png and /dev/null differ
diff --git a/assets/splash-icon.png b/assets/splash-icon.png
deleted file mode 100644
index 0fac318..0000000
Binary files a/assets/splash-icon.png and /dev/null differ
diff --git a/babel.config.js b/babel.config.js
deleted file mode 100644
index 1d96698..0000000
--- a/babel.config.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = function (api) {
- api.cache(true);
- return {
- presets: [
- ["babel-preset-expo", { jsxImportSource: "nativewind" }],
- "nativewind/babel",
- ],
- plugins: ["react-native-reanimated/plugin"],
- };
-};
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..6f48f61
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,4 @@
+plugins {
+ id 'com.android.application' version '8.5.2' apply false
+ id 'org.jetbrains.kotlin.android' version '1.9.24' apply false
+}
diff --git a/components/ErrorMessage.tsx b/components/ErrorMessage.tsx
deleted file mode 100644
index 14e2639..0000000
--- a/components/ErrorMessage.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import { View, Text } from "react-native";
-
-const ERROR_MESSAGES: Record = {
- TOKEN_EXPIRED: "Your session token has expired. Please reconfigure.",
- MISSING_ACCESS_TOKEN: "auth.json is missing the accessToken field.",
- INVALID_JSON: "The selected file is not valid JSON.",
- DOCUMENT_NOT_READABLE:
- "The selected file could not be read. Try copying auth.json into Files or Downloads and import it again.",
- NO_ORGS_FOUND: "No Claude organizations found for this session key.",
- INVALID_CODEX_RESPONSE:
- "Codex returned an unexpected response. The app was kept safe from invalid data.",
- INVALID_CLAUDE_RESPONSE:
- "Claude returned an unexpected usage response. The app was kept safe from invalid data.",
- INVALID_CLAUDE_ORGS_RESPONSE:
- "Claude returned an unexpected organizations response.",
- UNKNOWN_ERROR: "An unknown error occurred. Try refreshing.",
-};
-
-function humanize(code: string): string {
- if (code.startsWith("HTTP_ERROR_")) {
- const status = code.replace("HTTP_ERROR_", "");
- if (status === "429") return "Rate limited by the server. Try again shortly.";
- if (status === "500" || status === "502" || status === "503")
- return `Server error (${status}). The service may be down.`;
- return `Unexpected server response (HTTP ${status}).`;
- }
- if (
- code === "Network request failed" ||
- code.includes("fetch") ||
- code.includes("network")
- ) {
- return "Network error. Check your internet connection and try again.";
- }
- return ERROR_MESSAGES[code] ?? `Unexpected error: ${code}`;
-}
-
-interface ErrorMessageProps {
- message: string | null;
-}
-
-export function ErrorMessage({ message }: ErrorMessageProps) {
- if (!message) return null;
-
- return (
-
- {humanize(message)}
-
- );
-}
diff --git a/components/LastUpdated.tsx b/components/LastUpdated.tsx
deleted file mode 100644
index 2b3c553..0000000
--- a/components/LastUpdated.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { useEffect, useState } from "react";
-import { Text } from "react-native";
-import { COUNTDOWN_INTERVAL_MS } from "@/lib/constants";
-import { formatLastUpdated } from "@/lib/timeUtils";
-
-export function LastUpdated({ timestamp }: { timestamp: number | null }) {
- const [now, setNow] = useState(Date.now);
-
- useEffect(() => {
- const interval = setInterval(() => setNow(Date.now()), COUNTDOWN_INTERVAL_MS);
- return () => clearInterval(interval);
- }, []);
-
- if (!timestamp) return null;
-
- return (
-
- {formatLastUpdated(timestamp, now)}
-
- );
-}
diff --git a/components/ProgressBar.tsx b/components/ProgressBar.tsx
deleted file mode 100644
index ea5e709..0000000
--- a/components/ProgressBar.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { View } from "react-native";
-import { PROGRESS_THRESHOLDS } from "@/lib/constants";
-
-interface ProgressBarProps {
- percent: number;
-}
-
-function getBarColor(percent: number): string {
- if (percent >= PROGRESS_THRESHOLDS.danger) return "bg-red-500";
- if (percent >= PROGRESS_THRESHOLDS.warning) return "bg-yellow-400";
- return "bg-green-500";
-}
-
-export function ProgressBar({ percent }: ProgressBarProps) {
- const clamped = Math.max(0, Math.min(100, percent));
- return (
-
-
-
- );
-}
diff --git a/components/ResetCountdown.tsx b/components/ResetCountdown.tsx
deleted file mode 100644
index 1c2f04f..0000000
--- a/components/ResetCountdown.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { useEffect, useRef, useState } from "react";
-import { Text } from "react-native";
-import { COUNTDOWN_INTERVAL_MS } from "@/lib/constants";
-import { formatResetCountdown, formatResetCountdownISO } from "@/lib/timeUtils";
-
-interface ResetCountdownProps {
- resetAtSeconds?: number;
- resetAtISO?: string;
-}
-
-export function ResetCountdown({ resetAtSeconds, resetAtISO }: ResetCountdownProps) {
- const latest = useRef({ resetAtSeconds, resetAtISO });
- latest.current = { resetAtSeconds, resetAtISO };
-
- const getLabel = () => {
- if (latest.current.resetAtSeconds !== undefined) {
- return formatResetCountdown(latest.current.resetAtSeconds);
- }
- if (latest.current.resetAtISO) return formatResetCountdownISO(latest.current.resetAtISO);
- return "";
- };
-
- const [label, setLabel] = useState(getLabel);
-
- useEffect(() => {
- const update = () => setLabel(getLabel());
- update();
- const interval = setInterval(update, COUNTDOWN_INTERVAL_MS);
- return () => clearInterval(interval);
- }, []);
-
- useEffect(() => {
- setLabel(getLabel());
- }, [resetAtSeconds, resetAtISO]);
-
- if (!label) return null;
-
- return (
- {label}
- );
-}
diff --git a/components/ScreenErrorBoundary.tsx b/components/ScreenErrorBoundary.tsx
deleted file mode 100644
index d6be1c7..0000000
--- a/components/ScreenErrorBoundary.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from "react";
-import { Text, TouchableOpacity, View } from "react-native";
-import { COLORS } from "@/lib/constants";
-
-interface Props {
- children: React.ReactNode;
- screenName: string;
-}
-
-interface State {
- error: Error | null;
-}
-
-export class ScreenErrorBoundary extends React.Component {
- state: State = { error: null };
-
- static getDerivedStateFromError(error: Error): State {
- return { error };
- }
-
- render() {
- if (!this.state.error) return this.props.children;
-
- return (
-
-
- {this.props.screenName} hit a snag
-
-
- This screen could not be rendered. The rest of Codexbar is still available.
-
- this.setState({ error: null })}
- className="mt-5 rounded-xl px-4 py-3"
- style={{ backgroundColor: COLORS.codex }}
- >
- Try again
-
-
- );
- }
-}
diff --git a/components/SectionCard.tsx b/components/SectionCard.tsx
deleted file mode 100644
index 8730674..0000000
--- a/components/SectionCard.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import { View, Text } from "react-native";
-
-interface SectionCardProps {
- title: string;
- children: React.ReactNode;
- accentClass?: string;
-}
-
-export function SectionCard({ title, children, accentClass }: SectionCardProps) {
- return (
-
-
- {title}
-
- {children}
-
- );
-}
diff --git a/components/ServiceStatusCard.tsx b/components/ServiceStatusCard.tsx
deleted file mode 100644
index 323d4b9..0000000
--- a/components/ServiceStatusCard.tsx
+++ /dev/null
@@ -1,124 +0,0 @@
-import { View, Text, TouchableOpacity, ActivityIndicator } from "react-native";
-import { MaterialIcons } from "@expo/vector-icons";
-import { ProgressBar } from "./ProgressBar";
-import { ResetCountdown } from "./ResetCountdown";
-
-interface UsageRow {
- label: string;
- percent: number;
- resetAtSeconds?: number;
- resetAtISO?: string;
-}
-
-interface ServiceStatusCardProps {
- title: string;
- icon: React.ComponentProps["name"];
- accentColor: string;
- status: "idle" | "loading" | "success" | "error";
- badge?: string;
- rows?: UsageRow[];
- footer?: React.ReactNode;
- unconfiguredLabel?: string;
- onConfigurePress?: () => void;
-}
-
-export function ServiceStatusCard({
- title,
- icon,
- accentColor,
- status,
- badge,
- rows,
- footer,
- unconfiguredLabel,
- onConfigurePress,
-}: ServiceStatusCardProps) {
- return (
-
- {/* Header */}
-
-
-
-
-
-
- {title}
-
-
- {badge && (
-
-
- {badge}
-
-
- )}
- {status === "success" && !badge && (
-
- )}
- {status === "error" && (
-
- )}
-
-
- {/* Body */}
- {status === "loading" && (
-
- )}
-
- {status === "idle" && (
-
-
- {unconfiguredLabel ?? "Not configured"}
-
- {onConfigurePress && (
-
-
- Configure →
-
-
- )}
-
- )}
-
- {status === "error" && (
-
- Failed to load usage data
-
- )}
-
- {status === "success" && rows && (
-
- {rows.map((row, i) => (
-
-
-
- {row.label}
-
-
- {Math.round(row.percent)}%
-
-
-
-
-
- ))}
-
- )}
-
- {footer && (
-
- {footer}
-
- )}
-
- );
-}
diff --git a/components/UsageStat.tsx b/components/UsageStat.tsx
deleted file mode 100644
index b465f79..0000000
--- a/components/UsageStat.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { View, Text } from "react-native";
-import { ProgressBar } from "./ProgressBar";
-import { ResetCountdown } from "./ResetCountdown";
-
-interface UsageStatProps {
- label: string;
- percent: number;
- resetAtSeconds?: number;
- resetAtISO?: string;
-}
-
-export function UsageStat({ label, percent, resetAtSeconds, resetAtISO }: UsageStatProps) {
- return (
-
-
-
- {label}
-
-
- {Math.round(percent)}%
-
-
-
-
-
- );
-}
diff --git a/eas.json b/eas.json
deleted file mode 100644
index 4f71066..0000000
--- a/eas.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "cli": {
- "version": ">= 16.0.0",
- "appVersionSource": "remote"
- },
- "build": {
- "preview": {
- "channel": "preview",
- "distribution": "internal",
- "android": {
- "buildType": "apk"
- }
- },
- "production": {
- "channel": "production",
- "distribution": "internal",
- "android": {
- "buildType": "apk"
- }
- }
- },
- "submit": {
- "production": {}
- }
-}
diff --git a/global.css b/global.css
deleted file mode 100644
index b5c61c9..0000000
--- a/global.css
+++ /dev/null
@@ -1,3 +0,0 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..8f2e28c
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+android.useAndroidX=true
+android.nonTransitiveRClass=true
+kotlin.code.style=official
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e644113
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..b82aa23
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..c0cf937
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Copyright 2015-2021 the original authors.
+# Licensed under the Apache License, Version 2.0.
+
+APP_HOME=${0%/*}
+[ "$APP_HOME" = "$0" ] && APP_HOME=.
+APP_HOME=$(cd "$APP_HOME" >/dev/null && pwd -P) || exit
+APP_BASE_NAME=${0##*/}
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+if [ -n "$JAVA_HOME" ]; then
+ JAVACMD=$JAVA_HOME/bin/java
+else
+ JAVACMD=java
+fi
+
+if ! command -v "$JAVACMD" >/dev/null 2>&1 && [ ! -x "$JAVACMD" ]; then
+ echo "ERROR: Java is not available. Set JAVA_HOME to a JDK 17 installation." >&2
+ exit 1
+fi
+
+exec "$JAVACMD" "-Xmx64m" "-Xms64m" "-Dorg.gradle.appname=$APP_BASE_NAME" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..46b0556
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,23 @@
+@if "%DEBUG%"=="" @echo off
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+if defined JAVA_HOME goto findJavaFromJavaHome
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+echo ERROR: JAVA_HOME is not set and no java command could be found. 1>&2
+exit /b 1
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+if exist "%JAVA_EXE%" goto execute
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+exit /b 1
+:execute
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+exit /b %ERRORLEVEL%
diff --git a/hooks/useClaudeUsage.ts b/hooks/useClaudeUsage.ts
deleted file mode 100644
index 02f905b..0000000
--- a/hooks/useClaudeUsage.ts
+++ /dev/null
@@ -1,245 +0,0 @@
-import { useCallback, useEffect, useRef, useState } from "react";
-import {
- fetchClaudeOrgs,
- fetchClaudeUsage,
- parseClaudeUsageResponse,
-} from "@/lib/api/claudeApi";
-import {
- isClaudeSessionKeyValid,
- validateClaudeSessionKey,
-} from "@/lib/claudeCredentials";
-import { RETRY_DELAY_MS } from "@/lib/constants";
-import {
- clearClaudeLastActiveOrg,
- clearClaudeSessionKey,
- clearClaudeUsageCache,
- loadClaudeLastActiveOrg,
- loadClaudeSessionKey,
- loadClaudeUsageCache,
- saveClaudeLastActiveOrg,
- saveClaudeSessionKey,
- saveClaudeUsageCache,
-} from "@/lib/storage";
-import type { ClaudeAuth, ClaudeUsageResponse } from "@/types/claude";
-
-type Status = "idle" | "loading" | "success" | "error";
-
-function shouldRetry(error: unknown): boolean {
- const message = error instanceof Error ? error.message : "";
- return ![
- "TOKEN_EXPIRED",
- "NO_ORGS_FOUND",
- "INVALID_CLAUDE_RESPONSE",
- "INVALID_CLAUDE_ORGS_RESPONSE",
- ].includes(message);
-}
-
-function wait(ms: number): Promise {
- return new Promise((resolve) => setTimeout(resolve, ms));
-}
-
-async function requestClaudeUsage(auth: ClaudeAuth): Promise {
- let orgUuid = auth.lastActiveOrg?.trim();
- if (!orgUuid) {
- const orgs = await fetchClaudeOrgs(auth);
- if (!orgs.length) throw new Error("NO_ORGS_FOUND");
- orgUuid = orgs[0].uuid;
- await saveClaudeLastActiveOrg(orgUuid);
- }
- return fetchClaudeUsage(auth, orgUuid);
-}
-
-export function useClaudeUsage() {
- const [auth, setAuth] = useState(null);
- const [pendingKey, setPendingKey] = useState("");
- const [pendingOrg, setPendingOrg] = useState("");
- const [usage, setUsage] = useState(null);
- const [lastFetchedAt, setLastFetchedAt] = useState(null);
- const [status, setStatus] = useState("idle");
- const [error, setError] = useState(null);
- const mounted = useRef(true);
- const inFlight = useRef<{
- key: string;
- promise: Promise;
- } | null>(null);
- const requestVersion = useRef(0);
-
- useEffect(() => {
- mounted.current = true;
- return () => {
- mounted.current = false;
- };
- }, []);
-
- const fetchUsage = useCallback((credentials: ClaudeAuth): Promise => {
- const sanitized = {
- sessionKey: credentials.sessionKey.trim(),
- lastActiveOrg: credentials.lastActiveOrg?.trim() || undefined,
- };
- const requestKey = `${sanitized.lastActiveOrg ?? ""}:${sanitized.sessionKey}`;
- if (inFlight.current?.key === requestKey) return inFlight.current.promise;
- const version = ++requestVersion.current;
-
- const promise = (async () => {
- if (mounted.current) {
- setStatus("loading");
- setError(null);
- }
-
- try {
- let data: ClaudeUsageResponse;
- try {
- data = await requestClaudeUsage(sanitized);
- } catch (firstError) {
- if (!shouldRetry(firstError)) throw firstError;
- await wait(RETRY_DELAY_MS);
- if (version !== requestVersion.current) return;
- data = await requestClaudeUsage(sanitized);
- }
-
- if (version !== requestVersion.current) return;
- const fetchedAt = Date.now();
- await saveClaudeUsageCache({ data, lastFetchedAt: fetchedAt });
- if (mounted.current && version === requestVersion.current) {
- setUsage(data);
- setLastFetchedAt(fetchedAt);
- setStatus("success");
- }
- } catch (caught: unknown) {
- if (version !== requestVersion.current) return;
- const message = caught instanceof Error ? caught.message : "UNKNOWN_ERROR";
- if (message === "TOKEN_EXPIRED") {
- await clearClaudeSessionKey();
- if (mounted.current) {
- setAuth(null);
- setUsage(null);
- setLastFetchedAt(null);
- }
- }
- if (mounted.current) {
- setError(message);
- setStatus("error");
- }
- }
- })().finally(() => {
- if (inFlight.current?.promise === promise) inFlight.current = null;
- });
-
- inFlight.current = { key: requestKey, promise };
- return promise;
- }, []);
-
- useEffect(() => {
- let active = true;
-
- void Promise.all([
- loadClaudeSessionKey(),
- loadClaudeLastActiveOrg(),
- loadClaudeUsageCache(),
- ]).then(async ([key, org, cache]) => {
- if (!active) return;
-
- const storedAuth = key
- ? { sessionKey: key.trim(), lastActiveOrg: org?.trim() || undefined }
- : null;
-
- if (storedAuth && cache) {
- try {
- if (!Number.isFinite(cache.lastFetchedAt)) {
- throw new Error("INVALID_CACHE_TIMESTAMP");
- }
- const cachedUsage = parseClaudeUsageResponse(cache.data);
- setUsage(cachedUsage);
- setLastFetchedAt(cache.lastFetchedAt);
- setStatus("success");
- } catch {
- await clearClaudeUsageCache();
- }
- }
-
- setAuth(storedAuth);
- if (storedAuth) await fetchUsage(storedAuth);
- });
-
- return () => {
- active = false;
- };
- }, [fetchUsage]);
-
- const saveKey = useCallback(async () => {
- const trimmedKey = pendingKey.trim();
- const validationError = validateClaudeSessionKey(trimmedKey);
- if (validationError) {
- setError(validationError);
- return;
- }
-
- const trimmedOrg = pendingOrg.trim() || undefined;
- await saveClaudeSessionKey(trimmedKey);
- if (trimmedOrg) await saveClaudeLastActiveOrg(trimmedOrg);
- else await clearClaudeLastActiveOrg();
-
- const nextAuth = { sessionKey: trimmedKey, lastActiveOrg: trimmedOrg };
- setAuth(nextAuth);
- setPendingKey("");
- setPendingOrg("");
- setError(null);
- await fetchUsage(nextAuth);
- }, [fetchUsage, pendingKey, pendingOrg]);
-
- const refresh = useCallback(async () => {
- if (auth) await fetchUsage(auth);
- }, [auth, fetchUsage]);
-
- const reloadCredentials = useCallback(async () => {
- const [key, org] = await Promise.all([
- loadClaudeSessionKey(),
- loadClaudeLastActiveOrg(),
- ]);
- if (!key) {
- requestVersion.current += 1;
- setAuth(null);
- setUsage(null);
- setLastFetchedAt(null);
- setStatus("idle");
- return;
- }
-
- const stored = {
- sessionKey: key.trim(),
- lastActiveOrg: org?.trim() || undefined,
- };
- setAuth(stored);
- await fetchUsage(stored);
- }, [fetchUsage]);
-
- const clearKey = useCallback(async () => {
- requestVersion.current += 1;
- await clearClaudeSessionKey();
- setAuth(null);
- setUsage(null);
- setLastFetchedAt(null);
- setStatus("idle");
- setError(null);
- }, []);
-
- return {
- auth,
- pendingKey,
- setPendingKey,
- pendingOrg,
- setPendingOrg,
- usage,
- lastFetchedAt,
- status,
- error,
- keyValidationError: pendingKey
- ? validateClaudeSessionKey(pendingKey)
- : null,
- canSaveKey: isClaudeSessionKeyValid(pendingKey),
- saveKey,
- refresh,
- reloadCredentials,
- clearKey,
- };
-}
diff --git a/hooks/useCodexUsage.ts b/hooks/useCodexUsage.ts
deleted file mode 100644
index d359162..0000000
--- a/hooks/useCodexUsage.ts
+++ /dev/null
@@ -1,178 +0,0 @@
-import { useCallback, useEffect, useRef, useState } from "react";
-import {
- fetchCodexUsage,
- parseCodexUsageResponse,
-} from "@/lib/api/codexApi";
-import { RETRY_DELAY_MS } from "@/lib/constants";
-import { pickAndReadCodexAuth } from "@/lib/fileReader";
-import {
- clearCodexAuth,
- clearCodexUsageCache,
- loadCodexAuth,
- loadCodexUsageCache,
- saveCodexAuth,
- saveCodexUsageCache,
-} from "@/lib/storage";
-import type { CodexAuth, CodexUsageResponse } from "@/types/codex";
-
-type Status = "idle" | "loading" | "success" | "error";
-
-function shouldRetry(error: unknown): boolean {
- const message = error instanceof Error ? error.message : "";
- return message !== "TOKEN_EXPIRED" && message !== "INVALID_CODEX_RESPONSE";
-}
-
-function wait(ms: number): Promise {
- return new Promise((resolve) => setTimeout(resolve, ms));
-}
-
-export function useCodexUsage() {
- const [auth, setAuth] = useState(null);
- const [usage, setUsage] = useState(null);
- const [lastFetchedAt, setLastFetchedAt] = useState(null);
- const [status, setStatus] = useState("idle");
- const [error, setError] = useState(null);
- const mounted = useRef(true);
- const inFlight = useRef<{
- key: string;
- promise: Promise;
- } | null>(null);
- const requestVersion = useRef(0);
-
- useEffect(() => {
- mounted.current = true;
- return () => {
- mounted.current = false;
- };
- }, []);
-
- const fetchUsage = useCallback((credentials: CodexAuth): Promise => {
- const requestKey = `${credentials.accountId ?? ""}:${credentials.accessToken}`;
- if (inFlight.current?.key === requestKey) return inFlight.current.promise;
- const version = ++requestVersion.current;
-
- const promise = (async () => {
- if (mounted.current) {
- setStatus("loading");
- setError(null);
- }
-
- try {
- let data: CodexUsageResponse;
- try {
- data = await fetchCodexUsage(credentials);
- } catch (firstError) {
- if (!shouldRetry(firstError)) throw firstError;
- await wait(RETRY_DELAY_MS);
- if (version !== requestVersion.current) return;
- data = await fetchCodexUsage(credentials);
- }
-
- if (version !== requestVersion.current) return;
- const fetchedAt = Date.now();
- await saveCodexUsageCache({ data, lastFetchedAt: fetchedAt });
- if (mounted.current && version === requestVersion.current) {
- setUsage(data);
- setLastFetchedAt(fetchedAt);
- setStatus("success");
- }
- } catch (caught: unknown) {
- if (version !== requestVersion.current) return;
- const message = caught instanceof Error ? caught.message : "UNKNOWN_ERROR";
- if (mounted.current) {
- setError(message);
- setStatus("error");
- }
- }
- })().finally(() => {
- if (inFlight.current?.promise === promise) inFlight.current = null;
- });
-
- inFlight.current = { key: requestKey, promise };
- return promise;
- }, []);
-
- useEffect(() => {
- let active = true;
-
- void Promise.all([loadCodexAuth(), loadCodexUsageCache()]).then(
- async ([storedAuth, cache]) => {
- if (!active) return;
-
- if (storedAuth && cache) {
- try {
- if (!Number.isFinite(cache.lastFetchedAt)) {
- throw new Error("INVALID_CACHE_TIMESTAMP");
- }
- const cachedUsage = parseCodexUsageResponse(cache.data);
- setUsage(cachedUsage);
- setLastFetchedAt(cache.lastFetchedAt);
- setStatus("success");
- } catch {
- await clearCodexUsageCache();
- }
- }
-
- setAuth(storedAuth);
- if (storedAuth) await fetchUsage(storedAuth);
- }
- );
-
- return () => {
- active = false;
- };
- }, [fetchUsage]);
-
- const importAuthFile = useCallback(async () => {
- try {
- const parsed = await pickAndReadCodexAuth();
- await saveCodexAuth(parsed);
- setAuth(parsed);
- setError(null);
- await fetchUsage(parsed);
- } catch (caught: unknown) {
- const message = caught instanceof Error ? caught.message : "UNKNOWN_ERROR";
- if (message !== "PICKER_CANCELLED") setError(message);
- }
- }, [fetchUsage]);
-
- const refresh = useCallback(async () => {
- if (auth) await fetchUsage(auth);
- }, [auth, fetchUsage]);
-
- const reloadCredentials = useCallback(async () => {
- const stored = await loadCodexAuth();
- if (!stored) {
- requestVersion.current += 1;
- setAuth(null);
- setUsage(null);
- setLastFetchedAt(null);
- setStatus("idle");
- return;
- }
- setAuth(stored);
- await fetchUsage(stored);
- }, [fetchUsage]);
-
- const clearAuth = useCallback(async () => {
- requestVersion.current += 1;
- await clearCodexAuth();
- setAuth(null);
- setUsage(null);
- setLastFetchedAt(null);
- setStatus("idle");
- setError(null);
- }, []);
-
- return {
- auth,
- usage,
- lastFetchedAt,
- status,
- error,
- importAuthFile,
- refresh,
- reloadCredentials,
- clearAuth,
- };
-}
diff --git a/hooks/useNotificationSettings.ts b/hooks/useNotificationSettings.ts
deleted file mode 100644
index f044648..0000000
--- a/hooks/useNotificationSettings.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import { useState, useEffect, useCallback } from "react";
-import {
- loadNotifSettings,
- saveNotifSettings,
- type NotifSettings,
-} from "@/lib/storage";
-import {
- requestPermissions,
- getPermissionStatus,
- scheduleDailyDigest,
- cancelDailyDigest,
-} from "@/lib/notifications";
-
-export function useNotificationSettings() {
- const [settings, setSettings] = useState({
- dailyEnabled: false,
- dailyHour: 9,
- dailyMinute: 0,
- thresholdEnabled: false,
- thresholdPct: 20,
- });
- const [permissionStatus, setPermissionStatus] = useState("undetermined");
- const [loaded, setLoaded] = useState(false);
-
- useEffect(() => {
- Promise.all([loadNotifSettings(), getPermissionStatus()]).then(
- ([stored, status]) => {
- setSettings(stored);
- setPermissionStatus(status);
- setLoaded(true);
- }
- );
- }, []);
-
- const askPermissions = useCallback(async (): Promise => {
- const granted = await requestPermissions();
- setPermissionStatus(granted ? "granted" : "denied");
- return granted;
- }, []);
-
- const update = useCallback(
- async (patch: Partial) => {
- const next = { ...settings, ...patch };
- setSettings(next);
- await saveNotifSettings(next);
-
- // Keep scheduled notification in sync when toggling or changing time
- const dailyChanged =
- "dailyEnabled" in patch ||
- "dailyHour" in patch ||
- "dailyMinute" in patch;
- if (dailyChanged) {
- if (next.dailyEnabled) {
- await scheduleDailyDigest(next.dailyHour, next.dailyMinute, null, null);
- } else {
- await cancelDailyDigest();
- }
- }
- },
- [settings]
- );
-
- return { settings, permissionStatus, loaded, askPermissions, update };
-}
diff --git a/index.ts b/index.ts
deleted file mode 100644
index 1d6e981..0000000
--- a/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { registerRootComponent } from 'expo';
-
-import App from './App';
-
-// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
-// It also ensures that whether you load the app in Expo Go or in a native build,
-// the environment is set up appropriately
-registerRootComponent(App);
diff --git a/lib/api/claudeApi.ts b/lib/api/claudeApi.ts
deleted file mode 100644
index a89bce6..0000000
--- a/lib/api/claudeApi.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-import type { ClaudeAuth, ClaudeOrg, ClaudeUsageResponse } from "@/types/claude";
-
-const BASE_URL = "https://claude.ai/api";
-
-const BROWSER_UA =
- "Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36";
-
-function buildHeaders(auth: ClaudeAuth): Record {
- const cookies = [`sessionKey=${auth.sessionKey}`];
- if (auth.lastActiveOrg) cookies.push(`lastActiveOrg=${auth.lastActiveOrg}`);
- return {
- Cookie: cookies.join("; "),
- Accept: "application/json, text/plain, */*",
- "Accept-Language": "en-US,en;q=0.9",
- "User-Agent": BROWSER_UA,
- Referer: "https://claude.ai/",
- Origin: "https://claude.ai",
- "anthropic-client-platform": "web_claude_to_cc_migration",
- };
-}
-
-function isClaudeWindow(value: unknown): boolean {
- if (!value || typeof value !== "object") return false;
- const window = value as Record;
- return (
- typeof window.utilization === "number" &&
- Number.isFinite(window.utilization) &&
- (window.resets_at === undefined ||
- window.resets_at === null ||
- typeof window.resets_at === "string")
- );
-}
-
-export function parseClaudeOrgsResponse(data: unknown): ClaudeOrg[] {
- if (
- !Array.isArray(data) ||
- data.some(
- (org) =>
- !org ||
- typeof org !== "object" ||
- typeof (org as Record).uuid !== "string" ||
- typeof (org as Record).name !== "string"
- )
- ) {
- throw new Error("INVALID_CLAUDE_ORGS_RESPONSE");
- }
- return data.map((org) => {
- const value = org as Record;
- return { uuid: value.uuid as string, name: value.name as string };
- });
-}
-
-export function parseClaudeUsageResponse(data: unknown): ClaudeUsageResponse {
- if (!data || typeof data !== "object") {
- throw new Error("INVALID_CLAUDE_RESPONSE");
- }
-
- const value = data as Record;
- if (
- !isClaudeWindow(value.five_hour) ||
- !isClaudeWindow(value.seven_day) ||
- (value.seven_day_sonnet !== undefined &&
- value.seven_day_sonnet !== null &&
- !isClaudeWindow(value.seven_day_sonnet)) ||
- (value.seven_day_opus !== undefined &&
- value.seven_day_opus !== null &&
- !isClaudeWindow(value.seven_day_opus))
- ) {
- throw new Error("INVALID_CLAUDE_RESPONSE");
- }
-
- const toWindow = (window: unknown) => {
- const item = window as Record;
- return {
- utilization: item.utilization as number,
- ...(typeof item.resets_at === "string"
- ? { resets_at: item.resets_at }
- : {}),
- };
- };
-
- return {
- five_hour: toWindow(value.five_hour),
- seven_day: toWindow(value.seven_day),
- ...(value.seven_day_sonnet
- ? { seven_day_sonnet: toWindow(value.seven_day_sonnet) }
- : {}),
- ...(value.seven_day_opus
- ? { seven_day_opus: toWindow(value.seven_day_opus) }
- : {}),
- };
-}
-
-export async function fetchClaudeOrgs(auth: ClaudeAuth): Promise {
- const response = await fetch(`${BASE_URL}/organizations`, {
- headers: buildHeaders(auth),
- credentials: "omit",
- });
-
- if (!response.ok) {
- await response.text().catch(() => null);
- if (response.status === 401 || response.status === 403) throw new Error("TOKEN_EXPIRED");
- throw new Error(`HTTP_ERROR_${response.status}`);
- }
-
- const data: unknown = await response.json();
- return parseClaudeOrgsResponse(data);
-}
-
-export async function fetchClaudeUsage(
- auth: ClaudeAuth,
- orgUuid: string
-): Promise {
- const response = await fetch(`${BASE_URL}/organizations/${orgUuid}/usage`, {
- headers: buildHeaders(auth),
- credentials: "omit",
- });
-
- if (!response.ok) {
- await response.text().catch(() => null);
- if (response.status === 401 || response.status === 403) throw new Error("TOKEN_EXPIRED");
- throw new Error(`HTTP_ERROR_${response.status}`);
- }
-
- const data: unknown = await response.json();
- return parseClaudeUsageResponse(data);
-}
diff --git a/lib/api/codexApi.ts b/lib/api/codexApi.ts
deleted file mode 100644
index 0ed5c01..0000000
--- a/lib/api/codexApi.ts
+++ /dev/null
@@ -1,215 +0,0 @@
-import type { CodexAuth, CodexUsageResponse } from "@/types/codex";
-
-const USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
-const RESET_CREDITS_URL =
- "https://chatgpt.com/backend-api/wham/rate-limit-reset-credits";
-
-interface RawUsageWindow {
- used_percent?: number;
- limit_window_seconds?: number;
- reset_at?: number;
-}
-
-interface RawUsageResponse {
- plan_type?: string | null;
- rate_limit?: {
- primary_window?: RawUsageWindow | null;
- secondary_window?: RawUsageWindow | null;
- } | null;
- credits?: {
- has_credits?: boolean;
- unlimited?: boolean;
- balance?: string | number;
- } | null;
- rate_limit_reached_type?: string | null;
- rate_limit_reset_credits?: {
- available_count?: number | null;
- } | null;
-}
-
-interface RawResetCredit {
- status?: string;
- granted_at?: string | null;
- expires_at?: string | null;
-}
-
-interface RawResetCreditsResponse {
- available_count?: number | null;
- total_earned_count?: number | null;
- credits?: RawResetCredit[] | null;
-}
-
-function isNumber(value: unknown): value is number {
- return typeof value === "number" && Number.isFinite(value);
-}
-
-function formatDurationUntil(isoString: string | null | undefined): string | null {
- if (!isoString) return null;
-
- const targetMs = new Date(isoString).getTime();
- if (Number.isNaN(targetMs)) return null;
-
- let remainingSeconds = Math.max(Math.round((targetMs - Date.now()) / 1000), 0);
- const days = Math.floor(remainingSeconds / 86400);
- remainingSeconds -= days * 86400;
- const hours = Math.floor(remainingSeconds / 3600);
- remainingSeconds -= hours * 3600;
- const minutes = Math.floor(remainingSeconds / 60);
- remainingSeconds -= minutes * 60;
-
- const parts: string[] = [];
- if (days > 0) parts.push(`${days}d`);
- if (hours > 0) parts.push(`${hours}h`);
- if (minutes > 0) parts.push(`${minutes}m`);
- if (remainingSeconds > 0 || parts.length === 0) parts.push(`${remainingSeconds}s`);
- return parts.join(" ");
-}
-
-function normalizeWindow(window: RawUsageWindow | null | undefined) {
- if (!window) return null;
-
- const windowSeconds =
- typeof window.limit_window_seconds === "number" ? window.limit_window_seconds : 0;
- const resetsAt = typeof window.reset_at === "number" ? window.reset_at : 0;
-
- return {
- usedPercent: typeof window.used_percent === "number" ? window.used_percent : 0,
- resetsAt,
- windowMinutes: Math.round(windowSeconds / 60),
- windowSeconds,
- };
-}
-
-function buildBaseHeaders(auth: CodexAuth): Record {
- const headers: Record = {
- Authorization: `Bearer ${auth.accessToken}`,
- "Content-Type": "application/json",
- };
-
- if (auth.accountId) {
- headers["ChatGPT-Account-Id"] = auth.accountId;
- }
-
- return headers;
-}
-
-async function fetchResetCoupons(auth: CodexAuth, usage: RawUsageResponse) {
- const headers = {
- ...buildBaseHeaders(auth),
- "OpenAI-Beta": "codex-1",
- originator: "Codex Desktop",
- };
-
- try {
- const response = await fetch(RESET_CREDITS_URL, { headers });
- if (!response.ok) {
- throw new Error(`HTTP_ERROR_${response.status}`);
- }
-
- const payload = (await response.json()) as RawResetCreditsResponse;
- const credits = Array.isArray(payload.credits) ? payload.credits : [];
- const normalizedCredits = credits
- .map((credit, index) => ({
- index: index + 1,
- status: credit.status,
- grantedAt: credit.granted_at ?? null,
- grantedAtLocal: credit.granted_at
- ? new Date(credit.granted_at).toLocaleString()
- : null,
- expiresAt: credit.expires_at ?? null,
- expiresAtLocal: credit.expires_at
- ? new Date(credit.expires_at).toLocaleString()
- : null,
- timeUntilExpiry: formatDurationUntil(credit.expires_at),
- }))
- .sort((a, b) => {
- const left = a.expiresAt ? new Date(a.expiresAt).getTime() : Number.MAX_SAFE_INTEGER;
- const right = b.expiresAt ? new Date(b.expiresAt).getTime() : Number.MAX_SAFE_INTEGER;
- return left - right;
- });
-
- const availableCredits = normalizedCredits.filter(
- (credit) => credit.status === "available"
- );
-
- return {
- source: "live_api" as const,
- sourceDescription: "Live Codex reset-credit endpoint",
- availableCount:
- payload.available_count ?? usage.rate_limit_reset_credits?.available_count ?? null,
- totalEarnedCount: payload.total_earned_count ?? null,
- credits: normalizedCredits,
- nextExpiringCredit: availableCredits[0] ?? normalizedCredits[0] ?? null,
- };
- } catch (error) {
- const message = error instanceof Error ? error.message : "UNKNOWN_ERROR";
- return {
- source: "unavailable" as const,
- sourceDescription: "Reset-credit endpoint unavailable",
- availableCount: usage.rate_limit_reset_credits?.available_count ?? null,
- fallbackReason: message,
- error: message,
- };
- }
-}
-
-export function parseCodexUsageResponse(data: unknown): CodexUsageResponse {
- if (!data || typeof data !== "object") {
- throw new Error("INVALID_CODEX_RESPONSE");
- }
-
- const value = data as Record;
- const primary = value.primary as Record | null | undefined;
- const secondary = value.secondary as Record | null | undefined;
- const credits = value.credits as Record | undefined;
-
- const validWindow = (window: Record | null | undefined) =>
- window === null ||
- window === undefined ||
- (isNumber(window.usedPercent) &&
- isNumber(window.resetsAt) &&
- isNumber(window.windowMinutes) &&
- isNumber(window.windowSeconds));
-
- if (
- !validWindow(primary) ||
- !validWindow(secondary) ||
- !credits ||
- typeof credits.hasCredits !== "boolean" ||
- typeof credits.unlimited !== "boolean" ||
- !isNumber(credits.balance)
- ) {
- throw new Error("INVALID_CODEX_RESPONSE");
- }
-
- return value as unknown as CodexUsageResponse;
-}
-
-export async function fetchCodexUsage(auth: CodexAuth): Promise {
- const headers = buildBaseHeaders(auth);
- const response = await fetch(USAGE_URL, { headers });
-
- if (response.status === 401 || response.status === 403) {
- throw new Error("TOKEN_EXPIRED");
- }
- if (!response.ok) {
- await response.text().catch(() => null);
- throw new Error(`HTTP_ERROR_${response.status}`);
- }
-
- const payload = (await response.json()) as RawUsageResponse;
- const resetCoupons = await fetchResetCoupons(auth, payload);
-
- return {
- planType: payload.plan_type ?? null,
- rateLimitReachedType: payload.rate_limit_reached_type ?? null,
- primary: normalizeWindow(payload.rate_limit?.primary_window),
- secondary: normalizeWindow(payload.rate_limit?.secondary_window),
- credits: {
- hasCredits: Boolean(payload.credits?.has_credits),
- unlimited: Boolean(payload.credits?.unlimited),
- balance: Number(payload.credits?.balance ?? 0),
- },
- resetCoupons,
- };
-}
diff --git a/lib/claudeCredentials.ts b/lib/claudeCredentials.ts
deleted file mode 100644
index 46da57f..0000000
--- a/lib/claudeCredentials.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-const CLAUDE_SESSION_KEY_PATTERN = /^sk-ant-[A-Za-z0-9_-]+$/;
-
-export function validateClaudeSessionKey(value: string): string | null {
- const key = value.trim();
- if (!key.startsWith("sk-ant-")) {
- return "Session key must start with sk-ant-";
- }
- if (key.length <= 40) {
- return "Session key looks too short. Paste the complete cookie value.";
- }
- if (!CLAUDE_SESSION_KEY_PATTERN.test(key)) {
- return "Session key contains unexpected characters. Check the pasted value.";
- }
- return null;
-}
-
-export function isClaudeSessionKeyValid(value: string): boolean {
- return validateClaudeSessionKey(value) === null;
-}
diff --git a/lib/constants.ts b/lib/constants.ts
deleted file mode 100644
index 2ca2a64..0000000
--- a/lib/constants.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-export const COLORS = {
- codex: "#10a37f",
- claude: "#d97706",
- danger: "#ef4444",
- warning: "#f59e0b",
- disabled: "#e5e5e5",
- muted: "#a3a3a3",
- appBackground: "#090d11",
-} as const;
-
-export const PROGRESS_THRESHOLDS = {
- warning: 60,
- danger: 85,
-} as const;
-
-export const COUNTDOWN_INTERVAL_MS = 60_000;
-export const RETRY_DELAY_MS = 5_000;
-
-export function getUsageColor(percent: number): string {
- if (percent >= PROGRESS_THRESHOLDS.danger) return COLORS.danger;
- if (percent >= PROGRESS_THRESHOLDS.warning) return COLORS.warning;
- return COLORS.codex;
-}
diff --git a/lib/fileReader.ts b/lib/fileReader.ts
deleted file mode 100644
index 3541d09..0000000
--- a/lib/fileReader.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import * as DocumentPicker from "expo-document-picker";
-import * as LegacyFileSystem from "expo-file-system/legacy";
-import type { CodexAuth } from "@/types/codex";
-
-function sanitizeFileName(name: string): string {
- return name.replace(/[^a-zA-Z0-9._-]/g, "_");
-}
-
-async function readPickedTextFile(uri: string, fileName?: string): Promise {
- try {
- const response = await fetch(uri);
- if (!response.ok) {
- throw new Error(`HTTP_ERROR_${response.status}`);
- }
- return await response.text();
- } catch {
- try {
- return await LegacyFileSystem.readAsStringAsync(uri);
- } catch {
- const cacheDirectory = LegacyFileSystem.cacheDirectory;
- if (!cacheDirectory) {
- throw new Error("DOCUMENT_NOT_READABLE");
- }
-
- const destination = `${cacheDirectory}${Date.now()}-${sanitizeFileName(
- fileName ?? "import.json"
- )}`;
-
- try {
- await LegacyFileSystem.copyAsync({ from: uri, to: destination });
- return await LegacyFileSystem.readAsStringAsync(destination);
- } catch {
- throw new Error("DOCUMENT_NOT_READABLE");
- }
- }
- }
-}
-
-export async function pickAndReadCodexAuth(): Promise {
- const result = await DocumentPicker.getDocumentAsync({
- type: "application/json",
- copyToCacheDirectory: true,
- });
-
- if (result.canceled) throw new Error("PICKER_CANCELLED");
-
- const { uri, name } = result.assets[0];
- const text = await readPickedTextFile(uri, name);
-
- let parsed: Record;
- try {
- parsed = JSON.parse(text);
- } catch {
- throw new Error("INVALID_JSON");
- }
-
- const tokens = parsed["tokens"] as Record | undefined;
- const accessToken = (tokens?.["access_token"] ?? parsed["accessToken"]) as string | undefined;
- const accountId = (
- tokens?.["account_id"] ??
- parsed["accountId"] ??
- parsed["account_id"]
- ) as string | undefined;
-
- if (!accessToken || typeof accessToken !== "string") {
- throw new Error("MISSING_ACCESS_TOKEN");
- }
-
- return { accessToken, accountId };
-}
diff --git a/lib/notifications.ts b/lib/notifications.ts
deleted file mode 100644
index 29f6358..0000000
--- a/lib/notifications.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-import type * as NotificationsType from "expo-notifications";
-import {
- loadNotifSettings,
- loadNotifThresholdLastFired,
- saveNotifThresholdLastFired,
-} from "@/lib/storage";
-import type { ClaudeUsageResponse } from "@/types/claude";
-import type { CodexUsageResponse } from "@/types/codex";
-
-// expo-notifications push notifications were removed from Expo Go in SDK 53.
-// Use require() so the initialization error is caught gracefully in Expo Go.
-let Notifications: typeof NotificationsType | null = null;
-try {
- Notifications = require("expo-notifications") as typeof NotificationsType;
- Notifications.setNotificationHandler({
- handleNotification: async () => ({
- shouldShowAlert: true,
- shouldShowBanner: true,
- shouldShowList: true,
- shouldPlaySound: false,
- shouldSetBadge: false,
- }),
- });
-} catch {
- // Running in Expo Go or native module unavailable — notifications disabled.
-}
-
-export async function requestPermissions(): Promise {
- if (!Notifications) return false;
- const { status } = await Notifications.requestPermissionsAsync();
- return status === "granted";
-}
-
-export async function getPermissionStatus(): Promise {
- if (!Notifications) return "undetermined";
- const { status } = await Notifications.getPermissionsAsync();
- return status;
-}
-
-const DAILY_ID = "codexbar-daily-digest";
-
-export async function scheduleDailyDigest(
- hour: number,
- minute: number,
- claudeUsage: ClaudeUsageResponse | null,
- codexUsage: CodexUsageResponse | null
-): Promise {
- if (!Notifications) return;
- try {
- await Notifications.cancelScheduledNotificationAsync(DAILY_ID);
- } catch {}
-
- const parts: string[] = [];
- if (claudeUsage) {
- parts.push(`Claude 7d: ${Math.round(claudeUsage.seven_day.utilization)}% used`);
- }
- if (codexUsage) {
- parts.push(
- `Codex: ${Math.round(codexUsage.secondary?.usedPercent ?? 0)}% used`
- );
- }
-
- await Notifications.scheduleNotificationAsync({
- identifier: DAILY_ID,
- content: {
- title: "Usage Digest",
- body:
- parts.length > 0
- ? parts.join(" · ")
- : "Open to check your usage limits",
- },
- trigger: {
- type: Notifications.SchedulableTriggerInputTypes.CALENDAR,
- hour,
- minute,
- repeats: true,
- },
- });
-}
-
-export async function cancelDailyDigest(): Promise {
- if (!Notifications) return;
- try {
- await Notifications.cancelScheduledNotificationAsync(DAILY_ID);
- } catch {}
-}
-
-interface ThresholdAlert {
- service: string;
- window: string;
- remaining: number;
-}
-
-function buildThresholdAlerts(
- thresholdPct: number,
- claudeUsage: ClaudeUsageResponse | null,
- codexUsage: CodexUsageResponse | null
-): ThresholdAlert[] {
- const alerts: ThresholdAlert[] = [];
-
- if (claudeUsage) {
- const remaining = 100 - claudeUsage.seven_day.utilization;
- if (remaining <= thresholdPct) {
- alerts.push({ service: "Claude", window: "7-day", remaining });
- }
- }
-
- if (codexUsage) {
- const remaining = 100 - (codexUsage.secondary?.usedPercent ?? 0);
- if (remaining <= thresholdPct) {
- alerts.push({ service: "Codex", window: "weekly", remaining });
- }
- }
-
- return alerts;
-}
-
-/** Call this after every successful usage fetch. Reschedules daily digest and fires threshold alerts. */
-export async function onUsageDataLoaded(
- claudeUsage: ClaudeUsageResponse | null,
- codexUsage: CodexUsageResponse | null
-): Promise {
- const settings = await loadNotifSettings();
-
- if (settings.dailyEnabled) {
- await scheduleDailyDigest(
- settings.dailyHour,
- settings.dailyMinute,
- claudeUsage,
- codexUsage
- );
- }
-
- if (settings.thresholdEnabled) {
- const today = new Date().toISOString().slice(0, 10);
- const lastFired = await loadNotifThresholdLastFired();
- if (lastFired !== today) {
- const alerts = buildThresholdAlerts(
- settings.thresholdPct,
- claudeUsage,
- codexUsage
- );
- if (alerts.length > 0 && Notifications) {
- await Notifications.scheduleNotificationAsync({
- content: {
- title: "Low quota warning",
- body: alerts
- .map(
- (a) =>
- `${a.service} ${a.window}: ${Math.round(a.remaining)}% remaining`
- )
- .join("\n"),
- },
- trigger: null,
- });
- await saveNotifThresholdLastFired(today);
- }
- }
- }
-}
diff --git a/lib/setupState.ts b/lib/setupState.ts
deleted file mode 100644
index f1e05f4..0000000
--- a/lib/setupState.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import * as SecureStore from "expo-secure-store";
-
-const KEY = "codexbar_onboarding_v1";
-
-export async function hasCompletedOnboarding(): Promise {
- const val = await SecureStore.getItemAsync(KEY);
- return val === "done";
-}
-
-export async function markOnboardingComplete(): Promise {
- await SecureStore.setItemAsync(KEY, "done");
-}
-
-export async function resetOnboarding(): Promise {
- await SecureStore.deleteItemAsync(KEY);
-}
diff --git a/lib/storage.ts b/lib/storage.ts
deleted file mode 100644
index 31f6f14..0000000
--- a/lib/storage.ts
+++ /dev/null
@@ -1,159 +0,0 @@
-import * as SecureStore from "expo-secure-store";
-import type { ClaudeUsageResponse } from "@/types/claude";
-import type { CodexUsageResponse } from "@/types/codex";
-
-const KEYS = {
- CODEX_AUTH: "codexbar_codex_auth",
- CLAUDE_SESSION_KEY: "codexbar_claude_session_key",
- CLAUDE_LAST_ACTIVE_ORG: "codexbar_claude_last_active_org",
- CODEX_USAGE_CACHE: "codexbar_codex_usage_cache",
- CLAUDE_USAGE_CACHE: "codexbar_claude_usage_cache",
- NOTIF_DAILY_ENABLED: "notifDailyEnabled",
- NOTIF_DAILY_HOUR: "notifDailyHour",
- NOTIF_DAILY_MINUTE: "notifDailyMinute",
- NOTIF_THRESHOLD_ENABLED: "notifThresholdEnabled",
- NOTIF_THRESHOLD_PCT: "notifThresholdPct",
- NOTIF_THRESHOLD_LAST_FIRED: "notifThresholdLastFired",
-} as const;
-
-export interface UsageCache {
- data: T;
- lastFetchedAt: number;
-}
-
-async function loadJson(key: string): Promise {
- const raw = await SecureStore.getItemAsync(key);
- if (!raw) return null;
-
- try {
- return JSON.parse(raw) as T;
- } catch {
- await SecureStore.deleteItemAsync(key);
- return null;
- }
-}
-
-async function saveJson(key: string, value: unknown): Promise {
- await SecureStore.setItemAsync(key, JSON.stringify(value));
-}
-
-export interface NotifSettings {
- dailyEnabled: boolean;
- dailyHour: number;
- dailyMinute: number;
- thresholdEnabled: boolean;
- /** Alert when remaining quota falls below this % (e.g. 20 = fire when < 20% left) */
- thresholdPct: number;
-}
-
-export async function loadNotifSettings(): Promise {
- const [de, dh, dm, te, tp] = await Promise.all([
- SecureStore.getItemAsync(KEYS.NOTIF_DAILY_ENABLED),
- SecureStore.getItemAsync(KEYS.NOTIF_DAILY_HOUR),
- SecureStore.getItemAsync(KEYS.NOTIF_DAILY_MINUTE),
- SecureStore.getItemAsync(KEYS.NOTIF_THRESHOLD_ENABLED),
- SecureStore.getItemAsync(KEYS.NOTIF_THRESHOLD_PCT),
- ]);
- return {
- dailyEnabled: de === "true",
- dailyHour: dh !== null ? parseInt(dh, 10) : 9,
- dailyMinute: dm !== null ? parseInt(dm, 10) : 0,
- thresholdEnabled: te === "true",
- thresholdPct: tp !== null ? parseInt(tp, 10) : 20,
- };
-}
-
-export async function saveNotifSettings(s: NotifSettings): Promise {
- await Promise.all([
- SecureStore.setItemAsync(KEYS.NOTIF_DAILY_ENABLED, String(s.dailyEnabled)),
- SecureStore.setItemAsync(KEYS.NOTIF_DAILY_HOUR, String(s.dailyHour)),
- SecureStore.setItemAsync(KEYS.NOTIF_DAILY_MINUTE, String(s.dailyMinute)),
- SecureStore.setItemAsync(KEYS.NOTIF_THRESHOLD_ENABLED, String(s.thresholdEnabled)),
- SecureStore.setItemAsync(KEYS.NOTIF_THRESHOLD_PCT, String(s.thresholdPct)),
- ]);
-}
-
-export async function loadNotifThresholdLastFired(): Promise {
- return SecureStore.getItemAsync(KEYS.NOTIF_THRESHOLD_LAST_FIRED);
-}
-
-export async function saveNotifThresholdLastFired(date: string): Promise {
- await SecureStore.setItemAsync(KEYS.NOTIF_THRESHOLD_LAST_FIRED, date);
-}
-
-export async function saveCodexAuth(auth: {
- accessToken: string;
- accountId?: string;
-}): Promise {
- await saveJson(KEYS.CODEX_AUTH, auth);
-}
-
-export async function loadCodexAuth(): Promise<{
- accessToken: string;
- accountId?: string;
-} | null> {
- return loadJson(KEYS.CODEX_AUTH);
-}
-
-export function loadCodexUsageCache(): Promise | null> {
- return loadJson(KEYS.CODEX_USAGE_CACHE);
-}
-
-export function saveCodexUsageCache(
- cache: UsageCache
-): Promise {
- return saveJson(KEYS.CODEX_USAGE_CACHE, cache);
-}
-
-export function clearCodexUsageCache(): Promise {
- return SecureStore.deleteItemAsync(KEYS.CODEX_USAGE_CACHE);
-}
-
-export function loadClaudeUsageCache(): Promise | null> {
- return loadJson(KEYS.CLAUDE_USAGE_CACHE);
-}
-
-export function saveClaudeUsageCache(
- cache: UsageCache
-): Promise {
- return saveJson(KEYS.CLAUDE_USAGE_CACHE, cache);
-}
-
-export function clearClaudeUsageCache(): Promise {
- return SecureStore.deleteItemAsync(KEYS.CLAUDE_USAGE_CACHE);
-}
-
-export async function saveClaudeSessionKey(key: string): Promise {
- await SecureStore.setItemAsync(KEYS.CLAUDE_SESSION_KEY, key.trim());
-}
-
-export async function loadClaudeSessionKey(): Promise {
- return SecureStore.getItemAsync(KEYS.CLAUDE_SESSION_KEY);
-}
-
-export async function saveClaudeLastActiveOrg(orgId: string): Promise {
- await SecureStore.setItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG, orgId.trim());
-}
-
-export async function loadClaudeLastActiveOrg(): Promise {
- return SecureStore.getItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG);
-}
-
-export async function clearClaudeLastActiveOrg(): Promise {
- await SecureStore.deleteItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG);
-}
-
-export async function clearCodexAuth(): Promise {
- await Promise.all([
- SecureStore.deleteItemAsync(KEYS.CODEX_AUTH),
- clearCodexUsageCache(),
- ]);
-}
-
-export async function clearClaudeSessionKey(): Promise {
- await Promise.all([
- SecureStore.deleteItemAsync(KEYS.CLAUDE_SESSION_KEY),
- SecureStore.deleteItemAsync(KEYS.CLAUDE_LAST_ACTIVE_ORG),
- clearClaudeUsageCache(),
- ]);
-}
diff --git a/lib/timeUtils.ts b/lib/timeUtils.ts
deleted file mode 100644
index b5bf488..0000000
--- a/lib/timeUtils.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-export function formatResetCountdown(resetAtSeconds: number): string {
- const nowSeconds = Math.floor(Date.now() / 1000);
- const diffSeconds = resetAtSeconds - nowSeconds;
-
- if (diffSeconds <= 0) return "resetting now";
- if (diffSeconds < 60) return "resets in <1m";
-
- const totalHours = Math.floor(diffSeconds / 3600);
- const minutes = Math.floor((diffSeconds % 3600) / 60);
-
- if (totalHours >= 24) {
- const days = Math.floor(totalHours / 24);
- const hours = totalHours % 24;
- if (hours > 0) return `resets in ${days}d ${hours}h`;
- return `resets in ${days}d`;
- }
- if (totalHours > 0 && minutes > 0) return `resets in ${totalHours}h ${minutes}m`;
- if (totalHours > 0) return `resets in ${totalHours}h`;
- return `resets in ${minutes}m`;
-}
-
-export function parseTimeInput(
- value: string
-): { hour: number; minute: number } | null {
- const match = value.trim().match(/^(\d{1,2}):(\d{2})$/);
- if (!match) return null;
-
- const hour = Number.parseInt(match[1], 10);
- const minute = Number.parseInt(match[2], 10);
- if (hour > 23 || minute > 59) return null;
-
- return { hour, minute };
-}
-
-export function formatTime(hour: number, minute: number): string {
- return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
-}
-
-export function formatLastUpdated(timestamp: number, now = Date.now()): string {
- const elapsedSeconds = Math.max(0, Math.floor((now - timestamp) / 1000));
- if (elapsedSeconds < 60) return "Updated just now";
-
- const minutes = Math.floor(elapsedSeconds / 60);
- if (minutes < 60) return `Updated ${minutes} min ago`;
-
- const hours = Math.floor(minutes / 60);
- if (hours < 24) return `Updated ${hours} hr${hours === 1 ? "" : "s"} ago`;
-
- const days = Math.floor(hours / 24);
- return `Updated ${days} day${days === 1 ? "" : "s"} ago`;
-}
-
-export function formatResetCountdownISO(isoString: string): string {
- const resetAtSeconds = Math.floor(new Date(isoString).getTime() / 1000);
- return formatResetCountdown(resetAtSeconds);
-}
-
-export function windowLabel(limitWindowSeconds: number): string {
- const hours = limitWindowSeconds / 3600;
- if (hours < 24) return `${Math.round(hours)}h`;
- const days = hours / 24;
- const wholeDays = Math.floor(days);
- const remainderHours = Math.round(hours - wholeDays * 24);
- if (remainderHours === 0) return `${wholeDays}d`;
- return `${wholeDays}d ${remainderHours}h`;
-}
diff --git a/metro.config.js b/metro.config.js
deleted file mode 100644
index b0963fe..0000000
--- a/metro.config.js
+++ /dev/null
@@ -1,6 +0,0 @@
-const { getDefaultConfig } = require("expo/metro-config");
-const { withNativeWind } = require("nativewind/metro");
-
-const config = getDefaultConfig(__dirname);
-
-module.exports = withNativeWind(config, { input: "./global.css" });
diff --git a/nativewind-env.d.ts b/nativewind-env.d.ts
deleted file mode 100644
index 250fbd3..0000000
--- a/nativewind-env.d.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-///
-
-declare module "*.css" {
- const content: unknown;
- export default content;
-}
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 3d6d179..0000000
--- a/package-lock.json
+++ /dev/null
@@ -1,8792 +0,0 @@
-{
- "name": "codexbar.mobile",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "codexbar.mobile",
- "version": "1.0.0",
- "dependencies": {
- "@expo/metro-runtime": "~56.0.15",
- "@expo/vector-icons": "^15.1.1",
- "babel-preset-expo": "~56.0.0",
- "expo": "~56.0.14",
- "expo-constants": "~56.0.20",
- "expo-document-picker": "~56.0.4",
- "expo-file-system": "~56.0.8",
- "expo-font": "~56.0.7",
- "expo-linking": "~56.0.15",
- "expo-notifications": "~56.0.19",
- "expo-router": "~56.2.13",
- "expo-secure-store": "~56.0.4",
- "expo-splash-screen": "~56.0.10",
- "expo-status-bar": "~56.0.4",
- "expo-system-ui": "~56.0.5",
- "expo-updates": "~56.0.21",
- "nativewind": "^4.2.6",
- "react": "19.2.3",
- "react-dom": "^19.2.3",
- "react-native": "0.85.3",
- "react-native-reanimated": "4.3.1",
- "react-native-safe-area-context": "~5.7.0",
- "react-native-screens": "4.25.2",
- "react-native-web": "^0.21.2",
- "react-native-worklets": "^0.8.3"
- },
- "devDependencies": {
- "@types/react": "~19.2.2",
- "tailwindcss": "^3.4.19",
- "typescript": "~6.0.3"
- }
- },
- "node_modules/@adobe/css-tools": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.5.0.tgz",
- "integrity": "sha512-6OzddxPio9UiWTCemp4N8cYLV2ZN1ncRnV1cVGtve7dhPOtRkleRyx32GQCYSwDYgaHU3USMm84tNsvKzRCa1Q==",
- "license": "MIT"
- },
- "node_modules/@alloc/quick-lru": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
- "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
- "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.29.7",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.1.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
- "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
- "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/generator": "^7.29.7",
- "@babel/helper-compilation-targets": "^7.29.7",
- "@babel/helper-module-transforms": "^7.29.7",
- "@babel/helpers": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/template": "^7.29.7",
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7",
- "@jridgewell/remapping": "^2.3.5",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/core/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",
- "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.29.7",
- "@babel/types": "^7.29.7",
- "@jridgewell/gen-mapping": "^0.3.12",
- "@jridgewell/trace-mapping": "^0.3.28",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz",
- "integrity": "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
- "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.29.7",
- "@babel/helper-validator-option": "^7.29.7",
- "browserslist": "^4.24.0",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz",
- "integrity": "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.29.7",
- "@babel/helper-member-expression-to-functions": "^7.29.7",
- "@babel/helper-optimise-call-expression": "^7.29.7",
- "@babel/helper-replace-supers": "^7.29.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
- "@babel/traverse": "^7.29.7",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/@babel/helper-create-regexp-features-plugin": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.29.7.tgz",
- "integrity": "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.29.7",
- "regexpu-core": "^6.3.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/@babel/helper-define-polyfill-provider": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.8.tgz",
- "integrity": "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-compilation-targets": "^7.28.6",
- "@babel/helper-plugin-utils": "^7.28.6",
- "debug": "^4.4.3",
- "lodash.debounce": "^4.0.8",
- "resolve": "^1.22.11"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/@babel/helper-globals": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
- "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz",
- "integrity": "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==",
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
- "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
- "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.29.7",
- "@babel/helper-validator-identifier": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz",
- "integrity": "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-plugin-utils": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz",
- "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-remap-async-to-generator": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.29.7.tgz",
- "integrity": "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.29.7",
- "@babel/helper-wrap-function": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-replace-supers": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz",
- "integrity": "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-member-expression-to-functions": "^7.29.7",
- "@babel/helper-optimise-call-expression": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz",
- "integrity": "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
- "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
- "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
- "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-wrap-function": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.29.7.tgz",
- "integrity": "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw==",
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.29.7",
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
- "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
- "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.7"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/plugin-proposal-decorators": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.29.7.tgz",
- "integrity": "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/plugin-syntax-decorators": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-proposal-export-default-from": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.29.7.tgz",
- "integrity": "sha512-p+G5BNXDcy3bOXplhY4HybQ1GxH3i2Tppmdm/3epyRu2VgJJZuUlZ61MqRTg582Q7ZLBdP7fePYvsumSEkMxcQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-decorators": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.29.7.tgz",
- "integrity": "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-dynamic-import": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
- "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-export-default-from": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.29.7.tgz",
- "integrity": "sha512-foag0BB37ROhdeIX9O8G0jX7hw0UekJc04cHMrYLOnrErsnBKqJGHJ8eDRpoCFZBvEPPygmmtw4qyU97qa4oOw==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-flow": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.29.7.tgz",
- "integrity": "sha512-ajMX6QPcyomotqwpzhkYGxcK2i/us0rs1Qo9QvUpa+Fca0FTmqrzKrctoIYLMxcOhGZldGT/BAVkRGTWBiR8gQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz",
- "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
- "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-optional-chaining": {
- "version": "7.8.3",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
- "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.8.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-syntax-typescript": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz",
- "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.29.7.tgz",
- "integrity": "sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-async-generator-functions": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.7.tgz",
- "integrity": "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/helper-remap-async-to-generator": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-async-to-generator": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.29.7.tgz",
- "integrity": "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/helper-remap-async-to-generator": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.29.7.tgz",
- "integrity": "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-class-properties": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.29.7.tgz",
- "integrity": "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-class-static-block": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.29.7.tgz",
- "integrity": "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.12.0"
- }
- },
- "node_modules/@babel/plugin-transform-classes": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.29.7.tgz",
- "integrity": "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.29.7",
- "@babel/helper-compilation-targets": "^7.29.7",
- "@babel/helper-globals": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/helper-replace-supers": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.29.7.tgz",
- "integrity": "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-export-namespace-from": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.29.7.tgz",
- "integrity": "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-flow-strip-types": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.29.7.tgz",
- "integrity": "sha512-wRHeUjUjCZnMHmiO5bRgjFLcoEh7JyTdByOW11ahhwNa4V0bmeGEaIvt51yq0zQp2yWIpqfxXXPyUP6GFJZHOQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/plugin-syntax-flow": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-for-of": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.29.7.tgz",
- "integrity": "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-logical-assignment-operators": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.29.7.tgz",
- "integrity": "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz",
- "integrity": "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-transforms": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.7.tgz",
- "integrity": "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.29.7.tgz",
- "integrity": "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-object-rest-spread": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.29.7.tgz",
- "integrity": "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-compilation-targets": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/plugin-transform-destructuring": "^7.29.7",
- "@babel/plugin-transform-parameters": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-optional-catch-binding": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.29.7.tgz",
- "integrity": "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-optional-chaining": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.29.7.tgz",
- "integrity": "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-parameters": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.29.7.tgz",
- "integrity": "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-private-methods": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.29.7.tgz",
- "integrity": "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-private-property-in-object": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.29.7.tgz",
- "integrity": "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.29.7",
- "@babel/helper-create-class-features-plugin": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-display-name": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.29.7.tgz",
- "integrity": "sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.29.7.tgz",
- "integrity": "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.29.7",
- "@babel/helper-module-imports": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/plugin-syntax-jsx": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-development": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.29.7.tgz",
- "integrity": "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g==",
- "license": "MIT",
- "dependencies": {
- "@babel/plugin-transform-react-jsx": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz",
- "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz",
- "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-react-pure-annotations": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.29.7.tgz",
- "integrity": "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-regenerator": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.7.tgz",
- "integrity": "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-runtime": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.29.7.tgz",
- "integrity": "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7",
- "babel-plugin-polyfill-corejs2": "^0.4.14",
- "babel-plugin-polyfill-corejs3": "^0.13.0",
- "babel-plugin-polyfill-regenerator": "^0.6.5",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.29.7.tgz",
- "integrity": "sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.29.7.tgz",
- "integrity": "sha512-NCSEJ4sLFU2gqAub45HYh4fus2yQ36rr6ei6vpU7NdoJqCpxvEG8E6eJpscGyXP3VHD2Ny+fSXr04k1hoUrFqA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-typescript": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz",
- "integrity": "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.29.7",
- "@babel/helper-create-class-features-plugin": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.29.7",
- "@babel/plugin-syntax-typescript": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/plugin-transform-unicode-regex": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.29.7.tgz",
- "integrity": "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-create-regexp-features-plugin": "^7.29.7",
- "@babel/helper-plugin-utils": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/preset-typescript": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz",
- "integrity": "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-plugin-utils": "^7.29.7",
- "@babel/helper-validator-option": "^7.29.7",
- "@babel/plugin-syntax-jsx": "^7.29.7",
- "@babel/plugin-transform-modules-commonjs": "^7.29.7",
- "@babel/plugin-transform-typescript": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0-0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
- "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
- "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
- "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/generator": "^7.29.7",
- "@babel/helper-globals": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/template": "^7.29.7",
- "@babel/types": "^7.29.7",
- "debug": "^4.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
- "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.29.7",
- "@babel/helper-validator-identifier": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@expo-google-fonts/material-symbols": {
- "version": "0.4.38",
- "resolved": "https://registry.npmjs.org/@expo-google-fonts/material-symbols/-/material-symbols-0.4.38.tgz",
- "integrity": "sha512-IJkBtN1o8u9BW5fvSii1MyHPQ7Q0HxbWcVBvOrOzgMLpVtZw7R2w94wBTVR7kZwv3w1JNTESMmLA5Sqn1+Z36A==",
- "license": "MIT AND Apache-2.0"
- },
- "node_modules/@expo/code-signing-certificates": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/@expo/code-signing-certificates/-/code-signing-certificates-0.0.6.tgz",
- "integrity": "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==",
- "license": "MIT",
- "dependencies": {
- "node-forge": "^1.3.3"
- }
- },
- "node_modules/@expo/config": {
- "version": "56.0.11",
- "resolved": "https://registry.npmjs.org/@expo/config/-/config-56.0.11.tgz",
- "integrity": "sha512-Rt3U9Rqr6midz/sDeubFN5fefR0KzHpcEEgAUnV98XsLSSTnfzIxoC1blICb7pUUscKc8TtlVyn7/Gita2wnOQ==",
- "license": "MIT",
- "dependencies": {
- "@expo/config-plugins": "~56.0.11",
- "@expo/config-types": "^56.0.7",
- "@expo/json-file": "^10.2.0",
- "@expo/require-utils": "^56.1.4",
- "deepmerge": "^4.3.1",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "resolve-workspace-root": "^2.0.0",
- "semver": "^7.6.0",
- "slugify": "^1.3.4"
- }
- },
- "node_modules/@expo/config-plugins": {
- "version": "56.0.11",
- "resolved": "https://registry.npmjs.org/@expo/config-plugins/-/config-plugins-56.0.11.tgz",
- "integrity": "sha512-be/FpnTUCY0Qt6OH9qFknj9/R7v0OW0Tsxkf/V0CkXuhHjZtL3J8N4kZhhDj5KiHnw7lkbtMvgxGnCHqieF/7g==",
- "license": "MIT",
- "dependencies": {
- "@expo/config-types": "^56.0.7",
- "@expo/json-file": "~10.2.0",
- "@expo/plist": "^0.7.0",
- "@expo/require-utils": "^56.1.4",
- "@expo/sdk-runtime-versions": "^1.0.0",
- "chalk": "^4.1.2",
- "debug": "^4.3.5",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "semver": "^7.5.4",
- "slugify": "^1.6.6",
- "xcode": "^3.0.1",
- "xml2js": "0.6.0"
- }
- },
- "node_modules/@expo/config-types": {
- "version": "56.0.7",
- "resolved": "https://registry.npmjs.org/@expo/config-types/-/config-types-56.0.7.tgz",
- "integrity": "sha512-V7bxawNsNned/yMppAHdisIOxniZXgPKRWpIUiQOQBs45/A5MBd2gfDM4Ecq5gnbilnQUTaI6Zxn6JcW7L3TAA==",
- "license": "MIT"
- },
- "node_modules/@expo/devcert": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@expo/devcert/-/devcert-1.2.1.tgz",
- "integrity": "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==",
- "license": "MIT",
- "dependencies": {
- "@expo/sudo-prompt": "^9.3.1",
- "debug": "^3.1.0"
- }
- },
- "node_modules/@expo/devcert/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.1"
- }
- },
- "node_modules/@expo/devtools": {
- "version": "56.0.2",
- "resolved": "https://registry.npmjs.org/@expo/devtools/-/devtools-56.0.2.tgz",
- "integrity": "sha512-ANl4kPdbe0/HQYWkDEN79S6bQhI+i/ZCnPxuC853pPsB4svhINC7Ku9lmGOKPsUUWWnrHg1spkDGQBZ4sD6JxQ==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.1.2"
- },
- "peerDependencies": {
- "react": "*",
- "react-native": "*"
- },
- "peerDependenciesMeta": {
- "react": {
- "optional": true
- },
- "react-native": {
- "optional": true
- }
- }
- },
- "node_modules/@expo/dom-webview": {
- "version": "56.0.6",
- "resolved": "https://registry.npmjs.org/@expo/dom-webview/-/dom-webview-56.0.6.tgz",
- "integrity": "sha512-DQY3Tj5nrPbpIfEQiD9xbyEFTu25yEORa02Eyzl5rXszDzxDT4VkZDHkyErNQOyE1qjublJHNFhE5bDm4tRfqA==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*",
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/@expo/env": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/@expo/env/-/env-2.3.1.tgz",
- "integrity": "sha512-JvBdZa5OkTd+dGEtt3fLW9OF6RlIp9SNu9VyMSiWPV5szMDTSAYbX8Uj3cRvZcU1zzaRbqnTSsHk2AE8WXHfxQ==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^4.0.0",
- "debug": "^4.3.4",
- "getenv": "^2.0.0"
- },
- "engines": {
- "node": ">=20.12.0"
- }
- },
- "node_modules/@expo/expo-modules-macros-plugin": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/@expo/expo-modules-macros-plugin/-/expo-modules-macros-plugin-0.2.2.tgz",
- "integrity": "sha512-4IMzPDIo/VOXREQjsJtliSfqYVZvfzU2SLFS/9sKMWF848S8CHx+e/E+Vf0TcMvpWCCKX5umyqxb13KJJ+YUzg==",
- "license": "MIT"
- },
- "node_modules/@expo/fingerprint": {
- "version": "0.19.6",
- "resolved": "https://registry.npmjs.org/@expo/fingerprint/-/fingerprint-0.19.6.tgz",
- "integrity": "sha512-qNcb/8aDVi1QeQzS6bSkKU/7vld8WUSHYZnZbOtJx98BroztcN50yoj7PZ3ccuMB7PUHsWNAHJVM94VvDWnPPw==",
- "license": "MIT",
- "dependencies": {
- "@expo/env": "^2.3.1",
- "@expo/spawn-async": "^1.8.0",
- "arg": "^5.0.2",
- "chalk": "^4.1.2",
- "debug": "^4.3.4",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "ignore": "^5.3.1",
- "minimatch": "^10.2.2",
- "resolve-from": "^5.0.0",
- "semver": "^7.6.0"
- },
- "bin": {
- "fingerprint": "bin/cli.js"
- }
- },
- "node_modules/@expo/image-utils": {
- "version": "0.10.2",
- "resolved": "https://registry.npmjs.org/@expo/image-utils/-/image-utils-0.10.2.tgz",
- "integrity": "sha512-qQUGaacqXduoFTCUQAMceIWYzlKU0xX4/BKTyh8TdVj0uHv9/W3MfHOy5yXoOqBVrSccXk++Gm4D/NfS5HnCNA==",
- "license": "MIT",
- "dependencies": {
- "@expo/require-utils": "^56.1.4",
- "@expo/spawn-async": "^1.8.0",
- "chalk": "^4.0.0",
- "getenv": "^2.0.0",
- "jimp-compact": "0.16.1",
- "parse-png": "^2.1.0",
- "semver": "^7.6.0"
- }
- },
- "node_modules/@expo/inline-modules": {
- "version": "0.0.13",
- "resolved": "https://registry.npmjs.org/@expo/inline-modules/-/inline-modules-0.0.13.tgz",
- "integrity": "sha512-26RllWesRmYsAAo70cRcR9DaqXPKJct9MIGxZteS+Tkg25ljOkFeG7fYEsSazZOLpAslKBiilqtZykVYrxSzCw==",
- "license": "MIT",
- "dependencies": {
- "@expo/config-plugins": "~56.0.11"
- }
- },
- "node_modules/@expo/json-file": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-10.2.0.tgz",
- "integrity": "sha512-S6XzKe3R9GQeHiUPXc3xJjOv2VJhOEwFYf7xdC2z2cUqt3kZJ9mSO877sNQloVdnW/SUCtPY3bexlM7nwq+CAQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.20.0",
- "json5": "^2.2.3"
- }
- },
- "node_modules/@expo/local-build-cache-provider": {
- "version": "56.0.9",
- "resolved": "https://registry.npmjs.org/@expo/local-build-cache-provider/-/local-build-cache-provider-56.0.9.tgz",
- "integrity": "sha512-VMJC5ul7dXPfD2OO16ObPi6ym4H8vlnCBUuCM/KeKh0OvLRub35X8OB2uYrFQ+vbWkPemAEOWvk0oOptpPxbzA==",
- "license": "MIT",
- "dependencies": {
- "@expo/config": "~56.0.11",
- "chalk": "^4.1.2"
- }
- },
- "node_modules/@expo/log-box": {
- "version": "56.0.14",
- "resolved": "https://registry.npmjs.org/@expo/log-box/-/log-box-56.0.14.tgz",
- "integrity": "sha512-3Eadcxz0J2NESG2iKe8DnAggsRCWqY0mBLhgQPNzClPVjS6o4NyD0F8kuOvWNngFwpJBC08HhY2o8P1mgSgeJg==",
- "license": "MIT",
- "dependencies": {
- "@expo/dom-webview": "^56.0.6",
- "anser": "^1.4.9",
- "stacktrace-parser": "^0.1.10"
- },
- "peerDependencies": {
- "@expo/dom-webview": "^56.0.6",
- "expo": "*",
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/@expo/metro": {
- "version": "56.0.0",
- "resolved": "https://registry.npmjs.org/@expo/metro/-/metro-56.0.0.tgz",
- "integrity": "sha512-5gIgQHtEpjjvsjKfVtIv23a98LLRV0/y07PDShEwYSytAMlE3FSF8RHXqtHc1sUJL6dn7hnuIBpIbrLXXuVi0A==",
- "license": "MIT",
- "dependencies": {
- "metro": "0.84.4",
- "metro-babel-transformer": "0.84.4",
- "metro-cache": "0.84.4",
- "metro-cache-key": "0.84.4",
- "metro-config": "0.84.4",
- "metro-core": "0.84.4",
- "metro-file-map": "0.84.4",
- "metro-minify-terser": "0.84.4",
- "metro-resolver": "0.84.4",
- "metro-runtime": "0.84.4",
- "metro-source-map": "0.84.4",
- "metro-symbolicate": "0.84.4",
- "metro-transform-plugins": "0.84.4",
- "metro-transform-worker": "0.84.4"
- }
- },
- "node_modules/@expo/metro-config": {
- "version": "56.0.16",
- "resolved": "https://registry.npmjs.org/@expo/metro-config/-/metro-config-56.0.16.tgz",
- "integrity": "sha512-mxPZ23exC6kkEpPYQOteamaiWYER3uDk2IqKys7EJwtIKc3F1207Xtsdko/DNNG04DLwpN/WM2UlNl+Ak8uPRg==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.20.0",
- "@babel/core": "^7.20.0",
- "@babel/generator": "^7.20.5",
- "@expo/config": "~56.0.11",
- "@expo/env": "~2.3.1",
- "@expo/json-file": "~10.2.0",
- "@expo/metro": "~56.0.0",
- "@expo/require-utils": "^56.1.4",
- "@expo/spawn-async": "^1.8.0",
- "@jridgewell/gen-mapping": "^0.3.13",
- "@jridgewell/remapping": "^2.3.5",
- "@jridgewell/sourcemap-codec": "^1.5.5",
- "browserslist": "^4.25.0",
- "chalk": "^4.1.0",
- "debug": "^4.3.2",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "hermes-parser": "^0.33.3",
- "jsc-safe-url": "^0.2.4",
- "lightningcss": "^1.30.1",
- "picomatch": "^4.0.4",
- "postcss": "^8.5.14",
- "resolve-from": "^5.0.0"
- },
- "peerDependencies": {
- "expo": "*"
- },
- "peerDependenciesMeta": {
- "expo": {
- "optional": true
- }
- }
- },
- "node_modules/@expo/metro-config/node_modules/hermes-estree": {
- "version": "0.33.3",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.33.3.tgz",
- "integrity": "sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg==",
- "license": "MIT"
- },
- "node_modules/@expo/metro-config/node_modules/hermes-parser": {
- "version": "0.33.3",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.33.3.tgz",
- "integrity": "sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA==",
- "license": "MIT",
- "dependencies": {
- "hermes-estree": "0.33.3"
- }
- },
- "node_modules/@expo/metro-config/node_modules/picomatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
- "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/@expo/metro-file-map": {
- "version": "56.0.3",
- "resolved": "https://registry.npmjs.org/@expo/metro-file-map/-/metro-file-map-56.0.3.tgz",
- "integrity": "sha512-5OGW3z8LgEYgMJOR7F3pC8llFLkb1fVqwAewbCl6S4Vkha8AFQMwOjT+9Wbka+V4rmpljpGqOnMhF4xZbD961w==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.4",
- "fb-watchman": "^2.0.2",
- "invariant": "^2.2.4",
- "jest-worker": "^29.7.0",
- "micromatch": "^4.0.4",
- "walker": "^1.0.8"
- }
- },
- "node_modules/@expo/metro-runtime": {
- "version": "56.0.16",
- "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-56.0.16.tgz",
- "integrity": "sha512-UsKrBLOCa+kAVHW1S0HdGkM0hkiQXeh3fZIpjcriOmoNg/CVRgdKQhUxUkNoXAoPfT85uW1x2fzNbiYhPQO1SA==",
- "license": "MIT",
- "dependencies": {
- "@expo/log-box": "^56.0.14",
- "anser": "^1.4.9",
- "pretty-format": "^29.7.0",
- "stacktrace-parser": "^0.1.10",
- "whatwg-fetch": "^3.0.0"
- },
- "peerDependencies": {
- "@expo/log-box": "^56.0.14",
- "expo": "*",
- "react": "*",
- "react-dom": "*",
- "react-native": "*"
- },
- "peerDependenciesMeta": {
- "react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@expo/osascript": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/@expo/osascript/-/osascript-2.7.0.tgz",
- "integrity": "sha512-wKIXL8UtbuX4KwavPasIW3CUcgTbYfjzLcgUhjyKUAYDEqMaf6gmU1bqz3ffBPTokmX+G8/vFG1ZuI9etQWukA==",
- "license": "MIT",
- "dependencies": {
- "@expo/spawn-async": "^1.8.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@expo/package-manager": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/@expo/package-manager/-/package-manager-1.13.0.tgz",
- "integrity": "sha512-s3W3eZafJDEyVL7W/jxj2Nz3eONKxSCU604S5xj8ijrVaRz83x0DnZznLf/UXQEI1w+FyibH68nHeQyk767b1A==",
- "license": "MIT",
- "dependencies": {
- "@expo/json-file": "^11.0.0",
- "@expo/spawn-async": "^1.8.0",
- "chalk": "^4.0.0",
- "npm-package-arg": "^11.0.0",
- "ora": "^3.4.0",
- "resolve-workspace-root": "^2.0.0"
- }
- },
- "node_modules/@expo/package-manager/node_modules/@expo/json-file": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/@expo/json-file/-/json-file-11.0.0.tgz",
- "integrity": "sha512-pHJCETqFL5x5BzNV6cEPwjwuECgGmnl0bNmfHIJ6LM1tlh2eVXi5HEdit3zby/JO/B8Otk5cgcqtJXgvvUat3A==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.20.0",
- "json5": "^2.2.3"
- }
- },
- "node_modules/@expo/plist": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/@expo/plist/-/plist-0.7.0.tgz",
- "integrity": "sha512-vrpryU1GoqSIRNqRB2D3IjXDmzNYfiQpEF6AH/xknlD7eiYmEDt3mb26V7cLcedcPG8PY/1xWHdBXVQJfEAh6Q==",
- "license": "MIT",
- "dependencies": {
- "@xmldom/xmldom": "^0.8.8",
- "base64-js": "^1.5.1",
- "xmlbuilder": "^15.1.1"
- }
- },
- "node_modules/@expo/prebuild-config": {
- "version": "56.0.18",
- "resolved": "https://registry.npmjs.org/@expo/prebuild-config/-/prebuild-config-56.0.18.tgz",
- "integrity": "sha512-OnzuPMVUWbj8x5XeYkzxW4X36AUGkp1Kif2h9FrcyXNT67NoWOgxeTB8udQBBA1uodR+wcf8Hxz8H5TgIpp4ig==",
- "license": "MIT",
- "dependencies": {
- "@expo/config": "~56.0.11",
- "@expo/config-plugins": "~56.0.11",
- "@expo/config-types": "^56.0.7",
- "@expo/image-utils": "^0.10.2",
- "@expo/json-file": "^10.2.0",
- "@react-native/normalize-colors": "0.85.3",
- "debug": "^4.3.1",
- "expo-modules-autolinking": "~56.0.18",
- "resolve-from": "^5.0.0",
- "semver": "^7.6.0"
- }
- },
- "node_modules/@expo/require-utils": {
- "version": "56.1.4",
- "resolved": "https://registry.npmjs.org/@expo/require-utils/-/require-utils-56.1.4.tgz",
- "integrity": "sha512-IX7XXg9obnrH3ni0TClBbVKgqk0nT0bjTEPTBtbD+WgIeZ0hpcgwxMJH3j5uBsUqEAq1jqUAkJWrPcg7ZRSV7g==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.20.0",
- "@babel/core": "^7.25.2",
- "@babel/plugin-transform-modules-commonjs": "^7.24.8"
- },
- "peerDependencies": {
- "typescript": "^5.0.0 || ^5.0.0-0 || ^6.0.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@expo/schema-utils": {
- "version": "56.0.2",
- "resolved": "https://registry.npmjs.org/@expo/schema-utils/-/schema-utils-56.0.2.tgz",
- "integrity": "sha512-WcOH1E6rwxRqNwBzPOVhd5GBbMlS04+5n+ZMdhdwKOg/Kt3suV+F8F6An+z8mUJ8eSuMM3HD9Sj09t7vc/Xjkw==",
- "license": "MIT"
- },
- "node_modules/@expo/sdk-runtime-versions": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz",
- "integrity": "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==",
- "license": "MIT"
- },
- "node_modules/@expo/spawn-async": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/@expo/spawn-async/-/spawn-async-1.8.0.tgz",
- "integrity": "sha512-eb9xxd/LbuEGSdua4NumCu/McVB9EM+F/JxB9pWgnERw4HQ9XyTNH1KapG6oqLWR8TuRK2LQfzJlmNi94CVobw==",
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.6"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@expo/sudo-prompt": {
- "version": "9.3.2",
- "resolved": "https://registry.npmjs.org/@expo/sudo-prompt/-/sudo-prompt-9.3.2.tgz",
- "integrity": "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw==",
- "license": "MIT"
- },
- "node_modules/@expo/ui": {
- "version": "56.0.20",
- "resolved": "https://registry.npmjs.org/@expo/ui/-/ui-56.0.20.tgz",
- "integrity": "sha512-GdQ0tE4YhI/Ij0Nl/NHoul0GC0N4riRN0d7gE+1mSOLykVtHsR19eD3MUWr6PwQZCC45uUxviSJ9c3hOztswPw==",
- "license": "MIT",
- "dependencies": {
- "sf-symbols-typescript": "^2.1.0",
- "vaul": "^1.1.2"
- },
- "peerDependencies": {
- "@babel/core": "*",
- "expo": "*",
- "react": "*",
- "react-dom": "*",
- "react-native": "*",
- "react-native-worklets": "*"
- },
- "peerDependenciesMeta": {
- "@babel/core": {
- "optional": true
- },
- "react-dom": {
- "optional": true
- },
- "react-native-worklets": {
- "optional": true
- }
- }
- },
- "node_modules/@expo/vector-icons": {
- "version": "15.1.1",
- "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-15.1.1.tgz",
- "integrity": "sha512-Iu2VkcoI5vygbtYngm7jb4ifxElNVXQYdDrYkT7UCEIiKLeWnQY0wf2ZhHZ+Wro6Sc5TaumpKUOqDRpLi5rkvw==",
- "license": "MIT",
- "peerDependencies": {
- "expo-font": ">=14.0.4",
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/@expo/xcpretty": {
- "version": "4.4.4",
- "resolved": "https://registry.npmjs.org/@expo/xcpretty/-/xcpretty-4.4.4.tgz",
- "integrity": "sha512-4aQzz9vgxcNXFfo/iyNgDDYfsU5XGKKxWxZopw0cVotHiW+U8IJbIxMaxsINs6bHhtkG3StKNPcOrn3eBuxKPw==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "@babel/code-frame": "^7.20.0",
- "chalk": "^4.1.0",
- "js-yaml": "^4.1.0"
- },
- "bin": {
- "excpretty": "build/cli.js"
- }
- },
- "node_modules/@isaacs/ttlcache": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz",
- "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jest/types": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
- "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
- "@types/node": "*",
- "@types/yargs": "^17.0.8",
- "chalk": "^4.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/remapping": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
- "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/source-map": {
- "version": "0.3.11",
- "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
- "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@radix-ui/primitive": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.4.tgz",
- "integrity": "sha512-7AdCK9PQyiljKoBDbN8OuctCbd/esdwZPQ8RtOE3SsyQtUpiPb+ND75q0jEhC1m1ecBI0MFNeLJvwIh9iKHRcQ==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/react-collection": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.11.tgz",
- "integrity": "sha512-djW9+zeg137KQdlPtmE8xnaD+K2rcXXMWFrSg0hsmYZ6HRbdTA7tDHFgpaW9+huWVEu0RCabL+985T4TA0BE7g==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.3",
- "@radix-ui/react-context": "1.1.4",
- "@radix-ui/react-primitive": "2.1.7",
- "@radix-ui/react-slot": "1.3.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.3.tgz",
- "integrity": "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-context": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.4.tgz",
- "integrity": "sha512-QwH4PO5urrbO+FaGd5Aglg+YJgWTyyuZ3g/6mKvsqraLkglDdckw9JafgL5McL5VEJ6EPNduPaT3ZE9BttDAqg==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-dialog": {
- "version": "1.1.18",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.18.tgz",
- "integrity": "sha512-apa28mldjMgORmE6g/w3sCcA0Y9UAVeeDVoozN4i7kOw12mLl9RBchfzK3Nn6qxOWjrZhK1Lfy7f07kyzxtnBw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.4",
- "@radix-ui/react-compose-refs": "1.1.3",
- "@radix-ui/react-context": "1.1.4",
- "@radix-ui/react-dismissable-layer": "1.1.14",
- "@radix-ui/react-focus-guards": "1.1.4",
- "@radix-ui/react-focus-scope": "1.1.11",
- "@radix-ui/react-id": "1.1.2",
- "@radix-ui/react-portal": "1.1.13",
- "@radix-ui/react-presence": "1.1.6",
- "@radix-ui/react-primitive": "2.1.7",
- "@radix-ui/react-slot": "1.3.0",
- "@radix-ui/react-use-controllable-state": "1.2.3",
- "aria-hidden": "^1.2.4",
- "react-remove-scroll": "^2.7.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-direction": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.2.tgz",
- "integrity": "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-dismissable-layer": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.14.tgz",
- "integrity": "sha512-4lUhWTWAjbDIqFrAPWJ3WqBOpO5YchVZ88X3nh6H9Lu5AFi5nCUeTPj3D8FSDmabmFeRe9ME0BDA4MwKTha5GQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.4",
- "@radix-ui/react-compose-refs": "1.1.3",
- "@radix-ui/react-primitive": "2.1.7",
- "@radix-ui/react-use-callback-ref": "1.1.2",
- "@radix-ui/react-use-effect-event": "0.0.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-focus-guards": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.4.tgz",
- "integrity": "sha512-cot/aB/mOm0IYVYTTmQcEEK1M48lZWi8FlYe5nDPQQ8NYZUlXEFgncJ9p2Kzer3RKSrY7cTTpEMLZKNo9QoP5Q==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-focus-scope": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.11.tgz",
- "integrity": "sha512-Mn88Vg2whaRocGJNOH+DKFqYm6ySFPQaiwHNxZPyjn99B52KAEJWWY9NP83+nWdk2HM3rdov+STu9AG471Rt9w==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.3",
- "@radix-ui/react-primitive": "2.1.7",
- "@radix-ui/react-use-callback-ref": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-id": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.2.tgz",
- "integrity": "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-portal": {
- "version": "1.1.13",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.13.tgz",
- "integrity": "sha512-z3oXfmaHLJTF1wktbjgD6cn9jiEbq3WSondB10LIuIt2m2Ym4iJlrW04/euMwENDdWDdE7z+OuY7Qyp1YpRSwA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-primitive": "2.1.7",
- "@radix-ui/react-use-layout-effect": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-presence": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.6.tgz",
- "integrity": "sha512-zdTk4PlUO0E18HnZ3wYbW0KkJJxWCdiNYp6g6X1PtONFhxVkg01vliTJAmwIszU6mHiyBOoW9P0rAugl5/hULQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-primitive": {
- "version": "2.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.7.tgz",
- "integrity": "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-slot": "1.3.0"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-roving-focus": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.14.tgz",
- "integrity": "sha512-8Qcnx9447tx/aCBgw6Jenfqg4Skq+vqab9mCBmuGNipIS5YXvL275wbKEu7+ICYHIlAPgCduUMJH1XOYewKF6Q==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.4",
- "@radix-ui/react-collection": "1.1.11",
- "@radix-ui/react-compose-refs": "1.1.3",
- "@radix-ui/react-context": "1.1.4",
- "@radix-ui/react-direction": "1.1.2",
- "@radix-ui/react-id": "1.1.2",
- "@radix-ui/react-primitive": "2.1.7",
- "@radix-ui/react-use-callback-ref": "1.1.2",
- "@radix-ui/react-use-controllable-state": "1.2.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-slot": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.0.tgz",
- "integrity": "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-compose-refs": "1.1.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-tabs": {
- "version": "1.1.16",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.16.tgz",
- "integrity": "sha512-v3Ab2l7z6U7tRB4xA0IyKdq0OsqaO1o9ZjsIEoKKnSZ/l96mZz8aCTX0NCXw+YVHJXr8Km4d+Mn6/Q8YjXa+gw==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.4",
- "@radix-ui/react-context": "1.1.4",
- "@radix-ui/react-direction": "1.1.2",
- "@radix-ui/react-id": "1.1.2",
- "@radix-ui/react-presence": "1.1.6",
- "@radix-ui/react-primitive": "2.1.7",
- "@radix-ui/react-roving-focus": "1.1.14",
- "@radix-ui/react-use-controllable-state": "1.2.3"
- },
- "peerDependencies": {
- "@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "@types/react-dom": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-callback-ref": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.2.tgz",
- "integrity": "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-controllable-state": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.3.tgz",
- "integrity": "sha512-PLzC90MS+ReootmjC597dvopoelpZ8Q61HJkDXZSExitIq7PL55vHNnesAHwguHK0aPfBnpdNzQtv1uliaqQrA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-effect-event": "0.0.3",
- "@radix-ui/react-use-layout-effect": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-effect-event": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.3.tgz",
- "integrity": "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.2"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@radix-ui/react-use-layout-effect": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.2.tgz",
- "integrity": "sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==",
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@react-native-masked-view/masked-view": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@react-native-masked-view/masked-view/-/masked-view-0.3.2.tgz",
- "integrity": "sha512-XwuQoW7/GEgWRMovOQtX3A4PrXhyaZm0lVUiY8qJDvdngjLms9Cpdck6SmGAUNqQwcj2EadHC1HwL0bEyoa/SQ==",
- "license": "MIT",
- "peerDependencies": {
- "react": ">=16",
- "react-native": ">=0.57"
- }
- },
- "node_modules/@react-native/assets-registry": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.85.3.tgz",
- "integrity": "sha512-u9ZiYP23vA2IFtdFQFmetzSmk6SM0xgKIoiOsr1hXNHjHaLhOm+/Ph1ud57wX6+Dbwdzx8coJgnzSKL3W21PCg==",
- "license": "MIT",
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/@react-native/babel-plugin-codegen": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.85.3.tgz",
- "integrity": "sha512-Wc94zGfeFG8Njf9SHMPfYZP04kjigkOps6F1TYTvd7ZVXuGxqseCDgxc50LWcOhOCLypI9n3oVVqz81C3p44ZA==",
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.29.0",
- "@react-native/codegen": "0.85.3"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/@react-native/babel-preset": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/babel-preset/-/babel-preset-0.85.3.tgz",
- "integrity": "sha512-fD7fxEhkJB/aF57tWoXjaAWpklfrExYZS3k6aXPP3BQ77DZY7gvf/b7dbirwjID6NVnP1JDRJyTuPBGr0K/vlw==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.25.2",
- "@babel/plugin-proposal-export-default-from": "^7.24.7",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
- "@babel/plugin-syntax-export-default-from": "^7.24.7",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-transform-async-generator-functions": "^7.25.4",
- "@babel/plugin-transform-async-to-generator": "^7.24.7",
- "@babel/plugin-transform-block-scoping": "^7.25.0",
- "@babel/plugin-transform-class-properties": "^7.25.4",
- "@babel/plugin-transform-classes": "^7.25.4",
- "@babel/plugin-transform-destructuring": "^7.24.8",
- "@babel/plugin-transform-flow-strip-types": "^7.25.2",
- "@babel/plugin-transform-for-of": "^7.24.7",
- "@babel/plugin-transform-modules-commonjs": "^7.24.8",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
- "@babel/plugin-transform-optional-catch-binding": "^7.24.7",
- "@babel/plugin-transform-optional-chaining": "^7.24.8",
- "@babel/plugin-transform-private-methods": "^7.24.7",
- "@babel/plugin-transform-private-property-in-object": "^7.24.7",
- "@babel/plugin-transform-react-display-name": "^7.24.7",
- "@babel/plugin-transform-react-jsx": "^7.25.2",
- "@babel/plugin-transform-react-jsx-self": "^7.24.7",
- "@babel/plugin-transform-react-jsx-source": "^7.24.7",
- "@babel/plugin-transform-regenerator": "^7.24.7",
- "@babel/plugin-transform-runtime": "^7.24.7",
- "@babel/plugin-transform-typescript": "^7.25.2",
- "@babel/plugin-transform-unicode-regex": "^7.24.7",
- "@react-native/babel-plugin-codegen": "0.85.3",
- "babel-plugin-syntax-hermes-parser": "0.33.3",
- "babel-plugin-transform-flow-enums": "^0.0.2",
- "react-refresh": "^0.14.0"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- },
- "peerDependencies": {
- "@babel/core": "*"
- }
- },
- "node_modules/@react-native/codegen": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/codegen/-/codegen-0.85.3.tgz",
- "integrity": "sha512-/JkS1lGLyzBWP1FbgDwaqEf7qShIC6pUC1M0a/YMAd/v4iqR24MRkQWe7jkYvcBQ2LpEhs5NGE9InhxSv21zCA==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.25.2",
- "@babel/parser": "^7.29.0",
- "hermes-parser": "0.33.3",
- "invariant": "^2.2.4",
- "nullthrows": "^1.1.1",
- "tinyglobby": "^0.2.15",
- "yargs": "^17.6.2"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- },
- "peerDependencies": {
- "@babel/core": "*"
- }
- },
- "node_modules/@react-native/codegen/node_modules/hermes-estree": {
- "version": "0.33.3",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.33.3.tgz",
- "integrity": "sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg==",
- "license": "MIT"
- },
- "node_modules/@react-native/codegen/node_modules/hermes-parser": {
- "version": "0.33.3",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.33.3.tgz",
- "integrity": "sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA==",
- "license": "MIT",
- "dependencies": {
- "hermes-estree": "0.33.3"
- }
- },
- "node_modules/@react-native/community-cli-plugin": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/community-cli-plugin/-/community-cli-plugin-0.85.3.tgz",
- "integrity": "sha512-fs85dmbIqNmtzEixDb0g+q6R3Vt4H9eAt8/inIZdDKfjN76+sUJA2r1nxODQ76bU23MrIbz8sI7KFBPaWk/zQw==",
- "license": "MIT",
- "dependencies": {
- "@react-native/dev-middleware": "0.85.3",
- "debug": "^4.4.0",
- "invariant": "^2.2.4",
- "metro": "^0.84.3",
- "metro-config": "^0.84.3",
- "metro-core": "^0.84.3",
- "semver": "^7.1.3"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- },
- "peerDependencies": {
- "@react-native-community/cli": "*",
- "@react-native/metro-config": "0.85.3"
- },
- "peerDependenciesMeta": {
- "@react-native-community/cli": {
- "optional": true
- },
- "@react-native/metro-config": {
- "optional": true
- }
- }
- },
- "node_modules/@react-native/debugger-frontend": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/debugger-frontend/-/debugger-frontend-0.85.3.tgz",
- "integrity": "sha512-uAu7rM5o/Np1zgp6fi5zM1sP1aB8DcS7DdOLcj/TkSutOAjkMqqd2lWt1/+3S7qXexRHVK5XcP+o3VXo4L/V0A==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/@react-native/debugger-shell": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/debugger-shell/-/debugger-shell-0.85.3.tgz",
- "integrity": "sha512-/jRAaT9boiCttIcEwS02WPwYkUihqsjSaK/TMtHz05vT6uMgac9PaQt5kzBQLIABv5aEIa5gtrMmKVz49MjkjQ==",
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.6",
- "debug": "^4.4.0",
- "fb-dotslash": "0.5.8"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/@react-native/dev-middleware": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/dev-middleware/-/dev-middleware-0.85.3.tgz",
- "integrity": "sha512-JYzBiT4A8w+KQt+dOD5v+ti+tDrGoPnsSTuApq3Ls4RB5sfWbDlYMyz3dbc8qBIHz9tv0sQ5+eOu6Xwqzr5AQA==",
- "license": "MIT",
- "dependencies": {
- "@isaacs/ttlcache": "^1.4.1",
- "@react-native/debugger-frontend": "0.85.3",
- "@react-native/debugger-shell": "0.85.3",
- "chrome-launcher": "^0.15.2",
- "chromium-edge-launcher": "^0.3.0",
- "connect": "^3.6.5",
- "debug": "^4.4.0",
- "invariant": "^2.2.4",
- "nullthrows": "^1.1.1",
- "open": "^7.0.3",
- "serve-static": "^1.16.2",
- "ws": "^7.5.10"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/@react-native/gradle-plugin": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/gradle-plugin/-/gradle-plugin-0.85.3.tgz",
- "integrity": "sha512-39dY2j50Q1pntejzwt3XL7vwXtrj8jcIfHq6E+gyu3jzYxZJVvMkMutQ39vSg6zinIQOX36oQDhidXUbCXzgoA==",
- "license": "MIT",
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/@react-native/js-polyfills": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/js-polyfills/-/js-polyfills-0.85.3.tgz",
- "integrity": "sha512-U2+aMshIXf1uFn77tpBb/xhHWB9vkVrMpt7kkucAugF8hJKYTDGB587X7WwelHduK2KBfhl4giSv0rzZGoef9A==",
- "license": "MIT",
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/@react-native/metro-babel-transformer": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.85.3.tgz",
- "integrity": "sha512-omuKq+r7jM4XvCMIlNMPP7Up3SyB8o5EAdZtF7YXniKyq7UOMBqhYHFqgsdOXr0lT+3ADf7VCJG3sb82jlBrrQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.25.2",
- "@react-native/babel-preset": "0.85.3",
- "hermes-parser": "0.33.3",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- },
- "peerDependencies": {
- "@babel/core": "*"
- }
- },
- "node_modules/@react-native/metro-babel-transformer/node_modules/hermes-estree": {
- "version": "0.33.3",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.33.3.tgz",
- "integrity": "sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg==",
- "license": "MIT"
- },
- "node_modules/@react-native/metro-babel-transformer/node_modules/hermes-parser": {
- "version": "0.33.3",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.33.3.tgz",
- "integrity": "sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA==",
- "license": "MIT",
- "dependencies": {
- "hermes-estree": "0.33.3"
- }
- },
- "node_modules/@react-native/metro-config": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/metro-config/-/metro-config-0.85.3.tgz",
- "integrity": "sha512-sVo6HepUmCcpdfozEf91lA0FjpLNNZYu/Zi9FiYiAQTK8pzATXDVTqhvdxpFrQn435p5eUTSbllvbH/KN+bnyA==",
- "license": "MIT",
- "dependencies": {
- "@react-native/js-polyfills": "0.85.3",
- "@react-native/metro-babel-transformer": "0.85.3",
- "metro-config": "^0.84.3",
- "metro-runtime": "^0.84.3"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/@react-native/normalize-colors": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.85.3.tgz",
- "integrity": "sha512-hj0PScZEhIbcOvQV5yMKX3ha4XEIOy/SVE1Rrpp0beW0dpNLOgSC7KDxGewmDnIHK9YdQUXGY9eMEfShUMIaZw==",
- "license": "MIT"
- },
- "node_modules/@react-native/virtualized-lists": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.85.3.tgz",
- "integrity": "sha512-dsCjI//OIPEUJMyNHp4l7zNLVjCx7bcaRUceOCkU+IB17hkbtbGWvi7HjGFSzy7FJGmS/MOlcfpb72xXiy1Oig==",
- "license": "MIT",
- "dependencies": {
- "invariant": "^2.2.4",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- },
- "peerDependencies": {
- "@types/react": "^19.2.0",
- "react": "*",
- "react-native": "0.85.3"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/@sinclair/typebox": {
- "version": "0.27.10",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz",
- "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==",
- "license": "MIT"
- },
- "node_modules/@testing-library/dom": {
- "version": "10.4.1",
- "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz",
- "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.10.4",
- "@babel/runtime": "^7.12.5",
- "@types/aria-query": "^5.0.1",
- "aria-query": "5.3.0",
- "dom-accessibility-api": "^0.5.9",
- "lz-string": "^1.5.0",
- "picocolors": "1.1.1",
- "pretty-format": "^27.0.2"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@testing-library/dom/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@testing-library/dom/node_modules/pretty-format": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
- "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1",
- "ansi-styles": "^5.0.0",
- "react-is": "^17.0.1"
- },
- "engines": {
- "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
- }
- },
- "node_modules/@testing-library/dom/node_modules/react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
- "license": "MIT"
- },
- "node_modules/@testing-library/jest-dom": {
- "version": "6.9.1",
- "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz",
- "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==",
- "license": "MIT",
- "dependencies": {
- "@adobe/css-tools": "^4.4.0",
- "aria-query": "^5.0.0",
- "css.escape": "^1.5.1",
- "dom-accessibility-api": "^0.6.3",
- "picocolors": "^1.1.1",
- "redent": "^3.0.0"
- },
- "engines": {
- "node": ">=14",
- "npm": ">=6",
- "yarn": ">=1"
- }
- },
- "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
- "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
- "license": "MIT"
- },
- "node_modules/@testing-library/user-event": {
- "version": "14.6.1",
- "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
- "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
- "license": "MIT",
- "engines": {
- "node": ">=12",
- "npm": ">=6"
- },
- "peerDependencies": {
- "@testing-library/dom": ">=7.21.4"
- }
- },
- "node_modules/@types/aria-query": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
- "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
- "license": "MIT"
- },
- "node_modules/@types/istanbul-lib-coverage": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
- "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
- "license": "MIT"
- },
- "node_modules/@types/istanbul-lib-report": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
- "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
- "license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-coverage": "*"
- }
- },
- "node_modules/@types/istanbul-reports": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
- "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
- "license": "MIT",
- "dependencies": {
- "@types/istanbul-lib-report": "*"
- }
- },
- "node_modules/@types/node": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-26.0.0.tgz",
- "integrity": "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==",
- "license": "MIT",
- "dependencies": {
- "undici-types": "~8.3.0"
- }
- },
- "node_modules/@types/react": {
- "version": "19.2.17",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
- "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "csstype": "^3.2.2"
- }
- },
- "node_modules/@types/react-test-renderer": {
- "version": "19.1.0",
- "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-19.1.0.tgz",
- "integrity": "sha512-XD0WZrHqjNrxA/MaR9O22w/RNidWR9YZmBdRGI7wcnWGrv/3dA8wKCJ8m63Sn+tLJhcjmuhOi629N66W6kgWzQ==",
- "license": "MIT",
- "dependencies": {
- "@types/react": "*"
- }
- },
- "node_modules/@types/yargs": {
- "version": "17.0.35",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
- "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==",
- "license": "MIT",
- "dependencies": {
- "@types/yargs-parser": "*"
- }
- },
- "node_modules/@types/yargs-parser": {
- "version": "21.0.3",
- "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
- "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
- "license": "MIT"
- },
- "node_modules/@ungap/structured-clone": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.2.tgz",
- "integrity": "sha512-5jsZFwgR5rTdKwidH9Qmat75RKwqfpKlWWB1frDkljN127mwqBu8K0PYo7/hFpF03IEJpfVPpCQDY/eDx3iHvA==",
- "license": "ISC"
- },
- "node_modules/@xmldom/xmldom": {
- "version": "0.8.13",
- "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz",
- "integrity": "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==",
- "license": "MIT",
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/abort-controller": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
- "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
- "license": "MIT",
- "dependencies": {
- "event-target-shim": "^5.0.0"
- },
- "engines": {
- "node": ">=6.5"
- }
- },
- "node_modules/accepts": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
- "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
- "license": "MIT",
- "dependencies": {
- "mime-types": "^3.0.0",
- "negotiator": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/acorn": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
- "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/agent-base": {
- "version": "7.1.4",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
- "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/agent-cli-detector": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/agent-cli-detector/-/agent-cli-detector-0.1.2.tgz",
- "integrity": "sha512-qdZ/9JFORtTKJNhT/IczMeEfEUbUU0K5umYeiIQHX+AjHs+Y9SXVzSgaYlpZeyNMrvuh2HpZiOTpvS57iPfBkQ==",
- "license": "MIT",
- "bin": {
- "agent-cli-detector": "dist/cli.js"
- },
- "engines": {
- "node": ">=18.18"
- }
- },
- "node_modules/anser": {
- "version": "1.4.10",
- "resolved": "https://registry.npmjs.org/anser/-/anser-1.4.10.tgz",
- "integrity": "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww==",
- "license": "MIT"
- },
- "node_modules/ansi-escapes": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
- "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
- "license": "MIT",
- "dependencies": {
- "type-fest": "^0.21.3"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ansi-escapes/node_modules/type-fest": {
- "version": "0.21.3",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
- "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/any-promise": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
- "license": "MIT"
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "license": "ISC",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/arg": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
- "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
- "license": "MIT"
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "license": "Python-2.0"
- },
- "node_modules/aria-hidden": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz",
- "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/aria-query": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
- "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
- "license": "Apache-2.0",
- "dependencies": {
- "dequal": "^2.0.3"
- }
- },
- "node_modules/array-timsort": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
- "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==",
- "license": "MIT"
- },
- "node_modules/asap": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
- "license": "MIT"
- },
- "node_modules/babel-plugin-polyfill-corejs2": {
- "version": "0.4.17",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.17.tgz",
- "integrity": "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==",
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.28.6",
- "@babel/helper-define-polyfill-provider": "^0.6.8",
- "semver": "^6.3.1"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/babel-plugin-polyfill-corejs3": {
- "version": "0.13.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz",
- "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.5",
- "core-js-compat": "^3.43.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/babel-plugin-polyfill-regenerator": {
- "version": "0.6.8",
- "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.8.tgz",
- "integrity": "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-define-polyfill-provider": "^0.6.8"
- },
- "peerDependencies": {
- "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
- }
- },
- "node_modules/babel-plugin-react-compiler": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz",
- "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.26.0"
- }
- },
- "node_modules/babel-plugin-react-native-web": {
- "version": "0.21.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-react-native-web/-/babel-plugin-react-native-web-0.21.2.tgz",
- "integrity": "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA==",
- "license": "MIT"
- },
- "node_modules/babel-plugin-syntax-hermes-parser": {
- "version": "0.33.3",
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-hermes-parser/-/babel-plugin-syntax-hermes-parser-0.33.3.tgz",
- "integrity": "sha512-/Z9xYdaJ1lC0pT9do6TqCqhOSLfZ5Ot8D5za1p+feEfWYupCOfGbhhEXN9r2ZgJtDNUNRw/Z+T2CvAGKBqtqWA==",
- "license": "MIT",
- "dependencies": {
- "hermes-parser": "0.33.3"
- }
- },
- "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-estree": {
- "version": "0.33.3",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.33.3.tgz",
- "integrity": "sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg==",
- "license": "MIT"
- },
- "node_modules/babel-plugin-syntax-hermes-parser/node_modules/hermes-parser": {
- "version": "0.33.3",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.33.3.tgz",
- "integrity": "sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA==",
- "license": "MIT",
- "dependencies": {
- "hermes-estree": "0.33.3"
- }
- },
- "node_modules/babel-plugin-transform-flow-enums": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz",
- "integrity": "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/plugin-syntax-flow": "^7.12.1"
- }
- },
- "node_modules/babel-preset-expo": {
- "version": "56.0.16",
- "resolved": "https://registry.npmjs.org/babel-preset-expo/-/babel-preset-expo-56.0.16.tgz",
- "integrity": "sha512-HkTZP+nWVGTibw+JCiy2yCXPPXhFUbqG6xdZRSnnAv+tZUdsCdvGnfEl14shS1mZWIY0VSf/rWpkzIEsZKyqhQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/generator": "^7.20.5",
- "@babel/helper-module-imports": "^7.25.9",
- "@babel/plugin-proposal-decorators": "^7.12.9",
- "@babel/plugin-proposal-export-default-from": "^7.24.7",
- "@babel/plugin-syntax-dynamic-import": "^7.8.3",
- "@babel/plugin-syntax-export-default-from": "^7.24.7",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-transform-async-generator-functions": "^7.25.4",
- "@babel/plugin-transform-async-to-generator": "^7.24.7",
- "@babel/plugin-transform-block-scoping": "^7.25.0",
- "@babel/plugin-transform-class-properties": "^7.25.4",
- "@babel/plugin-transform-class-static-block": "^7.27.1",
- "@babel/plugin-transform-classes": "^7.25.4",
- "@babel/plugin-transform-destructuring": "^7.24.8",
- "@babel/plugin-transform-export-namespace-from": "^7.25.9",
- "@babel/plugin-transform-flow-strip-types": "^7.25.2",
- "@babel/plugin-transform-for-of": "^7.24.7",
- "@babel/plugin-transform-logical-assignment-operators": "^7.24.7",
- "@babel/plugin-transform-modules-commonjs": "^7.24.8",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7",
- "@babel/plugin-transform-object-rest-spread": "^7.24.7",
- "@babel/plugin-transform-optional-catch-binding": "^7.24.7",
- "@babel/plugin-transform-optional-chaining": "^7.24.8",
- "@babel/plugin-transform-parameters": "^7.24.7",
- "@babel/plugin-transform-private-methods": "^7.24.7",
- "@babel/plugin-transform-private-property-in-object": "^7.24.7",
- "@babel/plugin-transform-react-display-name": "^7.24.7",
- "@babel/plugin-transform-react-jsx": "^7.28.6",
- "@babel/plugin-transform-react-jsx-development": "^7.27.1",
- "@babel/plugin-transform-react-pure-annotations": "^7.27.1",
- "@babel/plugin-transform-runtime": "^7.24.7",
- "@babel/plugin-transform-typescript": "^7.25.2",
- "@babel/plugin-transform-unicode-regex": "^7.24.7",
- "@babel/preset-typescript": "^7.23.0",
- "@react-native/babel-plugin-codegen": "0.85.3",
- "babel-plugin-react-compiler": "^1.0.0",
- "babel-plugin-react-native-web": "~0.21.0",
- "babel-plugin-syntax-hermes-parser": "^0.33.3",
- "babel-plugin-transform-flow-enums": "^0.0.2",
- "debug": "^4.3.4"
- },
- "peerDependencies": {
- "@babel/runtime": "^7.20.0",
- "expo": "*",
- "expo-widgets": "^56.0.20",
- "react-refresh": ">=0.14.0 <1.0.0"
- },
- "peerDependenciesMeta": {
- "@babel/runtime": {
- "optional": true
- },
- "expo": {
- "optional": true
- },
- "expo-widgets": {
- "optional": true
- }
- }
- },
- "node_modules/badgin": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/badgin/-/badgin-1.2.3.tgz",
- "integrity": "sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw==",
- "license": "MIT"
- },
- "node_modules/balanced-match": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
- "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
- "license": "MIT",
- "engines": {
- "node": "18 || 20 || >=22"
- }
- },
- "node_modules/base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/baseline-browser-mapping": {
- "version": "2.10.38",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.38.tgz",
- "integrity": "sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==",
- "license": "Apache-2.0",
- "bin": {
- "baseline-browser-mapping": "dist/cli.cjs"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/big-integer": {
- "version": "1.6.52",
- "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
- "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==",
- "license": "Unlicense",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/bplist-creator": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.1.0.tgz",
- "integrity": "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==",
- "license": "MIT",
- "dependencies": {
- "stream-buffers": "2.2.x"
- }
- },
- "node_modules/bplist-parser": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.2.tgz",
- "integrity": "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==",
- "license": "MIT",
- "dependencies": {
- "big-integer": "1.6.x"
- },
- "engines": {
- "node": ">= 5.10.0"
- }
- },
- "node_modules/brace-expansion": {
- "version": "5.0.7",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz",
- "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^4.0.2"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/browserslist": {
- "version": "4.28.4",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz",
- "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "baseline-browser-mapping": "^2.10.38",
- "caniuse-lite": "^1.0.30001799",
- "electron-to-chromium": "^1.5.376",
- "node-releases": "^2.0.48",
- "update-browserslist-db": "^1.2.3"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/bser": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
- "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "node-int64": "^0.4.0"
- }
- },
- "node_modules/buffer-from": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
- "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
- "license": "MIT"
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/camelcase-css": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
- "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001799",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz",
- "integrity": "sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
- "node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "license": "MIT",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/chokidar/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/chrome-launcher": {
- "version": "0.15.2",
- "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.15.2.tgz",
- "integrity": "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "@types/node": "*",
- "escape-string-regexp": "^4.0.0",
- "is-wsl": "^2.2.0",
- "lighthouse-logger": "^1.0.0"
- },
- "bin": {
- "print-chrome-path": "bin/print-chrome-path.js"
- },
- "engines": {
- "node": ">=12.13.0"
- }
- },
- "node_modules/chromium-edge-launcher": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/chromium-edge-launcher/-/chromium-edge-launcher-0.3.0.tgz",
- "integrity": "sha512-p03azHlGjtyRvFEee3cyvtsRYdniSkwjkzmM/KmVnqT5d7QkkwpJBhis/zCLMYdQMVJ5tt140TBNqqrZPaWeFA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@types/node": "*",
- "escape-string-regexp": "^4.0.0",
- "is-wsl": "^2.2.0",
- "lighthouse-logger": "^1.0.0",
- "mkdirp": "^1.0.4"
- }
- },
- "node_modules/ci-info": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
- "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
- "license": "MIT"
- },
- "node_modules/cli-cursor": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
- "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==",
- "license": "MIT",
- "dependencies": {
- "restore-cursor": "^2.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/cli-spinners": {
- "version": "2.9.2",
- "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
- "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/client-only": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
- "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
- "license": "MIT"
- },
- "node_modules/cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "license": "ISC",
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/clone": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
- "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.8"
- }
- },
- "node_modules/color": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
- "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1",
- "color-string": "^1.9.0"
- },
- "engines": {
- "node": ">=12.5.0"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "license": "MIT"
- },
- "node_modules/color-string": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
- "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "^1.0.0",
- "simple-swizzle": "^0.2.2"
- }
- },
- "node_modules/commander": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
- "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
- "license": "MIT",
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/comment-json": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.6.2.tgz",
- "integrity": "sha512-R2rze/hDX30uul4NZoIZ76ImSJLFxn/1/ZxtKC1L77y2X1k+yYu1joKbAtMA2Fg3hZrTOiw0I5mwVMo0cf250w==",
- "license": "MIT",
- "dependencies": {
- "array-timsort": "^1.0.3",
- "esprima": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/compressible": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
- "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
- "license": "MIT",
- "dependencies": {
- "mime-db": ">= 1.43.0 < 2"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/compression": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz",
- "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==",
- "license": "MIT",
- "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"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/compression/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/compression/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/compression/node_modules/negotiator": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
- "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/connect": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
- "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "2.6.9",
- "finalhandler": "1.1.2",
- "parseurl": "~1.3.3",
- "utils-merge": "1.0.1"
- },
- "engines": {
- "node": ">= 0.10.0"
- }
- },
- "node_modules/connect/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/connect/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "license": "MIT"
- },
- "node_modules/core-js-compat": {
- "version": "3.49.0",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.49.0.tgz",
- "integrity": "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==",
- "license": "MIT",
- "dependencies": {
- "browserslist": "^4.28.1"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/core-js"
- }
- },
- "node_modules/cross-fetch": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
- "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
- "license": "MIT",
- "dependencies": {
- "node-fetch": "^2.7.0"
- }
- },
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/css-in-js-utils": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz",
- "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==",
- "license": "MIT",
- "dependencies": {
- "hyphenate-style-name": "^1.0.3"
- }
- },
- "node_modules/css.escape": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
- "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
- "license": "MIT"
- },
- "node_modules/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "license": "MIT",
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/csstype": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "license": "MIT"
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/decode-uri-component": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
- "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/deepmerge": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
- "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/defaults": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
- "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
- "license": "MIT",
- "dependencies": {
- "clone": "^1.0.2"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/destroy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
- "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8",
- "npm": "1.2.8000 || >= 1.4.16"
- }
- },
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/detect-node-es": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz",
- "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==",
- "license": "MIT"
- },
- "node_modules/didyoumean": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
- "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
- "license": "Apache-2.0"
- },
- "node_modules/dlv": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
- "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
- "license": "MIT"
- },
- "node_modules/dnssd-advertise": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/dnssd-advertise/-/dnssd-advertise-1.1.6.tgz",
- "integrity": "sha512-Ndrrf6BMPalkQPd/zubL+4YghH2J9NspapQ09uDXwYbvOPkP0oaqf5CkcwJ0b50kS2O3ul6yVu+jz+RY62Cejg==",
- "license": "MIT"
- },
- "node_modules/dom-accessibility-api": {
- "version": "0.5.16",
- "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
- "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
- "license": "MIT"
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "license": "MIT"
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.378",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.378.tgz",
- "integrity": "sha512-VinvOAuuPmdD1guEgGv5f2Qp7/vlfqOrUOMYNnOD4wj3pit8kRsQHzfIf6teyUGWo15Tg5+bOJaRunvyltpVWQ==",
- "license": "ISC"
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
- "node_modules/encodeurl": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
- "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/error-stack-parser": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
- "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
- "license": "MIT",
- "dependencies": {
- "stackframe": "^1.3.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "license": "MIT"
- },
- "node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "license": "BSD-2-Clause",
- "bin": {
- "esparse": "bin/esparse.js",
- "esvalidate": "bin/esvalidate.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/event-target-shim": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
- "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/expo": {
- "version": "56.0.14",
- "resolved": "https://registry.npmjs.org/expo/-/expo-56.0.14.tgz",
- "integrity": "sha512-YfjXv/owsBhys0HS2K9kd5ONi+FYTNKzoMOCZB5sza0K7JjzjQ1dVC+KzUA27B3GN2RuAyeBoW8jItNr56EBGg==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@babel/runtime": "^7.20.0",
- "@expo/cli": "^56.1.18",
- "@expo/config": "~56.0.11",
- "@expo/config-plugins": "~56.0.11",
- "@expo/devtools": "~56.0.2",
- "@expo/dom-webview": "~56.0.6",
- "@expo/fingerprint": "^0.19.6",
- "@expo/local-build-cache-provider": "^56.0.9",
- "@expo/log-box": "^56.0.14",
- "@expo/metro": "~56.0.0",
- "@expo/metro-config": "~56.0.16",
- "@ungap/structured-clone": "^1.3.0",
- "babel-preset-expo": "~56.0.16",
- "expo-asset": "~56.0.18",
- "expo-constants": "~56.0.20",
- "expo-file-system": "~56.0.8",
- "expo-font": "~56.0.7",
- "expo-keep-awake": "~56.0.3",
- "expo-modules-autolinking": "~56.0.18",
- "expo-modules-core": "~56.0.19",
- "pretty-format": "^29.7.0",
- "react-refresh": "^0.14.2",
- "whatwg-url-minimum": "^0.1.2"
- },
- "bin": {
- "expo": "bin/cli",
- "expo-modules-autolinking": "bin/autolinking",
- "fingerprint": "bin/fingerprint"
- },
- "peerDependencies": {
- "@expo/dom-webview": "*",
- "@expo/metro-runtime": "*",
- "react": "*",
- "react-dom": "*",
- "react-native": "*",
- "react-native-web": "*",
- "react-native-webview": "*"
- },
- "peerDependenciesMeta": {
- "@expo/dom-webview": {
- "optional": true
- },
- "@expo/metro-runtime": {
- "optional": true
- },
- "react-dom": {
- "optional": true
- },
- "react-native-web": {
- "optional": true
- },
- "react-native-webview": {
- "optional": true
- }
- }
- },
- "node_modules/expo-application": {
- "version": "56.0.3",
- "resolved": "https://registry.npmjs.org/expo-application/-/expo-application-56.0.3.tgz",
- "integrity": "sha512-DdGGPlMuM6cSTeKhbvh6OeLr2O/+EI5BHKYrD+Do8sJPYgLwzGrgESELfyjJCpEhFzT+TgKIdmLmWXhNUQnHiw==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*"
- }
- },
- "node_modules/expo-asset": {
- "version": "56.0.18",
- "resolved": "https://registry.npmjs.org/expo-asset/-/expo-asset-56.0.18.tgz",
- "integrity": "sha512-koV8oOW/U4mPP+sWHhsSxk4GdYrO6s/vZU3/OMeDwiyjeqeNJWfjpVUS94HERzwvcthPiX419X3PNj0p9XKt+g==",
- "license": "MIT",
- "dependencies": {
- "@expo/image-utils": "^0.10.1",
- "expo-constants": "~56.0.19"
- },
- "peerDependencies": {
- "expo": "*",
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo-constants": {
- "version": "56.0.20",
- "resolved": "https://registry.npmjs.org/expo-constants/-/expo-constants-56.0.20.tgz",
- "integrity": "sha512-4HgoVvUiMvcqujr/CUj7L1tumLWj8WX0PLM77OriDPoaJrMEwUHd841m4o4IoUyMPVT8XTiTiPFwJtGali8+9Q==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@expo/env": "~2.3.1"
- },
- "peerDependencies": {
- "expo": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo-document-picker": {
- "version": "56.0.4",
- "resolved": "https://registry.npmjs.org/expo-document-picker/-/expo-document-picker-56.0.4.tgz",
- "integrity": "sha512-75Apf74XNkYYohObIH19VZw42xpe0gmEnPccuzGXKVAzlvTYCfibSgW17F+6vt4paOfZEnAoZ1QFZM6dmaujRA==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*"
- }
- },
- "node_modules/expo-eas-client": {
- "version": "56.0.1",
- "resolved": "https://registry.npmjs.org/expo-eas-client/-/expo-eas-client-56.0.1.tgz",
- "integrity": "sha512-r8h0ZIExacCrSRgY+ARfhMvFqosLHLJt1L7jyhvabfr1DN/ZDKDsYbovss2tzkpEUZGxZ3BPcB5epCwUsBBdOA==",
- "license": "MIT"
- },
- "node_modules/expo-file-system": {
- "version": "56.0.8",
- "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-56.0.8.tgz",
- "integrity": "sha512-NrH41/8snGIBSbYicwVLB4txPdgCATd7ZYhMAGS3YJZ9GbnduhlAoV4/YCbGayjrbpE9bJb/6wegPL/zmvRMnQ==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo-font": {
- "version": "56.0.7",
- "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-56.0.7.tgz",
- "integrity": "sha512-hpU/vRwPzsby9lPGkA4blDqLIIXYzoWnCZHr6PxvcWbY/uPObAiyhh6q+e0WYsB65SthK+PLH95jEnVag7fwEg==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "fontfaceobserver": "^2.1.0"
- },
- "peerDependencies": {
- "expo": "*",
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo-glass-effect": {
- "version": "56.0.4",
- "resolved": "https://registry.npmjs.org/expo-glass-effect/-/expo-glass-effect-56.0.4.tgz",
- "integrity": "sha512-xI9rXtDwi7RW82uAlfyaXO6+k21ApWJ2tHAWYqPr/FjfmZbKsgNJ4Q0iZzGPCwboqjTGxaRZ61SZxBl8hDt5iA==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*",
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo-json-utils": {
- "version": "56.0.0",
- "resolved": "https://registry.npmjs.org/expo-json-utils/-/expo-json-utils-56.0.0.tgz",
- "integrity": "sha512-lUqyv9aIGDbYTQ5Nux2FnH2/Dz0w5uJ8Pr080eS0StXi2jr5OmuMNErpzUnpfnYOU55xKotd4AHv68PfV/ludg==",
- "license": "MIT"
- },
- "node_modules/expo-keep-awake": {
- "version": "56.0.3",
- "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-56.0.3.tgz",
- "integrity": "sha512-CLMJXtEiMKknD3Rpm8CRwE6ZJUzu2yCEmRk1sgfHAJ1zIbuEWY3dpPDubtsnuzWm+2k6Sru+yaFbYsvPWmTiBA==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*",
- "react": "*"
- }
- },
- "node_modules/expo-linking": {
- "version": "56.0.15",
- "resolved": "https://registry.npmjs.org/expo-linking/-/expo-linking-56.0.15.tgz",
- "integrity": "sha512-V3tkCxHIWO624ayw2L5Nfi0/bPgYy/0MgmoQR7g3FAKF4nyAayK8IhgAInz4MZ5Ao5Bb+5uZWDdUaS4yyEb+Gw==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "expo-constants": "~56.0.20",
- "invariant": "^2.2.4"
- },
- "peerDependencies": {
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo-manifests": {
- "version": "56.0.4",
- "resolved": "https://registry.npmjs.org/expo-manifests/-/expo-manifests-56.0.4.tgz",
- "integrity": "sha512-Fokawl2UkiExIF0bqGoblRFA8lYpROVD+EpvDwSW4LgqQyPwNua1gLSgHZjdl5GsVugfRMMWE3LHaibDyX93hw==",
- "license": "MIT",
- "dependencies": {
- "expo-json-utils": "~56.0.0"
- },
- "peerDependencies": {
- "expo": "*"
- }
- },
- "node_modules/expo-modules-autolinking": {
- "version": "56.0.18",
- "resolved": "https://registry.npmjs.org/expo-modules-autolinking/-/expo-modules-autolinking-56.0.18.tgz",
- "integrity": "sha512-8+NyEpTKjrUpHRFw+WihXXnLa/nqPlUpFz4SdtzPovW24rJikyw160gVSCbuILp+AgC8yasjHT+C6xuqRSdiew==",
- "license": "MIT",
- "dependencies": {
- "@expo/require-utils": "^56.1.4",
- "@expo/spawn-async": "^1.8.0",
- "chalk": "^4.1.0",
- "commander": "^7.2.0"
- },
- "bin": {
- "expo-modules-autolinking": "bin/expo-modules-autolinking.js"
- }
- },
- "node_modules/expo-modules-core": {
- "version": "56.0.19",
- "resolved": "https://registry.npmjs.org/expo-modules-core/-/expo-modules-core-56.0.19.tgz",
- "integrity": "sha512-nJCXHNK4y7X8/Z40zssp8hRpxzwEEpWGtA4b9b3gf67aaj4Z7l5PDstfv+8d5QnsAcOM+Vxum9E+itqNB27qXQ==",
- "license": "MIT",
- "dependencies": {
- "@expo/expo-modules-macros-plugin": "0.2.2",
- "expo-modules-jsi": "~56.0.11",
- "invariant": "^2.2.4"
- },
- "peerDependencies": {
- "react": "*",
- "react-native": "*",
- "react-native-worklets": "^0.7.4 || ^0.8.0"
- },
- "peerDependenciesMeta": {
- "react-native-worklets": {
- "optional": true
- }
- }
- },
- "node_modules/expo-modules-jsi": {
- "version": "56.0.11",
- "resolved": "https://registry.npmjs.org/expo-modules-jsi/-/expo-modules-jsi-56.0.11.tgz",
- "integrity": "sha512-vhjaTb63ekITnSz8ah+k+GOUDRB9TB8NmY8Iq7cj5O8iKXcqJi/3ZyHyhiFSu0Pjb+UXEeFX+42KZ/a3XZDd4Q==",
- "license": "MIT",
- "peerDependencies": {
- "react-native": "*"
- }
- },
- "node_modules/expo-notifications": {
- "version": "56.0.19",
- "resolved": "https://registry.npmjs.org/expo-notifications/-/expo-notifications-56.0.19.tgz",
- "integrity": "sha512-3sTegn8Wwu84TLIAxAqC725kqQ412U2NG9qUH4k3gQzBU49vROhvsslj7gARgvOJY8KohuJz82csuZfZnHDDHw==",
- "license": "MIT",
- "dependencies": {
- "@expo/image-utils": "^0.10.1",
- "abort-controller": "^3.0.0",
- "badgin": "^1.1.5",
- "expo-application": "~56.0.3",
- "expo-constants": "~56.0.19"
- },
- "peerDependencies": {
- "expo": "*",
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo-router": {
- "version": "56.2.13",
- "resolved": "https://registry.npmjs.org/expo-router/-/expo-router-56.2.13.tgz",
- "integrity": "sha512-Iln0473krRnI8m1EnZ29Sg1kWRgQ2W9a8bsDkslPPnpdAHQee28HajkQHXZsNPxD1t4hii1lajRRHKNmJs37rA==",
- "license": "MIT",
- "dependencies": {
- "@expo/log-box": "^56.0.14",
- "@expo/metro-runtime": "^56.0.16",
- "@expo/schema-utils": "^56.0.2",
- "@expo/ui": "^56.0.20",
- "@radix-ui/react-slot": "^1.2.0",
- "@radix-ui/react-tabs": "^1.1.12",
- "@react-native-masked-view/masked-view": "^0.3.2",
- "@testing-library/jest-dom": "^6.9.1",
- "@testing-library/user-event": "^14.6.1",
- "client-only": "^0.0.1",
- "color": "^4.2.3",
- "debug": "^4.3.4",
- "escape-string-regexp": "^4.0.0",
- "expo-glass-effect": "^56.0.4",
- "expo-server": "^56.0.5",
- "expo-symbols": "^56.0.6",
- "fast-deep-equal": "^3.1.3",
- "invariant": "^2.2.4",
- "nanoid": "^3.3.8",
- "query-string": "^7.1.3",
- "react-fast-compare": "^3.2.2",
- "react-is": "^19.1.0",
- "react-native-drawer-layout": "^4.2.2",
- "react-native-screens": "^4.25.2",
- "server-only": "^0.0.1",
- "sf-symbols-typescript": "^2.1.0",
- "shallowequal": "^1.1.0",
- "standard-navigation": "^0.0.5",
- "vaul": "^1.1.2"
- },
- "peerDependencies": {
- "@expo/log-box": "^56.0.14",
- "@expo/metro-runtime": "^56.0.16",
- "@testing-library/react-native": ">= 13.2.0",
- "expo": "*",
- "expo-constants": "^56.0.20",
- "expo-linking": "^56.0.15",
- "react": "*",
- "react-dom": "*",
- "react-native": "*",
- "react-native-gesture-handler": "*",
- "react-native-reanimated": "*",
- "react-native-safe-area-context": ">= 5.4.0",
- "react-native-screens": "^4.25.2",
- "react-native-web": "*",
- "react-server-dom-webpack": "~19.0.4 || ~19.1.5 || ~19.2.4"
- },
- "peerDependenciesMeta": {
- "@testing-library/react-native": {
- "optional": true
- },
- "react-dom": {
- "optional": true
- },
- "react-native-gesture-handler": {
- "optional": true
- },
- "react-native-reanimated": {
- "optional": true
- },
- "react-native-web": {
- "optional": true
- },
- "react-server-dom-webpack": {
- "optional": true
- }
- }
- },
- "node_modules/expo-router/node_modules/react-is": {
- "version": "19.2.7",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz",
- "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==",
- "license": "MIT"
- },
- "node_modules/expo-secure-store": {
- "version": "56.0.4",
- "resolved": "https://registry.npmjs.org/expo-secure-store/-/expo-secure-store-56.0.4.tgz",
- "integrity": "sha512-hjEi/gmpdFFJ9lYbdp3k3p/WchV7Gi0Qt8jt/m/0WJadqQrskafHAlDxbZkII1cN3Yd7zp9Lvkeq3UfGhSwirQ==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*"
- }
- },
- "node_modules/expo-server": {
- "version": "56.0.5",
- "resolved": "https://registry.npmjs.org/expo-server/-/expo-server-56.0.5.tgz",
- "integrity": "sha512-SmM2p2g3Jrktpiazcst+OxhjSzOHXKAY4BPURHYHXvApzzoybMmrNF4IEZ8DKZ145BhSe4ydAmlEFCRTsdtgUQ==",
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=20.16.0"
- }
- },
- "node_modules/expo-splash-screen": {
- "version": "56.0.12",
- "resolved": "https://registry.npmjs.org/expo-splash-screen/-/expo-splash-screen-56.0.12.tgz",
- "integrity": "sha512-RvEtJ78aNpuxdVD8TCe9viKtlYGzS9hW20fbvqvkeXDN6WAaYo1CRitPdjWNkaNNSPKOolp3zfha4EGdhXOtxg==",
- "license": "MIT",
- "dependencies": {
- "@expo/config-plugins": "~56.0.11",
- "@expo/image-utils": "^0.10.2",
- "xml2js": "0.6.0"
- },
- "peerDependencies": {
- "expo": "*"
- }
- },
- "node_modules/expo-status-bar": {
- "version": "56.0.4",
- "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-56.0.4.tgz",
- "integrity": "sha512-IGs/fDfkHXofy2ZQrGiXayhFK04HB85FZXorhcEhDZEcqASKgSqpak+HwUtAaR0MeTJwWyHNF7I6VmVbbp8EcA==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*",
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo-structured-headers": {
- "version": "56.0.0",
- "resolved": "https://registry.npmjs.org/expo-structured-headers/-/expo-structured-headers-56.0.0.tgz",
- "integrity": "sha512-Yv4x+SQxNnMQm4nu8NFfzx197YaDhdYH2N0u7tGErwWTmH9Tm1SAhqo7bLbBWLC9kf7W+kdzTshLU9rTiCXWGw==",
- "license": "MIT"
- },
- "node_modules/expo-symbols": {
- "version": "56.0.6",
- "resolved": "https://registry.npmjs.org/expo-symbols/-/expo-symbols-56.0.6.tgz",
- "integrity": "sha512-BrA81DjcNafdj7gXVhdrExb9LtUiSVyOf/NavyMmDAHgHMY1GqeR5cnn1PSAZeYKnSgQhee/H89XUpAxtog5hg==",
- "license": "MIT",
- "dependencies": {
- "@expo-google-fonts/material-symbols": "^0.4.1",
- "sf-symbols-typescript": "^2.0.0"
- },
- "peerDependencies": {
- "expo": "*",
- "expo-font": "*",
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/expo-system-ui": {
- "version": "56.0.5",
- "resolved": "https://registry.npmjs.org/expo-system-ui/-/expo-system-ui-56.0.5.tgz",
- "integrity": "sha512-n1MmnUArV4cc3gVed9fGtluPme00PE9axKVx+NHbKxHFMam5l4GcOI7PxbYKFNx8o7WA1LRD7eLW33agmZrxGg==",
- "license": "MIT",
- "dependencies": {
- "@react-native/normalize-colors": "0.85.3",
- "debug": "^4.3.2"
- },
- "peerDependencies": {
- "expo": "*",
- "react-native": "*",
- "react-native-web": "*"
- },
- "peerDependenciesMeta": {
- "react-native-web": {
- "optional": true
- }
- }
- },
- "node_modules/expo-updates": {
- "version": "56.0.21",
- "resolved": "https://registry.npmjs.org/expo-updates/-/expo-updates-56.0.21.tgz",
- "integrity": "sha512-7kYS2/ra9Lg4xBG6Fadcq/YR8DngdCeBVc0lQeHvqH/dZHL2N0bJRu0y4utJd9tpIzQtNCmceGu1SmGZVT57/Q==",
- "license": "MIT",
- "dependencies": {
- "@expo/code-signing-certificates": "^0.0.6",
- "@expo/plist": "^0.7.0",
- "@expo/spawn-async": "^1.8.0",
- "arg": "^4.1.0",
- "chalk": "^4.1.2",
- "debug": "^4.3.4",
- "expo-eas-client": "~56.0.0",
- "expo-manifests": "~56.0.4",
- "expo-structured-headers": "~56.0.0",
- "expo-updates-interface": "~56.0.1",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "ignore": "^5.3.1",
- "nullthrows": "^1.1.1",
- "resolve-from": "^5.0.0"
- },
- "bin": {
- "expo-updates": "bin/cli.js"
- },
- "peerDependencies": {
- "expo": "*",
- "expo-dev-client": "*",
- "react": "*",
- "react-native": "*"
- },
- "peerDependenciesMeta": {
- "expo-dev-client": {
- "optional": true
- }
- }
- },
- "node_modules/expo-updates-interface": {
- "version": "56.0.2",
- "resolved": "https://registry.npmjs.org/expo-updates-interface/-/expo-updates-interface-56.0.2.tgz",
- "integrity": "sha512-eWTwSZ9y8vrULG2oBn2TQSSIwBGSq/TxGJ3jY6tuVS2FWH/ASRIiKs3zkUZTRoC3ZuV2alz0mUClYV7nNrFx8g==",
- "license": "MIT",
- "peerDependencies": {
- "expo": "*"
- }
- },
- "node_modules/expo-updates/node_modules/arg": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
- "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
- "license": "MIT"
- },
- "node_modules/expo/node_modules/@expo/cli": {
- "version": "56.1.18",
- "resolved": "https://registry.npmjs.org/@expo/cli/-/cli-56.1.18.tgz",
- "integrity": "sha512-ACzbK2mLPevgjdJ7EeDyjPem+WU9oDcCLD2Ajwrl6dVvN9xP5wchGrwRQvVx55TU3bdTCEXpiHC2AGRXfXVc6g==",
- "license": "MIT",
- "dependencies": {
- "@expo/code-signing-certificates": "^0.0.6",
- "@expo/config": "~56.0.11",
- "@expo/config-plugins": "~56.0.11",
- "@expo/devcert": "^1.2.1",
- "@expo/env": "~2.3.1",
- "@expo/image-utils": "^0.10.2",
- "@expo/inline-modules": "^0.0.13",
- "@expo/json-file": "^10.2.0",
- "@expo/log-box": "^56.0.14",
- "@expo/metro": "~56.0.0",
- "@expo/metro-config": "~56.0.16",
- "@expo/metro-file-map": "^56.0.3",
- "@expo/osascript": "^2.6.0",
- "@expo/package-manager": "^1.12.1",
- "@expo/plist": "^0.7.0",
- "@expo/prebuild-config": "^56.0.18",
- "@expo/require-utils": "^56.1.4",
- "@expo/router-server": "^56.0.15",
- "@expo/schema-utils": "^56.0.2",
- "@expo/spawn-async": "^1.8.0",
- "@expo/ws-tunnel": "^2.0.0",
- "@expo/xcpretty": "^4.4.4",
- "@react-native/dev-middleware": "0.85.3",
- "accepts": "^1.3.8",
- "agent-cli-detector": "^0.1.2",
- "arg": "^5.0.2",
- "bplist-creator": "0.1.0",
- "bplist-parser": "^0.3.1",
- "chalk": "^4.0.0",
- "ci-info": "^3.3.0",
- "compression": "^1.7.4",
- "connect": "^3.7.0",
- "debug": "^4.3.4",
- "dnssd-advertise": "^1.1.6",
- "expo-server": "^56.0.5",
- "fetch-nodeshim": "^0.4.10",
- "getenv": "^2.0.0",
- "glob": "^13.0.0",
- "lan-network": "^0.2.1",
- "multitars": "^1.0.0",
- "node-forge": "^1.3.3",
- "npm-package-arg": "^11.0.0",
- "ora": "^3.4.0",
- "picomatch": "^4.0.4",
- "pretty-format": "^29.7.0",
- "progress": "^2.0.3",
- "prompts": "^2.3.2",
- "resolve-from": "^5.0.0",
- "semver": "^7.6.0",
- "send": "^0.19.0",
- "slugify": "^1.3.4",
- "stacktrace-parser": "^0.1.10",
- "structured-headers": "^0.4.1",
- "terminal-link": "^2.1.1",
- "toqr": "^0.1.1",
- "wrap-ansi": "^7.0.0",
- "ws": "^8.12.1",
- "zod": "^3.25.76"
- },
- "bin": {
- "expo-internal": "main.js"
- },
- "peerDependencies": {
- "expo": "*",
- "expo-router": "*",
- "react-native": "*"
- },
- "peerDependenciesMeta": {
- "expo-router": {
- "optional": true
- },
- "react-native": {
- "optional": true
- }
- }
- },
- "node_modules/expo/node_modules/@expo/cli/node_modules/@expo/router-server": {
- "version": "56.0.15",
- "resolved": "https://registry.npmjs.org/@expo/router-server/-/router-server-56.0.15.tgz",
- "integrity": "sha512-eXTwUEKR6MPeoJVwyGOX5eIvUUKCGL0mItTXBMTb2TIr9M6IH7ORVo8yHB70RVSLVXo8AuwsCtDfKFKZ3rUZ5w==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.4"
- },
- "peerDependencies": {
- "@expo/metro-runtime": "^56.0.16",
- "expo": "*",
- "expo-constants": "^56.0.19",
- "expo-font": "^56.0.7",
- "expo-router": "*",
- "expo-server": "^56.0.5",
- "react": "*",
- "react-dom": "*",
- "react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1"
- },
- "peerDependenciesMeta": {
- "@expo/metro-runtime": {
- "optional": true
- },
- "expo-router": {
- "optional": true
- },
- "react-dom": {
- "optional": true
- },
- "react-server-dom-webpack": {
- "optional": true
- }
- }
- },
- "node_modules/expo/node_modules/@expo/ws-tunnel": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@expo/ws-tunnel/-/ws-tunnel-2.0.0.tgz",
- "integrity": "sha512-j+JfTRdCk820J9dU0sA2SqshQIKFOMo7ED84w9MJFcebfbNQgsLztEY/SABDkGnjatrW4xGqnUhVRxSBVyCkXw==",
- "license": "MIT",
- "peerDependencies": {
- "ws": "^8.0.0"
- }
- },
- "node_modules/expo/node_modules/accepts": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
- "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
- "license": "MIT",
- "dependencies": {
- "mime-types": "~2.1.34",
- "negotiator": "0.6.3"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/expo/node_modules/ci-info": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
- "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/expo/node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/expo/node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/expo/node_modules/negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/expo/node_modules/picomatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
- "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/expo/node_modules/ws": {
- "version": "8.21.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
- "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
- "license": "MIT",
- "peer": true,
- "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
- }
- }
- },
- "node_modules/exponential-backoff": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
- "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==",
- "license": "Apache-2.0"
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "license": "MIT"
- },
- "node_modules/fast-glob": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
- "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.8"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fastq": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/fb-dotslash": {
- "version": "0.5.8",
- "resolved": "https://registry.npmjs.org/fb-dotslash/-/fb-dotslash-0.5.8.tgz",
- "integrity": "sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA==",
- "license": "(MIT OR Apache-2.0)",
- "bin": {
- "dotslash": "bin/dotslash"
- },
- "engines": {
- "node": ">=20"
- }
- },
- "node_modules/fb-watchman": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
- "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
- "license": "Apache-2.0",
- "dependencies": {
- "bser": "2.1.1"
- }
- },
- "node_modules/fbjs": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
- "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==",
- "license": "MIT",
- "dependencies": {
- "cross-fetch": "^3.1.5",
- "fbjs-css-vars": "^1.0.0",
- "loose-envify": "^1.0.0",
- "object-assign": "^4.1.0",
- "promise": "^7.1.1",
- "setimmediate": "^1.0.5",
- "ua-parser-js": "^1.0.35"
- }
- },
- "node_modules/fbjs-css-vars": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
- "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==",
- "license": "MIT"
- },
- "node_modules/fbjs/node_modules/promise": {
- "version": "7.3.1",
- "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
- "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
- "license": "MIT",
- "dependencies": {
- "asap": "~2.0.3"
- }
- },
- "node_modules/fetch-nodeshim": {
- "version": "0.4.10",
- "resolved": "https://registry.npmjs.org/fetch-nodeshim/-/fetch-nodeshim-0.4.10.tgz",
- "integrity": "sha512-m6I8ALe4L4XpdETy7MJZWs6L1IVMbjs99bwbpIKphxX+0CTns4IKDWJY0LWfr4YsFjfg+z1TjzTMU8lKl8rG0w==",
- "license": "MIT"
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/filter-obj": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
- "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/finalhandler": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
- "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
- "license": "MIT",
- "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"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/finalhandler/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/finalhandler/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/flow-enums-runtime": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.6.tgz",
- "integrity": "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw==",
- "license": "MIT"
- },
- "node_modules/fontfaceobserver": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
- "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==",
- "license": "BSD-2-Clause"
- },
- "node_modules/fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "license": "ISC",
- "engines": {
- "node": "6.* || 8.* || >= 10.*"
- }
- },
- "node_modules/get-nonce": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
- "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/getenv": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/getenv/-/getenv-2.0.0.tgz",
- "integrity": "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/glob": {
- "version": "13.0.6",
- "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
- "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "minimatch": "^10.2.2",
- "minipass": "^7.1.3",
- "path-scurry": "^2.0.2"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "license": "ISC"
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
- "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/hermes-compiler": {
- "version": "250829098.0.10",
- "resolved": "https://registry.npmjs.org/hermes-compiler/-/hermes-compiler-250829098.0.10.tgz",
- "integrity": "sha512-TcRlZ0/TlyfJqquRFAWoyElVNnkdYRi/sEp4/Qy8/GYxjg8j2cS9D4MjuaQ+qimkmLN7AmO+44IznRf06mAr0w==",
- "license": "MIT"
- },
- "node_modules/hermes-estree": {
- "version": "0.35.0",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.35.0.tgz",
- "integrity": "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg==",
- "license": "MIT"
- },
- "node_modules/hermes-parser": {
- "version": "0.35.0",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.35.0.tgz",
- "integrity": "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA==",
- "license": "MIT",
- "dependencies": {
- "hermes-estree": "0.35.0"
- }
- },
- "node_modules/hosted-git-info": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
- "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
- "license": "ISC",
- "dependencies": {
- "lru-cache": "^10.0.1"
- },
- "engines": {
- "node": "^16.14.0 || >=18.0.0"
- }
- },
- "node_modules/hosted-git-info/node_modules/lru-cache": {
- "version": "10.4.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
- "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
- "license": "ISC"
- },
- "node_modules/http-errors": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
- "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
- "license": "MIT",
- "dependencies": {
- "depd": "~2.0.0",
- "inherits": "~2.0.4",
- "setprototypeof": "~1.2.0",
- "statuses": "~2.0.2",
- "toidentifier": "~1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/http-errors/node_modules/statuses": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/https-proxy-agent": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
- "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/hyphenate-style-name": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz",
- "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==",
- "license": "BSD-3-Clause"
- },
- "node_modules/ignore": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
- "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/image-size": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
- "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
- "license": "MIT",
- "dependencies": {
- "queue": "6.0.2"
- },
- "bin": {
- "image-size": "bin/image-size.js"
- },
- "engines": {
- "node": ">=16.x"
- }
- },
- "node_modules/indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/inline-style-prefixer": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz",
- "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==",
- "license": "MIT",
- "dependencies": {
- "css-in-js-utils": "^3.1.0"
- }
- },
- "node_modules/invariant": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
- "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.0.0"
- }
- },
- "node_modules/is-arrayish": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz",
- "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
- "license": "MIT"
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "license": "MIT",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.16.2",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
- "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-docker": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
- "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
- "license": "MIT",
- "bin": {
- "is-docker": "cli.js"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-wsl": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
- "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
- "license": "MIT",
- "dependencies": {
- "is-docker": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "license": "ISC"
- },
- "node_modules/jest-get-type": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
- "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-util": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
- "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "@types/node": "*",
- "chalk": "^4.0.0",
- "ci-info": "^3.2.0",
- "graceful-fs": "^4.2.9",
- "picomatch": "^2.2.3"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-util/node_modules/ci-info": {
- "version": "3.9.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
- "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/sibiraj-s"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/jest-validate": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
- "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
- "license": "MIT",
- "dependencies": {
- "@jest/types": "^29.6.3",
- "camelcase": "^6.2.0",
- "chalk": "^4.0.0",
- "jest-get-type": "^29.6.3",
- "leven": "^3.1.0",
- "pretty-format": "^29.7.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-worker": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
- "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
- "license": "MIT",
- "dependencies": {
- "@types/node": "*",
- "jest-util": "^29.7.0",
- "merge-stream": "^2.0.0",
- "supports-color": "^8.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/jest-worker/node_modules/supports-color": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
- "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/supports-color?sponsor=1"
- }
- },
- "node_modules/jimp-compact": {
- "version": "0.16.1",
- "resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz",
- "integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==",
- "license": "MIT"
- },
- "node_modules/jiti": {
- "version": "1.21.7",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
- "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
- "license": "MIT",
- "peer": true,
- "bin": {
- "jiti": "bin/jiti.js"
- }
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "license": "MIT"
- },
- "node_modules/js-yaml": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
- "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/puzrin"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/nodeca"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsc-safe-url": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz",
- "integrity": "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q==",
- "license": "0BSD"
- },
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/kleur": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
- "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/lan-network": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/lan-network/-/lan-network-0.2.1.tgz",
- "integrity": "sha512-ONPnazC96VKDntab9j9JKwIWhZ4ZUceB4A9Epu4Ssg0hYFmtHZSeQ+n15nIwTFmcBUKtExOer8WTJ4GF9MO64A==",
- "license": "MIT",
- "bin": {
- "lan-network": "dist/lan-network-cli.js"
- }
- },
- "node_modules/leven": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
- "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/lighthouse-logger": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz",
- "integrity": "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g==",
- "license": "Apache-2.0",
- "dependencies": {
- "debug": "^2.6.9",
- "marky": "^1.2.2"
- }
- },
- "node_modules/lighthouse-logger/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/lighthouse-logger/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/lightningcss": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
- "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
- "license": "MPL-2.0",
- "dependencies": {
- "detect-libc": "^2.0.3"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "lightningcss-android-arm64": "1.32.0",
- "lightningcss-darwin-arm64": "1.32.0",
- "lightningcss-darwin-x64": "1.32.0",
- "lightningcss-freebsd-x64": "1.32.0",
- "lightningcss-linux-arm-gnueabihf": "1.32.0",
- "lightningcss-linux-arm64-gnu": "1.32.0",
- "lightningcss-linux-arm64-musl": "1.32.0",
- "lightningcss-linux-x64-gnu": "1.32.0",
- "lightningcss-linux-x64-musl": "1.32.0",
- "lightningcss-win32-arm64-msvc": "1.32.0",
- "lightningcss-win32-x64-msvc": "1.32.0"
- }
- },
- "node_modules/lightningcss-android-arm64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
- "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-arm64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
- "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-x64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
- "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-freebsd-x64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
- "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
- "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
- "cpu": [
- "arm"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
- "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
- "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
- "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-musl": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
- "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
- "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
- "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lilconfig": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
- "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
- "license": "MIT",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
- }
- },
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "license": "MIT"
- },
- "node_modules/lodash.debounce": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
- "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
- "license": "MIT"
- },
- "node_modules/lodash.throttle": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
- "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==",
- "license": "MIT"
- },
- "node_modules/log-symbols": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
- "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^2.0.1"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/log-symbols/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/log-symbols/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/log-symbols/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/log-symbols/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "license": "MIT"
- },
- "node_modules/log-symbols/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/log-symbols/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/log-symbols/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "license": "MIT",
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/lz-string": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
- "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
- "license": "MIT",
- "bin": {
- "lz-string": "bin/bin.js"
- }
- },
- "node_modules/makeerror": {
- "version": "1.0.12",
- "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
- "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "tmpl": "1.0.5"
- }
- },
- "node_modules/marky": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz",
- "integrity": "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==",
- "license": "Apache-2.0"
- },
- "node_modules/memoize-one": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
- "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==",
- "license": "MIT"
- },
- "node_modules/merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "license": "MIT"
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/metro": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro/-/metro-0.84.4.tgz",
- "integrity": "sha512-8ETTubqfD6ornDy2zYDvRcKnVDOXdFJsjetYDBsY4oAsb6NJkiwFR+FaMESyGppFmQUyBQA4H4sFGxzcQSGtFA==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.29.0",
- "@babel/core": "^7.25.2",
- "@babel/generator": "^7.29.1",
- "@babel/parser": "^7.29.0",
- "@babel/template": "^7.28.6",
- "@babel/traverse": "^7.29.0",
- "@babel/types": "^7.29.0",
- "accepts": "^2.0.0",
- "ci-info": "^2.0.0",
- "connect": "^3.6.5",
- "debug": "^4.4.0",
- "error-stack-parser": "^2.0.6",
- "flow-enums-runtime": "^0.0.6",
- "graceful-fs": "^4.2.4",
- "hermes-parser": "0.35.0",
- "image-size": "^1.0.2",
- "invariant": "^2.2.4",
- "jest-worker": "^29.7.0",
- "jsc-safe-url": "^0.2.2",
- "lodash.throttle": "^4.1.1",
- "metro-babel-transformer": "0.84.4",
- "metro-cache": "0.84.4",
- "metro-cache-key": "0.84.4",
- "metro-config": "0.84.4",
- "metro-core": "0.84.4",
- "metro-file-map": "0.84.4",
- "metro-resolver": "0.84.4",
- "metro-runtime": "0.84.4",
- "metro-source-map": "0.84.4",
- "metro-symbolicate": "0.84.4",
- "metro-transform-plugins": "0.84.4",
- "metro-transform-worker": "0.84.4",
- "mime-types": "^3.0.1",
- "nullthrows": "^1.1.1",
- "serialize-error": "^2.1.0",
- "source-map": "^0.5.6",
- "throat": "^5.0.0",
- "ws": "^7.5.10",
- "yargs": "^17.6.2"
- },
- "bin": {
- "metro": "src/cli.js"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-babel-transformer": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.84.4.tgz",
- "integrity": "sha512-rvCfz8snl9h20VcvpOHxZuHP1SlAkv4HXbzw7nyyVwu6Eqo5PRerbakQ9XmUCOsRy70spJ37O+G1TK8oMzo48g==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.25.2",
- "flow-enums-runtime": "^0.0.6",
- "hermes-parser": "0.35.0",
- "metro-cache-key": "0.84.4",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-cache": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.84.4.tgz",
- "integrity": "sha512-gpcFQdSLUwUCk71saKoE64jLFbx2nwTfVCcPSULMNT8QYq0p1eZZE29Jvd0HtT/UlhC3ZOutLxJME5xqD2JUZg==",
- "license": "MIT",
- "dependencies": {
- "exponential-backoff": "^3.1.1",
- "flow-enums-runtime": "^0.0.6",
- "https-proxy-agent": "^7.0.5",
- "metro-core": "0.84.4"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-cache-key": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.84.4.tgz",
- "integrity": "sha512-wVO79aGrkYImpnaVS4+d5RrRBRPX31QtvKB3wKGBuiNSznduZTQHzsrJZRroFJSwnygrzdsGUtDQPuqqFjFdvw==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-config": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.84.4.tgz",
- "integrity": "sha512-PMotGDjXcXLWo2TMRH+VR99phFNgYTwqh4OoieIKK3yTJa1Jmkl+fZJxDO0jfBvNF+WESHciHvpNuBtXaF3B0Q==",
- "license": "MIT",
- "dependencies": {
- "connect": "^3.6.5",
- "flow-enums-runtime": "^0.0.6",
- "jest-validate": "^29.7.0",
- "metro": "0.84.4",
- "metro-cache": "0.84.4",
- "metro-core": "0.84.4",
- "metro-runtime": "0.84.4",
- "yaml": "^2.6.1"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-core": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.84.4.tgz",
- "integrity": "sha512-HONpWC5LGXZn3ffkd4Hu6AIrfE7j4Z0g0wMo/goV24WOB3lhuFZ40KgvaDiSw8iyQHloMYay5N/wPX+z8oN/PQ==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6",
- "lodash.throttle": "^4.1.1",
- "metro-resolver": "0.84.4"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-file-map": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.84.4.tgz",
- "integrity": "sha512-KSVDi/u60hKPx++NLu3MTIvyjzNoJnFAF8PQFxaj1jiSka/wjw+Ua6sNuJ0TDHQv+7AAoFQxeMgaRAe8Yic5wQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "fb-watchman": "^2.0.0",
- "flow-enums-runtime": "^0.0.6",
- "graceful-fs": "^4.2.4",
- "invariant": "^2.2.4",
- "jest-worker": "^29.7.0",
- "micromatch": "^4.0.4",
- "nullthrows": "^1.1.1",
- "walker": "^1.0.7"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-minify-terser": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.84.4.tgz",
- "integrity": "sha512-5qpbaVOMC7CPitIpuewzVeGw7E+C3ykbv2mqTjQLl85Z3annSVGlSCTcsZjqXZzjupfK4Ztj3dDc4kc44NZwtQ==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6",
- "terser": "^5.15.0"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-resolver": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.84.4.tgz",
- "integrity": "sha512-1qLgbxQ5ZGhhutuPot1Yp348ofDsATL2WkrHF65TobqTT9K3P9qJXw38bomk7ncp5B7OYMfWwtyBZo1lCV792A==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-runtime": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.84.4.tgz",
- "integrity": "sha512-Jibypds4g7AhzdRKY+kDoj51s5EXMwgyp5ddtlreDAsWefMdOx+agWqgm0H2XSZ/ueanHHVM89fnf5OJnlxa8Q==",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.25.0",
- "flow-enums-runtime": "^0.0.6"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-source-map": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.84.4.tgz",
- "integrity": "sha512-jbWkPxIesVuo1IWkvezmMJld6iu8nD62GsrZiV6jP37AOdbo4OBq1FJ+qkOg8sV05wAHB//jAbziuW0SlJfW4g==",
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.29.0",
- "@babel/types": "^7.29.0",
- "flow-enums-runtime": "^0.0.6",
- "invariant": "^2.2.4",
- "metro-symbolicate": "0.84.4",
- "nullthrows": "^1.1.1",
- "ob1": "0.84.4",
- "source-map": "^0.5.6",
- "vlq": "^1.0.0"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-symbolicate": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.84.4.tgz",
- "integrity": "sha512-OnfpacxUqGPZQ27t8qK9mFa7uqHIlVWeqRqkCbvMvreEBiamEeOn8krKtcwgP5M4cYDPwuSmCTopHMVthqG4zA==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6",
- "invariant": "^2.2.4",
- "metro-source-map": "0.84.4",
- "nullthrows": "^1.1.1",
- "source-map": "^0.5.6",
- "vlq": "^1.0.0"
- },
- "bin": {
- "metro-symbolicate": "src/index.js"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-transform-plugins": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.84.4.tgz",
- "integrity": "sha512-kehr6HbAecqD0/a3xLXobELdPaAmRAl8bel0qagPF4vhZtux93nS8S4eq2kgKt6J2GnQpVjSoW1PXdst04mwow==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.25.2",
- "@babel/generator": "^7.29.1",
- "@babel/template": "^7.28.6",
- "@babel/traverse": "^7.29.0",
- "flow-enums-runtime": "^0.0.6",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/metro-transform-worker": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.84.4.tgz",
- "integrity": "sha512-W1IYMvvXTu4MxYr7d9h7CeG2vpIr3bmLLIavkPY4O1ilzDrvS8z/NEe6y+pC44Ff7raMXQgYSfdqDUwN/i39gg==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.25.2",
- "@babel/generator": "^7.29.1",
- "@babel/parser": "^7.29.0",
- "@babel/types": "^7.29.0",
- "flow-enums-runtime": "^0.0.6",
- "metro": "0.84.4",
- "metro-babel-transformer": "0.84.4",
- "metro-cache": "0.84.4",
- "metro-cache-key": "0.84.4",
- "metro-minify-terser": "0.84.4",
- "metro-source-map": "0.84.4",
- "metro-transform-plugins": "0.84.4",
- "nullthrows": "^1.1.1"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/mime": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
- "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
- "license": "MIT",
- "bin": {
- "mime": "cli.js"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/mime-db": {
- "version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
- "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "^1.54.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/mimic-fn": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
- "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/min-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
- "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/minimatch": {
- "version": "10.2.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
- "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "brace-expansion": "^5.0.5"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
- "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/mkdirp": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
- "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
- "license": "MIT",
- "bin": {
- "mkdirp": "bin/cmd.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/multitars": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/multitars/-/multitars-1.0.0.tgz",
- "integrity": "sha512-H/J4fMLedtudftaYMOg7ajzLYgT3/rwbWVJbqr/iUgB8DQztn38ys5HOqI1CzSxx8QhXXwOOnnBvd4v3jG5+Mg==",
- "license": "MIT"
- },
- "node_modules/mz": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
- "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
- "license": "MIT",
- "dependencies": {
- "any-promise": "^1.0.0",
- "object-assign": "^4.0.1",
- "thenify-all": "^1.0.0"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.15",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz",
- "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/nativewind": {
- "version": "4.2.6",
- "resolved": "https://registry.npmjs.org/nativewind/-/nativewind-4.2.6.tgz",
- "integrity": "sha512-kLPRH3Yh/hhIFufXzUZDe39fuK471GwaPBCqYNgcRygILr+obV+wFfDmG+zaJnniVUFFQzYOTCEldem6XktZ+A==",
- "license": "MIT",
- "dependencies": {
- "comment-json": "^4.2.5",
- "debug": "^4.3.7",
- "react-native-css-interop": "0.2.6"
- },
- "engines": {
- "node": ">=16"
- },
- "peerDependencies": {
- "tailwindcss": ">3.3.0"
- }
- },
- "node_modules/negotiator": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
- "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/node-forge": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz",
- "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==",
- "license": "(BSD-3-Clause OR GPL-2.0)",
- "engines": {
- "node": ">= 6.13.0"
- }
- },
- "node_modules/node-int64": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
- "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
- "license": "MIT"
- },
- "node_modules/node-releases": {
- "version": "2.0.49",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.49.tgz",
- "integrity": "sha512-f06bl1D+8ZDkn2oOQQKAh5/otFWqVnM1Q5oerA8Pex7UfT66Tx4IPHIqVVFKqFT3FUtaDstdgkM7yT7JWhqxfw==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/npm-package-arg": {
- "version": "11.0.3",
- "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz",
- "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==",
- "license": "ISC",
- "dependencies": {
- "hosted-git-info": "^7.0.0",
- "proc-log": "^4.0.0",
- "semver": "^7.3.5",
- "validate-npm-package-name": "^5.0.0"
- },
- "engines": {
- "node": "^16.14.0 || >=18.0.0"
- }
- },
- "node_modules/nullthrows": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz",
- "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==",
- "license": "MIT"
- },
- "node_modules/ob1": {
- "version": "0.84.4",
- "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.84.4.tgz",
- "integrity": "sha512-eJXMpz4aQHXF/YBB9ddqZDIS+ooO91hObo9FoW/xBkr54/zCwYYCDqT/O54vNo8kOkWs5Ou/y28NgdrV0edQNA==",
- "license": "MIT",
- "dependencies": {
- "flow-enums-runtime": "^0.0.6"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- }
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/on-headers": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
- "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/onetime": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
- "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==",
- "license": "MIT",
- "dependencies": {
- "mimic-fn": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/open": {
- "version": "7.4.2",
- "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
- "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
- "license": "MIT",
- "dependencies": {
- "is-docker": "^2.0.0",
- "is-wsl": "^2.1.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ora": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz",
- "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==",
- "license": "MIT",
- "dependencies": {
- "chalk": "^2.4.2",
- "cli-cursor": "^2.1.0",
- "cli-spinners": "^2.0.0",
- "log-symbols": "^2.2.0",
- "strip-ansi": "^5.2.0",
- "wcwidth": "^1.0.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/ora/node_modules/ansi-regex": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
- "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/ora/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/ora/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/ora/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/ora/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "license": "MIT"
- },
- "node_modules/ora/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/ora/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/ora/node_modules/strip-ansi": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
- "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^4.1.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/ora/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/parse-png": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/parse-png/-/parse-png-2.1.0.tgz",
- "integrity": "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ==",
- "license": "MIT",
- "dependencies": {
- "pngjs": "^3.3.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "license": "MIT"
- },
- "node_modules/path-scurry": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
- "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "lru-cache": "^11.0.0",
- "minipass": "^7.1.2"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/path-scurry/node_modules/lru-cache": {
- "version": "11.5.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz",
- "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": "20 || >=22"
- }
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
- "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
- "license": "MIT",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/pirates": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
- "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/plist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.1.tgz",
- "integrity": "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==",
- "license": "MIT",
- "dependencies": {
- "@xmldom/xmldom": "^0.9.10",
- "base64-js": "^1.5.1",
- "xmlbuilder": "^15.1.1"
- },
- "engines": {
- "node": ">=10.4.0"
- }
- },
- "node_modules/plist/node_modules/@xmldom/xmldom": {
- "version": "0.9.10",
- "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.10.tgz",
- "integrity": "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==",
- "license": "MIT",
- "engines": {
- "node": ">=14.6"
- }
- },
- "node_modules/pngjs": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
- "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==",
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.15",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
- "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "nanoid": "^3.3.12",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-import": {
- "version": "15.1.0",
- "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
- "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
- "license": "MIT",
- "dependencies": {
- "postcss-value-parser": "^4.0.0",
- "read-cache": "^1.0.0",
- "resolve": "^1.1.7"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.0.0"
- }
- },
- "node_modules/postcss-js": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz",
- "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "camelcase-css": "^2.0.1"
- },
- "engines": {
- "node": "^12 || ^14 || >= 16"
- },
- "peerDependencies": {
- "postcss": "^8.4.21"
- }
- },
- "node_modules/postcss-load-config": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz",
- "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "lilconfig": "^3.1.1"
- },
- "engines": {
- "node": ">= 18"
- },
- "peerDependencies": {
- "jiti": ">=1.21.0",
- "postcss": ">=8.0.9",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- },
- "postcss": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
- }
- },
- "node_modules/postcss-nested": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
- "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "postcss-selector-parser": "^6.1.1"
- },
- "engines": {
- "node": ">=12.0"
- },
- "peerDependencies": {
- "postcss": "^8.2.14"
- }
- },
- "node_modules/postcss-selector-parser": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz",
- "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==",
- "license": "MIT",
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "license": "MIT"
- },
- "node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/proc-log": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz",
- "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==",
- "license": "ISC",
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/promise": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz",
- "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==",
- "license": "MIT",
- "dependencies": {
- "asap": "~2.0.6"
- }
- },
- "node_modules/prompts": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
- "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
- "license": "MIT",
- "dependencies": {
- "kleur": "^3.0.3",
- "sisteransi": "^1.0.5"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/query-string": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/query-string/-/query-string-7.1.3.tgz",
- "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==",
- "license": "MIT",
- "dependencies": {
- "decode-uri-component": "^0.2.2",
- "filter-obj": "^1.1.0",
- "split-on-first": "^1.0.0",
- "strict-uri-encode": "^2.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/queue": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
- "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
- "license": "MIT",
- "dependencies": {
- "inherits": "~2.0.3"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/react": {
- "version": "19.2.3",
- "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
- "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-devtools-core": {
- "version": "6.1.5",
- "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-6.1.5.tgz",
- "integrity": "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==",
- "license": "MIT",
- "dependencies": {
- "shell-quote": "^1.6.1",
- "ws": "^7"
- }
- },
- "node_modules/react-dom": {
- "version": "19.2.3",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
- "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "scheduler": "^0.27.0"
- },
- "peerDependencies": {
- "react": "^19.2.3"
- }
- },
- "node_modules/react-fast-compare": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
- "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
- "license": "MIT"
- },
- "node_modules/react-freeze": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz",
- "integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "react": ">=17.0.0"
- }
- },
- "node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "license": "MIT"
- },
- "node_modules/react-native": {
- "version": "0.85.3",
- "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.85.3.tgz",
- "integrity": "sha512-HN/fGC+3nZVcDNcw7gfbM/DuqZAvI9Mz+/SxuhODaua4JY0BPzhfTzWXRyTR4mRgMHmShTPpH2PYMTxvZrsdZA==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@react-native/assets-registry": "0.85.3",
- "@react-native/codegen": "0.85.3",
- "@react-native/community-cli-plugin": "0.85.3",
- "@react-native/gradle-plugin": "0.85.3",
- "@react-native/js-polyfills": "0.85.3",
- "@react-native/normalize-colors": "0.85.3",
- "@react-native/virtualized-lists": "0.85.3",
- "abort-controller": "^3.0.0",
- "anser": "^1.4.9",
- "ansi-regex": "^5.0.0",
- "babel-plugin-syntax-hermes-parser": "0.33.3",
- "base64-js": "^1.5.1",
- "commander": "^12.0.0",
- "flow-enums-runtime": "^0.0.6",
- "hermes-compiler": "250829098.0.10",
- "invariant": "^2.2.4",
- "memoize-one": "^5.0.0",
- "metro-runtime": "^0.84.3",
- "metro-source-map": "^0.84.3",
- "nullthrows": "^1.1.1",
- "pretty-format": "^29.7.0",
- "promise": "^8.3.0",
- "react-devtools-core": "^6.1.5",
- "react-refresh": "^0.14.0",
- "regenerator-runtime": "^0.13.2",
- "scheduler": "0.27.0",
- "semver": "^7.1.3",
- "stacktrace-parser": "^0.1.10",
- "tinyglobby": "^0.2.15",
- "whatwg-fetch": "^3.0.0",
- "ws": "^7.5.10",
- "yargs": "^17.6.2"
- },
- "bin": {
- "react-native": "cli.js"
- },
- "engines": {
- "node": "^20.19.4 || ^22.13.0 || ^24.3.0 || >= 25.0.0"
- },
- "peerDependencies": {
- "@react-native/jest-preset": "0.85.3",
- "@types/react": "^19.1.1",
- "react": "^19.2.3"
- },
- "peerDependenciesMeta": {
- "@react-native/jest-preset": {
- "optional": true
- },
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-native-css-interop": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.2.6.tgz",
- "integrity": "sha512-uXad6EWqufupnRjrba2De30tiAx26kLEcwSV3eSLVBwpfYeOnrpDc9k6kHk6SBNbmHHlE5sc9vsfKdVRS9msYg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.22.15",
- "@babel/traverse": "^7.23.0",
- "@babel/types": "^7.23.0",
- "debug": "^4.3.7",
- "lightningcss": "~1.27.0",
- "semver": "^7.6.3"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "react": ">=18",
- "react-native": "*",
- "react-native-reanimated": ">=3.6.2",
- "tailwindcss": "~3"
- },
- "peerDependenciesMeta": {
- "react-native-safe-area-context": {
- "optional": true
- },
- "react-native-svg": {
- "optional": true
- }
- }
- },
- "node_modules/react-native-css-interop/node_modules/detect-libc": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
- "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
- "license": "Apache-2.0",
- "bin": {
- "detect-libc": "bin/detect-libc.js"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.27.0.tgz",
- "integrity": "sha512-8f7aNmS1+etYSLHht0fQApPc2kNO8qGRutifN5rVIc6Xo6ABsEbqOr758UwI7ALVbTt4x1fllKt0PYgzD9S3yQ==",
- "license": "MPL-2.0",
- "dependencies": {
- "detect-libc": "^1.0.3"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "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"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-darwin-arm64": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.27.0.tgz",
- "integrity": "sha512-Gl/lqIXY+d+ySmMbgDf0pgaWSqrWYxVHoc88q+Vhf2YNzZ8DwoRzGt5NZDVqqIW5ScpSnmmjcgXP87Dn2ylSSQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-darwin-x64": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.27.0.tgz",
- "integrity": "sha512-0+mZa54IlcNAoQS9E0+niovhyjjQWEMrwW0p2sSdLRhLDc8LMQ/b67z7+B5q4VmjYCMSfnFi3djAAQFIDuj/Tg==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-freebsd-x64": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.27.0.tgz",
- "integrity": "sha512-n1sEf85fePoU2aDN2PzYjoI8gbBqnmLGEhKq7q0DKLj0UTVmOTwDC7PtLcy/zFxzASTSBlVQYJUhwIStQMIpRA==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.27.0.tgz",
- "integrity": "sha512-MUMRmtdRkOkd5z3h986HOuNBD1c2lq2BSQA1Jg88d9I7bmPGx08bwGcnB75dvr17CwxjxD6XPi3Qh8ArmKFqCA==",
- "cpu": [
- "arm"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.27.0.tgz",
- "integrity": "sha512-cPsxo1QEWq2sfKkSq2Bq5feQDHdUEwgtA9KaB27J5AX22+l4l0ptgjMZZtYtUnteBofjee+0oW1wQ1guv04a7A==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.27.0.tgz",
- "integrity": "sha512-rCGBm2ax7kQ9pBSeITfCW9XSVF69VX+fm5DIpvDZQl4NnQoMQyRwhZQm9pd59m8leZ1IesRqWk2v/DntMo26lg==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.27.0.tgz",
- "integrity": "sha512-Dk/jovSI7qqhJDiUibvaikNKI2x6kWPN79AQiD/E/KeQWMjdGe9kw51RAgoWFDi0coP4jinaH14Nrt/J8z3U4A==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-linux-x64-musl": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.27.0.tgz",
- "integrity": "sha512-QKjTxXm8A9s6v9Tg3Fk0gscCQA1t/HMoF7Woy1u68wCk5kS4fR+q3vXa1p3++REW784cRAtkYKrPy6JKibrEZA==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.27.0.tgz",
- "integrity": "sha512-/wXegPS1hnhkeG4OXQKEMQeJd48RDC3qdh+OA8pCuOPCyvnm/yEayrJdJVqzBsqpy1aJklRCVxscpFur80o6iQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-css-interop/node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.27.0",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.27.0.tgz",
- "integrity": "sha512-/OJLj94Zm/waZShL8nB5jsNj3CfNATLCTyFxZyouilfTmSoLDX7VlVAmhPHoZWVFp4vdmoiEbPEYC8HID3m6yw==",
- "cpu": [
- "x64"
- ],
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/react-native-drawer-layout": {
- "version": "4.2.5",
- "resolved": "https://registry.npmjs.org/react-native-drawer-layout/-/react-native-drawer-layout-4.2.5.tgz",
- "integrity": "sha512-Yl82uLkXjXuq7222hWGIDsq5A6R/bsCeCEgdIxQUxAEHf00oRdDnRByLx3Fsij3qwtmYNPGrHV1NH8G8hbCbLQ==",
- "license": "MIT",
- "dependencies": {
- "color": "^4.2.3",
- "use-latest-callback": "^0.2.4"
- },
- "peerDependencies": {
- "react": ">= 18.2.0",
- "react-native": "*",
- "react-native-gesture-handler": ">= 2.0.0",
- "react-native-reanimated": ">= 2.0.0"
- }
- },
- "node_modules/react-native-gesture-handler": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-3.0.2.tgz",
- "integrity": "sha512-XBTgmvr2jh/xrMwlHTV2Z1x6IFUl3zfLxyaCAnvj3GSXK5YlY3ZmiIs57hniPmh3I7RtjPFxtGdRr0i+PzyBrg==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@types/react-test-renderer": "^19.1.0",
- "invariant": "^2.2.4"
- },
- "peerDependencies": {
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/react-native-is-edge-to-edge": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.3.1.tgz",
- "integrity": "sha512-NIXU/iT5+ORyCc7p0z2nnlkouYKX425vuU1OEm6bMMtWWR9yvb+Xg5AZmImTKoF9abxCPqrKC3rOZsKzUYgYZA==",
- "license": "MIT",
- "peerDependencies": {
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/react-native-reanimated": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.3.1.tgz",
- "integrity": "sha512-KhGsS0YkCA+gusgyzlf9hnqzVPIR398KTpqXyqq/+yYJJPAvyEEPKcxlB0xtOOXSMrR2A9uRKVARVQhZwrOh+Q==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "react-native-is-edge-to-edge": "^1.3.1",
- "semver": "^7.7.3"
- },
- "peerDependencies": {
- "react": "*",
- "react-native": "0.81 - 0.85",
- "react-native-worklets": "0.8.x"
- }
- },
- "node_modules/react-native-safe-area-context": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.7.0.tgz",
- "integrity": "sha512-/9/MtQz8ODphjsLdZ+GZAIcC/RtoqW9EeShf7Uvnfgm/pzYrJ75y3PV/J1wuAV1T5Dye5ygq4EAW20RoBq0ABQ==",
- "license": "MIT",
- "peer": true,
- "peerDependencies": {
- "react": "*",
- "react-native": "*"
- }
- },
- "node_modules/react-native-screens": {
- "version": "4.25.2",
- "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.25.2.tgz",
- "integrity": "sha512-1Nj1fusFd+rIMKU/qC9yGKVG+3ofh11d3OdBQKL1iVvQfKvcB8vhvTGQf2TkfxW3bamxN+hCZIXmNuU0mRkyDg==",
- "license": "MIT",
- "dependencies": {
- "react-freeze": "^1.0.0",
- "warn-once": "^0.1.0"
- },
- "peerDependencies": {
- "react": "*",
- "react-native": ">=0.82.0"
- }
- },
- "node_modules/react-native-web": {
- "version": "0.21.2",
- "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz",
- "integrity": "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@babel/runtime": "^7.18.6",
- "@react-native/normalize-colors": "^0.74.1",
- "fbjs": "^3.0.4",
- "inline-style-prefixer": "^7.0.1",
- "memoize-one": "^6.0.0",
- "nullthrows": "^1.1.1",
- "postcss-value-parser": "^4.2.0",
- "styleq": "^0.1.3"
- },
- "peerDependencies": {
- "react": "^18.0.0 || ^19.0.0",
- "react-dom": "^18.0.0 || ^19.0.0"
- }
- },
- "node_modules/react-native-web/node_modules/@react-native/normalize-colors": {
- "version": "0.74.89",
- "resolved": "https://registry.npmjs.org/@react-native/normalize-colors/-/normalize-colors-0.74.89.tgz",
- "integrity": "sha512-qoMMXddVKVhZ8PA1AbUCk83trpd6N+1nF2A6k1i6LsQObyS92fELuk8kU/lQs6M7BsMHwqyLCpQJ1uFgNvIQXg==",
- "license": "MIT"
- },
- "node_modules/react-native-web/node_modules/memoize-one": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
- "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
- "license": "MIT"
- },
- "node_modules/react-native-worklets": {
- "version": "0.8.3",
- "resolved": "https://registry.npmjs.org/react-native-worklets/-/react-native-worklets-0.8.3.tgz",
- "integrity": "sha512-oCBJROyLU7yG/1R8s0INMflygTH71bx+5XcYkH0CM938TlhSoVbiunE1WVW5FZa51vwYqfLie/IXMX2s1Kh3eg==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@babel/plugin-transform-arrow-functions": "^7.27.1",
- "@babel/plugin-transform-class-properties": "^7.27.1",
- "@babel/plugin-transform-classes": "^7.28.4",
- "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1",
- "@babel/plugin-transform-optional-chaining": "^7.27.1",
- "@babel/plugin-transform-shorthand-properties": "^7.27.1",
- "@babel/plugin-transform-template-literals": "^7.27.1",
- "@babel/plugin-transform-unicode-regex": "^7.27.1",
- "@babel/preset-typescript": "^7.27.1",
- "convert-source-map": "^2.0.0",
- "semver": "^7.7.3"
- },
- "peerDependencies": {
- "@babel/core": "*",
- "@react-native/metro-config": "*",
- "react": "*",
- "react-native": "0.81 - 0.85"
- }
- },
- "node_modules/react-native/node_modules/commander": {
- "version": "12.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
- "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/react-refresh": {
- "version": "0.14.2",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
- "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-remove-scroll": {
- "version": "2.7.2",
- "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",
- "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==",
- "license": "MIT",
- "dependencies": {
- "react-remove-scroll-bar": "^2.3.7",
- "react-style-singleton": "^2.2.3",
- "tslib": "^2.1.0",
- "use-callback-ref": "^1.3.3",
- "use-sidecar": "^1.1.3"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-remove-scroll-bar": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz",
- "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==",
- "license": "MIT",
- "dependencies": {
- "react-style-singleton": "^2.2.2",
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/react-style-singleton": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
- "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==",
- "license": "MIT",
- "dependencies": {
- "get-nonce": "^1.0.0",
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/read-cache": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
- "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
- "license": "MIT",
- "dependencies": {
- "pify": "^2.3.0"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "license": "MIT",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/redent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
- "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
- "license": "MIT",
- "dependencies": {
- "indent-string": "^4.0.0",
- "strip-indent": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/regenerate": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
- "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
- "license": "MIT"
- },
- "node_modules/regenerate-unicode-properties": {
- "version": "10.2.2",
- "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz",
- "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==",
- "license": "MIT",
- "dependencies": {
- "regenerate": "^1.4.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/regenerator-runtime": {
- "version": "0.13.11",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
- "license": "MIT"
- },
- "node_modules/regexpu-core": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz",
- "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==",
- "license": "MIT",
- "dependencies": {
- "regenerate": "^1.4.2",
- "regenerate-unicode-properties": "^10.2.2",
- "regjsgen": "^0.8.0",
- "regjsparser": "^0.13.0",
- "unicode-match-property-ecmascript": "^2.0.0",
- "unicode-match-property-value-ecmascript": "^2.2.1"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/regjsgen": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz",
- "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
- "license": "MIT"
- },
- "node_modules/regjsparser": {
- "version": "0.13.2",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.2.tgz",
- "integrity": "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "jsesc": "~3.1.0"
- },
- "bin": {
- "regjsparser": "bin/parser"
- }
- },
- "node_modules/require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve": {
- "version": "1.22.12",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
- "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "is-core-module": "^2.16.1",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/resolve-workspace-root": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/resolve-workspace-root/-/resolve-workspace-root-2.0.1.tgz",
- "integrity": "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w==",
- "license": "MIT"
- },
- "node_modules/restore-cursor": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
- "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==",
- "license": "MIT",
- "dependencies": {
- "onetime": "^2.0.0",
- "signal-exit": "^3.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/reusify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
- "license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/safe-buffer": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
- "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "license": "MIT"
- },
- "node_modules/sax": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz",
- "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=11.0.0"
- }
- },
- "node_modules/scheduler": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
- "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
- "license": "MIT"
- },
- "node_modules/semver": {
- "version": "7.8.5",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
- "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/send": {
- "version": "0.19.2",
- "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz",
- "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==",
- "license": "MIT",
- "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.1",
- "mime": "1.6.0",
- "ms": "2.1.3",
- "on-finished": "~2.4.1",
- "range-parser": "~1.2.1",
- "statuses": "~2.0.2"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/send/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "license": "MIT",
- "dependencies": {
- "ms": "2.0.0"
- }
- },
- "node_modules/send/node_modules/debug/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
- "license": "MIT"
- },
- "node_modules/send/node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/send/node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/send/node_modules/statuses": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/serialize-error": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz",
- "integrity": "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/serve-static": {
- "version": "1.16.3",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz",
- "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==",
- "license": "MIT",
- "dependencies": {
- "encodeurl": "~2.0.0",
- "escape-html": "~1.0.3",
- "parseurl": "~1.3.3",
- "send": "~0.19.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/serve-static/node_modules/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/server-only": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz",
- "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
- "license": "MIT"
- },
- "node_modules/setimmediate": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
- "license": "MIT"
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "license": "ISC"
- },
- "node_modules/sf-symbols-typescript": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/sf-symbols-typescript/-/sf-symbols-typescript-2.2.0.tgz",
- "integrity": "sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/shallowequal": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
- "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
- "license": "MIT"
- },
- "node_modules/shebang-command": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
- "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shell-quote": {
- "version": "1.8.4",
- "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.4.tgz",
- "integrity": "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "license": "ISC"
- },
- "node_modules/simple-plist": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz",
- "integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==",
- "license": "MIT",
- "dependencies": {
- "bplist-creator": "0.1.0",
- "bplist-parser": "0.3.1",
- "plist": "^3.0.5"
- }
- },
- "node_modules/simple-plist/node_modules/bplist-parser": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz",
- "integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==",
- "license": "MIT",
- "dependencies": {
- "big-integer": "1.6.x"
- },
- "engines": {
- "node": ">= 5.10.0"
- }
- },
- "node_modules/simple-swizzle": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz",
- "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==",
- "license": "MIT",
- "dependencies": {
- "is-arrayish": "^0.3.1"
- }
- },
- "node_modules/sisteransi": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
- "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
- "license": "MIT"
- },
- "node_modules/slugify": {
- "version": "1.6.9",
- "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.9.tgz",
- "integrity": "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==",
- "license": "MIT",
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-support": {
- "version": "0.5.21",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
- "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
- "license": "MIT",
- "dependencies": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
- },
- "node_modules/source-map-support/node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/split-on-first": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
- "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/stackframe": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
- "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
- "license": "MIT"
- },
- "node_modules/stacktrace-parser": {
- "version": "0.1.11",
- "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz",
- "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==",
- "license": "MIT",
- "dependencies": {
- "type-fest": "^0.7.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/standard-navigation": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/standard-navigation/-/standard-navigation-0.0.5.tgz",
- "integrity": "sha512-YAmzwAiiQVocZxO/VGPFiQHcu5pKiz09QIGC0MK6aRMoa3E0QkoTQgcqJr7ZZ3OMiNhu4DkaGElFI5htjOIDbw==",
- "license": "MIT"
- },
- "node_modules/statuses": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
- "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/stream-buffers": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz",
- "integrity": "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==",
- "license": "Unlicense",
- "engines": {
- "node": ">= 0.10.0"
- }
- },
- "node_modules/strict-uri-encode": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
- "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-indent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
- "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
- "license": "MIT",
- "dependencies": {
- "min-indent": "^1.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/structured-headers": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/structured-headers/-/structured-headers-0.4.1.tgz",
- "integrity": "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==",
- "license": "MIT"
- },
- "node_modules/styleq": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/styleq/-/styleq-0.1.3.tgz",
- "integrity": "sha512-3ZUifmCDCQanjeej1f6kyl/BeP/Vae5EYkQ9iJfUm/QwZvlgnZzyflqAsAWYURdtea8Vkvswu2GrC57h3qffcA==",
- "license": "MIT"
- },
- "node_modules/sucrase": {
- "version": "3.35.1",
- "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz",
- "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.2",
- "commander": "^4.0.0",
- "lines-and-columns": "^1.1.6",
- "mz": "^2.7.0",
- "pirates": "^4.0.1",
- "tinyglobby": "^0.2.11",
- "ts-interface-checker": "^0.1.9"
- },
- "bin": {
- "sucrase": "bin/sucrase",
- "sucrase-node": "bin/sucrase-node"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/sucrase/node_modules/commander": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
- "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-hyperlinks": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
- "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0",
- "supports-color": "^7.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/tailwindcss": {
- "version": "3.4.19",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz",
- "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==",
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@alloc/quick-lru": "^5.2.0",
- "arg": "^5.0.2",
- "chokidar": "^3.6.0",
- "didyoumean": "^1.2.2",
- "dlv": "^1.1.3",
- "fast-glob": "^3.3.2",
- "glob-parent": "^6.0.2",
- "is-glob": "^4.0.3",
- "jiti": "^1.21.7",
- "lilconfig": "^3.1.3",
- "micromatch": "^4.0.8",
- "normalize-path": "^3.0.0",
- "object-hash": "^3.0.0",
- "picocolors": "^1.1.1",
- "postcss": "^8.4.47",
- "postcss-import": "^15.1.0",
- "postcss-js": "^4.0.1",
- "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
- "postcss-nested": "^6.2.0",
- "postcss-selector-parser": "^6.1.2",
- "resolve": "^1.22.8",
- "sucrase": "^3.35.0"
- },
- "bin": {
- "tailwind": "lib/cli.js",
- "tailwindcss": "lib/cli.js"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/terminal-link": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
- "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
- "license": "MIT",
- "dependencies": {
- "ansi-escapes": "^4.2.1",
- "supports-hyperlinks": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/terser": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz",
- "integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==",
- "license": "BSD-2-Clause",
- "dependencies": {
- "@jridgewell/source-map": "^0.3.3",
- "acorn": "^8.15.0",
- "commander": "^2.20.0",
- "source-map-support": "~0.5.20"
- },
- "bin": {
- "terser": "bin/terser"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/terser/node_modules/commander": {
- "version": "2.20.3",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "license": "MIT"
- },
- "node_modules/thenify": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
- "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
- "license": "MIT",
- "dependencies": {
- "any-promise": "^1.0.0"
- }
- },
- "node_modules/thenify-all": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
- "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
- "license": "MIT",
- "dependencies": {
- "thenify": ">= 3.1.0 < 4"
- },
- "engines": {
- "node": ">=0.8"
- }
- },
- "node_modules/throat": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
- "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
- "license": "MIT"
- },
- "node_modules/tinyglobby": {
- "version": "0.2.17",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
- "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.4"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "node_modules/tinyglobby/node_modules/fdir": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
- "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
- "license": "MIT",
- "engines": {
- "node": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/tinyglobby/node_modules/picomatch": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
- "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
- "license": "MIT",
- "peer": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/tmpl": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
- "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
- "license": "BSD-3-Clause"
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/toqr": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/toqr/-/toqr-0.1.1.tgz",
- "integrity": "sha512-FWAPzCIHZHnrE/5/w9MPk0kK25hSQSH2IKhYh9PyjS3SG/+IEMvlwIHbhz+oF7xl54I+ueZlVnMjyzdSwLmAwA==",
- "license": "MIT"
- },
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "license": "MIT"
- },
- "node_modules/ts-interface-checker": {
- "version": "0.1.13",
- "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
- "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
- "license": "Apache-2.0"
- },
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "license": "0BSD"
- },
- "node_modules/type-fest": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
- "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/typescript": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
- "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
- "devOptional": true,
- "license": "Apache-2.0",
- "peer": true,
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/ua-parser-js": {
- "version": "1.0.41",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.41.tgz",
- "integrity": "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/ua-parser-js"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/faisalman"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/faisalman"
- }
- ],
- "license": "MIT",
- "bin": {
- "ua-parser-js": "script/cli.js"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/undici-types": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
- "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
- "license": "MIT"
- },
- "node_modules/unicode-canonical-property-names-ecmascript": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
- "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unicode-match-property-ecmascript": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
- "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
- "license": "MIT",
- "dependencies": {
- "unicode-canonical-property-names-ecmascript": "^2.0.0",
- "unicode-property-aliases-ecmascript": "^2.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unicode-match-property-value-ecmascript": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz",
- "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unicode-property-aliases-ecmascript": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz",
- "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/update-browserslist-db": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
- "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/use-callback-ref": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz",
- "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==",
- "license": "MIT",
- "dependencies": {
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/use-latest-callback": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.6.tgz",
- "integrity": "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg==",
- "license": "MIT",
- "peerDependencies": {
- "react": ">=16.8"
- }
- },
- "node_modules/use-sidecar": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
- "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==",
- "license": "MIT",
- "dependencies": {
- "detect-node-es": "^1.1.0",
- "tslib": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "@types/react": "*",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- }
- }
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "license": "MIT"
- },
- "node_modules/utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4.0"
- }
- },
- "node_modules/uuid": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
- "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
- "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
- "license": "MIT",
- "bin": {
- "uuid": "dist/bin/uuid"
- }
- },
- "node_modules/validate-npm-package-name": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz",
- "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==",
- "license": "ISC",
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/vaul": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz",
- "integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==",
- "license": "MIT",
- "dependencies": {
- "@radix-ui/react-dialog": "^1.1.1"
- },
- "peerDependencies": {
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
- }
- },
- "node_modules/vlq": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
- "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==",
- "license": "MIT"
- },
- "node_modules/walker": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
- "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "makeerror": "1.0.12"
- }
- },
- "node_modules/warn-once": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz",
- "integrity": "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==",
- "license": "MIT"
- },
- "node_modules/wcwidth": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
- "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
- "license": "MIT",
- "dependencies": {
- "defaults": "^1.0.3"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "license": "BSD-2-Clause"
- },
- "node_modules/whatwg-fetch": {
- "version": "3.6.20",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
- "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==",
- "license": "MIT"
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/whatwg-url-minimum": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/whatwg-url-minimum/-/whatwg-url-minimum-0.1.2.tgz",
- "integrity": "sha512-XPEm0XFQWNVG292lII1PrRRJl3sItrs7CettZ4ncYxuDVpLyy+NwlGyut2hXI0JswcJUxeCH+CyOJK0ZzAXD6A==",
- "license": "MIT"
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/ws": {
- "version": "7.5.11",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.11.tgz",
- "integrity": "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA==",
- "license": "MIT",
- "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
- }
- }
- },
- "node_modules/xcode": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/xcode/-/xcode-3.0.1.tgz",
- "integrity": "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==",
- "license": "Apache-2.0",
- "dependencies": {
- "simple-plist": "^1.1.0",
- "uuid": "^7.0.3"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/xml2js": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.0.tgz",
- "integrity": "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w==",
- "license": "MIT",
- "dependencies": {
- "sax": ">=0.6.0",
- "xmlbuilder": "~11.0.0"
- },
- "engines": {
- "node": ">=4.0.0"
- }
- },
- "node_modules/xml2js/node_modules/xmlbuilder": {
- "version": "11.0.1",
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
- "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
- "license": "MIT",
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/xmlbuilder": {
- "version": "15.1.1",
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
- "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
- "license": "MIT",
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "license": "ISC"
- },
- "node_modules/yaml": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
- "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
- "license": "ISC",
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/eemeli"
- }
- },
- "node_modules/yargs": {
- "version": "17.7.3",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz",
- "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==",
- "license": "MIT",
- "dependencies": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/zod": {
- "version": "3.25.76",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
- "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- }
- }
-}
diff --git a/package.json b/package.json
deleted file mode 100644
index 7d92963..0000000
--- a/package.json
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "name": "codexbar.mobile",
- "version": "1.0.0",
- "main": "expo-router/entry",
- "dependencies": {
- "@expo/metro-runtime": "~56.0.15",
- "@expo/vector-icons": "^15.1.1",
- "babel-preset-expo": "~56.0.0",
- "expo": "~56.0.14",
- "expo-constants": "~56.0.20",
- "expo-document-picker": "~56.0.4",
- "expo-file-system": "~56.0.8",
- "expo-font": "~56.0.7",
- "expo-linking": "~56.0.15",
- "expo-notifications": "~56.0.19",
- "expo-router": "~56.2.13",
- "expo-secure-store": "~56.0.4",
- "expo-splash-screen": "~56.0.10",
- "expo-status-bar": "~56.0.4",
- "expo-system-ui": "~56.0.5",
- "expo-updates": "~56.0.21",
- "nativewind": "^4.2.6",
- "react": "19.2.3",
- "react-dom": "^19.2.3",
- "react-native": "0.85.3",
- "react-native-reanimated": "4.3.1",
- "react-native-safe-area-context": "~5.7.0",
- "react-native-screens": "4.25.2",
- "react-native-web": "^0.21.2",
- "react-native-worklets": "^0.8.3"
- },
- "devDependencies": {
- "@types/react": "~19.2.2",
- "tailwindcss": "^3.4.19",
- "typescript": "~6.0.3"
- },
- "scripts": {
- "start": "expo start",
- "android": "expo start --android",
- "ios": "expo start --ios",
- "web": "expo start --web",
- "update:preview": "eas update --channel preview --environment preview",
- "update:production": "eas update --channel production --environment production",
- "build:android:preview": "eas build --platform android --profile preview --non-interactive",
- "build:android:production": "eas build --platform android --profile production --non-interactive"
- },
- "private": true
-}
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..c954e70
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,18 @@
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.name = 'CodexMobile'
+include ':app'
diff --git a/tailwind.config.js b/tailwind.config.js
deleted file mode 100644
index 6d797b5..0000000
--- a/tailwind.config.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-module.exports = {
- content: [
- "./app/**/*.{js,jsx,ts,tsx}",
- "./components/**/*.{js,jsx,ts,tsx}",
- "./hooks/**/*.{js,jsx,ts,tsx}",
- ],
- presets: [require("nativewind/preset")],
- theme: {
- extend: {
- colors: {
- brand: {
- codex: "#10a37f",
- claude: "#d97706",
- },
- },
- },
- },
- plugins: [],
-};
diff --git a/tsconfig.json b/tsconfig.json
deleted file mode 100644
index a7bbebe..0000000
--- a/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "expo/tsconfig.base",
- "compilerOptions": {
- "strict": true,
- "paths": {
- "@/*": ["./*"]
- }
- },
- "include": [
- "**/*.ts",
- "**/*.tsx",
- ".expo/types/**/*.d.ts",
- "nativewind-env.d.ts"
- ]
-}
diff --git a/types/claude.ts b/types/claude.ts
deleted file mode 100644
index 2019d15..0000000
--- a/types/claude.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-export interface ClaudeAuth {
- sessionKey: string;
- lastActiveOrg?: string;
-}
-
-export interface ClaudeOrg {
- uuid: string;
- name: string;
-}
-
-export interface ClaudeWindowUsage {
- utilization: number;
- resets_at?: string;
-}
-
-export interface ClaudeUsageResponse {
- five_hour: ClaudeWindowUsage;
- seven_day: ClaudeWindowUsage;
- seven_day_sonnet?: ClaudeWindowUsage;
- seven_day_opus?: ClaudeWindowUsage;
-}
diff --git a/types/codex.ts b/types/codex.ts
deleted file mode 100644
index 86a3c40..0000000
--- a/types/codex.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-export interface CodexAuth {
- accessToken: string;
- accountId?: string;
-}
-
-export interface CodexUsageWindow {
- usedPercent: number;
- resetsAt: number;
- windowMinutes: number;
- windowSeconds: number;
-}
-
-export interface CodexCreditsSummary {
- hasCredits: boolean;
- unlimited: boolean;
- balance: number;
-}
-
-export interface CodexResetCredit {
- index: number;
- status?: string;
- grantedAt?: string | null;
- grantedAtLocal?: string | null;
- expiresAt?: string | null;
- expiresAtLocal?: string | null;
- timeUntilExpiry?: string | null;
-}
-
-export interface CodexResetCoupons {
- source: "live_api" | "local_state_fallback" | "unavailable";
- sourceDescription: string;
- availableCount?: number | null;
- totalEarnedCount?: number | null;
- credits?: CodexResetCredit[];
- nextExpiringCredit?: CodexResetCredit | null;
- dismissedAtLocal?: string | null;
- latestPossibleExpiryLocal?: string | null;
- latestPossibleExpiryNote?: string | null;
- fallbackReason?: string;
- error?: string;
-}
-
-export interface CodexDesktopSnapshot {
- sessionFile?: string;
- threadId?: string | null;
- snapshotTimestamp?: string | null;
- limitId?: string | null;
- planType?: string | null;
- rateLimitReachedType?: string | null;
- primary: CodexUsageWindow | null;
- secondary: CodexUsageWindow | null;
-}
-
-export interface CodexUsageResponse extends CodexDesktopSnapshot {
- credits: CodexCreditsSummary;
- resetCoupons?: CodexResetCoupons | null;
-}