diff --git a/.eas/workflows/development-builds.yml b/.eas/workflows/development-builds.yml new file mode 100644 index 00000000..541e5ff2 --- /dev/null +++ b/.eas/workflows/development-builds.yml @@ -0,0 +1,22 @@ +name: Create development builds + +on: + pull_request: + branches: + - main + - release/* + +jobs: + build_android: + name: Build Android (dev) + type: build + params: + platform: android + profile: development + + build_ios_simulator: + name: Build iOS Simulator (dev) + type: build + params: + platform: ios + profile: preview diff --git a/.eas/workflows/preview-update.yml b/.eas/workflows/preview-update.yml new file mode 100644 index 00000000..cb317dd6 --- /dev/null +++ b/.eas/workflows/preview-update.yml @@ -0,0 +1,14 @@ +name: Publish preview update + +on: + push: + branches: + - '*' + - '!main' + +jobs: + publish_preview: + name: Publish preview update + type: update + params: + branch: ${{ github.ref_name || 'preview' }} diff --git a/.eas/workflows/production-deploy.yml b/.eas/workflows/production-deploy.yml new file mode 100644 index 00000000..501d8d92 --- /dev/null +++ b/.eas/workflows/production-deploy.yml @@ -0,0 +1,67 @@ +name: Deploy to production + +on: + push: + branches: + - main + +jobs: + fingerprint: + name: Fingerprint + type: fingerprint + + # NOTE: get-build intentionally uses default behavior (completed builds only). + # If a build is in-progress, we skip and let it complete on its own. + # This prevents duplicate builds and OTA updates that would race with ongoing builds. + # Set wait_for_in_progress: true if you want to wait for in-progress builds instead. + get_android_build: + name: Check existing Android build + needs: [fingerprint] + type: get-build + params: + fingerprint_hash: ${{ needs.fingerprint.outputs.android_fingerprint_hash }} + profile: production + + get_ios_build: + name: Check existing iOS build + needs: [fingerprint] + type: get-build + params: + fingerprint_hash: ${{ needs.fingerprint.outputs.ios_fingerprint_hash }} + profile: production + + build_android: + name: Build Android + needs: [get_android_build] + if: ${{ !needs.get_android_build.outputs.build_id }} + type: build + params: + platform: android + profile: production + + build_ios: + name: Build iOS + needs: [get_ios_build] + if: ${{ !needs.get_ios_build.outputs.build_id }} + type: build + params: + platform: ios + profile: production + + publish_android_update: + name: Publish Android OTA update + needs: [get_android_build] + if: ${{ needs.get_android_build.outputs.build_id }} + type: update + params: + branch: production + platform: android + + publish_ios_update: + name: Publish iOS OTA update + needs: [get_ios_build] + if: ${{ needs.get_ios_build.outputs.build_id }} + type: update + params: + branch: production + platform: ios diff --git a/.github/actions/setup-thumbcode/action.yml b/.github/actions/setup-thumbcode/action.yml index a5d51458..3260df07 100644 --- a/.github/actions/setup-thumbcode/action.yml +++ b/.github/actions/setup-thumbcode/action.yml @@ -2,14 +2,10 @@ name: 'Setup ThumbCode Environment' description: 'Reusable setup action for ThumbCode workflows - installs Node, pnpm, dependencies, and generates tokens' inputs: - node-version: - description: 'Node.js version to use' + node-version-file: + description: 'File containing Node.js version (defaults to .nvmrc)' required: false - default: '20' - pnpm-version: - description: 'pnpm version to use' - required: false - default: '10' + default: '.nvmrc' generate-tokens: description: 'Whether to generate design tokens' required: false @@ -24,13 +20,12 @@ runs: steps: - name: Install pnpm uses: pnpm/action-setup@c5ba7f7862a0f64c1b1a05fbac13e0b8e86ba08c # v4 - with: - version: ${{ inputs.pnpm-version }} + # Reads version from packageManager field in package.json - name: Setup Node.js - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6 with: - node-version: ${{ inputs.node-version }} + node-version-file: ${{ inputs.node-version-file }} cache: 'pnpm' - name: Install dependencies diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 00000000..f77b06bc --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,185 @@ +name: CD + +on: + push: + branches: [main] + paths: + - 'src/**' + - 'app.json' + - 'eas.json' + - 'package.json' + pull_request: + branches: [main] + paths: + - 'src/**' + - 'app.json' + - 'eas.json' + - 'package.json' + workflow_dispatch: + inputs: + platform: + description: 'Platform to build' + required: true + default: 'all' + type: choice + options: + - all + - android + - ios + - web + profile: + description: 'Build profile' + required: true + default: 'preview' + type: choice + options: + - development + - preview + - production + +# Prevent concurrent deployments +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +permissions: + contents: read + pull-requests: write + +jobs: + # ============================================ + # EAS Update for PRs (OTA Updates) + # ============================================ + eas-update: + name: EAS Update (PR Preview) + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + pull-requests: write + + steps: + - name: Check for EXPO_TOKEN + id: check-token + env: + EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} + run: | + if [ -z "$EXPO_TOKEN" ]; then + echo "::warning::EXPO_TOKEN secret is not configured. Skipping EAS update." + echo "Learn more: https://docs.expo.dev/eas-update/github-actions" + echo "has_token=false" >> $GITHUB_OUTPUT + else + echo "has_token=true" >> $GITHUB_OUTPUT + fi + + - name: Checkout code + if: steps.check-token.outputs.has_token == 'true' + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup ThumbCode environment + if: steps.check-token.outputs.has_token == 'true' + uses: ./.github/actions/setup-thumbcode + + - name: Setup Expo and EAS + if: steps.check-token.outputs.has_token == 'true' + uses: expo/expo-github-action@c7b66a9c327a43a8fa7c0158e7f30d6040d2481e # v8 + with: + eas-version: latest + token: ${{ secrets.EXPO_TOKEN }} + + - name: Create preview update + if: steps.check-token.outputs.has_token == 'true' + uses: expo/expo-github-action/preview@c7b66a9c327a43a8fa7c0158e7f30d6040d2481e # v8 + with: + command: eas update --auto + env: + # Use production slug to match EAS project configuration + EXPO_PUBLIC_APP_ENV: production + + # ============================================ + # EAS Build - Android + # ============================================ + build-android: + name: Build Android + if: | + (github.event_name == 'push' && github.ref == 'refs/heads/main') || + (github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'android')) + runs-on: ubuntu-latest + timeout-minutes: 60 + + steps: + - name: Check for EXPO_TOKEN + env: + EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} + run: | + if [ -z "$EXPO_TOKEN" ]; then + echo "::error::EXPO_TOKEN secret is required for EAS builds" + exit 1 + fi + + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup ThumbCode environment + uses: ./.github/actions/setup-thumbcode + + - name: Setup Expo and EAS + uses: expo/expo-github-action@c7b66a9c327a43a8fa7c0158e7f30d6040d2481e # v8 + with: + eas-version: latest + token: ${{ secrets.EXPO_TOKEN }} + + - name: Build Android + run: | + PROFILE="${{ github.event.inputs.profile || 'preview' }}" + eas build --platform android --profile $PROFILE --non-interactive --no-wait + + # ============================================ + # EAS Build - iOS + # ============================================ + build-ios: + name: Build iOS + if: | + (github.event_name == 'push' && github.ref == 'refs/heads/main') || + (github.event_name == 'workflow_dispatch' && (github.event.inputs.platform == 'all' || github.event.inputs.platform == 'ios')) + runs-on: ubuntu-latest + timeout-minutes: 60 + + steps: + - name: Check for EXPO_TOKEN + env: + EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }} + run: | + if [ -z "$EXPO_TOKEN" ]; then + echo "::error::EXPO_TOKEN secret is required for EAS builds" + exit 1 + fi + + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup ThumbCode environment + uses: ./.github/actions/setup-thumbcode + + - name: Setup Expo and EAS + uses: expo/expo-github-action@c7b66a9c327a43a8fa7c0158e7f30d6040d2481e # v8 + with: + eas-version: latest + token: ${{ secrets.EXPO_TOKEN }} + + - name: Build iOS + run: | + PROFILE="${{ github.event.inputs.profile || 'preview' }}" + eas build --platform ios --profile $PROFILE --non-interactive --no-wait + + # ============================================ + # NOTE: App Store Submissions + # ============================================ + # Production submission jobs are not yet configured. + # See issue #66 for required credentials and setup. + # + # Current release strategy: + # - Web staging: Automatic via Render.com (render.yaml) + # - Mobile builds: Download from expo.dev after EAS build completes + # - Debug APK: Can be downloaded from expo.dev build artifacts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d8e2d26..fbfa5438 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - fetch-depth: 0 # Shallow clones disabled for SonarCloud + fetch-depth: 0 # Shallow clones disabled for SonarCloud - name: Setup ThumbCode environment uses: ./.github/actions/setup-thumbcode @@ -69,7 +69,7 @@ jobs: run: pnpm run test:coverage - name: Upload coverage to Codecov - uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 + uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 if: always() with: token: ${{ secrets.CODECOV_TOKEN }} @@ -78,7 +78,7 @@ jobs: name: codecov-umbrella - name: Upload coverage to Coveralls - uses: coverallsapp/github-action@643bc377ffa44ace6394b2b5d0d3950076de9f63 # v2.3.0 + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2 if: always() with: github-token: ${{ secrets.GITHUB_TOKEN }} @@ -87,7 +87,7 @@ jobs: flag-name: unit-tests - name: SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@e44258b109568baa0df60ed515909fc6c72cba92 # v2.3.0 + uses: SonarSource/sonarcloud-github-action@ffc3010689be73b8e5ae0c57ce35968afd7909e8 # v5 if: always() env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -98,8 +98,8 @@ jobs: -Dsonar.pullrequest.branch=${{ github.head_ref }} -Dsonar.pullrequest.base=${{ github.base_ref }} - build: - name: Build + build-web: + name: Build Web runs-on: ubuntu-latest timeout-minutes: 15 @@ -116,13 +116,48 @@ jobs: CI: true - name: Upload build artifacts - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 if: success() with: name: web-build path: dist/ retention-days: 7 + e2e-web: + name: E2E Tests (Web) + runs-on: ubuntu-latest + timeout-minutes: 20 + needs: build-web + + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Setup ThumbCode environment + uses: ./.github/actions/setup-thumbcode + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + + - name: Download web build + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 + with: + name: web-build + path: dist/ + + - name: Run E2E tests + run: pnpm run test:e2e:web + env: + CI: true + + - name: Upload Playwright report + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + if: failure() + with: + name: playwright-report + path: playwright-report/ + retention-days: 7 + # Finalize Coveralls parallel build coveralls-finish: name: Finish Coveralls @@ -132,7 +167,7 @@ jobs: steps: - name: Coveralls Finished - uses: coverallsapp/github-action@643bc377ffa44ace6394b2b5d0d3950076de9f63 # v2.3.0 + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e # v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} parallel-finished: true diff --git a/.github/workflows/deploy-gh-pages.yml b/.github/workflows/deploy-gh-pages.yml index 63eb70e2..163dd64b 100644 --- a/.github/workflows/deploy-gh-pages.yml +++ b/.github/workflows/deploy-gh-pages.yml @@ -1,8 +1,13 @@ -name: Deploy to GitHub Pages +name: Deploy Documentation to GitHub Pages on: push: branches: [main] + paths: + - 'docs/**' + - 'src/**/*.ts' + - 'src/**/*.tsx' + - '.github/workflows/deploy-gh-pages.yml' workflow_dispatch: permissions: @@ -17,7 +22,7 @@ concurrency: jobs: build: - name: Build Staging Web App + name: Build Documentation runs-on: ubuntu-latest timeout-minutes: 10 @@ -25,35 +30,108 @@ jobs: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Use Node.js - uses: actions/setup-node@v4 - with: - node-version: '20.x' - - name: Setup pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@c5ba7f7862a0f64c1b1a05fbac13e0b8e86ba08c # v4 + # Reads version from packageManager field in package.json + + - name: Use Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6 with: - version: 8 + node-version-file: '.nvmrc' + cache: 'pnpm' - name: Install dependencies - run: pnpm install + run: pnpm install --frozen-lockfile - - name: Build web app - run: npx expo export --platform web + - name: Generate API documentation with TypeDoc + run: npx typedoc --out docs-dist/api src/index.ts --plugin typedoc-plugin-markdown - - name: Inject no-cache headers for staging + - name: Build documentation site run: | - # Add no-cache meta tags to all HTML files for staging environment - find dist -name "*.html" -exec sed -i 's//\n \n \n /' {} \; - echo "Injected no-cache headers into $(find dist -name '*.html' | wc -l) HTML files" + # Create a simple docs site from markdown + mkdir -p docs-dist + + # Copy documentation files + cp -r docs/* docs-dist/ 2>/dev/null || true + cp README.md docs-dist/ 2>/dev/null || true + cp CLAUDE.md docs-dist/ 2>/dev/null || true + cp DECISIONS.md docs-dist/ 2>/dev/null || true + + # Create index.html + cat > docs-dist/index.html << 'HTMLEOF' + + + + + + ThumbCode Documentation + + + + +

ThumbCode Documentation

+

Code with your thumbs. A decentralized multi-agent mobile development platform.

+ +
+

Quick Links

+ +
+ +
+

Documentation

+ +
+ +
+

Brand Guidelines

+ +
+ + + HTMLEOF - name: Setup Pages uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0 - name: Upload artifact - uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1 + uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4 with: - path: 'dist' + path: 'docs-dist' deploy: name: Deploy to GitHub Pages diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..1d9b7831 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22.12.0 diff --git a/app.config.ts b/app.config.ts index b9536512..706f2dc1 100644 --- a/app.config.ts +++ b/app.config.ts @@ -136,7 +136,7 @@ export default ({ config }: ConfigContext): ExpoConfig => { // EAS configuration eas: { - projectId: process.env.EXPO_PROJECT_ID || '', + projectId: process.env.EXPO_PROJECT_ID || '36e52acc-b39a-4bfa-a9dc-4a1053e87032', }, // Public environment variables (accessible at runtime) @@ -144,6 +144,6 @@ export default ({ config }: ConfigContext): ExpoConfig => { githubClientId: process.env.EXPO_PUBLIC_GITHUB_CLIENT_ID || '', }, - owner: process.env.EXPO_OWNER || 'thumbcode', + owner: process.env.EXPO_OWNER || 'jbcom', }; }; diff --git a/app.json b/app.json index 4cc111e2..9f16d81b 100644 --- a/app.json +++ b/app.json @@ -48,17 +48,16 @@ ] ], "experiments": { - "typedRoutes": true, - "baseUrl": "/thumbcode" + "typedRoutes": true }, "extra": { "router": { "origin": false }, "eas": { - "projectId": "${EXPO_PROJECT_ID:-your-project-id}" + "projectId": "36e52acc-b39a-4bfa-a9dc-4a1053e87032" } }, - "owner": "${EXPO_OWNER:-thumbcode}" + "owner": "jbcom" } } diff --git a/docs/memory-bank/DEVELOPMENT-LOG.md b/docs/memory-bank/DEVELOPMENT-LOG.md index 61f35858..eb1acc4f 100644 --- a/docs/memory-bank/DEVELOPMENT-LOG.md +++ b/docs/memory-bank/DEVELOPMENT-LOG.md @@ -275,6 +275,82 @@ All compiled into NativeWind-compatible Tailwind config. --- +## Market Research & Competitive Analysis (Jan 18, 2026) + +### AI Coding Assistant Market 2026 + +**Market Size**: $4.91B (2024) → $30.1B projected (2032) at 27.1% CAGR + +**Key Competitors**: +- GitHub Copilot (68% developer adoption) +- ChatGPT (82% usage for coding) +- Claude (41% developer usage) +- Cursor (leading "agentic IDE" with multi-platform integration) +- Windsurf (Codeium's "world's first agentic IDE") +- Various CLI tools: Claude Code, Gemini CLI + +**2026 Trends**: +1. **Quality > Speed** — 2025 was "year of AI speed"; 2026 focuses on quality/governance +2. **Multi-Platform Integration** — Winning pattern: terminal + IDE + web + desktop +3. **Agent Mode** — Autonomous multi-step workflows (refactoring, bug fixing, modules) +4. **Security Concerns** — 48% of AI-generated code has potential vulnerabilities +5. **Mobile "Vibe Coding"** — Emerging category with natural language prompts + +### ThumbCode's Competitive Advantage + +**CRITICAL INSIGHT**: NO major competitor is mobile-first. + +| Differentiator | ThumbCode | Competition | +|----------------|-----------|-------------| +| **Platform** | Mobile-first | Desktop/web-first | +| **Architecture** | Decentralized BYOK | Cloud-hosted | +| **Privacy** | User owns keys | Vendor manages keys | +| **Cost Model** | $0 infrastructure | Per-seat subscriptions | +| **Agent Model** | Multi-agent orchestration | Single assistant | + +ThumbCode addresses the **top market concerns**: +- Privacy/Security → BYOK model with SecureStore +- Cost → Zero per-user cost +- Mobile accessibility → Only mobile-first solution +- Agent capabilities → Full multi-agent orchestration + +--- + +## 1.0 Roadmap Execution Plan + +### Phase 1: Foundation (Current Sprint) +- [x] EAS Workflows (development, production, preview) +- [x] CI/CD pipeline with GitHub Actions +- [ ] Fix GitHub Pages loading issue (#63) +- [ ] Configure staging deployment (Render.com) +- [ ] Environment configuration (.env validation) + +### Phase 2: Core Services (Next Sprint) +- [ ] Credential management (expo-secure-store) +- [ ] Git service (isomorphic-git integration) +- [ ] Zustand state management stores +- [ ] Error handling and logging infrastructure + +### Phase 3: Agent System (Major Milestone) +- [ ] Agent orchestration engine +- [ ] Specialized agents (Architect, Implementer, Reviewer, Tester) +- [ ] Chat system with streaming +- [ ] MCP integration + +### Phase 4: UI/UX Polish +- [ ] Expand component library (40+ components) +- [ ] Implement all screens from Canva designs +- [ ] Guided onboarding flow +- [ ] Accessibility compliance (WCAG AA) + +### Phase 5: Production Hardening +- [ ] Security audit +- [ ] Performance optimization +- [ ] Analytics and monitoring (privacy-focused) +- [ ] App store submission + +--- + ## Open Questions / Future Decisions 1. **Domain registration** — thumbcode.app, thumbcode.dev not yet purchased diff --git a/package.json b/package.json index 8488030e..ce1c447b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "thumbcode", "version": "0.1.0", + "packageManager": "pnpm@10.11.0", "description": "Code with your thumbs. A decentralized multi-agent mobile development platform.", "main": "expo-router/entry", "scripts": { @@ -37,7 +38,6 @@ "@anthropic-ai/sdk": "^0.32.0", "@react-native-async-storage/async-storage": "^2.0.0", "@react-native-community/netinfo": "^11.4.1", - "react-native-ssl-public-key-pinning": "^1.2.6", "@react-navigation/native": "^7.0.0", "@thumbcode/config": "workspace:*", "@thumbcode/core": "workspace:*", @@ -63,6 +63,7 @@ "expo-secure-store": "~14.0.0", "expo-splash-screen": "~0.29.0", "expo-status-bar": "~2.0.0", + "expo-updates": "^29.0.16", "expo-web-browser": "~14.0.0", "immer": "^10.2.0", "isomorphic-git": "^1.27.0", @@ -76,6 +77,7 @@ "react-native-reanimated": "~3.16.0", "react-native-safe-area-context": "~4.12.0", "react-native-screens": "~4.0.0", + "react-native-ssl-public-key-pinning": "^1.2.6", "react-native-svg": "~15.8.0", "react-native-web": "~0.19.13", "tailwindcss": "^3.4.0", @@ -104,6 +106,8 @@ "jest-expo": "~52.0.6", "react-test-renderer": "18.3.1", "serve": "^14.2.5", + "typedoc": "^0.28.0", + "typedoc-plugin-markdown": "^4.9.0", "typescript": "~5.6.0" }, "pnpm": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c2f0836..742c9ce1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -95,6 +95,9 @@ importers: expo-status-bar: specifier: ~2.0.0 version: 2.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) + expo-updates: + specifier: ^29.0.16 + version: 29.0.16(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) expo-web-browser: specifier: ~14.0.0 version: 14.0.2(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)) @@ -109,7 +112,7 @@ importers: version: 4.17.22 nativewind: specifier: ^4.1.0 - version: 4.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)) + version: 4.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) openai: specifier: ^4.70.0 version: 4.104.0(ws@8.19.0)(zod@3.25.76) @@ -145,7 +148,7 @@ importers: version: 0.19.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tailwindcss: specifier: ^3.4.0 - version: 3.4.19(tsx@4.21.0) + version: 3.4.19(tsx@4.21.0)(yaml@2.8.2) zod: specifier: ^3.23.0 version: 3.25.76 @@ -216,6 +219,12 @@ importers: serve: specifier: ^14.2.5 version: 14.2.5 + typedoc: + specifier: ^0.28.0 + version: 0.28.16(typescript@5.6.3) + typedoc-plugin-markdown: + specifier: ^4.9.0 + version: 4.9.0(typedoc@0.28.16(typescript@5.6.3)) typescript: specifier: ~5.6.0 version: 5.6.3 @@ -350,7 +359,7 @@ importers: version: 4.0.22(ca3003e1f7f8d1ffc6d1fe044df18e11) nativewind: specifier: ^4.1.0 - version: 4.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)) + version: 4.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) react: specifier: '>=18.0.0' version: 18.3.1 @@ -1439,15 +1448,27 @@ packages: '@expo/code-signing-certificates@0.0.5': resolution: {integrity: sha512-BNhXkY1bblxKZpltzAx98G2Egj9g1Q+JRcvR7E99DOj862FTCX+ZPsAUtPTr7aHxwtrL7+fL3r0JSmM9kBm+Bw==} + '@expo/code-signing-certificates@0.0.6': + resolution: {integrity: sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w==} + + '@expo/config-plugins@54.0.4': + resolution: {integrity: sha512-g2yXGICdoOw5i3LkQSDxl2Q5AlQCrG7oniu0pCPPO+UxGb7He4AFqSvPSy8HpRUj55io17hT62FTjYRD+d6j3Q==} + '@expo/config-plugins@9.0.17': resolution: {integrity: sha512-m24F1COquwOm7PBl5wRbkT9P9DviCXe0D7S7nQsolfbhdCWuvMkfXeoWmgjtdhy7sDlOyIgBrAdnB6MfsWKqIg==} '@expo/config-types@52.0.5': resolution: {integrity: sha512-AMDeuDLHXXqd8W+0zSjIt7f37vUd/BP8p43k68NHpyAvQO+z8mbQZm3cNQVAMySeayK2XoPigAFB1JF2NFajaA==} + '@expo/config-types@54.0.10': + resolution: {integrity: sha512-/J16SC2an1LdtCZ67xhSkGXpALYUVUNyZws7v+PVsFZxClYehDSoKLqyRaGkpHlYrCc08bS0RF5E0JV6g50psA==} + '@expo/config@10.0.11': resolution: {integrity: sha512-nociJ4zr/NmbVfMNe9j/+zRlt7wz/siISu7PjdWE4WE+elEGxWWxsGzltdJG0llzrM+khx8qUiFK5aiVcdMBww==} + '@expo/config@12.0.13': + resolution: {integrity: sha512-Cu52arBa4vSaupIWsF0h7F/Cg//N374nYb7HAxV0I4KceKA7x2UXpYaHOL7EEYYvp7tZdThBjvGpVmr8ScIvaQ==} + '@expo/devcert@1.2.1': resolution: {integrity: sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA==} @@ -1488,6 +1509,9 @@ packages: '@expo/plist@0.2.2': resolution: {integrity: sha512-ZZGvTO6vEWq02UAPs3LIdja+HRO18+LRI5QuDl6Hs3Ps7KX7xU6Y6kjahWKY37Rx2YjNpX07dGpBFzzC+vKa2g==} + '@expo/plist@0.4.8': + resolution: {integrity: sha512-pfNtErGGzzRwHP+5+RqswzPDKkZrx+Cli0mzjQaus1ZWFsog5ibL+nVT3NcporW51o8ggnt7x813vtRbPiyOrQ==} + '@expo/prebuild-config@8.2.0': resolution: {integrity: sha512-CxiPpd980s0jyxi7eyN3i/7YKu3XL+8qPjBZUCYtc0+axpGweqIkq2CslyLSKHyqVyH/zlPkbVgWdyiYavFS5Q==} @@ -1518,6 +1542,9 @@ packages: resolution: {integrity: sha512-ReZxZ8pdnoI3tP/dNnJdnmAk7uLT4FjsKDGW7YeDdvdOMz2XCQSmSCM9IWlrXuWtMF9zeSB6WJtEhCQ41gQOfw==} hasBin: true + '@gerrit0/mini-shiki@3.21.0': + resolution: {integrity: sha512-9PrsT5DjZA+w3lur/aOIx3FlDeHdyCEFlv9U+fmsVyjPZh61G5SYURQ/1ebe2U63KbDmI2V8IhIUegWb8hjOyg==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1674,6 +1701,14 @@ packages: cpu: [x64] os: [win32] + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -2002,6 +2037,21 @@ packages: '@segment/loosely-validate-event@2.0.0': resolution: {integrity: sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw==} + '@shikijs/engine-oniguruma@3.21.0': + resolution: {integrity: sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==} + + '@shikijs/langs@3.21.0': + resolution: {integrity: sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==} + + '@shikijs/themes@3.21.0': + resolution: {integrity: sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==} + + '@shikijs/types@3.21.0': + resolution: {integrity: sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -2062,6 +2112,9 @@ packages: '@types/hammerjs@2.0.46': resolution: {integrity: sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} @@ -2118,6 +2171,9 @@ packages: '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -2478,6 +2534,9 @@ packages: arch@2.2.0: resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} + arg@4.1.0: + resolution: {integrity: sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==} + arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} @@ -3586,6 +3645,9 @@ packages: peerDependencies: expo: '*' + expo-eas-client@1.0.8: + resolution: {integrity: sha512-5or11NJhSeDoHHI6zyvQDW2cz/yFyE+1Cz8NTs5NK8JzC7J0JrkUgptWtxyfB6Xs/21YRNifd3qgbBN3hfKVgA==} + expo-file-system@18.0.12: resolution: {integrity: sha512-HAkrd/mb8r+G3lJ9MzmGeuW2B+BxQR1joKfeCyY4deLl1zoZ48FrAWjgZjHK9aHUVhJ0ehzInu/NQtikKytaeg==} peerDependencies: @@ -3614,6 +3676,9 @@ packages: react-native-web: optional: true + expo-json-utils@0.15.0: + resolution: {integrity: sha512-duRT6oGl80IDzH2LD2yEFWNwGIC2WkozsB6HF3cDYNoNNdUvFk6uN3YiwsTsqVM/D0z6LEAQ01/SlYvN+Fw0JQ==} + expo-keep-awake@14.0.3: resolution: {integrity: sha512-6Jh94G6NvTZfuLnm2vwIpKe3GdOiVBuISl7FI8GqN0/9UOg9E0WXXp5cDcfAG8bn80RfgLJS8P7EPUGTZyOvhg==} peerDependencies: @@ -3631,6 +3696,11 @@ packages: peerDependencies: expo: '*' + expo-manifests@1.0.10: + resolution: {integrity: sha512-oxDUnURPcL4ZsOBY6X1DGWGuoZgVAFzp6PISWV7lPP2J0r8u1/ucuChBgpK7u1eLGFp6sDIPwXyEUCkI386XSQ==} + peerDependencies: + expo: '*' + expo-modules-autolinking@2.0.8: resolution: {integrity: sha512-DezgnEYFQYic8hKGhkbztBA3QUmSftjaNDIKNAtS2iGJmzCcNIkatjN2slFDSWjSTNo8gOvPQyMKfyHWFvLpOQ==} hasBin: true @@ -3680,6 +3750,22 @@ packages: react: '*' react-native: '*' + expo-structured-headers@5.0.0: + resolution: {integrity: sha512-RmrBtnSphk5REmZGV+lcdgdpxyzio5rJw8CXviHE6qH5pKQQ83fhMEcigvrkBdsn2Efw2EODp4Yxl1/fqMvOZw==} + + expo-updates-interface@2.0.0: + resolution: {integrity: sha512-pTzAIufEZdVPKql6iMi5ylVSPqV1qbEopz9G6TSECQmnNde2nwq42PxdFBaUEd8IZJ/fdJLQnOT3m6+XJ5s7jg==} + peerDependencies: + expo: '*' + + expo-updates@29.0.16: + resolution: {integrity: sha512-E9/fxRz/Eurtc7hxeI/6ZPyHH3To9Xoccm1kXoICZTRojmuTo+dx0Xv53UHyHn4G5zGMezyaKF2Qtj3AKcT93w==} + hasBin: true + peerDependencies: + expo: '*' + react: '*' + react-native: '*' + expo-web-browser@14.0.2: resolution: {integrity: sha512-Hncv2yojhTpHbP6SGWARBFdl7P6wBHc1O8IKaNsH0a/IEakq887o1eRhLxZ5IwztPQyRDhpqHdgJ+BjWolOnwA==} peerDependencies: @@ -3918,6 +4004,10 @@ packages: resolution: {integrity: sha512-7yetJWqbS9sbn0vIfliPsFgoXMKn/YMF+Wuiog97x+urnSRRRZ7xB+uVkwGKzRgq9CDFfMQnE9ruL5DHv9c6Xg==} engines: {node: '>=6'} + getenv@2.0.0: + resolution: {integrity: sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ==} + engines: {node: '>=6'} + git-raw-commits@4.0.0: resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} engines: {node: '>=16'} @@ -3938,6 +4028,10 @@ packages: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} hasBin: true + glob@13.0.0: + resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} + engines: {node: 20 || >=22} + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -4711,6 +4805,9 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + loader-runner@4.3.1: resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} engines: {node: '>=6.11.5'} @@ -4784,9 +4881,16 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.2.4: + resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -4801,6 +4905,10 @@ packages: makeerror@1.0.12: resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + marky@1.3.0: resolution: {integrity: sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ==} @@ -4819,6 +4927,9 @@ packages: mdn-data@2.0.14: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} @@ -4943,6 +5054,10 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} + minimatch@10.1.1: + resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -5289,6 +5404,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.1: + resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} + engines: {node: 20 || >=22} + path-to-regexp@3.3.0: resolution: {integrity: sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==} @@ -5447,6 +5566,10 @@ packages: pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -6345,6 +6468,19 @@ packages: resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} engines: {node: '>= 0.4'} + typedoc-plugin-markdown@4.9.0: + resolution: {integrity: sha512-9Uu4WR9L7ZBgAl60N/h+jqmPxxvnC9nQAlnnO/OujtG2ubjnKTVUFY1XDhcMY+pCqlX3N2HsQM2QTYZIU9tJuw==} + engines: {node: '>= 18'} + peerDependencies: + typedoc: 0.28.x + + typedoc@0.28.16: + resolution: {integrity: sha512-x4xW77QC3i5DUFMBp0qjukOTnr/sSg+oEs86nB3LjDslvAmwe/PUGDWbe3GrIqt59oTqoXK5GRK9tAa0sYMiog==} + engines: {node: '>= 18', pnpm: '>= 10'} + hasBin: true + peerDependencies: + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x + typescript@5.6.3: resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} engines: {node: '>=14.17'} @@ -6358,6 +6494,9 @@ packages: resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} hasBin: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} @@ -6696,6 +6835,11 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -8041,6 +8185,29 @@ snapshots: node-forge: 1.3.3 nullthrows: 1.1.1 + '@expo/code-signing-certificates@0.0.6': + dependencies: + node-forge: 1.3.3 + + '@expo/config-plugins@54.0.4': + dependencies: + '@expo/config-types': 54.0.10 + '@expo/json-file': 10.0.8 + '@expo/plist': 0.4.8 + '@expo/sdk-runtime-versions': 1.0.0 + chalk: 4.1.2 + debug: 4.4.3 + getenv: 2.0.0 + glob: 13.0.0 + resolve-from: 5.0.0 + semver: 7.7.3 + slash: 3.0.0 + slugify: 1.6.6 + xcode: 3.0.1 + xml2js: 0.6.0 + transitivePeerDependencies: + - supports-color + '@expo/config-plugins@9.0.17': dependencies: '@expo/config-types': 52.0.5 @@ -8062,6 +8229,8 @@ snapshots: '@expo/config-types@52.0.5': {} + '@expo/config-types@54.0.10': {} + '@expo/config@10.0.11': dependencies: '@babel/code-frame': 7.10.4 @@ -8080,6 +8249,24 @@ snapshots: transitivePeerDependencies: - supports-color + '@expo/config@12.0.13': + dependencies: + '@babel/code-frame': 7.10.4 + '@expo/config-plugins': 54.0.4 + '@expo/config-types': 54.0.10 + '@expo/json-file': 10.0.8 + deepmerge: 4.3.1 + getenv: 2.0.0 + glob: 13.0.0 + require-from-string: 2.0.2 + resolve-from: 5.0.0 + resolve-workspace-root: 2.0.1 + semver: 7.7.3 + slugify: 1.6.6 + sucrase: 3.35.1 + transitivePeerDependencies: + - supports-color + '@expo/devcert@1.2.1': dependencies: '@expo/sudo-prompt': 9.3.2 @@ -8188,6 +8375,12 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 14.0.0 + '@expo/plist@0.4.8': + dependencies: + '@xmldom/xmldom': 0.8.11 + base64-js: 1.5.1 + xmlbuilder: 15.1.1 + '@expo/prebuild-config@8.2.0': dependencies: '@expo/config': 10.0.11 @@ -8246,6 +8439,14 @@ snapshots: find-up: 5.0.0 js-yaml: 4.1.1 + '@gerrit0/mini-shiki@3.21.0': + dependencies: + '@shikijs/engine-oniguruma': 3.21.0 + '@shikijs/langs': 3.21.0 + '@shikijs/themes': 3.21.0 + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.7': @@ -8355,6 +8556,12 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -9002,6 +9209,26 @@ snapshots: component-type: 1.2.2 join-component: 1.1.0 + '@shikijs/engine-oniguruma@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + + '@shikijs/themes@3.21.0': + dependencies: + '@shikijs/types': 3.21.0 + + '@shikijs/types@3.21.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + '@sinclair/typebox@0.27.8': {} '@sinonjs/commons@3.0.1': @@ -9075,6 +9302,10 @@ snapshots: '@types/hammerjs@2.0.46': {} + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/istanbul-lib-coverage@2.0.6': {} '@types/istanbul-lib-report@3.0.3': @@ -9138,6 +9369,8 @@ snapshots: '@types/tough-cookie@4.0.5': {} + '@types/unist@3.0.3': {} + '@types/yargs-parser@21.0.3': {} '@types/yargs@17.0.35': @@ -9515,6 +9748,8 @@ snapshots: arch@2.2.0: {} + arg@4.1.0: {} + arg@5.0.2: {} argparse@1.0.10: @@ -10879,6 +11114,8 @@ snapshots: expo: 52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) ua-parser-js: 0.7.41 + expo-eas-client@1.0.8: {} + expo-file-system@18.0.12(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)): dependencies: expo: 52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) @@ -10903,6 +11140,8 @@ snapshots: optionalDependencies: react-native-web: 0.19.13(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + expo-json-utils@0.15.0: {} + expo-keep-awake@14.0.3(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react@18.3.1): dependencies: expo: 52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) @@ -10923,6 +11162,14 @@ snapshots: expo: 52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) invariant: 2.2.4 + expo-manifests@1.0.10(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)): + dependencies: + '@expo/config': 12.0.13 + expo: 52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) + expo-json-utils: 0.15.0 + transitivePeerDependencies: + - supports-color + expo-modules-autolinking@2.0.8: dependencies: '@expo/spawn-async': 1.7.2 @@ -10998,6 +11245,34 @@ snapshots: react: 18.3.1 react-native: 0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1) + expo-structured-headers@5.0.0: {} + + expo-updates-interface@2.0.0(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)): + dependencies: + expo: 52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) + + expo-updates@29.0.16(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1): + dependencies: + '@expo/code-signing-certificates': 0.0.6 + '@expo/plist': 0.4.8 + '@expo/spawn-async': 1.7.2 + arg: 4.1.0 + chalk: 4.1.2 + debug: 4.4.3 + expo: 52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) + expo-eas-client: 1.0.8 + expo-manifests: 1.0.10(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)) + expo-structured-headers: 5.0.0 + expo-updates-interface: 2.0.0(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)) + getenv: 2.0.0 + glob: 13.0.0 + ignore: 5.3.2 + react: 18.3.1 + react-native: 0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1) + resolve-from: 5.0.0 + transitivePeerDependencies: + - supports-color + expo-web-browser@14.0.2(expo@52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)): dependencies: expo: 52.0.48(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@expo/metro-runtime@4.0.1(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1)))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) @@ -11278,6 +11553,8 @@ snapshots: getenv@1.0.0: {} + getenv@2.0.0: {} + git-raw-commits@4.0.0: dependencies: dargs: 8.1.0 @@ -11303,6 +11580,12 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@13.0.0: + dependencies: + minimatch: 10.1.1 + minipass: 7.1.2 + path-scurry: 2.0.1 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -12318,6 +12601,10 @@ snapshots: lines-and-columns@1.2.4: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + loader-runner@4.3.1: {} locate-path@3.0.0: @@ -12375,10 +12662,14 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@11.2.4: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 + lunr@2.3.9: {} + make-dir@2.1.0: dependencies: pify: 4.0.1 @@ -12394,6 +12685,15 @@ snapshots: dependencies: tmpl: 1.0.5 + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + marky@1.3.0: {} math-intrinsics@1.1.0: {} @@ -12410,6 +12710,8 @@ snapshots: mdn-data@2.0.14: {} + mdurl@2.0.0: {} + memoize-one@5.2.1: {} memoize-one@6.0.0: {} @@ -12625,6 +12927,10 @@ snapshots: min-indent@1.0.1: {} + minimatch@10.1.1: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -12681,12 +12987,12 @@ snapshots: napi-postinstall@0.3.4: {} - nativewind@4.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)): + nativewind@4.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)): dependencies: comment-json: 4.5.1 debug: 4.4.3 - react-native-css-interop: 0.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)) - tailwindcss: 3.4.19(tsx@4.21.0) + react-native-css-interop: 0.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) + tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - react - react-native @@ -12960,6 +13266,11 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.1: + dependencies: + lru-cache: 11.2.4 + minipass: 7.1.2 + path-to-regexp@3.3.0: {} path-type@4.0.0: {} @@ -13016,13 +13327,14 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.5.6 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.6 tsx: 4.21.0 + yaml: 2.8.2 postcss-nested@6.2.0(postcss@8.5.6): dependencies: @@ -13092,6 +13404,8 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 + punycode.js@2.3.1: {} + punycode@2.3.1: {} pure-rand@6.1.0: {} @@ -13164,7 +13478,7 @@ snapshots: react-is@19.2.3: {} - react-native-css-interop@0.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)): + react-native-css-interop@0.2.1(react-native-reanimated@3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native-svg@15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1))(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@babel/helper-module-imports': 7.28.6 '@babel/traverse': 7.28.6 @@ -13175,7 +13489,7 @@ snapshots: react-native: 0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1) react-native-reanimated: 3.16.7(@babel/core@7.28.6)(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) semver: 7.7.3 - tailwindcss: 3.4.19(tsx@4.21.0) + tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: react-native-safe-area-context: 4.12.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) react-native-svg: 15.8.0(react-native@0.76.0(@babel/core@7.28.6)(@babel/preset-env@7.28.6(@babel/core@7.28.6))(@types/react@18.3.27)(react@18.3.1))(react@18.3.1) @@ -13960,7 +14274,7 @@ snapshots: symbol-tree@3.2.4: {} - tailwindcss@3.4.19(tsx@4.21.0): + tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -13979,7 +14293,7 @@ snapshots: postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) postcss-js: 4.1.0(postcss@8.5.6) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 resolve: 1.22.11 @@ -14178,12 +14492,27 @@ snapshots: possible-typed-array-names: 1.1.0 reflect.getprototypeof: 1.0.10 + typedoc-plugin-markdown@4.9.0(typedoc@0.28.16(typescript@5.6.3)): + dependencies: + typedoc: 0.28.16(typescript@5.6.3) + + typedoc@0.28.16(typescript@5.6.3): + dependencies: + '@gerrit0/mini-shiki': 3.21.0 + lunr: 2.3.9 + markdown-it: 14.1.0 + minimatch: 9.0.5 + typescript: 5.6.3 + yaml: 2.8.2 + typescript@5.6.3: {} ua-parser-js@0.7.41: {} ua-parser-js@1.0.41: {} + uc.micro@2.1.0: {} + uglify-js@3.19.3: optional: true @@ -14522,6 +14851,8 @@ snapshots: yallist@5.0.0: {} + yaml@2.8.2: {} + yargs-parser@21.1.1: {} yargs@17.7.2: diff --git a/render.yaml b/render.yaml new file mode 100644 index 00000000..0af11634 --- /dev/null +++ b/render.yaml @@ -0,0 +1,49 @@ +# Render Blueprint for ThumbCode Staging +# https://render.com/docs/blueprint-spec + +services: + - type: web + name: thumbcode-staging + runtime: static + buildCommand: corepack enable && pnpm install --frozen-lockfile && npx expo export --platform web + staticPublishPath: ./dist + pullRequestPreviewsEnabled: true + headers: + # Security headers + - path: /* + name: X-Frame-Options + value: DENY + - path: /* + name: X-Content-Type-Options + value: nosniff + - path: /* + name: Referrer-Policy + value: strict-origin-when-cross-origin + - path: /* + name: Strict-Transport-Security + value: max-age=31536000; includeSubDomains + - path: /* + name: Permissions-Policy + value: camera=(), microphone=(), geolocation=() + # Cache static assets aggressively (hashed filenames) + # NOTE: Specific paths must come BEFORE /* to avoid nondeterministic matching + - path: /assets/* + name: Cache-Control + value: public, max-age=31536000, immutable + - path: /_expo/* + name: Cache-Control + value: public, max-age=31536000, immutable + # Staging: no-cache for HTML to always get fresh builds + - path: /* + name: Cache-Control + value: no-cache, no-store, must-revalidate + routes: + # SPA fallback - all routes serve index.html + - type: rewrite + source: /* + destination: /index.html + envVars: + - key: NODE_VERSION + value: 22 + - key: PNPM_VERSION + value: 10